Repository: bitcoin/bitcoin
File: test/functional/test_framework/p2p.py (Python)

Code before:

    def peer_accept_connection(self, connect_id, connect_cb=lambda: None, *, net, timeout_factor, supports_v2_p2p, reconnect):
        self.peer_connect_helper('0', 0, net, timeout_factor)
        self.reconnect = reconnect
        if supports_v2_p2p:
            self.v2_state = EncryptedP2PState(initiating=False, net=net)

        logger.debug('Listening for Bitcoin Node with id: {}'.format(connect_id))
        return lambda: NetworkThread.listen(self, connect_cb, idx=connect_id)

    def peer_disconnect(self):
        # Connection could have already been closed by other end.
        NetworkThread.network_event_loop.call_soon_threadsafe(lambda: self._transport and self._transport.abort())

    # Connection and disconnection methods

    def connection_made(self, transport):
        """asyncio callback when a connection is opened."""
        assert not self._transport
        logger.debug("Connected & Listening: %s:%d" % (self.dstaddr, self.dstport))
        self._transport = transport
        # in an inbound connection to the TestNode with P2PConnection as the initiator, [TestNode <---- P2PConnection]
        # send the initial handshake immediately
        if self.supports_v2_p2p and self.v2_state.initiating and not self.v2_state.tried_v2_handshake:
            send_handshake_bytes = self.v2_state.initiate_v2_handshake()
            logger.debug(f"sending {len(self.v2_state.sent_garbage)} bytes of garbage data")
            self.send_raw_message(send_handshake_bytes)
        # for v1 outbound connections, send version message immediately after opening
        # (for v2 outbound connections, send it after the initial v2 handshake)
        if self.p2p_connected_to_node and not self.supports_v2_p2p:
            self.send_version()
        self.on_open()

    def connection_lost(self, exc):
        """asyncio callback when a connection is closed."""
        # don't display warning if reconnection needs to be attempted using v1 P2P
        if exc and not self.reconnect:
            logger.warning("Connection lost to {}:{} due to {}".format(self.dstaddr, self.dstport, exc))
        else:
            logger.debug("Closed connection to: %s:%d" % (self.dstaddr, self.dstport))
        self._transport = None
        self.recvbuf = b""
        self.on_close()

    # v2 handshake method
    def _on_data_v2_handshake(self):
        """v2 handshake performed before P2P messages are exchanged (see BIP324). P2PConnection is the initiator
        (in inbound connections to TestNode) and the responder (in outbound connections from TestNode).
        Performed by:
            * initiator using `initiate_v2_handshake()`, `complete_handshake()` and `authenticate_handshake()`
            * responder using `respond_v2_handshake()`, `complete_handshake()` and `authenticate_handshake()`

Review comment (suggestion):
https://github.com/bitcoin/bitcoin/pull/29420/commits/9a9b545c7fc044242c4dd8a4916b2ba13b3ea850

Why do we need to replace these values?
I changed this to:
```python
        assert self.dstaddr == them[0]
        assert self.dstport == them[1]
```
...and all the p2p tests still passed

Code after:
        return lambda: loop.call_soon_threadsafe(loop.create_task, coroutine)

    def peer_accept_connection(self, connect_id, connect_cb=lambda: None, *, net, timeout_factor, supports_v2_p2p, reconnect):
        self.peer_connect_helper('0', 0, net, timeout_factor)
        self.reconnect = reconnect
        if supports_v2_p2p:
            self.v2_state = EncryptedP2PState(initiating=False, net=net)

        logger.debug('Listening for Bitcoin Node with id: {}'.format(connect_id))
        return lambda: NetworkThread.listen(self, connect_cb, idx=connect_id)

    def peer_disconnect(self):
        # Connection could have already been closed by other end.
        NetworkThread.network_event_loop.call_soon_threadsafe(lambda: self._transport and self._transport.abort())

    # Connection and disconnection methods

    def connection_made(self, transport):
        """asyncio callback when a connection is opened."""
        assert not self._transport
        info = transport.get_extra_info("socket")
        us = info.getsockname()
        them = info.getpeername()
        logger.debug(f"Connected: us={us[0]}:{us[1]}, them={them[0]}:{them[1]}")
        self.dstaddr = them[0]
        self.dstport = them[1]
        self._transport = transport
        # in an inbound connection to the TestNode with P2PConnection as the initiator, [TestNode <---- P2PConnection]
        # send the initial handshake immediately
        if self.supports_v2_p2p and self.v2_state.initiating and not self.v2_state.tried_v2_handshake:
            send_handshake_bytes = self.v2_state.initiate_v2_handshake()
            logger.debug(f"sending {len(self.v2_state.sent_garbage)} bytes of garbage data")
            self.send_raw_message(send_handshake_bytes)
        # for v1 outbound connections, send version message immediately after opening
        # (for v2 outbound connections, send it after the initial v2 handshake)
        if self.p2p_connected_to_node and not self.supports_v2_p2p:
            self.send_version()
        self.on_open()

    def connection_lost(self, exc):
        """asyncio callback when a connection is closed."""
        # don't display warning if reconnection needs to be attempted using v1 P2P
        if exc and not self.reconnect:
            logger.warning("Connection lost to {}:{} due to {}".format(self.dstaddr, self.dstport, exc))
        else:
            logger.debug("Closed connection to: %s:%d" % (self.dstaddr, self.dstport))
        self._transport = None
        self.recvbuf = b""
        self.on_close()

    # v2 handshake method