Changeset View
Changeset View
Standalone View
Standalone View
test/functional/p2p_leak.py
Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | class CLazyNode(P2PInterface): | ||||
def on_sendcmpct(self, message): self.bad_message(message) | def on_sendcmpct(self, message): self.bad_message(message) | ||||
def on_cmpctblock(self, message): self.bad_message(message) | def on_cmpctblock(self, message): self.bad_message(message) | ||||
def on_getblocktxn(self, message): self.bad_message(message) | def on_getblocktxn(self, message): self.bad_message(message) | ||||
def on_blocktxn(self, message): self.bad_message(message) | def on_blocktxn(self, message): self.bad_message(message) | ||||
# Node that never sends a version. We'll use this to send a bunch of messages | # Node that never sends a version. We'll use this to send a bunch of messages | ||||
# anyway, and eventually get disconnected. | # anyway, and eventually get disconnected. | ||||
class CNodeNoVersionMisbehavior(CLazyNode): | class CNodeNoVersionMisbehavior(CLazyNode): | ||||
# Send enough veracks without a message to reach the peer discouragement | pass | ||||
# threshold. This should get us disconnected. NOTE: implementation-specific | |||||
# test; update if our discouragement policy for peer misbehavior changes. | |||||
def on_open(self): | |||||
super().on_open() | |||||
for _ in range(DISCOURAGEMENT_THRESHOLD): | |||||
self.send_message(msg_verack()) | |||||
# Node that never sends a version. This one just sits idle and hopes to receive | # Node that never sends a version. This one just sits idle and hopes to receive | ||||
# any message (it shouldn't!) | # any message (it shouldn't!) | ||||
class CNodeNoVersionIdle(CLazyNode): | class CNodeNoVersionIdle(CLazyNode): | ||||
def __init__(self): | def __init__(self): | ||||
super().__init__() | super().__init__() | ||||
# Node that sends a version but not a verack. | # Node that sends a version but not a verack. | ||||
class CNodeNoVerackIdle(CLazyNode): | class CNodeNoVerackIdle(CLazyNode): | ||||
def __init__(self): | def __init__(self): | ||||
self.version_received = False | self.version_received = False | ||||
super().__init__() | super().__init__() | ||||
Show All 23 Lines | class P2PLeakTest(BitcoinTestFramework): | ||||
def run_test(self): | def run_test(self): | ||||
no_version_disconnect_node = self.nodes[0].add_p2p_connection( | no_version_disconnect_node = self.nodes[0].add_p2p_connection( | ||||
CNodeNoVersionMisbehavior(), send_version=False, wait_for_verack=False) | CNodeNoVersionMisbehavior(), send_version=False, wait_for_verack=False) | ||||
no_version_idlenode = self.nodes[0].add_p2p_connection( | no_version_idlenode = self.nodes[0].add_p2p_connection( | ||||
CNodeNoVersionIdle(), send_version=False, wait_for_verack=False) | CNodeNoVersionIdle(), send_version=False, wait_for_verack=False) | ||||
no_verack_idlenode = self.nodes[0].add_p2p_connection( | no_verack_idlenode = self.nodes[0].add_p2p_connection( | ||||
CNodeNoVerackIdle(), wait_for_verack=False) | CNodeNoVerackIdle(), wait_for_verack=False) | ||||
# Send enough veracks without a message to reach the peer discouragement | |||||
# threshold. This should get us disconnected. | |||||
for _ in range(DISCOURAGEMENT_THRESHOLD): | |||||
no_version_disconnect_node.send_message(msg_verack()) | |||||
# Wait until we got the verack in response to the version. Though, don't wait for the other node to receive the | # Wait until we got the verack in response to the version. Though, don't wait for the other node to receive the | ||||
# verack, since we never sent one | # verack, since we never sent one | ||||
no_verack_idlenode.wait_for_verack() | no_verack_idlenode.wait_for_verack() | ||||
wait_until( | wait_until( | ||||
lambda: no_version_disconnect_node.ever_connected, | lambda: no_version_disconnect_node.ever_connected, | ||||
timeout=10, | timeout=10, | ||||
lock=p2p_lock) | lock=p2p_lock) | ||||
Show All 31 Lines | def run_test(self): | ||||
assert_equal(ver.nStartingHeight, 201) | assert_equal(ver.nStartingHeight, 201) | ||||
assert_equal(ver.nRelay, 1) | assert_equal(ver.nRelay, 1) | ||||
self.log.info('Check that old nodes are disconnected') | self.log.info('Check that old nodes are disconnected') | ||||
p2p_old_node = self.nodes[0].add_p2p_connection( | p2p_old_node = self.nodes[0].add_p2p_connection( | ||||
P2PInterface(), send_version=False, wait_for_verack=False) | P2PInterface(), send_version=False, wait_for_verack=False) | ||||
old_version_msg = msg_version() | old_version_msg = msg_version() | ||||
old_version_msg.nVersion = 31799 | old_version_msg.nVersion = 31799 | ||||
wait_until(lambda: p2p_old_node.is_connected) | |||||
with self.nodes[0].assert_debug_log(['peer=4 using obsolete version 31799; disconnecting']): | with self.nodes[0].assert_debug_log(['peer=4 using obsolete version 31799; disconnecting']): | ||||
p2p_old_node.send_message(old_version_msg) | p2p_old_node.send_message(old_version_msg) | ||||
p2p_old_node.wait_for_disconnect() | p2p_old_node.wait_for_disconnect() | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
P2PLeakTest().main() | P2PLeakTest().main() |