dogecoin/qa/rpc-tests/test_framework/scrypt_auxpow.py
Patrick Lodder 6cee9dcd28 Bring back "target" property of getauxblock
Marked as deprecated but still used in many pool implementations,
as well as rpc-tests. This restores AuxPoW compatibility to 100%.
2015-10-13 16:56:14 +02:00

106 lines
3 KiB
Python

#!/usr/bin/env python
# Copyright (c) 2014 Daniel Kraft
# Copyright (c) 2015 The Dogecoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# General code for scrypt auxpow testing. This includes routines to
# solve an auxpow header and to generate auxpow blocks with scrypt.
# extends and modifies auxpow module by Daniel Kraft.
# This module requires a built and installed version of the ltc_scrypt
# package, which can be downloaded from:
# https://pypi.python.org/packages/source/l/ltc_scrypt/ltc_scrypt-1.0.tar.gz
import binascii
import hashlib
import auxpow
import ltc_scrypt
def computeAuxpowWithChainId (block, target, chainid, ok):
"""
Build an auxpow object (serialised as hex string) that solves the
block, for a given chain id.
"""
# Start by building the merge-mining coinbase. The merkle tree
# consists only of the block hash as root.
coinbase = "fabe" + binascii.hexlify ("m" * 2)
coinbase += block
coinbase += "01000000" + ("00" * 4)
# Construct "vector" of transaction inputs.
vin = "01"
vin += ("00" * 32) + ("ff" * 4)
vin += ("%02x" % (len (coinbase) / 2)) + coinbase
vin += ("ff" * 4)
# Build up the full coinbase transaction. It consists only
# of the input and has no outputs.
tx = "01000000" + vin + "00" + ("00" * 4)
txHash = auxpow.doubleHashHex (tx)
# Construct the parent block header. It need not be valid, just good
# enough for auxpow purposes.
header = "0100" + chainid + "00"
header += "00" * 32
header += auxpow.reverseHex (txHash)
header += "00" * 4
header += "00" * 4
header += "00" * 4
# Mine the block.
(header, blockhash) = mineScryptBlock (header, target, ok)
# Build the MerkleTx part of the auxpow.
output = tx
output += blockhash
output += "00"
output += "00" * 4
# Extend to full auxpow.
output += "00"
output += "00" * 4
output += header
return output
# for now, just offer hashes to rpc until it matches the work we need
def mineScryptAux (node, chainid, ok):
"""
Mine an auxpow block on the given RPC connection.
"""
auxblock = node.getauxblock ()
target = auxpow.reverseHex (auxblock['target'])
apow = computeAuxpowWithChainId (auxblock['hash'], target, chainid, ok)
res = node.getauxblock (auxblock['hash'], apow)
def mineScryptBlock (header, target, ok):
"""
Given a block header, update the nonce until it is ok (or not)
for the given target.
"""
data = bytearray (binascii.unhexlify (header))
while True:
assert data[79] < 255
data[79] += 1
hexData = binascii.hexlify (data)
scrypt = getScryptPoW(hexData)
if (ok and scrypt < target) or ((not ok) and scrypt > target):
break
blockhash = auxpow.doubleHashHex (hexData)
return (hexData, blockhash)
def getScryptPoW(hexData):
"""
Actual scrypt pow calculation
"""
data = binascii.unhexlify(hexData)
return auxpow.reverseHex(binascii.hexlify(ltc_scrypt.getPoWHash(data)))