Ejemplo n.º 1
0
async def handshake(
    remote: Node,
    privkey: datatypes.PrivateKey,
    peer_class: 'Type[BasePeer]',
    chaindb: ChainDB,
    network_id: int,
) -> 'BasePeer':
    """Perform the auth and P2P handshakes with the given remote.

    Return an instance of the given peer_class (must be a subclass of BasePeer) connected to that
    remote in case both handshakes are successful and at least one of the sub-protocols supported
    by peer_class is also supported by the remote.

    Raises UnreachablePeer if we cannot connect to the peer or HandshakeFailure if the remote
    disconnects before completing the handshake or if none of the sub-protocols supported by us is
    also supported by the remote.
    """
    try:
        (aes_secret, mac_secret, egress_mac, ingress_mac, reader,
         writer) = await auth.handshake(remote, privkey)
    except (ConnectionRefusedError, OSError) as e:
        raise UnreachablePeer(e)
    peer = peer_class(remote=remote,
                      privkey=privkey,
                      reader=reader,
                      writer=writer,
                      aes_secret=aes_secret,
                      mac_secret=mac_secret,
                      egress_mac=egress_mac,
                      ingress_mac=ingress_mac,
                      chaindb=chaindb,
                      network_id=network_id)
    await peer.do_p2p_handshake()
    await peer.do_sub_proto_handshake()
    return peer
Ejemplo n.º 2
0
async def handshake(
    remote: Node,
    privkey: datatypes.PrivateKey,
    peer_class: 'Type[BasePeer]',
    chaindb: BaseChainDB,
    network_id: int,
    received_msg_callback: Optional[_ReceivedMsgCallbackType] = None
) -> 'BasePeer':
    """Perform the auth and P2P handshakes with the given remote.

    Return an instance of the given peer_class (must be a subclass of BasePeer) connected to that
    remote in case both handshakes are successful and at least one of the sub-protocols supported
    by peer_class is also supported by the remote.

    Raises UnreachablePeer if we cannot connect to the peer or UselessPeer if none of the
    sub-protocols supported by us is also supported by the remote.
    """
    try:
        (aes_secret, mac_secret, egress_mac, ingress_mac, reader,
         writer) = await auth.handshake(remote, privkey)
    except (ConnectionRefusedError, OSError) as e:
        raise UnreachablePeer(e)
    peer = peer_class(remote=remote,
                      privkey=privkey,
                      reader=reader,
                      writer=writer,
                      aes_secret=aes_secret,
                      mac_secret=mac_secret,
                      egress_mac=egress_mac,
                      ingress_mac=ingress_mac,
                      chaindb=chaindb,
                      network_id=network_id,
                      received_msg_callback=received_msg_callback)
    peer.base_protocol.send_handshake()
    msg = await peer.read_msg()
    cmd, decoded = peer.process_msg(msg)
    if isinstance(cmd, Disconnect):
        # Peers may send a disconnect msg before they send the initial P2P handshake (e.g. when
        # they're not accepting more peers), so we special case that here because it's important
        # to distinguish this from a failed handshake (e.g. no matching protocols, etc).
        decoded = cast(Dict[str, Any], decoded)
        raise PeerDisconnected(
            "Peer disconnected before completing handshake: {}".format(
                decoded['reason_name']))
    if len(peer.enabled_sub_protocols) == 0:
        raise UselessPeer("No matching sub-protocols")
    for proto in peer.enabled_sub_protocols:
        proto.send_handshake(peer._local_chain_info)
    return peer
Ejemplo n.º 3
0
async def handshake(remote, privkey, peer_class, chaindb, network_id):
    """Perform the auth and P2P handshakes with the given remote.

    Return an instance of the given peer_class (must be a subclass of BasePeer) connected to that
    remote in case both handshakes are successful and at least one of the sub-protocols supported
    by peer_class is also supported by the remote.

    Raises UnreachablePeer if we cannot connect to the peer or UselessPeer if none of the
    sub-protocols supported by us is also supported by the remote.
    """
    try:
        (aes_secret, mac_secret, egress_mac, ingress_mac, reader,
         writer) = await auth.handshake(remote, privkey)
    except (ConnectionRefusedError, OSError) as e:
        raise UnreachablePeer(e)
    peer = peer_class(remote=remote,
                      privkey=privkey,
                      reader=reader,
                      writer=writer,
                      aes_secret=aes_secret,
                      mac_secret=mac_secret,
                      egress_mac=egress_mac,
                      ingress_mac=ingress_mac,
                      chaindb=chaindb,
                      network_id=network_id)
    peer.base_protocol.send_handshake()
    msg = await peer.read_msg()
    decoded = peer.process_msg(msg)
    if get_devp2p_cmd_id(msg) == Disconnect._cmd_id:
        # Peers may send a disconnect msg before they send the initial P2P handshake (e.g. when
        # they're not accepting more peers), so we special case that here because it's important
        # to distinguish this from a failed handshake (e.g. no matching protocols, etc).
        raise PeerDisconnected("{} disconnected before handshake: {}".format(
            peer, decoded['reason_name']))
    if len(peer.enabled_sub_protocols) == 0:
        raise UselessPeer("No matching sub-protocols with {}".format(peer))
    for proto in peer.enabled_sub_protocols:
        proto.send_handshake(peer.head_info)
    return peer
Ejemplo n.º 4
0
async def handshake(
    remote: Node,
    privkey: datatypes.PrivateKey,
    peer_class: 'Type[BasePeer]',
    chaindb: BaseChainDB,
    network_id: int,
    received_msg_callback: Optional[_ReceivedMsgCallbackType] = None
) -> 'BasePeer':
    """Perform the auth and P2P handshakes with the given remote.

    Return an instance of the given peer_class (must be a subclass of BasePeer) connected to that
    remote in case both handshakes are successful and at least one of the sub-protocols supported
    by peer_class is also supported by the remote.

    Raises UnreachablePeer if we cannot connect to the peer or UselessPeer if none of the
    sub-protocols supported by us is also supported by the remote.
    """
    try:
        (aes_secret, mac_secret, egress_mac, ingress_mac, reader,
         writer) = await auth.handshake(remote, privkey)
    except (ConnectionRefusedError, OSError) as e:
        raise UnreachablePeer(e)
    peer = peer_class(remote=remote,
                      privkey=privkey,
                      reader=reader,
                      writer=writer,
                      aes_secret=aes_secret,
                      mac_secret=mac_secret,
                      egress_mac=egress_mac,
                      ingress_mac=ingress_mac,
                      chaindb=chaindb,
                      network_id=network_id,
                      received_msg_callback=received_msg_callback)
    await peer.do_p2p_handshake()
    if peer.sub_proto is None:
        raise UselessPeer("No matching sub-protocols")
    await peer.do_sub_proto_handshake()
    return peer