def info_from_p2p_addr(addr: multiaddr.Multiaddr) -> PeerInfo: if not addr: raise InvalidAddrError("`addr` should not be `None`") if not isinstance(addr, multiaddr.Multiaddr): raise InvalidAddrError(f"`addr`={addr} should be of type `Multiaddr`") parts = addr.split() if not parts: raise InvalidAddrError( f"`parts`={parts} should at least have a protocol `P_P2P`") p2p_part = parts[-1] last_protocol_code = p2p_part.protocols()[0].code if last_protocol_code != multiaddr.protocols.P_P2P: raise InvalidAddrError( f"The last protocol should be `P_P2P` instead of `{last_protocol_code}`" ) # make sure the /p2p value parses as a peer.ID peer_id_str = p2p_part.value_for_protocol(multiaddr.protocols.P_P2P) peer_id = id_b58_decode(peer_id_str) # we might have received just an / p2p part, which means there's no addr. if len(parts) > 1: addr = multiaddr.Multiaddr.join(*parts[:-1]) peer_data = PeerData() peer_data.addrs = [addr] peer_data.protocols = [p.code for p in addr.protocols()] return PeerInfo(peer_id, peer_data)
def parse_conn_protocol(maddr: Multiaddr) -> int: proto_codes = set(proto.code for proto in maddr.protocols()) proto_cand = proto_codes.intersection(SUPPORT_CONN_PROTOCOLS) if len(proto_cand) != 1: raise ValueError( f"connection protocol should be only one protocol out of {SUPPORTED_PROTOS}" f", maddr={maddr}" ) return tuple(proto_cand)[0]
def parse_conn_protocol(maddr: Multiaddr) -> int: proto_codes = set(proto.code for proto in maddr.protocols()) proto_cand = proto_codes.intersection(_supported_conn_protocols) if len(proto_cand) != 1: supported_protos = (protocols.protocol_with_code(proto) for proto in _supported_conn_protocols) raise ValueError( f"connection protocol should be only one protocol out of {supported_protos}" f", maddr={maddr}") return tuple(proto_cand)[0]
def multiAddrTcp4(maddr): ipaddr, port = None, 0 try: multi = Multiaddr(maddr) except BaseException: return ipaddr, port for proto in multi.protocols(): if proto.name == 'ip4': ipaddr = multi.value_for_protocol(proto.code) if proto.name == 'tcp': port = int(multi.value_for_protocol(proto.code)) return ipaddr, port
def multiAddrTcp4(maddr): ipaddr, port = None, 0 try: multi = Multiaddr(maddr) except BaseException as err: log.debug(f'Invalid multiaddr {maddr}, error: {err}') return ipaddr, port for proto in multi.protocols(): if proto.name == 'ip4': ipaddr = multi.value_for_protocol(proto.code) if proto.name == 'tcp': port = int(multi.value_for_protocol(proto.code)) return ipaddr, port
def log_peer(peer): # needed because Multiaddr library not support ipfs protocol (suppressed by p2p) # for more info see this table: # https://github.com/multiformats/multiaddr/blob/master/protocols.csv multiaddr = Multiaddr(peer['Addr'].replace('/ipfs', '/p2p')) # get list of protocols in the multiaddress protocols = [] for p in multiaddr.protocols(): protocols.append(p.name) # find the location of the IP address location = find_ip(multiaddr) country = location['country_name'] if location else "Unknown" # retrieve the latency, converting it in milliseconds (as float) try: if peer['Latency'].endswith('ms'): # latency in milliseconds latency = round(float(peer['Latency'].replace("ms", "")), 4) elif 'm' in peer['Latency']: # latency in minutes latency_parts = peer['Latency'].split('m', 2) latency = (float(latency_parts[0]) * 60000) + float(latency_parts[1].replace("s", "")) * 1000 latency = round(latency, 4) elif peer['Latency'].endswith('s'): # latency in seconds latency = round(float(peer['Latency'].replace("s", "")) * 1000, 4) else: latency = "" except ValueError: latency = "" return { "peer": peer['Peer'], "protocols": "\"" + str(protocols) + "\"", "latency": latency, "country": country, "direction": peer['Direction'] }