mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
c340503b67
The test framework's p2p implementation currently sends out it's VERSION message immediately after an inbound connection (i.e. TestNode outbound connection) is made. This doesn't follow the usual protocol flow where the initiator sends a version first, and the responders processes that and only then responds with its own version message. Change that accordingly by only sending immediate VERSION message for outbound connections (or after v2 handshake for v2 connections, respectively), and sending out VERSION messages as response for incoming VERSION messages (i.e. in the function `on_version`) for inbound connections. Note that some of the overruled `on_version` methods in functional tests needed to be changed to send the version explicitly.
110 lines
4.9 KiB
Python
Executable file
110 lines
4.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# Copyright (c) 2020-2021 The Bitcoin Core developers
|
|
# Distributed under the MIT software license, see the accompanying
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
"""Test add_outbound_p2p_connection test framework functionality"""
|
|
|
|
from test_framework.p2p import P2PInterface
|
|
from test_framework.test_framework import BitcoinTestFramework
|
|
from test_framework.util import (
|
|
assert_equal,
|
|
check_node_connections,
|
|
)
|
|
|
|
class P2PFeelerReceiver(P2PInterface):
|
|
def on_version(self, message):
|
|
# The bitcoind node closes feeler connections as soon as a version
|
|
# message is received from the test framework. Don't send any responses
|
|
# to the node's version message since the connection will already be
|
|
# closed.
|
|
self.send_version()
|
|
|
|
class P2PAddConnections(BitcoinTestFramework):
|
|
def set_test_params(self):
|
|
self.num_nodes = 2
|
|
|
|
def setup_network(self):
|
|
self.setup_nodes()
|
|
# Don't connect the nodes
|
|
|
|
def run_test(self):
|
|
self.log.info("Add 8 outbounds to node 0")
|
|
for i in range(8):
|
|
self.log.info(f"outbound: {i}")
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i, connection_type="outbound-full-relay")
|
|
|
|
self.log.info("Add 2 block-relay-only connections to node 0")
|
|
for i in range(2):
|
|
self.log.info(f"block-relay-only: {i}")
|
|
# set p2p_idx based on the outbound connections already open to the
|
|
# node, so add 8 to account for the previous full-relay connections
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i + 8, connection_type="block-relay-only")
|
|
|
|
self.log.info("Add 2 block-relay-only connections to node 1")
|
|
for i in range(2):
|
|
self.log.info(f"block-relay-only: {i}")
|
|
self.nodes[1].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i, connection_type="block-relay-only")
|
|
|
|
self.log.info("Add 5 inbound connections to node 1")
|
|
for i in range(5):
|
|
self.log.info(f"inbound: {i}")
|
|
self.nodes[1].add_p2p_connection(P2PInterface())
|
|
|
|
self.log.info("Add 8 outbounds to node 1")
|
|
for i in range(8):
|
|
self.log.info(f"outbound: {i}")
|
|
# bump p2p_idx to account for the 2 existing outbounds on node 1
|
|
self.nodes[1].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i + 2)
|
|
|
|
self.log.info("Check the connections opened as expected")
|
|
check_node_connections(node=self.nodes[0], num_in=0, num_out=10)
|
|
check_node_connections(node=self.nodes[1], num_in=5, num_out=10)
|
|
|
|
self.log.info("Disconnect p2p connections & try to re-open")
|
|
self.nodes[0].disconnect_p2ps()
|
|
check_node_connections(node=self.nodes[0], num_in=0, num_out=0)
|
|
|
|
self.log.info("Add 8 outbounds to node 0")
|
|
for i in range(8):
|
|
self.log.info(f"outbound: {i}")
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i)
|
|
check_node_connections(node=self.nodes[0], num_in=0, num_out=8)
|
|
|
|
self.log.info("Add 2 block-relay-only connections to node 0")
|
|
for i in range(2):
|
|
self.log.info(f"block-relay-only: {i}")
|
|
# bump p2p_idx to account for the 8 existing outbounds on node 0
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i + 8, connection_type="block-relay-only")
|
|
check_node_connections(node=self.nodes[0], num_in=0, num_out=10)
|
|
|
|
self.log.info("Restart node 0 and try to reconnect to p2ps")
|
|
self.restart_node(0)
|
|
|
|
self.log.info("Add 4 outbounds to node 0")
|
|
for i in range(4):
|
|
self.log.info(f"outbound: {i}")
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i)
|
|
check_node_connections(node=self.nodes[0], num_in=0, num_out=4)
|
|
|
|
self.log.info("Add 2 block-relay-only connections to node 0")
|
|
for i in range(2):
|
|
self.log.info(f"block-relay-only: {i}")
|
|
# bump p2p_idx to account for the 4 existing outbounds on node 0
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i + 4, connection_type="block-relay-only")
|
|
check_node_connections(node=self.nodes[0], num_in=0, num_out=6)
|
|
|
|
check_node_connections(node=self.nodes[1], num_in=5, num_out=10)
|
|
|
|
self.log.info("Add 1 feeler connection to node 0")
|
|
feeler_conn = self.nodes[0].add_outbound_p2p_connection(P2PFeelerReceiver(), p2p_idx=6, connection_type="feeler")
|
|
|
|
# Feeler connection is closed
|
|
assert not feeler_conn.is_connected
|
|
|
|
# Verify version message received
|
|
assert_equal(feeler_conn.message_count["version"], 1)
|
|
# Feeler connections do not request tx relay
|
|
assert_equal(feeler_conn.last_message["version"].relay, 0)
|
|
|
|
if __name__ == '__main__':
|
|
P2PAddConnections().main()
|