[tests] Test disconnecting unsupported service bits logic.

In v0.15, we disconnect nodes that send us version messages with
unsupported service bits (1 << 5 and 1 << 7). This commit adds a test
that bitcoind will disconnect those nodes before August 1st 2018, and won't
disconnect those nodes after August 1st 2018.
This commit is contained in:
John Newbery 2017-08-07 11:37:49 -04:00
parent fa64636948
commit 5e35cd94c1
2 changed files with 35 additions and 1 deletions

View File

@ -9,7 +9,10 @@ received a VERACK.
This test connects to a node and sends it a few messages, trying to intice it This test connects to a node and sends it a few messages, trying to intice it
into sending us something it shouldn't. into sending us something it shouldn't.
"""
Also test that nodes that send unsupported service bits to bitcoind are disconnected
and don't receive a VERACK. Unsupported service bits are currently 1 << 5 and
1 << 7 (until August 1st 2018)."""
from test_framework.mininode import * from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
@ -98,20 +101,29 @@ class P2PLeakTest(BitcoinTestFramework):
no_version_bannode = CNodeNoVersionBan() no_version_bannode = CNodeNoVersionBan()
no_version_idlenode = CNodeNoVersionIdle() no_version_idlenode = CNodeNoVersionIdle()
no_verack_idlenode = CNodeNoVerackIdle() no_verack_idlenode = CNodeNoVerackIdle()
unsupported_service_bit5_node = CLazyNode()
unsupported_service_bit7_node = CLazyNode()
self.nodes[0].setmocktime(1501545600) # August 1st 2017
connections = [] connections = []
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_version_bannode, send_version=False)) connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_version_bannode, send_version=False))
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_version_idlenode, send_version=False)) connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_version_idlenode, send_version=False))
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_verack_idlenode)) connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], no_verack_idlenode))
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], unsupported_service_bit5_node, services=NODE_NETWORK|NODE_UNSUPPORTED_SERVICE_BIT_5))
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], unsupported_service_bit7_node, services=NODE_NETWORK|NODE_UNSUPPORTED_SERVICE_BIT_7))
no_version_bannode.add_connection(connections[0]) no_version_bannode.add_connection(connections[0])
no_version_idlenode.add_connection(connections[1]) no_version_idlenode.add_connection(connections[1])
no_verack_idlenode.add_connection(connections[2]) no_verack_idlenode.add_connection(connections[2])
unsupported_service_bit5_node.add_connection(connections[3])
unsupported_service_bit7_node.add_connection(connections[4])
NetworkThread().start() # Start up network handling in another thread NetworkThread().start() # Start up network handling in another thread
assert wait_until(lambda: no_version_bannode.ever_connected, timeout=10) assert wait_until(lambda: no_version_bannode.ever_connected, timeout=10)
assert wait_until(lambda: no_version_idlenode.ever_connected, timeout=10) assert wait_until(lambda: no_version_idlenode.ever_connected, timeout=10)
assert wait_until(lambda: no_verack_idlenode.version_received, timeout=10) assert wait_until(lambda: no_verack_idlenode.version_received, timeout=10)
assert wait_until(lambda: unsupported_service_bit5_node.ever_connected, timeout=10)
assert wait_until(lambda: unsupported_service_bit7_node.ever_connected, timeout=10)
# Mine a block and make sure that it's not sent to the connected nodes # Mine a block and make sure that it's not sent to the connected nodes
self.nodes[0].generate(1) self.nodes[0].generate(1)
@ -122,12 +134,32 @@ class P2PLeakTest(BitcoinTestFramework):
#This node should have been banned #This node should have been banned
assert not no_version_bannode.connected assert not no_version_bannode.connected
# These nodes should have been disconnected
assert not unsupported_service_bit5_node.connected
assert not unsupported_service_bit7_node.connected
[conn.disconnect_node() for conn in connections] [conn.disconnect_node() for conn in connections]
# Make sure no unexpected messages came in # Make sure no unexpected messages came in
assert(no_version_bannode.unexpected_msg == False) assert(no_version_bannode.unexpected_msg == False)
assert(no_version_idlenode.unexpected_msg == False) assert(no_version_idlenode.unexpected_msg == False)
assert(no_verack_idlenode.unexpected_msg == False) assert(no_verack_idlenode.unexpected_msg == False)
assert not unsupported_service_bit5_node.unexpected_msg
assert not unsupported_service_bit7_node.unexpected_msg
self.log.info("Service bits 5 and 7 are allowed after August 1st 2018")
self.nodes[0].setmocktime(1533168000) # August 2nd 2018
allowed_service_bit5_node = NodeConnCB()
allowed_service_bit7_node = NodeConnCB()
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], allowed_service_bit5_node, services=NODE_NETWORK|NODE_UNSUPPORTED_SERVICE_BIT_5))
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], allowed_service_bit7_node, services=NODE_NETWORK|NODE_UNSUPPORTED_SERVICE_BIT_7))
allowed_service_bit5_node.add_connection(connections[5])
allowed_service_bit7_node.add_connection(connections[6])
assert wait_until(lambda: allowed_service_bit5_node.message_count["verack"], timeout=10)
assert wait_until(lambda: allowed_service_bit7_node.message_count["verack"], timeout=10)
if __name__ == '__main__': if __name__ == '__main__':
P2PLeakTest().main() P2PLeakTest().main()

View File

@ -51,6 +51,8 @@ NODE_NETWORK = (1 << 0)
NODE_GETUTXO = (1 << 1) NODE_GETUTXO = (1 << 1)
NODE_BLOOM = (1 << 2) NODE_BLOOM = (1 << 2)
NODE_WITNESS = (1 << 3) NODE_WITNESS = (1 << 3)
NODE_UNSUPPORTED_SERVICE_BIT_5 = (1 << 5)
NODE_UNSUPPORTED_SERVICE_BIT_7 = (1 << 7)
logger = logging.getLogger("TestFramework.mininode") logger = logging.getLogger("TestFramework.mininode")