async def test_handshake_with_single_protocol(): token = CancelTokenFactory() alice_transport, bob_transport = MemoryTransportPairFactory() alice_p2p_params = DevP2PHandshakeParamsFactory( client_version_string='alice-client', listen_port=alice_transport.remote.address.tcp_port, ) bob_p2p_params = DevP2PHandshakeParamsFactory( client_version_string='bob-client', listen_port=bob_transport.remote.address.tcp_port, ) protocol_class = ProtocolFactory() alice_coro = negotiate_protocol_handshakes( alice_transport, alice_p2p_params, (NoopHandshaker(protocol_class), ), token=token, ) bob_coro = negotiate_protocol_handshakes( bob_transport, bob_p2p_params, (NoopHandshaker(protocol_class), ), token=token, ) alice_result, bob_result = await asyncio.gather(alice_coro, bob_coro) alice_multiplexer, alice_p2p_receipt, alice_receipts = alice_result bob_multiplexer, bob_p2p_receipt, bob_receipts = bob_result assert len(alice_receipts) == 1 assert len(bob_receipts) == 1 alice_receipt = alice_receipts[0] bob_receipt = bob_receipts[0] assert alice_p2p_receipt.client_version_string == 'bob-client' assert bob_p2p_receipt.client_version_string == 'alice-client' assert isinstance(alice_receipt.protocol, protocol_class) assert isinstance(bob_receipt.protocol, protocol_class) assert isinstance(alice_multiplexer.get_base_protocol(), P2PProtocolV5) assert isinstance(alice_multiplexer.get_protocols()[0], P2PProtocolV5) assert isinstance(alice_multiplexer.get_protocols()[1], protocol_class) assert isinstance(bob_multiplexer.get_base_protocol(), P2PProtocolV5) assert isinstance(bob_multiplexer.get_protocols()[0], P2PProtocolV5) assert isinstance(bob_multiplexer.get_protocols()[1], protocol_class) alice_p2p_protocol = alice_p2p_receipt.protocol assert alice_p2p_protocol.snappy_support is True bob_p2p_protocol = bob_p2p_receipt.protocol assert bob_p2p_protocol.snappy_support is True
async def test_handshake_with_v4_and_v5_disables_snappy(): token = CancelTokenFactory() alice_transport, bob_transport = MemoryTransportPairFactory() alice_p2p_params = DevP2PHandshakeParamsFactory( client_version_string='alice-client', listen_port=alice_transport.remote.address.tcp_port, ) bob_p2p_params = DevP2PHandshakeParams( client_version_string='bob-client', listen_port=bob_transport.remote.address.tcp_port, version=4, ) protocol_class = ProtocolFactory() alice_coro = negotiate_protocol_handshakes( alice_transport, alice_p2p_params, (NoopHandshaker(protocol_class), ), token=token, ) bob_coro = negotiate_protocol_handshakes( bob_transport, bob_p2p_params, (NoopHandshaker(protocol_class), ), token=token, ) alice_result, bob_result = await asyncio.gather(alice_coro, bob_coro) alice_multiplexer, alice_p2p_receipt, alice_receipts = alice_result bob_multiplexer, bob_p2p_receipt, bob_receipts = bob_result alice_p2p_protocol = alice_p2p_receipt.protocol bob_p2p_protocol = bob_p2p_receipt.protocol assert isinstance(alice_p2p_protocol, P2PProtocolV5) assert alice_p2p_protocol.snappy_support is False assert isinstance(bob_p2p_protocol, P2PProtocolV4) assert bob_p2p_protocol.snappy_support is False
async def _do_handshake(alice_handshakers, alice_version, bob_handshakers, bob_version): alice_transport, bob_transport = MemoryTransportPairFactory() alice_p2p_params = DevP2PHandshakeParamsFactory( client_version_string='alice-client', listen_port=alice_transport.remote.address.tcp_port, version=alice_version, ) bob_p2p_params = DevP2PHandshakeParams( client_version_string='bob-client', listen_port=bob_transport.remote.address.tcp_port, version=bob_version, ) alice_coro = negotiate_protocol_handshakes( alice_transport, alice_p2p_params, alice_handshakers, ) bob_coro = negotiate_protocol_handshakes( bob_transport, bob_p2p_params, bob_handshakers, ) alice_result, bob_result = await asyncio.gather(alice_coro, bob_coro) alice_multiplexer, alice_p2p_receipt, alice_receipts = alice_result bob_multiplexer, bob_p2p_receipt, bob_receipts = bob_result yield (alice_multiplexer, alice_p2p_receipt, alice_receipts, bob_multiplexer, bob_p2p_receipt, bob_receipts) # Need to manually stop the background streaming task started by # negotiate_protocol_handshakes() because we never use the multiplexers in a Connection, which # would do that for us. await alice_multiplexer.stop_streaming() await bob_multiplexer.stop_streaming()
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_handshake_with_multiple_protocols(): A1 = ProtocolFactory(name='a', version=1) A2 = ProtocolFactory(name='a', version=2) A3 = ProtocolFactory(name='a', version=3) B5 = ProtocolFactory(name='b', version=5) B6 = ProtocolFactory(name='b', version=6) B7 = ProtocolFactory(name='b', version=7) C2 = ProtocolFactory(name='c', version=2) C3 = ProtocolFactory(name='c', version=3) alice_protos = (A1, A2, A3, B5, B7, C3) bob_protos = (A2, B6, C3, C2) # expected overlap A2, C3 alice_handshakers = tuple(map(NoopHandshaker, alice_protos)) bob_handshakers = tuple(map(NoopHandshaker, bob_protos)) token = CancelTokenFactory() alice_transport, bob_transport = MemoryTransportPairFactory() alice_p2p_params = DevP2PHandshakeParamsFactory( client_version_string='alice-client', listen_port=alice_transport.remote.address.tcp_port, ) bob_p2p_params = DevP2PHandshakeParamsFactory( client_version_string='bob-client', listen_port=bob_transport.remote.address.tcp_port, ) alice_coro = negotiate_protocol_handshakes( alice_transport, alice_p2p_params, alice_handshakers, token=token, ) bob_coro = negotiate_protocol_handshakes( bob_transport, bob_p2p_params, bob_handshakers, token=token, ) alice_result, bob_result = await asyncio.gather(alice_coro, bob_coro) alice_multiplexer, alice_p2p_receipt, alice_receipts = alice_result bob_multiplexer, bob_p2p_receipt, bob_receipts = bob_result assert len(alice_receipts) == 2 assert len(bob_receipts) == 2 assert isinstance(alice_p2p_receipt.protocol, P2PProtocolV5) assert isinstance(alice_receipts[0].protocol, A2) assert isinstance(alice_receipts[1].protocol, C3) assert isinstance(alice_p2p_receipt.protocol, P2PProtocolV5) assert isinstance(bob_receipts[0].protocol, A2) assert isinstance(bob_receipts[1].protocol, C3) assert isinstance(alice_multiplexer.get_base_protocol(), P2PProtocolV5) assert isinstance(alice_multiplexer.get_protocols()[0], P2PProtocolV5) assert isinstance(alice_multiplexer.get_protocols()[1], A2) assert isinstance(alice_multiplexer.get_protocols()[2], C3) assert isinstance(bob_multiplexer.get_base_protocol(), P2PProtocolV5) assert isinstance(bob_multiplexer.get_protocols()[0], P2PProtocolV5) assert isinstance(bob_multiplexer.get_protocols()[1], A2) assert isinstance(bob_multiplexer.get_protocols()[2], C3)