10
10
3) Invalid block with bad coinbase value should be rejected and not
11
11
re-requested.
12
12
"""
13
-
14
- from test_framework .test_framework import ComparisonTestFramework
15
- from test_framework .util import *
16
- from test_framework .comptool import TestManager , TestInstance , RejectResult
17
- from test_framework .blocktools import *
18
- from test_framework .mininode import network_thread_start
19
13
import copy
20
- import time
21
14
22
- # Use the ComparisonTestFramework with 1 node: only use --testbinary.
23
- class InvalidBlockRequestTest (ComparisonTestFramework ):
15
+ from test_framework .blocktools import create_block , create_coinbase , create_transaction
16
+ from test_framework .messages import COIN
17
+ from test_framework .mininode import network_thread_start , P2PDataStore
18
+ from test_framework .test_framework import BitcoinTestFramework
19
+ from test_framework .util import assert_equal
24
20
25
- ''' Can either run this test as 1 node with expected answers, or two and compare them.
26
- Change the "outcome" variable from each TestInstance object to only do the comparison. '''
21
+ class InvalidBlockRequestTest (BitcoinTestFramework ):
27
22
def set_test_params (self ):
28
23
self .num_nodes = 1
29
24
self .setup_clean_chain = True
25
+ self .extra_args = [["-whitelist=127.0.0.1" ]]
30
26
31
27
def run_test (self ):
32
- test = TestManager ( self , self . options . tmpdir )
33
- test . add_all_connections ( self .nodes )
34
- self . tip = None
35
- self . block_time = None
28
+ # Add p2p connection to node0
29
+ node = self .nodes [ 0 ] # convenience reference to the node
30
+ node . add_p2p_connection ( P2PDataStore ())
31
+
36
32
network_thread_start ()
37
- test .run ()
33
+ node .p2p .wait_for_verack ()
34
+
35
+ best_block = node .getblock (node .getbestblockhash ())
36
+ tip = int (node .getbestblockhash (), 16 )
37
+ height = best_block ["height" ] + 1
38
+ block_time = best_block ["time" ] + 1
38
39
39
- def get_tests (self ):
40
- if self .tip is None :
41
- self .tip = int ("0x" + self .nodes [0 ].getbestblockhash (), 0 )
42
- self .block_time = int (time .time ())+ 1
40
+ self .log .info ("Create a new block with an anyone-can-spend coinbase" )
43
41
44
- '''
45
- Create a new block with an anyone-can-spend coinbase
46
- '''
47
42
height = 1
48
- block = create_block (self .tip , create_coinbase (height ), self .block_time )
49
- self .block_time += 1
43
+ block = create_block (tip , create_coinbase (height ), block_time )
50
44
block .solve ()
51
45
# Save the coinbase for later
52
- self .block1 = block
53
- self .tip = block .sha256
54
- height += 1
55
- yield TestInstance ([[block , True ]])
56
-
57
- '''
58
- Now we need that block to mature so we can spend the coinbase.
59
- '''
60
- test = TestInstance (sync_every_block = False )
61
- for i in range (100 ):
62
- block = create_block (self .tip , create_coinbase (height ), self .block_time )
63
- block .solve ()
64
- self .tip = block .sha256
65
- self .block_time += 1
66
- test .blocks_and_transactions .append ([block , True ])
67
- height += 1
68
- yield test
69
-
70
- '''
71
- Now we use merkle-root malleability to generate an invalid block with
72
- same blockheader.
73
- Manufacture a block with 3 transactions (coinbase, spend of prior
74
- coinbase, spend of that spend). Duplicate the 3rd transaction to
75
- leave merkle root and blockheader unchanged but invalidate the block.
76
- '''
77
- block2 = create_block (self .tip , create_coinbase (height ), self .block_time )
78
- self .block_time += 1
46
+ block1 = block
47
+ tip = block .sha256
48
+ node .p2p .send_blocks_and_test ([block1 ], node , True )
49
+
50
+ self .log .info ("Mature the block." )
51
+ node .generate (100 )
52
+
53
+ best_block = node .getblock (node .getbestblockhash ())
54
+ tip = int (node .getbestblockhash (), 16 )
55
+ height = best_block ["height" ] + 1
56
+ block_time = best_block ["time" ] + 1
57
+
58
+ # Use merkle-root malleability to generate an invalid block with
59
+ # same blockheader.
60
+ # Manufacture a block with 3 transactions (coinbase, spend of prior
61
+ # coinbase, spend of that spend). Duplicate the 3rd transaction to
62
+ # leave merkle root and blockheader unchanged but invalidate the block.
63
+ self .log .info ("Test merkle root malleability." )
64
+
65
+ block2 = create_block (tip , create_coinbase (height ), block_time )
66
+ block_time += 1
79
67
80
68
# b'0x51' is OP_TRUE
81
- tx1 = create_transaction (self . block1 .vtx [0 ], 0 , b'\x51 ' , 50 * COIN )
69
+ tx1 = create_transaction (block1 .vtx [0 ], 0 , b'\x51 ' , 50 * COIN )
82
70
tx2 = create_transaction (tx1 , 0 , b'\x51 ' , 50 * COIN )
83
71
84
72
block2 .vtx .extend ([tx1 , tx2 ])
@@ -94,24 +82,20 @@ def get_tests(self):
94
82
assert_equal (orig_hash , block2 .rehash ())
95
83
assert (block2_orig .vtx != block2 .vtx )
96
84
97
- self .tip = block2 .sha256
98
- yield TestInstance ([[block2 , RejectResult (16 , b'bad-txns-duplicate' )], [block2_orig , True ]])
99
- height += 1
100
-
101
- '''
102
- Make sure that a totally screwed up block is not valid.
103
- '''
104
- block3 = create_block (self .tip , create_coinbase (height ), self .block_time )
105
- self .block_time += 1
106
- block3 .vtx [0 ].vout [0 ].nValue = 100 * COIN # Too high!
107
- block3 .vtx [0 ].sha256 = None
85
+ node .p2p .send_blocks_and_test ([block2 ], node , False , False , 16 , b'bad-txns-duplicate' )
86
+
87
+ self .log .info ("Test very broken block." )
88
+
89
+ block3 = create_block (tip , create_coinbase (height ), block_time )
90
+ block_time += 1
91
+ block3 .vtx [0 ].vout [0 ].nValue = 100 * COIN # Too high!
92
+ block3 .vtx [0 ].sha256 = None
108
93
block3 .vtx [0 ].calc_sha256 ()
109
94
block3 .hashMerkleRoot = block3 .calc_merkle_root ()
110
95
block3 .rehash ()
111
96
block3 .solve ()
112
97
113
- yield TestInstance ([[block3 , RejectResult (16 , b'bad-cb-amount' )]])
114
-
98
+ node .p2p .send_blocks_and_test ([block3 ], node , False , False , 16 , b'bad-cb-amount' )
115
99
116
100
if __name__ == '__main__' :
117
101
InvalidBlockRequestTest ().main ()
0 commit comments