Extracted from #10387. Does implement BIP159, but only the signalling part. No connections are made to NODE_NETWORK_LIMITED in this PR.
The address relay and connection work (the more complicated part) can then be separated (probably in #10387).
e874478a42eded1c5952fc0407f04279dd4837c1 forgot to add node_network_limited.py to test_runner.py.
@fanquake! Thanks. Done.
utACK
utACK af05b92
utACK af05b92591b72c34f8fa04a0917b3c1225e2417c
1090 | @@ -1091,6 +1091,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam 1091 | pfrom->fDisconnect = true; 1092 | send = false; 1093 | } 1094 | + // Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold 1095 | + if (send && !pfrom->fWhitelisted && ( 1096 | + (((pfrom->GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom->GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && (chainActive.Tip()->nHeight - mi->second->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS) )
This needs a buffer beyond NODE_NETWORK_LIMITED_MIN_BLOCK. Because it gets a disconnect, one or two blocks should suffice.
1095 | + if (send && !pfrom->fWhitelisted && ( 1096 | + (((pfrom->GetLocalServices() & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom->GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && (chainActive.Tip()->nHeight - mi->second->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS) ) 1097 | + )) { 1098 | + LogPrint(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED threshold from peer=%d\n", pfrom->GetId()); 1099 | + 1100 | + //disconnect node
Can you fill out this comment a bit more? Something about how we could otherwise stall a node if we were just finishing IBD and announced blocks to our peers which they wanted?
41 | + node.wait_for_block(int(blockhash, 16), 3) 42 | + res = True 43 | + except: 44 | + pass 45 | + assert_equal(res, result) 46 | + self.nodes[0].disconnect_p2ps()
Can you move this into the try block? This checks that the node disconnected us, we didn't just timeout in the fail case.
The current pruning implementation does ensure to always conform to BIP159
Fixed points reported by @TheBlueMatt. Had to rebase and therefor amend changed the fixes. The only code change is the two blocks buffer extension for possible race conditions.
38 | + # check if we the peer sends us the block 39 | + res = False 40 | + try: 41 | + node.wait_for_block(int(blockhash, 16), 3) 42 | + res = True 43 | + assert_equal(res, result)
It seems we never check anything if we got disconnected, I guess this check needs to move to after the except?
Improved the disconnect test (amend commit).
utACK de74c625833bba8d8171a2d0dd6ede2e9d5da88b
utACK de74c62
test is racy:
node_network_limited.py failed, Duration: 61 s
stdout:
2017-12-11 18:39:35.906000 TestFramework (INFO): Initializing test directory /tmp/user/1000/bitcoin_test_runner_20171211_183839/node_network_limited_227
2017-12-11 18:39:36.171000 TestFramework.mininode (INFO): Connecting to Bitcoin Node: 127.0.0.1:12816
2017-12-11 18:39:36.498000 TestFramework.mininode (INFO): Connecting to Bitcoin Node: 127.0.0.1:12816
2017-12-11 18:39:36.604000 TestFramework.mininode (INFO): Connecting to Bitcoin Node: 127.0.0.1:12816
2017-12-11 18:39:36.757000 TestFramework.mininode (INFO): Connecting to Bitcoin Node: 127.0.0.1:12816
2017-12-11 18:40:36.768000 TestFramework (ERROR): Assertion failed
Traceback (most recent call last):
File "/home/ubuntu/bitcoin/test/functional/test_framework/test_framework.py", line 118, in main
self.run_test()
File "/home/ubuntu/bitcoin/test/functional/node_network_limited.py", line 65, in run_test
self.tryGetBlockViaGetData(blocks[0], True) #first block outside of the 288+2 limit
File "/home/ubuntu/bitcoin/test/functional/node_network_limited.py", line 33, in tryGetBlockViaGetData
node.wait_for_verack()
File "/home/ubuntu/bitcoin/test/functional/test_framework/mininode.py", line 373, in wait_for_verack
wait_until(test_function, timeout=timeout, lock=mininode_lock)
File "/home/ubuntu/bitcoin/test/functional/test_framework/util.py", line 222, in wait_until
assert_greater_than(timeout, time.time())
File "/home/ubuntu/bitcoin/test/functional/test_framework/util.py", line 42, in assert_greater_than
raise AssertionError("%s <= %s" % (str(thing1), str(thing2)))
AssertionError: 1513017636.75866 <= 1513017636.7688699
2017-12-11 18:40:36.769000 TestFramework (INFO): Stopping nodes
2017-12-11 18:40:36.931000 TestFramework (WARNING): Not cleaning up dir /tmp/user/1000/bitcoin_test_runner_20171211_183839/node_network_limited_227
2017-12-11 18:40:36.931000 TestFramework (ERROR): Test failed. Test logging available at /tmp/user/1000/bitcoin_test_runner_20171211_183839/node_network_limited_227/test_framework.log
2017-12-11 18:40:36.931000 TestFramework (ERROR): Hint: Call /home/ubuntu/bitcoin/test/functional/combine_logs.py '/tmp/user/1000/bitcoin_test_runner_20171211_183839/node_network_limited_227' to consolidate all logs
fix is here: https://github.com/jnewbery/bitcoin/tree/improve_node_network_test . I'll open a PR.
Thanks @jnewbery!