async def ConnectionPairFactoryNotRunning( *, alice_handshakers: Tuple[HandshakerAPI[ProtocolAPI], ...] = (), bob_handshakers: Tuple[HandshakerAPI[ProtocolAPI], ...] = (), alice_remote: NodeAPI = None, alice_private_key: keys.PrivateKey = None, alice_client_version: str = 'alice', alice_p2p_version: int = DEVP2P_V5, bob_remote: NodeAPI = None, bob_private_key: keys.PrivateKey = None, bob_client_version: str = 'bob', bob_p2p_version: int = DEVP2P_V5, cancel_token: CancelToken = None, start_streams: bool = True, ) -> Tuple[ConnectionAPI, ConnectionAPI]: if alice_handshakers or bob_handshakers: # We only leverage `negotiate_protocol_handshakes` if we have actual # protocol handshakers since it raises `NoMatchingPeerCapabilities` if # there are no matching capabilities. alice_transport, bob_transport = MemoryTransportPairFactory( alice_remote=alice_remote, alice_private_key=alice_private_key, bob_remote=bob_remote, bob_private_key=bob_private_key, ) alice_devp2p_params = DevP2PHandshakeParamsFactory( client_version_string=alice_client_version, listen_port=alice_transport.remote.address.tcp_port, version=alice_p2p_version, ) bob_devp2p_params = DevP2PHandshakeParamsFactory( client_version_string=bob_client_version, listen_port=bob_transport.remote.address.tcp_port, version=bob_p2p_version, ) if cancel_token is None: cancel_token = CancelTokenFactory() ( (alice_multiplexer, alice_p2p_receipt, alice_protocol_receipts), (bob_multiplexer, bob_p2p_receipt, bob_protocol_receipts), ) = await asyncio.gather( negotiate_protocol_handshakes( alice_transport, alice_devp2p_params, alice_handshakers, cancel_token, ), negotiate_protocol_handshakes( bob_transport, bob_devp2p_params, bob_handshakers, cancel_token, ), ) else: # This path is just for testing to allow us to establish a `Connection` # without any protocols beyond the base p2p protocol. alice_multiplexer, bob_multiplexer = MultiplexerPairFactory( alice_remote=alice_remote, alice_private_key=alice_private_key, alice_p2p_version=alice_p2p_version, bob_remote=bob_remote, bob_private_key=bob_private_key, bob_p2p_version=bob_p2p_version, cancel_token=cancel_token, ) alice_p2p_receipt = DevP2PReceipt( protocol=alice_multiplexer.get_base_protocol(), version=bob_p2p_version, client_version_string=bob_client_version, capabilities=(), listen_port=bob_multiplexer.remote.address.tcp_port, remote_public_key=bob_multiplexer.remote.pubkey, ) bob_p2p_receipt = DevP2PReceipt( protocol=bob_multiplexer.get_base_protocol(), version=alice_p2p_version, client_version_string=alice_client_version, capabilities=(), listen_port=alice_multiplexer.remote.address.tcp_port, remote_public_key=alice_multiplexer.remote.pubkey, ) alice_protocol_receipts = () bob_protocol_receipts = () alice_connection = Connection( multiplexer=alice_multiplexer, devp2p_receipt=alice_p2p_receipt, protocol_receipts=alice_protocol_receipts, is_dial_out=True, ) bob_connection = Connection( multiplexer=bob_multiplexer, devp2p_receipt=bob_p2p_receipt, protocol_receipts=bob_protocol_receipts, is_dial_out=False, ) return alice_connection, bob_connection
async def test_server_incoming_connection(monkeypatch, server, event_loop, receiver_remote, ): use_eip8 = False token = CancelToken("initiator") initiator = HandshakeInitiator(receiver_remote, INITIATOR_PRIVKEY, use_eip8, token) initiator_remote = NodeFactory( pubkey=INITIATOR_PUBKEY, address__ip='127.0.0.1', ) for _ in range(10): # The server isn't listening immediately so we give it a short grace # period while trying to connect. try: reader, writer = await initiator.connect() except ConnectionRefusedError: await asyncio.sleep(0) else: break else: raise AssertionError("Unable to connect within 10 loops") # Send auth init message to the server, then read and decode auth ack aes_secret, mac_secret, egress_mac, ingress_mac = await _handshake( initiator, reader, writer, token) transport = Transport( remote=receiver_remote, private_key=initiator.privkey, reader=reader, writer=writer, aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac, ingress_mac=ingress_mac, ) factory = ParagonPeerFactory( initiator.privkey, context=ParagonContext(), token=token, ) handshakers = await factory.get_handshakers() devp2p_handshake_params = DevP2PHandshakeParamsFactory( listen_port=initiator_remote.address.tcp_port, ) multiplexer, devp2p_receipt, protocol_receipts = await negotiate_protocol_handshakes( transport=transport, p2p_handshake_params=devp2p_handshake_params, protocol_handshakers=handshakers, token=token, ) connection = Connection( multiplexer=multiplexer, devp2p_receipt=devp2p_receipt, protocol_receipts=protocol_receipts, is_dial_out=False, ) initiator_peer = factory.create_peer(connection=connection) # wait for peer to be processed for _ in range(100): if len(server.peer_pool) > 0: break await asyncio.sleep(0) assert len(server.peer_pool.connected_nodes) == 1 receiver_peer = list(server.peer_pool.connected_nodes.values())[0] assert isinstance(receiver_peer, ParagonPeer) assert initiator_peer.sub_proto is not None assert initiator_peer.sub_proto.name == receiver_peer.sub_proto.name assert initiator_peer.sub_proto.version == receiver_peer.sub_proto.version assert initiator_peer.remote.pubkey == RECEIVER_PRIVKEY.public_key
async def test_server_incoming_connection(server, receiver_remote): use_eip8 = False initiator = HandshakeInitiator(receiver_remote, INITIATOR_PRIVKEY, use_eip8) initiator_remote = NodeFactory( pubkey=INITIATOR_PUBKEY, address__ip='127.0.0.1', ) for num_retries in range(10): # The server isn't listening immediately so we give it a short grace # period while trying to connect. try: reader, writer = await initiator.connect() except ConnectionRefusedError: await asyncio.sleep(0 + 0.001 * num_retries) else: break else: raise AssertionError("Unable to connect within 10 loops") # Send auth init message to the server, then read and decode auth ack aes_secret, mac_secret, egress_mac, ingress_mac = await _handshake( initiator, reader, writer) transport = Transport( remote=receiver_remote, private_key=initiator.privkey, reader=reader, writer=writer, aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac, ingress_mac=ingress_mac, ) factory = ParagonPeerFactory( initiator.privkey, context=ParagonContext(), ) handshakers = await factory.get_handshakers() devp2p_handshake_params = DevP2PHandshakeParamsFactory( listen_port=initiator_remote.address.tcp_port, ) multiplexer, devp2p_receipt, protocol_receipts = await negotiate_protocol_handshakes( transport=transport, p2p_handshake_params=devp2p_handshake_params, protocol_handshakers=handshakers, ) connection = Connection( multiplexer=multiplexer, devp2p_receipt=devp2p_receipt, protocol_receipts=protocol_receipts, is_dial_out=False, ) initiator_peer = factory.create_peer(connection=connection) # wait for peer to be processed for _ in range(100): if len(server.peer_pool) > 0: break await asyncio.sleep(0) assert len(server.peer_pool.connected_nodes) == 1 receiver_peer = list(server.peer_pool.connected_nodes.values())[0] assert isinstance(receiver_peer, ParagonPeer) assert initiator_peer.sub_proto is not None assert initiator_peer.sub_proto.name == receiver_peer.sub_proto.name assert initiator_peer.sub_proto.version == receiver_peer.sub_proto.version assert initiator_peer.remote.pubkey == RECEIVER_PRIVKEY.public_key # Our connections are created manually and we don't call run() on them, so we need to stop the # background streaming task or else we'll get asyncio warnings about task exceptions not being # retrieved. await initiator_peer.connection._multiplexer.stop_streaming() await receiver_peer.connection._multiplexer.stop_streaming()