qa: add test for minchainwork use in acceptblock

This commit is contained in:
Suhas Daftuar 2017-10-06 14:32:07 -04:00
parent ce8cd7a7da
commit 08fd822771

View file

@ -8,17 +8,22 @@ Since behavior differs when receiving unrequested blocks from whitelisted peers
versus non-whitelisted peers, this tests the behavior of both (effectively two versus non-whitelisted peers, this tests the behavior of both (effectively two
separate tests running in parallel). separate tests running in parallel).
Setup: two nodes, node0 and node1, not connected to each other. Node0 does not Setup: three nodes, node0+node1+node2, not connected to each other. Node0 does not
whitelist localhost, but node1 does. They will each be on their own chain for whitelist localhost, but node1 does. They will each be on their own chain for
this test. this test. Node2 will have nMinimumChainWork set to 0x10, so it won't process
low-work unrequested blocks.
We have one NodeConn connection to each, test_node and white_node respectively. We have one NodeConn connection to each, test_node, white_node, and min_work_node,
respectively.
The test: The test:
1. Generate one block on each node, to leave IBD. 1. Generate one block on each node, to leave IBD.
2. Mine a new block on each tip, and deliver to each node from node's peer. 2. Mine a new block on each tip, and deliver to each node from node's peer.
The tip should advance. The tip should advance for node0 and node1, but node2 should skip processing
due to nMinimumChainWork.
Node2 is unused in tests 3-7:
3. Mine a block that forks the previous block, and deliver to each node from 3. Mine a block that forks the previous block, and deliver to each node from
corresponding peer. corresponding peer.
@ -46,6 +51,10 @@ The test:
7. Send Node0 the missing block again. 7. Send Node0 the missing block again.
Node0 should process and the tip should advance. Node0 should process and the tip should advance.
8. Test Node2 is able to sync when connected to node0 (which should have sufficient
work on its chain).
""" """
from test_framework.mininode import * from test_framework.mininode import *
@ -62,52 +71,60 @@ class AcceptBlockTest(BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
self.setup_clean_chain = True self.setup_clean_chain = True
self.num_nodes = 2 self.num_nodes = 3
self.extra_args = [[], ["-whitelist=127.0.0.1"]] self.extra_args = [[], ["-whitelist=127.0.0.1"], ["-minimumchainwork=0x10"]]
def setup_network(self): def setup_network(self):
# Node0 will be used to test behavior of processing unrequested blocks # Node0 will be used to test behavior of processing unrequested blocks
# from peers which are not whitelisted, while Node1 will be used for # from peers which are not whitelisted, while Node1 will be used for
# the whitelisted case. # the whitelisted case.
# Node2 will be used for non-whitelisted peers to test the interaction
# with nMinimumChainWork.
self.setup_nodes() self.setup_nodes()
def run_test(self): def run_test(self):
# Setup the p2p connections and start up the network thread. # Setup the p2p connections and start up the network thread.
test_node = NodeConnCB() # connects to node0 (not whitelisted) test_node = NodeConnCB() # connects to node0 (not whitelisted)
white_node = NodeConnCB() # connects to node1 (whitelisted) white_node = NodeConnCB() # connects to node1 (whitelisted)
min_work_node = NodeConnCB() # connects to node2 (not whitelisted)
connections = [] connections = []
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node)) connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node))
connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], white_node)) connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], white_node))
connections.append(NodeConn('127.0.0.1', p2p_port(2), self.nodes[2], min_work_node))
test_node.add_connection(connections[0]) test_node.add_connection(connections[0])
white_node.add_connection(connections[1]) white_node.add_connection(connections[1])
min_work_node.add_connection(connections[2])
NetworkThread().start() # Start up network handling in another thread NetworkThread().start() # Start up network handling in another thread
# Test logic begins here # Test logic begins here
test_node.wait_for_verack() test_node.wait_for_verack()
white_node.wait_for_verack() white_node.wait_for_verack()
min_work_node.wait_for_verack()
# 1. Have both nodes mine a block (leave IBD) # 1. Have nodes mine a block (nodes1/2 leave IBD)
[ n.generate(1) for n in self.nodes ] [ n.generate(1) for n in self.nodes ]
tips = [ int("0x" + n.getbestblockhash(), 0) for n in self.nodes ] tips = [ int("0x" + n.getbestblockhash(), 0) for n in self.nodes ]
# 2. Send one block that builds on each tip. # 2. Send one block that builds on each tip.
# This should be accepted. # This should be accepted by nodes 1/2
blocks_h2 = [] # the height 2 blocks on each node's chain blocks_h2 = [] # the height 2 blocks on each node's chain
block_time = int(time.time()) + 1 block_time = int(time.time()) + 1
for i in range(2): for i in range(3):
blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time)) blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time))
blocks_h2[i].solve() blocks_h2[i].solve()
block_time += 1 block_time += 1
test_node.send_message(msg_block(blocks_h2[0])) test_node.send_message(msg_block(blocks_h2[0]))
white_node.send_message(msg_block(blocks_h2[1])) white_node.send_message(msg_block(blocks_h2[1]))
min_work_node.send_message(msg_block(blocks_h2[2]))
for x in [test_node, white_node]: for x in [test_node, white_node, min_work_node]:
x.sync_with_ping() x.sync_with_ping()
assert_equal(self.nodes[0].getblockcount(), 2) assert_equal(self.nodes[0].getblockcount(), 2)
assert_equal(self.nodes[1].getblockcount(), 2) assert_equal(self.nodes[1].getblockcount(), 2)
self.log.info("First height 2 block accepted by both nodes") assert_equal(self.nodes[2].getblockcount(), 1)
self.log.info("First height 2 block accepted by node0/node1; correctly rejected by node2")
# 3. Send another block that builds on the original tip. # 3. Send another block that builds on the original tip.
blocks_h2f = [] # Blocks at height 2 that fork off the main chain blocks_h2f = [] # Blocks at height 2 that fork off the main chain
@ -220,6 +237,11 @@ class AcceptBlockTest(BitcoinTestFramework):
assert_equal(self.nodes[0].getblockcount(), 290) assert_equal(self.nodes[0].getblockcount(), 290)
self.log.info("Successfully reorged to longer chain from non-whitelisted peer") self.log.info("Successfully reorged to longer chain from non-whitelisted peer")
# 8. Connect node2 to node0 and ensure it is able to sync
connect_nodes(self.nodes[0], 2)
sync_blocks([self.nodes[0], self.nodes[2]])
self.log.info("Successfully synced nodes 2 and 0")
[ c.disconnect_node() for c in connections ] [ c.disconnect_node() for c in connections ]
if __name__ == '__main__': if __name__ == '__main__':