diff options
| author | Ross Nicoll <[email protected]> | 2018-01-20 17:56:53 +0000 |
|---|---|---|
| committer | Ross Nicoll <[email protected]> | 2018-09-19 22:11:47 +0100 |
| commit | b6b5ee7502bf646bcd97a9f8fe1b0b8d78e3c9ae (patch) | |
| tree | 0d36b3a80575ee685b4760a3cd1e4fa6f7223e4a /qa/rpc-tests/test_framework/scrypt_auxpow.py | |
| parent | Replace HMAC_SHA256 with Bitcoin's version (#1438) (diff) | |
| download | discoin-b6b5ee7502bf646bcd97a9f8fe1b0b8d78e3c9ae.tar.xz discoin-b6b5ee7502bf646bcd97a9f8fe1b0b8d78e3c9ae.zip | |
Update RPC tests for Dogecoin (#1431)
* Make most of the RPC tests pass
* Add AUXPoW rpc tests
- Tests the auxpow rpc interface `getauxblock`
- Tests consensus constraints for auxpow:
- Minimum block height
- Valid scrypt proof of work
- Foreign chain ID
Diffstat (limited to 'qa/rpc-tests/test_framework/scrypt_auxpow.py')
| -rw-r--r-- | qa/rpc-tests/test_framework/scrypt_auxpow.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/qa/rpc-tests/test_framework/scrypt_auxpow.py b/qa/rpc-tests/test_framework/scrypt_auxpow.py new file mode 100644 index 000000000..1e95a5820 --- /dev/null +++ b/qa/rpc-tests/test_framework/scrypt_auxpow.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# Copyright (c) 2014 Daniel Kraft +# Copyright (c) 2015-2018 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 + +from .auxpow import * +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" + (b"m" * 2).hex() + coinbase += block + coinbase += "01000000" + ("00" * 4) + + # Construct "vector" of transaction inputs. + vin = "01" + vin += ("00" * 32) + ("ff" * 4) + vin += ("%02x" % int(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 = 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 += 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 = reverseHex (auxblock['_target']) + + apow = computeAuxpowWithChainId (auxblock['hash'], target, chainid, ok) + res = node.getauxblock (auxblock['hash'], apow) + return res + +def mineScryptBlock (header, target, ok): + """ + Given a block header, update the nonce until it is ok (or not) + for the given target. + """ + + data = bytearray (bytes.fromhex(header)) + while True: + assert data[79] < 255 + data[79] += 1 + hexData = data.hex() + + scrypt = getScryptPoW(hexData) + if (ok and scrypt < target) or ((not ok) and scrypt > target): + break + + blockhash = doubleHashHex (hexData) + return (hexData, blockhash) + +def getScryptPoW(hexData): + """ + Actual scrypt pow calculation + """ + + data = bytes.fromhex(hexData) + return reverseHex(ltc_scrypt.getPoWHash(data).hex()) |