nwaku/waku/v2/utils/peers.nim
Hanno Cornelius 50189a21a9
Update submodules: differentiate between local and remote PeerInfo (#730)
* Update submodules

* Remove PeerInfo where necessary
2021-10-06 14:29:08 +02:00

89 lines
2.6 KiB
Nim

{.push raises: [Defect].}
# Collection of utilities related to Waku peers
import
std/strutils,
stew/results,
libp2p/[errors,
multiaddress,
peerid,
peerinfo]
type
RemotePeerInfo* = ref object of RootObj
peerId*: PeerID
addrs*: seq[MultiAddress]
protocols*: seq[string]
func `$`*(remotePeerInfo: RemotePeerInfo): string =
$remotePeerInfo.peerId
proc init*(
p: typedesc[RemotePeerInfo],
peerId: PeerID,
addrs: seq[MultiAddress] = @[],
protocols: seq[string] = @[]): RemotePeerInfo =
let remotePeerInfo = RemotePeerInfo(
peerId: peerId,
addrs: addrs,
protocols: protocols)
return remotePeerInfo
proc init*(p: typedesc[RemotePeerInfo],
peerId: string,
addrs: seq[MultiAddress] = @[],
protocols: seq[string] = @[]): RemotePeerInfo
{.raises: [Defect, ResultError[cstring], LPError].} =
let remotePeerInfo = RemotePeerInfo(
peerId: PeerID.init(peerId).tryGet(),
addrs: addrs,
protocols: protocols)
return remotePeerInfo
proc initAddress(T: type MultiAddress, str: string): T {.raises: [Defect, ValueError, LPError].}=
# @TODO: Rather than raising exceptions, this should return a Result
let address = MultiAddress.init(str).tryGet()
if IPFS.match(address) and matchPartial(multiaddress.TCP, address):
return address
else:
raise newException(ValueError,
"Invalid bootstrap node multi-address")
## Parses a fully qualified peer multiaddr, in the
## format `(ip4|ip6)/tcp/p2p`, into dialable PeerInfo
proc parseRemotePeerInfo*(address: string): RemotePeerInfo {.raises: [Defect, ValueError, LPError].}=
let multiAddr = MultiAddress.initAddress(address)
var
ipPart, tcpPart, p2pPart: MultiAddress
for addrPart in multiAddr.items():
case addrPart[].protoName()[]
of "ip4", "ip6":
ipPart = addrPart.tryGet()
of "tcp":
tcpPart = addrPart.tryGet()
of "p2p":
p2pPart = addrPart.tryGet()
# nim-libp2p dialing requires remote peers to be initialised with a peerId and a wire address
let
peerIdStr = p2pPart.toString()[].split("/")[^1]
wireAddr = ipPart & tcpPart
if (not wireAddr.isWire()):
raise newException(ValueError, "Invalid node multi-address")
return RemotePeerInfo.init(peerIdStr, @[wireAddr])
## Converts the local peerInfo to dialable RemotePeerInfo
## Useful for testing or internal connections
proc toRemotePeerInfo*(peerInfo: PeerInfo): RemotePeerInfo =
RemotePeerInfo.init(peerInfo.peerId,
peerInfo.addrs,
peerInfo.protocols)