Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_mining_basic.py
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/usr/bin/env python3 | |||||
# Copyright (c) 2020 The Bitcoin developers | |||||
# Distributed under the MIT software license, see the accompanying | |||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
""" | |||||
Tests for Bitcoin ABC mining RPCs | |||||
""" | |||||
from test_framework.blocktools import ( | |||||
create_coinbase, | |||||
TIME_GENESIS_BLOCK, | |||||
) | |||||
from test_framework.messages import ( | |||||
CBlock, | |||||
) | |||||
from test_framework.test_framework import BitcoinTestFramework | |||||
from test_framework.util import ( | |||||
assert_equal, | |||||
assert_raises_rpc_error, | |||||
connect_nodes, | |||||
) | |||||
class AbcMiningBasicTest(BitcoinTestFramework): | |||||
def set_test_params(self): | |||||
self.num_nodes = 2 | |||||
self.setup_clean_chain = True | |||||
def mine_chain(self): | |||||
self.log.info('Create some old blocks') | |||||
node = self.nodes[0] | |||||
address = node.get_deterministic_priv_key().address | |||||
for t in range(TIME_GENESIS_BLOCK, | |||||
TIME_GENESIS_BLOCK + 200 * 600, 600): | |||||
node.setmocktime(t) | |||||
node.generatetoaddress(1, address) | |||||
mining_info = node.getmininginfo() | |||||
assert_equal(mining_info['blocks'], 200) | |||||
assert_equal(mining_info['currentblocktx'], 0) | |||||
self.restart_node(0) | |||||
connect_nodes(self.nodes[0], self.nodes[1]) | |||||
def run_test(self): | |||||
self.mine_chain() | |||||
node = self.nodes[0] | |||||
# Mine a block to leave initial block download | |||||
node.generatetoaddress(1, node.get_deterministic_priv_key().address) | |||||
# Get a block template and solve a block from it | |||||
blockTemplate = node.getblocktemplate() | |||||
next_height = int(blockTemplate["height"]) | |||||
coinbase_tx = create_coinbase(height=next_height) | |||||
coinbase_tx.rehash() | |||||
block = CBlock() | |||||
block.nVersion = blockTemplate["version"] | |||||
block.hashPrevBlock = int(blockTemplate["previousblockhash"], 16) | |||||
block.nTime = blockTemplate["curtime"] | |||||
block.nBits = int(blockTemplate["bits"], 16) | |||||
block.nNonce = 0 | |||||
block.vtx = [coinbase_tx] | |||||
block.hashMerkleRoot = block.calc_merkle_root() | |||||
block.solve() | |||||
def submitblocksolution(coinbase, nonce, templateId=0): | |||||
return node.submitblocksolution({ | |||||
"template": { | |||||
"template_id": templateId, | |||||
}, | |||||
"header": { | |||||
"coinbase": coinbase, | |||||
"nonce": nonce, | |||||
} | |||||
}) | |||||
# Submit some invalid solutions | |||||
assert_raises_rpc_error(-8, "Block solution has invalid template object", | |||||
lambda: node.submitblocksolution({})) | |||||
assert_raises_rpc_error(-8, "Block solution has invalid header object", | |||||
lambda: node.submitblocksolution({ | |||||
"template": { | |||||
"template_id": 0, | |||||
}, | |||||
})) | |||||
assert_raises_rpc_error(-8, "Template IDs other that '0' are not yet supported", | |||||
lambda: submitblocksolution(coinbase_tx.serialize().hex(), block.nNonce, templateId=1)) | |||||
assert_raises_rpc_error(-8, "Template ID is expected to be a number", | |||||
lambda: submitblocksolution(coinbase_tx.serialize().hex(), block.nNonce, templateId="invalid")) | |||||
assert_raises_rpc_error(-8, "Block solution header expects coinbase to be a hex string", | |||||
lambda: submitblocksolution(0xdeadbeef, block.nNonce)) | |||||
assert_raises_rpc_error(-22, "Coinbase decode failed", | |||||
lambda: submitblocksolution("invalid coinbase", block.nNonce)) | |||||
assert_raises_rpc_error(-8, "Nonce is expected to be a number", | |||||
lambda: submitblocksolution(coinbase_tx.serialize().hex(), "invalid nonce")) | |||||
# Valid block solution | |||||
submitblocksolution(coinbase_tx.serialize().hex(), block.nNonce) | |||||
def chain_tip(blockHash, *, height, status='headers-only', branchlen=1): | |||||
return {'hash': blockHash, 'height': height, | |||||
'branchlen': branchlen, 'status': status} | |||||
assert chain_tip(block.hash, height=202) in node.getchaintips() | |||||
if __name__ == '__main__': | |||||
AbcMiningBasicTest().main() |