88versus non-whitelisted peers, this tests the behavior of both (effectively two
99separate tests running in parallel).
1010
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
1212whitelist 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.
1415
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.
1618
1719The test:
18201. Generate one block on each node, to leave IBD.
1921
20222. 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:
2227
23283. Mine a block that forks the previous block, and deliver to each node from
2429 corresponding peer.
4651
47527. Send Node0 the missing block again.
4853 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+
4958"""
5059
5160from test_framework .mininode import *
@@ -62,52 +71,60 @@ def add_options(self, parser):
6271
6372 def set_test_params (self ):
6473 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" ] ]
6776
6877 def setup_network (self ):
6978 # Node0 will be used to test behavior of processing unrequested blocks
7079 # from peers which are not whitelisted, while Node1 will be used for
7180 # the whitelisted case.
81+ # Node2 will be used for non-whitelisted peers to test the interaction
82+ # with nMinimumChainWork.
7283 self .setup_nodes ()
7384
7485 def run_test (self ):
7586 # Setup the p2p connections and start up the network thread.
7687 test_node = NodeConnCB () # connects to node0 (not whitelisted)
7788 white_node = NodeConnCB () # connects to node1 (whitelisted)
89+ min_work_node = NodeConnCB () # connects to node2 (not whitelisted)
7890
7991 connections = []
8092 connections .append (NodeConn ('127.0.0.1' , p2p_port (0 ), self .nodes [0 ], test_node ))
8193 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 ))
8295 test_node .add_connection (connections [0 ])
8396 white_node .add_connection (connections [1 ])
97+ min_work_node .add_connection (connections [2 ])
8498
8599 NetworkThread ().start () # Start up network handling in another thread
86100
87101 # Test logic begins here
88102 test_node .wait_for_verack ()
89103 white_node .wait_for_verack ()
104+ min_work_node .wait_for_verack ()
90105
91- # 1. Have both nodes mine a block (leave IBD)
106+ # 1. Have nodes mine a block (nodes1/2 leave IBD)
92107 [ n .generate (1 ) for n in self .nodes ]
93108 tips = [ int ("0x" + n .getbestblockhash (), 0 ) for n in self .nodes ]
94109
95110 # 2. Send one block that builds on each tip.
96- # This should be accepted.
111+ # This should be accepted by nodes 1/2
97112 blocks_h2 = [] # the height 2 blocks on each node's chain
98113 block_time = int (time .time ()) + 1
99- for i in range (2 ):
114+ for i in range (3 ):
100115 blocks_h2 .append (create_block (tips [i ], create_coinbase (2 ), block_time ))
101116 blocks_h2 [i ].solve ()
102117 block_time += 1
103118 test_node .send_message (msg_block (blocks_h2 [0 ]))
104119 white_node .send_message (msg_block (blocks_h2 [1 ]))
120+ min_work_node .send_message (msg_block (blocks_h2 [2 ]))
105121
106- for x in [test_node , white_node ]:
122+ for x in [test_node , white_node , min_work_node ]:
107123 x .sync_with_ping ()
108124 assert_equal (self .nodes [0 ].getblockcount (), 2 )
109125 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" )
111128
112129 # 3. Send another block that builds on the original tip.
113130 blocks_h2f = [] # Blocks at height 2 that fork off the main chain
@@ -220,6 +237,11 @@ def run_test(self):
220237 assert_equal (self .nodes [0 ].getblockcount (), 290 )
221238 self .log .info ("Successfully reorged to longer chain from non-whitelisted peer" )
222239
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+
223245 [ c .disconnect_node () for c in connections ]
224246
225247if __name__ == '__main__' :
0 commit comments