@ -49,19 +49,17 @@ class MaxUploadTest(BitcoinTestFramework):
# Generate some old blocks
# Generate some old blocks
self . nodes [ 0 ] . generate ( 130 )
self . nodes [ 0 ] . generate ( 130 )
# test_nodes[0] will only request old blocks
# p2p_conns[0] will only request old blocks
# test_nodes[1] will only request new blocks
# p2p_conns[1] will only request new blocks
# test_nodes[2] will test resetting the counters
# p2p_conns[2] will test resetting the counters
test_nodes = [ ]
p2p_conns = [ ]
connections = [ ]
for i in range ( 3 ) :
for i in range ( 3 ) :
test_nodes . append ( TestNode ( ) )
p2p_conns . append ( self . nodes [ 0 ] . add_p2p_connection ( TestNode ( ) ) )
connections . append ( NodeConn ( ' 127.0.0.1 ' , p2p_port ( 0 ) , self . nodes [ 0 ] , test_nodes [ i ] ) )
test_nodes [ i ] . add_connection ( connections [ i ] )
NetworkThread ( ) . start ( ) # Start up network handling in another thread
NetworkThread ( ) . start ( ) # Start up network handling in another thread
[ x . wait_for_verack ( ) for x in test_nodes ]
for p2pc in p2p_conns :
p2pc . wait_for_verack ( )
# Test logic begins here
# Test logic begins here
@ -83,7 +81,7 @@ class MaxUploadTest(BitcoinTestFramework):
big_new_block = self . nodes [ 0 ] . getbestblockhash ( )
big_new_block = self . nodes [ 0 ] . getbestblockhash ( )
big_new_block = int ( big_new_block , 16 )
big_new_block = int ( big_new_block , 16 )
# test_node s[0] will test what happens if we just keep requesting the
# p2p_conn s[0] will test what happens if we just keep requesting the
# the same big old block too many times (expect: disconnect)
# the same big old block too many times (expect: disconnect)
getdata_request = msg_getdata ( )
getdata_request = msg_getdata ( )
@ -97,34 +95,34 @@ class MaxUploadTest(BitcoinTestFramework):
# 576MB will be reserved for relaying new blocks, so expect this to
# 576MB will be reserved for relaying new blocks, so expect this to
# succeed for ~235 tries.
# succeed for ~235 tries.
for i in range ( success_count ) :
for i in range ( success_count ) :
test_node s[ 0 ] . send_message ( getdata_request )
p2p_conn s[ 0 ] . send_message ( getdata_request )
test_node s[ 0 ] . sync_with_ping ( )
p2p_conn s[ 0 ] . sync_with_ping ( )
assert_equal ( test_node s[ 0 ] . block_receive_map [ big_old_block ] , i + 1 )
assert_equal ( p2p_conn s[ 0 ] . block_receive_map [ big_old_block ] , i + 1 )
assert_equal ( len ( self . nodes [ 0 ] . getpeerinfo ( ) ) , 3 )
assert_equal ( len ( self . nodes [ 0 ] . getpeerinfo ( ) ) , 3 )
# At most a couple more tries should succeed (depending on how long
# At most a couple more tries should succeed (depending on how long
# the test has been running so far).
# the test has been running so far).
for i in range ( 3 ) :
for i in range ( 3 ) :
test_node s[ 0 ] . send_message ( getdata_request )
p2p_conn s[ 0 ] . send_message ( getdata_request )
test_node s[ 0 ] . wait_for_disconnect ( )
p2p_conn s[ 0 ] . wait_for_disconnect ( )
assert_equal ( len ( self . nodes [ 0 ] . getpeerinfo ( ) ) , 2 )
assert_equal ( len ( self . nodes [ 0 ] . getpeerinfo ( ) ) , 2 )
self . log . info ( " Peer 0 disconnected after downloading old block too many times " )
self . log . info ( " Peer 0 disconnected after downloading old block too many times " )
# Requesting the current block on test_node s[1] should succeed indefinitely,
# Requesting the current block on p2p_conn s[1] should succeed indefinitely,
# even when over the max upload target.
# even when over the max upload target.
# We'll try 800 times
# We'll try 800 times
getdata_request . inv = [ CInv ( 2 , big_new_block ) ]
getdata_request . inv = [ CInv ( 2 , big_new_block ) ]
for i in range ( 800 ) :
for i in range ( 800 ) :
test_node s[ 1 ] . send_message ( getdata_request )
p2p_conn s[ 1 ] . send_message ( getdata_request )
test_node s[ 1 ] . sync_with_ping ( )
p2p_conn s[ 1 ] . sync_with_ping ( )
assert_equal ( test_node s[ 1 ] . block_receive_map [ big_new_block ] , i + 1 )
assert_equal ( p2p_conn s[ 1 ] . block_receive_map [ big_new_block ] , i + 1 )
self . log . info ( " Peer 1 able to repeatedly download new block " )
self . log . info ( " Peer 1 able to repeatedly download new block " )
# But if test_node s[1] tries for an old block, it gets disconnected too.
# But if p2p_conn s[1] tries for an old block, it gets disconnected too.
getdata_request . inv = [ CInv ( 2 , big_old_block ) ]
getdata_request . inv = [ CInv ( 2 , big_old_block ) ]
test_node s[ 1 ] . send_message ( getdata_request )
p2p_conn s[ 1 ] . send_message ( getdata_request )
test_node s[ 1 ] . wait_for_disconnect ( )
p2p_conn s[ 1 ] . wait_for_disconnect ( )
assert_equal ( len ( self . nodes [ 0 ] . getpeerinfo ( ) ) , 1 )
assert_equal ( len ( self . nodes [ 0 ] . getpeerinfo ( ) ) , 1 )
self . log . info ( " Peer 1 disconnected after trying to download old block " )
self . log . info ( " Peer 1 disconnected after trying to download old block " )
@ -132,39 +130,38 @@ class MaxUploadTest(BitcoinTestFramework):
self . log . info ( " Advancing system time on node to clear counters... " )
self . log . info ( " Advancing system time on node to clear counters... " )
# If we advance the time by 24 hours, then the counters should reset,
# If we advance the time by 24 hours, then the counters should reset,
# and test_node s[2] should be able to retrieve the old block.
# and p2p_conn s[2] should be able to retrieve the old block.
self . nodes [ 0 ] . setmocktime ( int ( time . time ( ) ) )
self . nodes [ 0 ] . setmocktime ( int ( time . time ( ) ) )
test_node s[ 2 ] . sync_with_ping ( )
p2p_conn s[ 2 ] . sync_with_ping ( )
test_node s[ 2 ] . send_message ( getdata_request )
p2p_conn s[ 2 ] . send_message ( getdata_request )
test_node s[ 2 ] . sync_with_ping ( )
p2p_conn s[ 2 ] . sync_with_ping ( )
assert_equal ( test_node s[ 2 ] . block_receive_map [ big_old_block ] , 1 )
assert_equal ( p2p_conn s[ 2 ] . block_receive_map [ big_old_block ] , 1 )
self . log . info ( " Peer 2 able to download old block " )
self . log . info ( " Peer 2 able to download old block " )
[ c . disconnect_node ( ) for c in connections ]
for i in range ( 3 ) :
self . nodes [ 0 ] . disconnect_p2p ( )
#stop and start node 0 with 1MB maxuploadtarget, whitelist 127.0.0.1
#stop and start node 0 with 1MB maxuploadtarget, whitelist 127.0.0.1
self . log . info ( " Restarting nodes with -whitelist=127.0.0.1 " )
self . log . info ( " Restarting nodes with -whitelist=127.0.0.1 " )
self . stop_node ( 0 )
self . stop_node ( 0 )
self . start_node ( 0 , [ " -whitelist=127.0.0.1 " , " -maxuploadtarget=1 " , " -blockmaxsize=999000 " ] )
self . start_node ( 0 , [ " -whitelist=127.0.0.1 " , " -maxuploadtarget=1 " , " -blockmaxsize=999000 " ] )
#recreate/reconnect a test node
# Reconnect to self.nodes[0]
test_nodes = [ TestNode ( ) ]
self . nodes [ 0 ] . add_p2p_connection ( TestNode ( ) )
connections = [ NodeConn ( ' 127.0.0.1 ' , p2p_port ( 0 ) , self . nodes [ 0 ] , test_nodes [ 0 ] ) ]
test_nodes [ 0 ] . add_connection ( connections [ 0 ] )
NetworkThread ( ) . start ( ) # Start up network handling in another thread
NetworkThread ( ) . start ( ) # Start up network handling in another thread
test_ nodes[ 0 ] . wait_for_verack ( )
self . nodes [ 0 ] . p2p . wait_for_verack ( )
#retrieve 20 blocks which should be enough to break the 1MB limit
#retrieve 20 blocks which should be enough to break the 1MB limit
getdata_request . inv = [ CInv ( 2 , big_new_block ) ]
getdata_request . inv = [ CInv ( 2 , big_new_block ) ]
for i in range ( 20 ) :
for i in range ( 20 ) :
test_ nodes[ 0 ] . send_message ( getdata_request )
self . nodes [ 0 ] . p2p . send_message ( getdata_request )
test_ nodes[ 0 ] . sync_with_ping ( )
self . nodes [ 0 ] . p2p . sync_with_ping ( )
assert_equal ( test_ nodes[ 0 ] . block_receive_map [ big_new_block ] , i + 1 )
assert_equal ( self . nodes [ 0 ] . p2p . block_receive_map [ big_new_block ] , i + 1 )
getdata_request . inv = [ CInv ( 2 , big_old_block ) ]
getdata_request . inv = [ CInv ( 2 , big_old_block ) ]
test_ nodes[ 0 ] . send_and_ping ( getdata_request )
self . nodes [ 0 ] . p2p . send_and_ping ( getdata_request )
assert_equal ( len ( self . nodes [ 0 ] . getpeerinfo ( ) ) , 1 ) #node is still connected because of the whitelist
assert_equal ( len ( self . nodes [ 0 ] . getpeerinfo ( ) ) , 1 ) #node is still connected because of the whitelist
self . log . info ( " Peer still connected after trying to download old block (whitelisted) " )
self . log . info ( " Peer still connected after trying to download old block (whitelisted) " )