mirror of
https://github.com/status-im/nim-libp2p.git
synced 2025-01-10 04:56:08 +00:00
d02735dc46
Peer Info is now for local peer data only. For other peers info, use the peer store. Previous reference to peer info are replaced with the peerid
163 lines
4.3 KiB
Nim
163 lines
4.3 KiB
Nim
## Nim-LibP2P
|
|
## Copyright (c) 2021 Status Research & Development GmbH
|
|
## 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.
|
|
|
|
{.push raises: [Defect].}
|
|
|
|
import
|
|
std/[tables, sets, sequtils, options],
|
|
./crypto/crypto,
|
|
./protocols/identify,
|
|
./peerid, ./peerinfo,
|
|
./multiaddress
|
|
|
|
type
|
|
#################
|
|
# Handler types #
|
|
#################
|
|
|
|
PeerBookChangeHandler*[T] = proc(peerId: PeerID, entry: T)
|
|
|
|
AddrChangeHandler* = PeerBookChangeHandler[HashSet[MultiAddress]]
|
|
ProtoChangeHandler* = PeerBookChangeHandler[HashSet[string]]
|
|
KeyChangeHandler* = PeerBookChangeHandler[PublicKey]
|
|
|
|
#########
|
|
# Books #
|
|
#########
|
|
|
|
# Each book contains a book (map) and event handler(s)
|
|
PeerBook*[T] = object of RootObj
|
|
book*: Table[PeerID, T]
|
|
changeHandlers: seq[PeerBookChangeHandler[T]]
|
|
|
|
SetPeerBook*[T] = object of PeerBook[HashSet[T]]
|
|
|
|
AddressBook* = object of SetPeerBook[MultiAddress]
|
|
ProtoBook* = object of SetPeerBook[string]
|
|
KeyBook* = object of PeerBook[PublicKey]
|
|
|
|
####################
|
|
# Peer store types #
|
|
####################
|
|
|
|
PeerStore* = ref object
|
|
addressBook*: AddressBook
|
|
protoBook*: ProtoBook
|
|
keyBook*: KeyBook
|
|
|
|
agentBook*: PeerBook[string]
|
|
protoVersionBook*: PeerBook[string]
|
|
|
|
## Constructs a new PeerStore with metadata of type M
|
|
proc new*(T: type PeerStore): PeerStore =
|
|
var p: PeerStore
|
|
new(p)
|
|
return p
|
|
|
|
#########################
|
|
# Generic Peer Book API #
|
|
#########################
|
|
|
|
proc get*[T](peerBook: PeerBook[T],
|
|
peerId: PeerID): T =
|
|
## Get all the known metadata of a provided peer.
|
|
|
|
peerBook.book.getOrDefault(peerId)
|
|
|
|
proc set*[T](peerBook: var PeerBook[T],
|
|
peerId: PeerID,
|
|
entry: T) =
|
|
## Set metadata for a given peerId. This will replace any
|
|
## previously stored metadata.
|
|
|
|
peerBook.book[peerId] = entry
|
|
|
|
# Notify clients
|
|
for handler in peerBook.changeHandlers:
|
|
handler(peerId, peerBook.get(peerId))
|
|
|
|
proc delete*[T](peerBook: var PeerBook[T],
|
|
peerId: PeerID): bool =
|
|
## Delete the provided peer from the book.
|
|
|
|
if not peerBook.book.hasKey(peerId):
|
|
return false
|
|
else:
|
|
peerBook.book.del(peerId)
|
|
return true
|
|
|
|
proc contains*[T](peerBook: PeerBook[T], peerId: PeerID): bool =
|
|
peerId in peerBook.book
|
|
|
|
################
|
|
# Set Book API #
|
|
################
|
|
|
|
proc add*[T](
|
|
peerBook: var SetPeerBook[T],
|
|
peerId: PeerID,
|
|
entry: T) =
|
|
## Add entry to a given peer. If the peer is not known,
|
|
## it will be set with the provided entry.
|
|
|
|
peerBook.book.mgetOrPut(peerId,
|
|
initHashSet[T]()).incl(entry)
|
|
|
|
# Notify clients
|
|
for handler in peerBook.changeHandlers:
|
|
handler(peerId, peerBook.get(peerId))
|
|
|
|
# Helper for seq
|
|
proc set*[T](
|
|
peerBook: var SetPeerBook[T],
|
|
peerId: PeerID,
|
|
entry: seq[T]) =
|
|
## Add entry to a given peer. If the peer is not known,
|
|
## it will be set with the provided entry.
|
|
peerBook.set(peerId, entry.toHashSet())
|
|
|
|
|
|
##################
|
|
# Peer Store API #
|
|
##################
|
|
|
|
proc addHandlers*(peerStore: PeerStore,
|
|
addrChangeHandler: AddrChangeHandler,
|
|
protoChangeHandler: ProtoChangeHandler,
|
|
keyChangeHandler: KeyChangeHandler) =
|
|
## Register event handlers to notify clients of changes in the peer store
|
|
|
|
peerStore.addressBook.changeHandlers.add(addrChangeHandler)
|
|
peerStore.protoBook.changeHandlers.add(protoChangeHandler)
|
|
peerStore.keyBook.changeHandlers.add(keyChangeHandler)
|
|
|
|
proc delete*(peerStore: PeerStore,
|
|
peerId: PeerID): bool =
|
|
## Delete the provided peer from every book.
|
|
|
|
peerStore.addressBook.delete(peerId) and
|
|
peerStore.protoBook.delete(peerId) and
|
|
peerStore.keyBook.delete(peerId)
|
|
|
|
proc updatePeerInfo*(
|
|
peerStore: PeerStore,
|
|
info: IdentifyInfo) =
|
|
|
|
if info.addrs.len > 0:
|
|
peerStore.addressBook.set(info.peerId, info.addrs)
|
|
|
|
if info.agentVersion.isSome:
|
|
peerStore.agentBook.set(info.peerId, info.agentVersion.get().string)
|
|
|
|
if info.protoVersion.isSome:
|
|
peerStore.protoVersionBook.set(info.peerId, info.protoVersion.get().string)
|
|
|
|
if info.protos.len > 0:
|
|
peerStore.protoBook.set(info.peerId, info.protos)
|