mirror of https://github.com/waku-org/nwaku.git
chore(core): move peers utils module to waku_core
This commit is contained in:
parent
67e96ba894
commit
e041e04342
|
@ -33,7 +33,6 @@ import
|
|||
../../waku/v2/node/waku_metrics,
|
||||
../../waku/v2/node/peer_manager,
|
||||
../../waku/v2/utils/compat,
|
||||
../../waku/v2/utils/peers,
|
||||
../../waku/common/utils/nat,
|
||||
./config_chat2
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ import
|
|||
libp2p/errors,
|
||||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/waku_node,
|
||||
../../../waku/v2/utils/peers,
|
||||
../../../waku/v2/node/peer_manager,
|
||||
../../waku/v2/waku_filter,
|
||||
../../waku/v2/waku_store,
|
||||
|
|
|
@ -46,7 +46,6 @@ import
|
|||
../../waku/v2/waku_discv5,
|
||||
../../waku/v2/waku_peer_exchange,
|
||||
../../waku/v2/waku_relay/validators,
|
||||
../../waku/v2/utils/peers,
|
||||
./wakunode2_setup_rest,
|
||||
./wakunode2_setup_rpc,
|
||||
./config
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
import
|
||||
./v2/waku_core/test_namespaced_topics,
|
||||
./v2/waku_core/test_time,
|
||||
./v2/waku_core/test_message_digest
|
||||
./v2/waku_core/test_message_digest,
|
||||
./v2/waku_core/test_peers
|
||||
|
||||
|
||||
# Waku archive test suite
|
||||
|
@ -50,7 +51,6 @@ import
|
|||
./v2/test_wakunode_filter,
|
||||
./v2/test_waku_peer_exchange,
|
||||
./v2/test_peer_store_extended,
|
||||
./v2/test_utils_peers,
|
||||
./v2/test_message_cache,
|
||||
./v2/test_peer_manager,
|
||||
./v2/test_peer_storage,
|
||||
|
|
|
@ -10,8 +10,8 @@ import
|
|||
libp2p/crypto/crypto,
|
||||
libp2p/protocols/pubsub/gossipsub
|
||||
import
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/waku_node,
|
||||
../../waku/v2/utils/peers,
|
||||
./testlib/wakucore,
|
||||
./testlib/wakunode
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ import
|
|||
libp2p/stream/connection,
|
||||
libp2p/crypto/crypto
|
||||
import
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/waku_node,
|
||||
../../waku/v2/utils/peers,
|
||||
./testlib/wakucore,
|
||||
./testlib/wakunode
|
||||
|
||||
|
|
|
@ -17,12 +17,11 @@ import
|
|||
libp2p/nameresolving/mockresolver,
|
||||
eth/p2p/discoveryv5/enr
|
||||
import
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/waku_node,
|
||||
../../waku/v2/node/peer_manager,
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/waku_relay,
|
||||
../../waku/v2/waku_peer_exchange,
|
||||
../../waku/v2/utils/peers,
|
||||
./testlib/wakucore,
|
||||
./testlib/wakunode
|
||||
|
||||
|
|
|
@ -7,10 +7,9 @@ import
|
|||
chronos,
|
||||
libp2p/crypto/crypto
|
||||
import
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/node/peer_manager,
|
||||
../../waku/v2/waku_node,
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/utils/peers,
|
||||
./testlib/common,
|
||||
./testlib/wakucore,
|
||||
./testlib/wakunode
|
||||
|
|
|
@ -11,7 +11,6 @@ import
|
|||
../../waku/v2/waku_core,
|
||||
../../waku/v2/waku_lightpush,
|
||||
../../waku/v2/node/peer_manager,
|
||||
../../waku/v2/utils/peers,
|
||||
../../waku/v2/waku_node,
|
||||
./testlib/common,
|
||||
./testlib/wakucore,
|
||||
|
|
|
@ -7,9 +7,9 @@ import
|
|||
libp2p/peerid,
|
||||
libp2p/errors
|
||||
import
|
||||
../../waku/v2/utils/peers
|
||||
../../waku/v2/waku_core
|
||||
|
||||
suite "Utils - Peers":
|
||||
suite "Waku Core - Peers":
|
||||
|
||||
test "Peer info parses correctly":
|
||||
## Given
|
|
@ -20,7 +20,6 @@ import
|
|||
import
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/node/peer_manager,
|
||||
../../waku/v2/utils/peers,
|
||||
../../waku/v2/waku_node,
|
||||
../../waku/v2/waku_relay,
|
||||
../../waku/v2/waku_relay/validators,
|
||||
|
|
|
@ -14,11 +14,10 @@ import
|
|||
libp2p/protocols/pubsub/pubsub,
|
||||
eth/keys
|
||||
import
|
||||
../../../waku/v2/waku_node,
|
||||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/waku_node,
|
||||
../../../waku/v2/waku_rln_relay,
|
||||
../../../waku/v2/waku_keystore,
|
||||
../../../waku/v2/utils/peers,
|
||||
../testlib/wakucore,
|
||||
../testlib/wakunode
|
||||
|
||||
|
|
|
@ -14,13 +14,12 @@ import
|
|||
libp2p/protocols/pubsub/gossipsub
|
||||
import
|
||||
../../../waku/common/sqlite,
|
||||
../../../waku/v2/node/peer_manager,
|
||||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/node/peer_manager,
|
||||
../../../waku/v2/waku_archive,
|
||||
../../../waku/v2/waku_archive/driver/sqlite_driver,
|
||||
../../../waku/v2/waku_store,
|
||||
../../../waku/v2/waku_filter,
|
||||
../../../waku/v2/utils/peers,
|
||||
../../../waku/v2/waku_node,
|
||||
../testlib/common,
|
||||
../testlib/wakucore,
|
||||
|
|
|
@ -10,6 +10,7 @@ import
|
|||
libp2p/crypto/crypto,
|
||||
json_rpc/[rpcserver, rpcclient]
|
||||
import
|
||||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/node/peer_manager,
|
||||
../../../waku/v2/waku_node,
|
||||
../../../waku/v2/node/jsonrpc/admin/handlers as admin_api,
|
||||
|
@ -19,7 +20,6 @@ import
|
|||
../../../waku/v2/waku_archive/driver/queue_driver,
|
||||
../../../waku/v2/waku_store,
|
||||
../../../waku/v2/waku_filter,
|
||||
../../../waku/v2/utils/peers,
|
||||
../testlib/wakucore,
|
||||
../testlib/wakunode
|
||||
|
||||
|
|
|
@ -8,16 +8,15 @@ import
|
|||
libp2p/crypto/crypto,
|
||||
json_rpc/[rpcserver, rpcclient]
|
||||
import
|
||||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/node/peer_manager,
|
||||
../../../waku/v2/waku_node,
|
||||
../../../waku/v2/node/message_cache,
|
||||
../../../waku/v2/node/jsonrpc/filter/handlers as filter_api,
|
||||
../../../waku/v2/node/jsonrpc/filter/client as filter_api_client,
|
||||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/waku_filter,
|
||||
../../../waku/v2/waku_filter/rpc,
|
||||
../../../waku/v2/waku_filter/client,
|
||||
../../../waku/v2/utils/peers,
|
||||
../testlib/wakucore,
|
||||
../testlib/wakunode
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import
|
|||
json_rpc/[rpcserver, rpcclient]
|
||||
import
|
||||
../../../waku/common/base64,
|
||||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/node/peer_manager,
|
||||
../../../waku/v2/node/message_cache,
|
||||
../../../waku/v2/waku_node,
|
||||
|
@ -17,7 +18,6 @@ import
|
|||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/waku_relay,
|
||||
../../../waku/v2/utils/compat,
|
||||
../../../waku/v2/utils/peers,
|
||||
../testlib/common,
|
||||
../testlib/wakucore,
|
||||
../testlib/wakunode
|
||||
|
|
|
@ -8,8 +8,8 @@ import
|
|||
libp2p/crypto/crypto,
|
||||
json_rpc/[rpcserver, rpcclient]
|
||||
import
|
||||
../../../waku/v2/node/peer_manager,
|
||||
../../../waku/v2/waku_core,
|
||||
../../../waku/v2/node/peer_manager,
|
||||
../../../waku/v2/waku_node,
|
||||
../../../waku/v2/node/jsonrpc/store/handlers as store_api,
|
||||
../../../waku/v2/node/jsonrpc/store/client as store_api_client,
|
||||
|
@ -17,7 +17,6 @@ import
|
|||
../../../waku/v2/waku_archive/driver/queue_driver,
|
||||
../../../waku/v2/waku_store,
|
||||
../../../waku/v2/waku_store/rpc,
|
||||
../../../waku/v2/utils/peers,
|
||||
../../v2/testlib/common,
|
||||
../../v2/testlib/wakucore,
|
||||
../../v2/testlib/wakunode
|
||||
|
|
|
@ -21,7 +21,6 @@ import
|
|||
../../../waku/v2/waku_archive,
|
||||
../../../waku/v2/waku_archive/driver/queue_driver,
|
||||
../../../waku/v2/waku_store as waku_store,
|
||||
../../../waku/v2/utils/peers,
|
||||
../../v2/testlib/common,
|
||||
../../v2/testlib/wakucore,
|
||||
../../v2/testlib/wakunode
|
||||
|
|
|
@ -20,7 +20,6 @@ import
|
|||
../../waku/v2/waku_core,
|
||||
../../waku/v2/waku_node,
|
||||
../../waku/v2/utils/compat,
|
||||
../../waku/v2/utils/peers,
|
||||
../test_helpers
|
||||
|
||||
import
|
||||
|
|
|
@ -20,13 +20,12 @@ import
|
|||
metrics/chronos_httpserver,
|
||||
presto/[route, server, client]
|
||||
import
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/node/peer_manager,
|
||||
../../waku/v2/waku_node,
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/waku_enr,
|
||||
../../waku/v2/waku_discv5,
|
||||
../../waku/v2/waku_dnsdisc,
|
||||
../../waku/v2/utils/peers,
|
||||
./networkmonitor_metrics,
|
||||
./networkmonitor_config,
|
||||
./networkmonitor_utils
|
||||
|
|
|
@ -11,8 +11,8 @@ import
|
|||
libp2p/multicodec
|
||||
import
|
||||
../../waku/v2/node/peer_manager,
|
||||
../../waku/v2/waku_node,
|
||||
../../waku/v2/utils/peers
|
||||
../../waku/v2/waku_core,
|
||||
../../waku/v2/waku_node
|
||||
|
||||
# protocols and their tag
|
||||
const ProtocolsTable = {
|
||||
|
|
|
@ -13,8 +13,8 @@ import
|
|||
libp2p/muxers/muxer
|
||||
import
|
||||
../../../common/nimchronos,
|
||||
../../waku_core,
|
||||
../../waku_relay,
|
||||
../../utils/peers,
|
||||
./peer_store/peer_storage,
|
||||
./waku_peer_store
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ else:
|
|||
import
|
||||
stew/results
|
||||
import
|
||||
../waku_peer_store,
|
||||
../../../utils/peers
|
||||
../../../waku_core,
|
||||
../waku_peer_store
|
||||
|
||||
## This module defines a peer storage interface. Implementations of
|
||||
## PeerStorage are used to store and retrieve peers
|
||||
|
|
|
@ -11,8 +11,8 @@ import
|
|||
libp2p/protobuf/minprotobuf
|
||||
import
|
||||
../../../../common/sqlite,
|
||||
../../../waku_core,
|
||||
../waku_peer_store,
|
||||
../../../utils/peers,
|
||||
./peer_storage
|
||||
|
||||
export sqlite
|
||||
|
|
|
@ -4,14 +4,14 @@ else:
|
|||
{.push raises: [].}
|
||||
|
||||
import
|
||||
std/[tables, sequtils, sets, options, times, math, strutils],
|
||||
std/[tables, sequtils, sets, options, times, strutils],
|
||||
chronos,
|
||||
eth/p2p/discoveryv5/enr,
|
||||
libp2p/builders,
|
||||
libp2p/peerstore
|
||||
|
||||
import
|
||||
../../utils/peers,
|
||||
../../waku_core,
|
||||
../../../common/utils/sequence
|
||||
|
||||
export peerstore, builders
|
||||
|
|
|
@ -38,7 +38,6 @@ import
|
|||
../waku_dnsdisc,
|
||||
../waku_discv5,
|
||||
../waku_peer_exchange,
|
||||
../utils/peers,
|
||||
./config,
|
||||
./peer_manager,
|
||||
./waku_switch
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# :warning: DEPRECATION NOTICE :warning:
|
||||
|
||||
The `utils` module has been marked as deprecated.
|
||||
This package submodules are planned to be moved to different modules.
|
||||
|
||||
**No new sub-modules must be added to this folder.**
|
|
@ -1,4 +0,0 @@
|
|||
# Utils
|
||||
|
||||
Collection of misc utilities that don't fit anywhere else, and are used by
|
||||
multiple independent modules.
|
|
@ -1,261 +0,0 @@
|
|||
when (NimMajor, NimMinor) < (1, 4):
|
||||
{.push raises: [Defect].}
|
||||
else:
|
||||
{.push raises: [].}
|
||||
|
||||
# Collection of utilities related to Waku peers
|
||||
import
|
||||
std/[options, sequtils, strutils, uri],
|
||||
chronos,
|
||||
stew/results,
|
||||
stew/shims/net,
|
||||
eth/keys,
|
||||
eth/p2p/discoveryv5/enr,
|
||||
libp2p/crypto/[crypto, secp],
|
||||
libp2p/[errors,
|
||||
multiaddress,
|
||||
multicodec,
|
||||
peerid,
|
||||
peerinfo,
|
||||
routing_record]
|
||||
|
||||
#import
|
||||
# ../node/peer_manager/waku_peer_store
|
||||
# todo organize this
|
||||
|
||||
type
|
||||
Connectedness* = enum
|
||||
# NotConnected: default state for a new peer. No connection and no further information on connectedness.
|
||||
NotConnected,
|
||||
# CannotConnect: attempted to connect to peer, but failed.
|
||||
CannotConnect,
|
||||
# CanConnect: was recently connected to peer and disconnected gracefully.
|
||||
CanConnect,
|
||||
# Connected: actively connected to peer.
|
||||
Connected
|
||||
|
||||
PeerOrigin* = enum
|
||||
UnknownOrigin,
|
||||
Discv5,
|
||||
Static,
|
||||
PeerExcahnge,
|
||||
Dns
|
||||
|
||||
PeerDirection* = enum
|
||||
UnknownDirection,
|
||||
Inbound,
|
||||
Outbound
|
||||
|
||||
type
|
||||
RemotePeerInfo* = ref object of RootObj
|
||||
peerId*: PeerID
|
||||
addrs*: seq[MultiAddress]
|
||||
enr*: Option[enr.Record]
|
||||
protocols*: seq[string]
|
||||
|
||||
agent*: string
|
||||
protoVersion*: string
|
||||
publicKey*: crypto.PublicKey
|
||||
connectedness*: Connectedness
|
||||
disconnectTime*: int64
|
||||
origin*: PeerOrigin
|
||||
direction*: PeerDirection
|
||||
lastFailedConn*: Moment
|
||||
numberFailedConn*: int
|
||||
|
||||
func `$`*(remotePeerInfo: RemotePeerInfo): string =
|
||||
$remotePeerInfo.peerId
|
||||
|
||||
proc init*(
|
||||
p: typedesc[RemotePeerInfo],
|
||||
peerId: PeerID,
|
||||
addrs: seq[MultiAddress] = @[],
|
||||
enr: Option[enr.Record] = none(enr.Record),
|
||||
protocols: seq[string] = @[]): RemotePeerInfo =
|
||||
|
||||
let remotePeerInfo = RemotePeerInfo(
|
||||
peerId: peerId,
|
||||
addrs: addrs,
|
||||
enr: enr,
|
||||
protocols: protocols)
|
||||
|
||||
return remotePeerInfo
|
||||
|
||||
proc init*(p: typedesc[RemotePeerInfo],
|
||||
peerId: string,
|
||||
addrs: seq[MultiAddress] = @[],
|
||||
enr: Option[enr.Record] = none(enr.Record),
|
||||
protocols: seq[string] = @[]): RemotePeerInfo
|
||||
{.raises: [Defect, ResultError[cstring], LPError].} =
|
||||
|
||||
let remotePeerInfo = RemotePeerInfo(
|
||||
peerId: PeerID.init(peerId).tryGet(),
|
||||
addrs: addrs,
|
||||
enr: enr,
|
||||
protocols: protocols)
|
||||
|
||||
return remotePeerInfo
|
||||
|
||||
## Check if wire Address is supported
|
||||
proc validWireAddr*(ma: MultiAddress): bool =
|
||||
const
|
||||
ValidTransports = mapOr(TCP, WebSockets)
|
||||
return ValidTransports.match(ma)
|
||||
|
||||
func getTransportProtocol(typedR: TypedRecord): Option[IpTransportProtocol] =
|
||||
if typedR.tcp6.isSome or typedR.tcp.isSome:
|
||||
return some(IpTransportProtocol.tcpProtocol)
|
||||
|
||||
if typedR.udp6.isSome or typedR.udp.isSome:
|
||||
return some(IpTransportProtocol.udpProtocol)
|
||||
|
||||
return none(IpTransportProtocol)
|
||||
|
||||
|
||||
proc parsePeerInfo*(peer: RemotePeerInfo|string):
|
||||
Result[RemotePeerInfo, string] =
|
||||
## Parses a fully qualified peer multiaddr, in the
|
||||
## format `(ip4|ip6)/tcp/p2p`, into dialable PeerInfo
|
||||
|
||||
if peer is RemotePeerInfo:
|
||||
return ok(cast[RemotePeerInfo](peer))
|
||||
|
||||
let multiAddr = ? MultiAddress.init($peer)
|
||||
.mapErr(proc(err: string):
|
||||
string = "MultiAddress.init [" & err & "]")
|
||||
|
||||
var p2pPart: MultiAddress
|
||||
var wireAddr = MultiAddress()
|
||||
for addrPart in multiAddr.items():
|
||||
case addrPart[].protoName()[]
|
||||
# All protocols listed here: https://github.com/multiformats/multiaddr/blob/b746a7d014e825221cc3aea6e57a92d78419990f/protocols.csv
|
||||
of "p2p":
|
||||
p2pPart = ? addrPart.mapErr(proc(err: string):string = "Error getting p2pPart [" & err & "]")
|
||||
of "ip4", "ip6", "dns", "dnsaddr", "dns4", "dns6", "tcp", "ws", "wss":
|
||||
let val = ? addrPart.mapErr(proc(err: string):string = "Error getting addrPart [" & err & "]")
|
||||
? wireAddr.append(val).mapErr(proc(err: string):string = "Error appending addrPart [" & err & "]")
|
||||
|
||||
let p2pPartStr = p2pPart.toString()[]
|
||||
if not p2pPartStr.contains("/"):
|
||||
let msg = "Error in parsePeerInfo: p2p part should contain / [p2pPartStr:" &
|
||||
p2pPartStr & "] [peer:" & $peer & "]"
|
||||
return err(msg)
|
||||
|
||||
let peerId = ? PeerID.init(p2pPartStr.split("/")[^1])
|
||||
.mapErr(proc (e:cstring):string = $e)
|
||||
|
||||
if not wireAddr.validWireAddr():
|
||||
return err("Error in parsePeerInfo: Invalid node multiaddress")
|
||||
|
||||
return ok(RemotePeerInfo.init(peerId, @[wireAddr]))
|
||||
|
||||
|
||||
# Checks whether the peerAddr parameter represents a valid p2p multiaddress.
|
||||
# The param must be in the format `(ip4|ip6)/tcp/p2p/$peerId` but URL-encoded
|
||||
proc parseUrlPeerAddr*(peerAddr: Option[string]):
|
||||
Result[Option[RemotePeerInfo], string] =
|
||||
|
||||
if not peerAddr.isSome() or peerAddr.get() == "":
|
||||
return ok(none(RemotePeerInfo))
|
||||
|
||||
let parsedAddr = decodeUrl(peerAddr.get())
|
||||
let parsedPeerInfo = parsePeerInfo(parsedAddr)
|
||||
|
||||
if parsedPeerInfo.isOk():
|
||||
return ok(some(parsedPeerInfo.value))
|
||||
else:
|
||||
return err("Failed parsing remote peer info [" &
|
||||
parsedPeerInfo.error & "]")
|
||||
|
||||
## Converts an ENR to dialable RemotePeerInfo
|
||||
proc toRemotePeerInfo*(enr: enr.Record): Result[RemotePeerInfo, cstring] =
|
||||
let typedR = ? enr.toTypedRecord
|
||||
|
||||
if not typedR.secp256k1.isSome:
|
||||
return err("enr: no secp256k1 key in record")
|
||||
|
||||
let
|
||||
pubKey = ? keys.PublicKey.fromRaw(typedR.secp256k1.get)
|
||||
peerId = ? PeerID.init(crypto.PublicKey(scheme: Secp256k1,
|
||||
skkey: secp.SkPublicKey(pubKey)))
|
||||
|
||||
var addrs = newSeq[MultiAddress]()
|
||||
|
||||
let transportProto = getTransportProtocol(typedR)
|
||||
if transportProto.isNone:
|
||||
return err("enr: could not determine transport protocol")
|
||||
|
||||
case transportProto.get()
|
||||
of tcpProtocol:
|
||||
if typedR.ip.isSome and typedR.tcp.isSome:
|
||||
let ip = ipv4(typedR.ip.get)
|
||||
addrs.add MultiAddress.init(ip, tcpProtocol, Port typedR.tcp.get)
|
||||
|
||||
if typedR.ip6.isSome:
|
||||
let ip = ipv6(typedR.ip6.get)
|
||||
if typedR.tcp6.isSome:
|
||||
addrs.add MultiAddress.init(ip, tcpProtocol, Port typedR.tcp6.get)
|
||||
elif typedR.tcp.isSome:
|
||||
addrs.add MultiAddress.init(ip, tcpProtocol, Port typedR.tcp.get)
|
||||
else:
|
||||
discard
|
||||
|
||||
of udpProtocol:
|
||||
if typedR.ip.isSome and typedR.udp.isSome:
|
||||
let ip = ipv4(typedR.ip.get)
|
||||
addrs.add MultiAddress.init(ip, udpProtocol, Port typedR.udp.get)
|
||||
|
||||
if typedR.ip6.isSome:
|
||||
let ip = ipv6(typedR.ip6.get)
|
||||
if typedR.udp6.isSome:
|
||||
addrs.add MultiAddress.init(ip, udpProtocol, Port typedR.udp6.get)
|
||||
elif typedR.udp.isSome:
|
||||
addrs.add MultiAddress.init(ip, udpProtocol, Port typedR.udp.get)
|
||||
else:
|
||||
discard
|
||||
|
||||
if addrs.len == 0:
|
||||
return err("enr: no addresses in record")
|
||||
|
||||
return ok(RemotePeerInfo.init(peerId, addrs, some(enr)))
|
||||
|
||||
## Converts peer records to dialable RemotePeerInfo
|
||||
## Useful if signed peer records have been received in an exchange
|
||||
proc toRemotePeerInfo*(peerRecord: PeerRecord): RemotePeerInfo =
|
||||
RemotePeerInfo.init(peerRecord.peerId,
|
||||
peerRecord.addresses.mapIt(it.address))
|
||||
|
||||
## Converts the local peerInfo to dialable RemotePeerInfo
|
||||
## Useful for testing or internal connections
|
||||
proc toRemotePeerInfo*(peerInfo: PeerInfo): RemotePeerInfo =
|
||||
RemotePeerInfo.init(peerInfo.peerId,
|
||||
peerInfo.listenAddrs,
|
||||
none(enr.Record), # we could generate an ENR from PeerInfo
|
||||
peerInfo.protocols)
|
||||
|
||||
## Checks if a multiaddress contains a given protocol
|
||||
## Useful for filtering multiaddresses based on their protocols
|
||||
proc hasProtocol*(ma: MultiAddress, proto: string): bool =
|
||||
## Returns ``true`` if ``ma`` contains protocol ``proto``.
|
||||
let protos = ma.protocols()
|
||||
if protos.isErr():
|
||||
return false
|
||||
for p in protos.get():
|
||||
if p == MultiCodec.codec(proto):
|
||||
return true
|
||||
return false
|
||||
|
||||
func hasUdpPort*(peer: RemotePeerInfo): bool =
|
||||
if peer.enr.isNone():
|
||||
return false
|
||||
|
||||
let
|
||||
enr = peer.enr.get()
|
||||
typedEnrRes = enr.toTypedRecord()
|
||||
|
||||
if typedEnrRes.isErr():
|
||||
return false
|
||||
|
||||
let typedEnr = typedEnrRes.get()
|
||||
typedEnr.udp.isSome() or typedEnr.udp6.isSome()
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
import
|
||||
./waku_core/topics,
|
||||
./waku_core/time,
|
||||
./waku_core/message
|
||||
./waku_core/message,
|
||||
./waku_core/peers
|
||||
|
||||
export
|
||||
topics,
|
||||
time,
|
||||
message
|
||||
message,
|
||||
peers
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
when (NimMajor, NimMinor) < (1, 4):
|
||||
{.push raises: [Defect].}
|
||||
else:
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
std/[options, sequtils, strutils, uri],
|
||||
stew/results,
|
||||
stew/shims/net,
|
||||
chronos,
|
||||
eth/keys,
|
||||
eth/p2p/discoveryv5/enr,
|
||||
libp2p/crypto/crypto,
|
||||
libp2p/crypto/secp,
|
||||
libp2p/errors,
|
||||
libp2p/multiaddress,
|
||||
libp2p/multicodec,
|
||||
libp2p/peerid,
|
||||
libp2p/peerinfo,
|
||||
libp2p/routing_record
|
||||
|
||||
|
||||
type
|
||||
Connectedness* = enum
|
||||
# NotConnected: default state for a new peer. No connection and no further information on connectedness.
|
||||
NotConnected,
|
||||
# CannotConnect: attempted to connect to peer, but failed.
|
||||
CannotConnect,
|
||||
# CanConnect: was recently connected to peer and disconnected gracefully.
|
||||
CanConnect,
|
||||
# Connected: actively connected to peer.
|
||||
Connected
|
||||
|
||||
PeerOrigin* = enum
|
||||
UnknownOrigin,
|
||||
Discv5,
|
||||
Static,
|
||||
PeerExcahnge,
|
||||
Dns
|
||||
|
||||
PeerDirection* = enum
|
||||
UnknownDirection,
|
||||
Inbound,
|
||||
Outbound
|
||||
|
||||
type RemotePeerInfo* = ref object
|
||||
peerId*: PeerID
|
||||
addrs*: seq[MultiAddress]
|
||||
enr*: Option[enr.Record]
|
||||
protocols*: seq[string]
|
||||
|
||||
agent*: string
|
||||
protoVersion*: string
|
||||
publicKey*: crypto.PublicKey
|
||||
connectedness*: Connectedness
|
||||
disconnectTime*: int64
|
||||
origin*: PeerOrigin
|
||||
direction*: PeerDirection
|
||||
lastFailedConn*: Moment
|
||||
numberFailedConn*: int
|
||||
|
||||
func `$`*(remotePeerInfo: RemotePeerInfo): string =
|
||||
$remotePeerInfo.peerId
|
||||
|
||||
proc init*(
|
||||
T: typedesc[RemotePeerInfo],
|
||||
peerId: PeerID,
|
||||
addrs: seq[MultiAddress] = @[],
|
||||
enr: Option[enr.Record] = none(enr.Record),
|
||||
protocols: seq[string] = @[]): T =
|
||||
|
||||
RemotePeerInfo(peerId: peerId, addrs: addrs, enr: enr, protocols: protocols)
|
||||
|
||||
proc init*(T: typedesc[RemotePeerInfo],
|
||||
peerId: string,
|
||||
addrs: seq[MultiAddress] = @[],
|
||||
enr: Option[enr.Record] = none(enr.Record),
|
||||
protocols: seq[string] = @[]): T
|
||||
{.raises: [Defect, ResultError[cstring], LPError].} =
|
||||
|
||||
let peerId = PeerID.init(peerId).tryGet()
|
||||
RemotePeerInfo(peerId: peerId, addrs: addrs, enr: enr, protocols: protocols)
|
||||
|
||||
|
||||
## Parse
|
||||
|
||||
proc validWireAddr*(ma: MultiAddress): bool =
|
||||
## Check if wire Address is supported
|
||||
const
|
||||
ValidTransports = mapOr(TCP, WebSockets)
|
||||
return ValidTransports.match(ma)
|
||||
|
||||
proc parsePeerInfo*(peer: RemotePeerInfo): Result[RemotePeerInfo, string] =
|
||||
## Parses a fully qualified peer multiaddr, in the
|
||||
## format `(ip4|ip6)/tcp/p2p`, into dialable PeerInfo
|
||||
ok(peer)
|
||||
|
||||
proc parsePeerInfo*(peer: MultiAddress): Result[RemotePeerInfo, string] =
|
||||
## Parses a fully qualified peer multiaddr, in the
|
||||
## format `(ip4|ip6)/tcp/p2p`, into dialable PeerInfo
|
||||
var p2pPart: MultiAddress
|
||||
var wireAddr = MultiAddress()
|
||||
for addrPart in peer.items():
|
||||
case addrPart[].protoName()[]
|
||||
# All protocols listed here: https://github.com/multiformats/multiaddr/blob/b746a7d014e825221cc3aea6e57a92d78419990f/protocols.csv
|
||||
of "p2p":
|
||||
p2pPart = ? addrPart.mapErr(proc(err: string): string = "Error getting p2pPart [" & err & "]")
|
||||
of "ip4", "ip6", "dns", "dnsaddr", "dns4", "dns6", "tcp", "ws", "wss":
|
||||
let val = ? addrPart.mapErr(proc(err: string): string = "Error getting addrPart [" & err & "]")
|
||||
? wireAddr.append(val).mapErr(proc(err: string): string = "Error appending addrPart [" & err & "]")
|
||||
|
||||
let p2pPartStr = p2pPart.toString().get()
|
||||
if not p2pPartStr.contains("/"):
|
||||
let msg = "Error in parsePeerInfo: p2p part should contain / [p2pPartStr:" & p2pPartStr & "] [peer:" & $peer & "]"
|
||||
return err(msg)
|
||||
|
||||
let peerId = ? PeerID.init(p2pPartStr.split("/")[^1])
|
||||
.mapErr(proc(e: cstring): string = $e)
|
||||
|
||||
if not wireAddr.validWireAddr():
|
||||
return err("invalid multiaddress: no supported transport found")
|
||||
|
||||
return ok(RemotePeerInfo.init(peerId, @[wireAddr]))
|
||||
|
||||
proc parsePeerInfo*(peer: string): Result[RemotePeerInfo, string] =
|
||||
## Parses a fully qualified peer multiaddr, in the
|
||||
## format `(ip4|ip6)/tcp/p2p`, into dialable PeerInfo
|
||||
let multiAddr = ? MultiAddress.init(peer)
|
||||
.mapErr(proc(err: string): string = "MultiAddress.init [" & err & "]")
|
||||
|
||||
parsePeerInfo(multiAddr)
|
||||
|
||||
|
||||
func getTransportProtocol(typedR: TypedRecord): Option[IpTransportProtocol] =
|
||||
if typedR.tcp6.isSome() or typedR.tcp.isSome():
|
||||
return some(IpTransportProtocol.tcpProtocol)
|
||||
|
||||
if typedR.udp6.isSome() or typedR.udp.isSome():
|
||||
return some(IpTransportProtocol.udpProtocol)
|
||||
|
||||
return none(IpTransportProtocol)
|
||||
|
||||
proc parseUrlPeerAddr*(peerAddr: Option[string]): Result[Option[RemotePeerInfo], string] =
|
||||
# Checks whether the peerAddr parameter represents a valid p2p multiaddress.
|
||||
# The param must be in the format `(ip4|ip6)/tcp/p2p/$peerId` but URL-encoded
|
||||
if not peerAddr.isSome() or peerAddr.get() == "":
|
||||
return ok(none(RemotePeerInfo))
|
||||
|
||||
let parsedAddr = decodeUrl(peerAddr.get())
|
||||
let parsedPeerInfo = parsePeerInfo(parsedAddr)
|
||||
if parsedPeerInfo.isErr():
|
||||
return err("Failed parsing remote peer info [" & parsedPeerInfo.error & "]")
|
||||
|
||||
return ok(some(parsedPeerInfo.value))
|
||||
|
||||
proc toRemotePeerInfo*(enr: enr.Record): Result[RemotePeerInfo, cstring] =
|
||||
## Converts an ENR to dialable RemotePeerInfo
|
||||
let typedR = ? enr.toTypedRecord()
|
||||
if not typedR.secp256k1.isSome():
|
||||
return err("enr: no secp256k1 key in record")
|
||||
|
||||
let
|
||||
pubKey = ? keys.PublicKey.fromRaw(typedR.secp256k1.get())
|
||||
peerId = ? PeerID.init(crypto.PublicKey(scheme: Secp256k1,
|
||||
skkey: secp.SkPublicKey(pubKey)))
|
||||
|
||||
let transportProto = getTransportProtocol(typedR)
|
||||
if transportProto.isNone():
|
||||
return err("enr: could not determine transport protocol")
|
||||
|
||||
var addrs = newSeq[MultiAddress]()
|
||||
case transportProto.get()
|
||||
of tcpProtocol:
|
||||
if typedR.ip.isSome() and typedR.tcp.isSome():
|
||||
let ip = ipv4(typedR.ip.get())
|
||||
addrs.add MultiAddress.init(ip, tcpProtocol, Port(typedR.tcp.get()))
|
||||
|
||||
if typedR.ip6.isSome():
|
||||
let ip = ipv6(typedR.ip6.get())
|
||||
if typedR.tcp6.isSome():
|
||||
addrs.add MultiAddress.init(ip, tcpProtocol, Port(typedR.tcp6.get()))
|
||||
elif typedR.tcp.isSome():
|
||||
addrs.add MultiAddress.init(ip, tcpProtocol, Port(typedR.tcp.get()))
|
||||
else:
|
||||
discard
|
||||
|
||||
of udpProtocol:
|
||||
if typedR.ip.isSome() and typedR.udp.isSome():
|
||||
let ip = ipv4(typedR.ip.get())
|
||||
addrs.add MultiAddress.init(ip, udpProtocol, Port(typedR.udp.get()))
|
||||
|
||||
if typedR.ip6.isSome():
|
||||
let ip = ipv6(typedR.ip6.get())
|
||||
if typedR.udp6.isSome():
|
||||
addrs.add MultiAddress.init(ip, udpProtocol, Port(typedR.udp6.get()))
|
||||
elif typedR.udp.isSome():
|
||||
addrs.add MultiAddress.init(ip, udpProtocol, Port(typedR.udp.get()))
|
||||
else:
|
||||
discard
|
||||
|
||||
if addrs.len == 0:
|
||||
return err("enr: no addresses in record")
|
||||
|
||||
return ok(RemotePeerInfo.init(peerId, addrs, some(enr)))
|
||||
|
||||
converter toRemotePeerInfo*(peerRecord: PeerRecord): RemotePeerInfo =
|
||||
## Converts peer records to dialable RemotePeerInfo
|
||||
## Useful if signed peer records have been received in an exchange
|
||||
RemotePeerInfo.init(
|
||||
peerRecord.peerId,
|
||||
peerRecord.addresses.mapIt(it.address)
|
||||
)
|
||||
|
||||
converter toRemotePeerInfo*(peerInfo: PeerInfo): RemotePeerInfo =
|
||||
## Converts the local peerInfo to dialable RemotePeerInfo
|
||||
## Useful for testing or internal connections
|
||||
RemotePeerInfo.init(
|
||||
peerInfo.peerId,
|
||||
peerInfo.listenAddrs,
|
||||
none(enr.Record),
|
||||
peerInfo.protocols
|
||||
)
|
||||
|
||||
proc hasProtocol*(ma: MultiAddress, proto: string): bool =
|
||||
## Checks if a multiaddress contains a given protocol
|
||||
## Useful for filtering multiaddresses based on their protocols
|
||||
##
|
||||
## Returns ``true`` if ``ma`` contains protocol ``proto``.
|
||||
let proto = MultiCodec.codec(proto)
|
||||
|
||||
let protos = ma.protocols()
|
||||
if protos.isErr():
|
||||
return false
|
||||
|
||||
return protos.get().anyIt(it == proto)
|
||||
|
||||
func hasUdpPort*(peer: RemotePeerInfo): bool =
|
||||
if peer.enr.isNone():
|
||||
return false
|
||||
|
||||
let
|
||||
enr = peer.enr.get()
|
||||
typedEnrRes = enr.toTypedRecord()
|
||||
|
||||
if typedEnrRes.isErr():
|
||||
return false
|
||||
|
||||
let typedEnr = typedEnrRes.get()
|
||||
typedEnr.udp.isSome() or typedEnr.udp6.isSome()
|
||||
|
|
@ -16,7 +16,7 @@ import
|
|||
eth/p2p/discoveryv5/node,
|
||||
eth/p2p/discoveryv5/protocol
|
||||
import
|
||||
./utils/peers,
|
||||
./waku_core,
|
||||
./waku_enr
|
||||
|
||||
export protocol, waku_enr
|
||||
|
|
|
@ -22,7 +22,7 @@ import
|
|||
libp2p/peerid,
|
||||
discovery/dnsdisc/client
|
||||
import
|
||||
./utils/peers
|
||||
./waku_core
|
||||
|
||||
export client
|
||||
|
||||
|
|
Loading…
Reference in New Issue