Beispiel #1
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
Beispiel #2
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
Beispiel #3
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