28
28
class RejectLowDifficultyHeadersTest (BitcoinTestFramework ):
29
29
def set_test_params (self ):
30
30
self .setup_clean_chain = True
31
- self .num_nodes = 3
31
+ self .num_nodes = 4
32
32
# Node0 has no required chainwork; node1 requires 15 blocks on top of the genesis block; node2 requires 2047
33
- self .extra_args = [["-minimumchainwork=0x0" , "-checkblockindex=0" ], ["-minimumchainwork=0x1f" , "-checkblockindex=0" ], ["-minimumchainwork=0x1000" , "-checkblockindex=0" ]]
33
+ self .
extra_args = [[
"-minimumchainwork=0x0" ,
"-checkblockindex=0" ], [
"-minimumchainwork=0x1f" ,
"-checkblockindex=0" ], [
"-minimumchainwork=0x1000" ,
"-checkblockindex=0" ]
, [ "-minimumchainwork=0x1000" , "-checkblockindex=0" , "[email protected] " ] ]
34
34
35
35
def setup_network (self ):
36
36
self .setup_nodes ()
@@ -40,17 +40,34 @@ def setup_network(self):
40
40
def disconnect_all (self ):
41
41
self .disconnect_nodes (0 , 1 )
42
42
self .disconnect_nodes (0 , 2 )
43
+ self .disconnect_nodes (0 , 3 )
43
44
44
45
def reconnect_all (self ):
45
46
self .connect_nodes (0 , 1 )
46
47
self .connect_nodes (0 , 2 )
48
+ self .connect_nodes (0 , 3 )
47
49
48
50
def test_chains_sync_when_long_enough (self ):
49
51
self .log .info ("Generate blocks on the node with no required chainwork, and verify nodes 1 and 2 have no new headers in their headers tree" )
50
52
with self .nodes [1 ].assert_debug_log (expected_msgs = ["[net] Ignoring low-work chain (height=14)" ]), self .nodes [2 ].assert_debug_log (expected_msgs = ["[net] Ignoring low-work chain (height=14)" ]):
51
53
self .generate (self .nodes [0 ], NODE1_BLOCKS_REQUIRED - 1 , sync_fun = self .no_op )
52
54
53
- for node in self .nodes [1 :]:
55
+ # Node3 should always allow headers due to noban permissions
56
+ self .log .info ("Check that node3 will sync headers (due to noban permissions)" )
57
+
58
+ def check_node3_chaintips (num_tips , tip_hash , height ):
59
+ node3_chaintips = self .nodes [3 ].getchaintips ()
60
+ assert (len (node3_chaintips ) == num_tips )
61
+ assert {
62
+ 'height' : height ,
63
+ 'hash' : tip_hash ,
64
+ 'branchlen' : height ,
65
+ 'status' : 'headers-only' ,
66
+ } in node3_chaintips
67
+
68
+ check_node3_chaintips (2 , self .nodes [0 ].getbestblockhash (), NODE1_BLOCKS_REQUIRED - 1 )
69
+
70
+ for node in self .nodes [1 :3 ]:
54
71
chaintips = node .getchaintips ()
55
72
assert (len (chaintips ) == 1 )
56
73
assert {
@@ -63,7 +80,7 @@ def test_chains_sync_when_long_enough(self):
63
80
self .log .info ("Generate more blocks to satisfy node1's minchainwork requirement, and verify node2 still has no new headers in headers tree" )
64
81
with self .nodes [2 ].assert_debug_log (expected_msgs = ["[net] Ignoring low-work chain (height=15)" ]):
65
82
self .generate (self .nodes [0 ], NODE1_BLOCKS_REQUIRED - self .nodes [0 ].getblockcount (), sync_fun = self .no_op )
66
- self .sync_blocks (self .nodes [0 :2 ])
83
+ self .sync_blocks (self .nodes [0 :2 ]) # node3 will sync headers (noban permissions) but not blocks (due to minchainwork)
67
84
68
85
assert {
69
86
'height' : 0 ,
@@ -74,10 +91,13 @@ def test_chains_sync_when_long_enough(self):
74
91
75
92
assert (len (self .nodes [2 ].getchaintips ()) == 1 )
76
93
77
- self .log .info ("Generate long chain for node0/node1" )
94
+ self .log .info ("Check that node3 accepted these headers as well" )
95
+ check_node3_chaintips (2 , self .nodes [0 ].getbestblockhash (), NODE1_BLOCKS_REQUIRED )
96
+
97
+ self .log .info ("Generate long chain for node0/node1/node3" )
78
98
self .generate (self .nodes [0 ], NODE2_BLOCKS_REQUIRED - self .nodes [0 ].getblockcount (), sync_fun = self .no_op )
79
99
80
- self .log .info ("Verify that node2 will sync the chain when it gets long enough" )
100
+ self .log .info ("Verify that node2 and node3 will sync the chain when it gets long enough" )
81
101
self .sync_blocks ()
82
102
83
103
def test_peerinfo_includes_headers_presync_height (self ):
0 commit comments