Skip to content

Commit e4f226a

Browse files
committed
Merge #10190: [tests] mining functional tests (including regression test for submitblock)
11ba8e9 [tests] rename getblocktemplate_proposals.py to mining.py (John Newbery) b29dd41 [tests] add test for submit block (John Newbery) 9bf0d80 [tests] run successful test in getblocktemplate first (John Newbery) 82dc597 [tests] don't build blocks manually in getblocktemplate test (John Newbery) f82c709 [tests] clarify assertions in getblocktemplate test (John Newbery) 66c570a [tests] Don't build the coinbase manually in getblocktemplate test (John Newbery) 38b38cd [tests] getblocktemplate_proposals.py: add logging (John Newbery) 0a3a5ff [tests] Fix flake8 warnings in getblocktemplate tests (John Newbery) 32cffe6 [tests] Fix import order in getblocktemplate test (John Newbery) Tree-SHA512: a51a57314fa1c4c4b8a7896492ec6e677b6bed12387060def34a62e9dfbee7961f71bb5553fbd70028be61ae32eccf13fd255fa9651f908e9a5e64c28f43f00e
2 parents 104f5f2 + 11ba8e9 commit e4f226a

File tree

3 files changed

+125
-158
lines changed

3 files changed

+125
-158
lines changed

test/functional/getblocktemplate_proposals.py

Lines changed: 0 additions & 157 deletions
This file was deleted.

