nim-libp2p/libp2p/peerinfo.nim

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

121 lines
3.9 KiB
Nim
Raw Normal View History

2022-07-01 18:19:57 +00:00
# Nim-LibP2P
2023-01-20 14:47:40 +00:00
# Copyright (c) 2023 Status Research & Development GmbH
2022-07-01 18:19:57 +00:00
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.
2023-06-07 11:12:49 +00:00
{.push raises: [].}
2022-07-01 18:19:57 +00:00
{.push public.}
import std/sequtils
import pkg/[chronos, chronicles, stew/results]
import peerid, multiaddress, multicodec, crypto/crypto, routing_record, errors, utility
export peerid, multiaddress, crypto, routing_record, errors, results
## Our local peer info
type
2022-10-20 10:22:28 +00:00
PeerInfoError* = object of LPError
AddressMapper* = proc(listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.
2023-06-07 11:12:49 +00:00
gcsafe, raises: []
.} ## A proc that expected to resolve the listen addresses into dialable addresses
2022-07-01 18:19:57 +00:00
PeerInfo* {.public.} = ref object
2021-12-16 10:05:20 +00:00
peerId*: PeerId
2022-10-20 10:22:28 +00:00
listenAddrs*: seq[MultiAddress]
## contains addresses the node listens on, which may include wildcard and private addresses (not directly reachable).
addrs*: seq[MultiAddress]
## contains resolved addresses that other peers can use to connect, including public-facing NAT and port-forwarded addresses.
2022-10-20 10:22:28 +00:00
addressMappers*: seq[AddressMapper]
## contains a list of procs that can be used to resolve the listen addresses into dialable addresses.
protocols*: seq[string]
2020-06-09 18:42:52 +00:00
protoVersion*: string
agentVersion*: string
privateKey*: PrivateKey
publicKey*: PublicKey
signedPeerRecord*: SignedPeerRecord
func shortLog*(p: PeerInfo): auto =
2020-06-09 18:42:52 +00:00
(
peerId: $p.peerId,
2022-10-20 10:22:28 +00:00
listenAddrs: mapIt(p.listenAddrs, $it),
2020-06-09 18:42:52 +00:00
addrs: mapIt(p.addrs, $it),
protocols: mapIt(p.protocols, $it),
protoVersion: p.protoVersion,
agentVersion: p.agentVersion,
)
chronicles.formatIt(PeerInfo):
shortLog(it)
2022-10-20 10:22:28 +00:00
proc update*(p: PeerInfo) {.async.} =
# p.addrs.len == 0 overrides addrs only if it is the first time update is being executed or if the field is empty.
# p.addressMappers.len == 0 is for when all addressMappers have been removed,
# and we wish to have addrs in its initial state, i.e., a copy of listenAddrs.
if p.addrs.len == 0 or p.addressMappers.len == 0:
p.addrs = p.listenAddrs
2022-10-20 10:22:28 +00:00
for mapper in p.addressMappers:
p.addrs = await mapper(p.addrs)
p.signedPeerRecord = SignedPeerRecord.init(
p.privateKey, PeerRecord.init(p.peerId, p.addrs)
).valueOr:
info "Can't update the signed peer record"
return
2022-10-20 10:22:28 +00:00
proc addrs*(p: PeerInfo): seq[MultiAddress] =
p.addrs
proc fullAddrs*(p: PeerInfo): MaResult[seq[MultiAddress]] =
let peerIdPart = ?MultiAddress.init(multiCodec("p2p"), p.peerId.data)
var res: seq[MultiAddress]
for address in p.addrs:
res.add(?concat(address, peerIdPart))
ok(res)
proc parseFullAddress*(ma: MultiAddress): MaResult[(PeerId, MultiAddress)] =
let p2pPart = ?ma[^1]
if ?p2pPart.protoCode != multiCodec("p2p"):
return err("Missing p2p part from multiaddress!")
let res =
(?PeerId.init(?p2pPart.protoArgument()).orErr("invalid peerid"), ?ma[0 .. ^2])
ok(res)
proc parseFullAddress*(ma: string | seq[byte]): MaResult[(PeerId, MultiAddress)] =
parseFullAddress(?MultiAddress.init(ma))
proc new*(
p: typedesc[PeerInfo],
key: PrivateKey,
2022-10-20 10:22:28 +00:00
listenAddrs: openArray[MultiAddress] = [],
2021-12-16 10:05:20 +00:00
protocols: openArray[string] = [],
protoVersion: string = "",
2022-10-20 10:22:28 +00:00
agentVersion: string = "",
addressMappers = newSeq[AddressMapper](),
2023-06-07 11:12:49 +00:00
): PeerInfo {.raises: [LPError].} =
let pubkey =
try:
key.getPublicKey().tryGet()
except CatchableError:
raise newException(PeerInfoError, "invalid private key")
2022-10-20 10:22:28 +00:00
let peerId = PeerId.init(key).tryGet()
let peerInfo = PeerInfo(
peerId: peerId,
publicKey: pubkey,
privateKey: key,
protoVersion: protoVersion,
agentVersion: agentVersion,
2022-10-20 10:22:28 +00:00
listenAddrs: @listenAddrs,
protocols: @protocols,
2022-10-20 10:22:28 +00:00
addressMappers: addressMappers,
)
return peerInfo