8
8
versus non-whitelisted peers, this tests the behavior of both (effectively two
9
9
separate tests running in parallel).
10
10
11
- Setup: two nodes, node0 and node1, not connected to each other. Node0 does not
11
+ Setup: three nodes, node0+ node1+node2 , not connected to each other. Node0 does not
12
12
whitelist localhost, but node1 does. They will each be on their own chain for
13
- this test.
13
+ this test. Node2 will have nMinimumChainWork set to 0x10, so it won't process
14
+ low-work unrequested blocks.
14
15
15
- We have one NodeConn connection to each, test_node and white_node respectively.
16
+ We have one NodeConn connection to each, test_node, white_node, and min_work_node,
17
+ respectively.
16
18
17
19
The test:
18
20
1. Generate one block on each node, to leave IBD.
19
21
20
22
2. Mine a new block on each tip, and deliver to each node from node's peer.
21
- The tip should advance.
23
+ The tip should advance for node0 and node1, but node2 should skip processing
24
+ due to nMinimumChainWork.
25
+
26
+ Node2 is unused in tests 3-7:
22
27
23
28
3. Mine a block that forks the previous block, and deliver to each node from
24
29
corresponding peer.
46
51
47
52
7. Send Node0 the missing block again.
48
53
Node0 should process and the tip should advance.
54
+
55
+ 8. Test Node2 is able to sync when connected to node0 (which should have sufficient
56
+ work on its chain).
57
+
49
58
"""
50
59
51
60
from test_framework .mininode import *
@@ -62,52 +71,60 @@ def add_options(self, parser):
62
71
63
72
def set_test_params (self ):
64
73
self .setup_clean_chain = True
65
- self .num_nodes = 2
66
- self .extra_args = [[], ["-whitelist=127.0.0.1" ]]
74
+ self .num_nodes = 3
75
+ self .extra_args = [[], ["-whitelist=127.0.0.1" ], [ "-minimumchainwork=0x10" ] ]
67
76
68
77
def setup_network (self ):
69
78
# Node0 will be used to test behavior of processing unrequested blocks
70
79
# from peers which are not whitelisted, while Node1 will be used for
71
80
# the whitelisted case.
81
+ # Node2 will be used for non-whitelisted peers to test the interaction
82
+ # with nMinimumChainWork.
72
83
self .setup_nodes ()
73
84
74
85
def run_test (self ):
75
86
# Setup the p2p connections and start up the network thread.
76
87
test_node = NodeConnCB () # connects to node0 (not whitelisted)
77
88
white_node = NodeConnCB () # connects to node1 (whitelisted)
89
+ min_work_node = NodeConnCB () # connects to node2 (not whitelisted)
78
90
79
91
connections = []
80
92
connections .append (NodeConn ('127.0.0.1' , p2p_port (0 ), self .nodes [0 ], test_node ))
81
93
connections .append (NodeConn ('127.0.0.1' , p2p_port (1 ), self .nodes [1 ], white_node ))
94
+ connections .append (NodeConn ('127.0.0.1' , p2p_port (2 ), self .nodes [2 ], min_work_node ))
82
95
test_node .add_connection (connections [0 ])
83
96
white_node .add_connection (connections [1 ])
97
+ min_work_node .add_connection (connections [2 ])
84
98
85
99
NetworkThread ().start () # Start up network handling in another thread
86
100
87
101
# Test logic begins here
88
102
test_node .wait_for_verack ()
89
103
white_node .wait_for_verack ()
104
+ min_work_node .wait_for_verack ()
90
105
91
- # 1. Have both nodes mine a block (leave IBD)
106
+ # 1. Have nodes mine a block (nodes1/2 leave IBD)
92
107
[ n .generate (1 ) for n in self .nodes ]
93
108
tips = [ int ("0x" + n .getbestblockhash (), 0 ) for n in self .nodes ]
94
109
95
110
# 2. Send one block that builds on each tip.
96
- # This should be accepted.
111
+ # This should be accepted by nodes 1/2
97
112
blocks_h2 = [] # the height 2 blocks on each node's chain
98
113
block_time = int (time .time ()) + 1
99
- for i in range (2 ):
114
+ for i in range (3 ):
100
115
blocks_h2 .append (create_block (tips [i ], create_coinbase (2 ), block_time ))
101
116
blocks_h2 [i ].solve ()
102
117
block_time += 1
103
118
test_node .send_message (msg_block (blocks_h2 [0 ]))
104
119
white_node .send_message (msg_block (blocks_h2 [1 ]))
120
+ min_work_node .send_message (msg_block (blocks_h2 [2 ]))
105
121
106
- for x in [test_node , white_node ]:
122
+ for x in [test_node , white_node , min_work_node ]:
107
123
x .sync_with_ping ()
108
124
assert_equal (self .nodes [0 ].getblockcount (), 2 )
109
125
assert_equal (self .nodes [1 ].getblockcount (), 2 )
110
- self .log .info ("First height 2 block accepted by both nodes" )
126
+ assert_equal (self .nodes [2 ].getblockcount (), 1 )
127
+ self .log .info ("First height 2 block accepted by node0/node1; correctly rejected by node2" )
111
128
112
129
# 3. Send another block that builds on the original tip.
113
130
blocks_h2f = [] # Blocks at height 2 that fork off the main chain
@@ -220,6 +237,11 @@ def run_test(self):
220
237
assert_equal (self .nodes [0 ].getblockcount (), 290 )
221
238
self .log .info ("Successfully reorged to longer chain from non-whitelisted peer" )
222
239
240
+ # 8. Connect node2 to node0 and ensure it is able to sync
241
+ connect_nodes (self .nodes [0 ], 2 )
242
+ sync_blocks ([self .nodes [0 ], self .nodes [2 ]])
243
+ self .log .info ("Successfully synced nodes 2 and 0" )
244
+
223
245
[ c .disconnect_node () for c in connections ]
224
246
225
247
if __name__ == '__main__' :
0 commit comments