Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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()