test/functional/mining.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2014-2016 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
"""Test mining RPCs
6+
7+
- getblocktemplate proposal mode
8+
- submitblock"""
9+
10+
from binascii import b2a_hex
11+
import copy
12+
13+
from test_framework.blocktools import create_coinbase
14+
from test_framework.test_framework import BitcoinTestFramework
15+
from test_framework.mininode import CBlock
16+
from test_framework.util import *
17+
18+
def b2x(b):
19+
return b2a_hex(b).decode('ascii')
20+
21+
def assert_template(node, block, expect, rehash=True):
22+
if rehash:
23+
block.hashMerkleRoot = block.calc_merkle_root()
24+
rsp = node.getblocktemplate({'data': b2x(block.serialize()), 'mode': 'proposal'})
25+
assert_equal(rsp, expect)
26+
27+
class MiningTest(BitcoinTestFramework):
28+
29+
def __init__(self):
30+
super().__init__()
31+
self.num_nodes = 2
32+
self.setup_clean_chain = False
33+
34+
def run_test(self):
35+
node = self.nodes[0]
36+
# Mine a block to leave initial block download
37+
node.generate(1)
38+
tmpl = node.getblocktemplate()
39+
self.log.info("getblocktemplate: Test capability advertised")
40+
assert 'proposal' in tmpl['capabilities']
41+
assert 'coinbasetxn' not in tmpl
42+
43+
coinbase_tx = create_coinbase(height=int(tmpl["height"]) + 1)
44+
# sequence numbers must not be max for nLockTime to have effect
45+
coinbase_tx.vin[0].nSequence = 2 ** 32 - 2
46+
coinbase_tx.rehash()
47+
48+
block = CBlock()
49+
block.nVersion = tmpl["version"]
50+
block.hashPrevBlock = int(tmpl["previousblockhash"], 16)
51+
block.nTime = tmpl["curtime"]
52+
block.nBits = int(tmpl["bits"], 16)
53+
block.nNonce = 0
54+
block.vtx = [coinbase_tx]
55+
56+
self.log.info("getblocktemplate: Test valid block")
57+
assert_template(node, block, None)
58+
59+
self.log.info("submitblock: Test block decode failure")
60+
assert_raises_jsonrpc(-22, "Block decode failed", node.submitblock, b2x(block.serialize()[:-15]))
61+
62+
self.log.info("getblocktemplate: Test bad input hash for coinbase transaction")
63+
bad_block = copy.deepcopy(block)
64+
bad_block.vtx[0].vin[0].prevout.hash += 1
65+
bad_block.vtx[0].rehash()
66+
assert_template(node, bad_block, 'bad-cb-missing')
67+
68+
self.log.info("submitblock: Test invalid coinbase transaction")
69+
assert_raises_jsonrpc(-22, "Block does not start with a coinbase", node.submitblock, b2x(bad_block.serialize()))
70+
71+
self.log.info("getblocktemplate: Test truncated final transaction")
72+
assert_raises_jsonrpc(-22, "Block decode failed", node.getblocktemplate, {'data': b2x(block.serialize()[:-1]), 'mode': 'proposal'})
73+
74+
self.log.info("getblocktemplate: Test duplicate transaction")
75+
bad_block = copy.deepcopy(block)
76+
bad_block.vtx.append(bad_block.vtx[0])
77+
assert_template(node, bad_block, 'bad-txns-duplicate')
78+
79+
self.log.info("getblocktemplate: Test invalid transaction")
80+
bad_block = copy.deepcopy(block)
81+
bad_tx = copy.deepcopy(bad_block.vtx[0])
82+
bad_tx.vin[0].prevout.hash = 255
83+
bad_tx.rehash()
84+
bad_block.vtx.append(bad_tx)
85+
assert_template(node, bad_block, 'bad-txns-inputs-missingorspent')
86+
87+
self.log.info("getblocktemplate: Test nonfinal transaction")
88+
bad_block = copy.deepcopy(block)
89+
bad_block.vtx[0].nLockTime = 2 ** 32 - 1
90+
bad_block.vtx[0].rehash()
91+
assert_template(node, bad_block, 'bad-txns-nonfinal')
92+
93+
self.log.info("getblocktemplate: Test bad tx count")
94+
# The tx count is immediately after the block header
95+
TX_COUNT_OFFSET = 80
96+
bad_block_sn = bytearray(block.serialize())
97+
assert_equal(bad_block_sn[TX_COUNT_OFFSET], 1)
98+
bad_block_sn[TX_COUNT_OFFSET] += 1
99+
assert_raises_jsonrpc(-22, "Block decode failed", node.getblocktemplate, {'data': b2x(bad_block_sn), 'mode': 'proposal'})
100+
101+
self.log.info("getblocktemplate: Test bad bits")
102+
bad_block = copy.deepcopy(block)
103+
bad_block.nBits = 469762303 # impossible in the real world
104+
assert_template(node, bad_block, 'bad-diffbits')
105+
106+
self.log.info("getblocktemplate: Test bad merkle root")
107+
bad_block = copy.deepcopy(block)
108+
bad_block.hashMerkleRoot += 1
109+
assert_template(node, bad_block, 'bad-txnmrklroot', False)
110+
111+
self.log.info("getblocktemplate: Test bad timestamps")
112+
bad_block = copy.deepcopy(block)
113+
bad_block.nTime = 2 ** 31 - 1
114+
assert_template(node, bad_block, 'time-too-new')
115+
bad_block.nTime = 0
116+
assert_template(node, bad_block, 'time-too-old')
117+
118+
self.log.info("getblocktemplate: Test not best block")
119+
bad_block = copy.deepcopy(block)
120+
bad_block.hashPrevBlock = 123
121+
assert_template(node, bad_block, 'inconclusive-not-best-prevblk')
122+
123+
if __name__ == '__main__':
124+
MiningTest().main()

test/functional/test_runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
'signmessages.py',
109109
'nulldummy.py',
110110
'import-rescan.py',
111+
'mining.py',
111112
'bumpfee.py',
112113
'rpcnamedargs.py',
113114
'listsinceblock.py',
@@ -141,7 +142,6 @@
141142
'bipdersig-p2p.py',
142143
'bipdersig.py',
143144
'example_test.py',
144-
'getblocktemplate_proposals.py',
145145
'txn_doublespend.py',
146146
'txn_clone.py --mineblock',
147147
'forknotify.py',

0 commit comments

Comments
 (0)