14 AcceptBlockTest -- test processing of unrequested blocks. 16 Since behavior differs when receiving unrequested blocks from whitelisted peers 17 versus non-whitelisted peers, this tests the behavior of both (effectively two 18 separate tests running in parallel). 20 Setup: two nodes, node0 and node1, not connected to each other. Node0 does not 21 whitelist localhost, but node1 does. They will each be on their own chain for 24 We have one NodeConn connection to each, test_node and white_node respectively. 27 1. Generate one block on each node, to leave IBD. 29 2. Mine a new block on each tip, and deliver to each node from node's peer. 30 The tip should advance. 32 3. Mine a block that forks the previous block, and deliver to each node from 34 Node0 should not process this block (just accept the header), because it is 35 unrequested and doesn't have more work than the tip. 36 Node1 should process because this is coming from a whitelisted peer. 38 4. Send another block that builds on the forking block. 39 Node0 should process this block but be stuck on the shorter chain, because 40 it's missing an intermediate block. 41 Node1 should reorg to this longer chain. 43 4b.Send 288 more blocks on the longer chain. 44 Node0 should process all but the last block (too far ahead in height). 45 Send all headers to Node1, and then send the last block in that chain. 46 Node1 should accept the block because it's coming from a whitelisted peer. 48 5. Send a duplicate of the block in #3 to Node0. 49 Node0 should not process the block because it is unrequested, and stay on 52 6. Send Node0 an inv for the height 3 block produced in #4 above. 53 Node0 should figure out that Node0 has the missing height 2 block and send a 56 7. Send Node0 the missing block again. 57 Node0 should process and the tip should advance. 64 NodeConnCB.__init__(self)
99 while not received_pong
and timeout > 0:
100 time.sleep(sleep_time)
101 timeout -= sleep_time
111 parser.add_option(
"--testbinary", dest=
"testbinary",
112 default=os.getenv(
"DASHD",
"dashd"),
113 help=
"bitcoind binary to test")
124 binary=self.options.testbinary))
126 [
"-debug",
"-whitelist=127.0.0.1"],
127 binary=self.options.testbinary))
137 test_node.add_connection(connections[0])
138 white_node.add_connection(connections[1])
143 test_node.wait_for_verack()
144 white_node.wait_for_verack()
147 [ n.generate(1)
for n
in self.
nodes ]
148 tips = [ int (
"0x" + n.getbestblockhash() +
"L", 0)
for n
in self.
nodes ]
153 block_time = int(time.time()) + 1
158 test_node.send_message(
msg_block(blocks_h2[0]))
159 white_node.send_message(
msg_block(blocks_h2[1]))
161 [ x.sync_with_ping()
for x
in [test_node, white_node] ]
164 print "First height 2 block accepted by both nodes" 170 blocks_h2f[i].solve()
171 test_node.send_message(
msg_block(blocks_h2f[0]))
172 white_node.send_message(
msg_block(blocks_h2f[1]))
174 [ x.sync_with_ping()
for x
in [test_node, white_node] ]
176 if x[
'hash'] == blocks_h2f[0].hash:
180 if x[
'hash'] == blocks_h2f[1].hash:
183 print "Second height 2 block accepted only from whitelisted peer" 190 test_node.send_message(
msg_block(blocks_h3[0]))
191 white_node.send_message(
msg_block(blocks_h3[1]))
193 [ x.sync_with_ping()
for x
in [test_node, white_node] ]
197 if x[
'hash'] == blocks_h3[0].hash:
203 print "Unrequested more-work block accepted from non-whitelisted peer" 205 raise AssertionError(
"Unrequested more work block was not processed")
209 print "Successfully reorged to length 3 chain from whitelisted peer" 218 for i
in xrange(288):
222 test_node.send_message(
msg_block(next_block))
223 all_blocks.append(next_block)
225 headers_message.headers.append(
CBlockHeader(next_block))
232 if x == all_blocks[287]:
233 raise AssertionError(
"Unrequested block too far-ahead should have been ignored")
235 if x == all_blocks[287]:
236 print "Unrequested block too far-ahead not processed" 238 raise AssertionError(
"Unrequested block with more work should have been accepted")
240 headers_message.headers.pop()
241 white_node.send_message(headers_message)
242 white_node.send_message(
msg_block(tips[1]))
244 white_node.sync_with_ping()
246 print "Unrequested block far ahead of tip accepted from whitelisted peer" 248 raise AssertionError(
"Unrequested block from whitelisted peer not accepted")
253 test_node.send_message(
msg_block(blocks_h2f[0]))
260 test_node.sync_with_ping()
262 print "Unrequested block that would complete more-work chain was ignored" 269 test_node.last_getdata =
None 270 test_node.send_message(
msg_inv([
CInv(2, blocks_h3[0].sha256)]))
272 test_node.sync_with_ping()
274 getdata = test_node.last_getdata
278 print "Inv at tip triggered getdata for unprocessed block" 281 test_node.send_message(
msg_block(blocks_h2f[0]))
283 test_node.sync_with_ping()
285 print "Successfully reorged to longer chain from non-whitelisted peer" 287 [ c.disconnect_node()
for c
in connections ]
289 if __name__ ==
'__main__':
def send_message(self, message)
def add_options(self, parser)
def on_getdata(self, conn, message)
UniValue getblock(const UniValue ¶ms, bool fHelp)
UniValue getblockcount(const UniValue ¶ms, bool fHelp)
def initialize_chain_clean(test_dir, num_nodes)
def sync_with_ping(self, timeout=30)
def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None)
def on_pong(self, conn, message)
def wait_for_verack(self)
def add_connection(self, conn)
def assert_equal(thing1, thing2)