2025-02-10 16:24:54 +01:00
|
|
|
import std/os
|
2025-02-10 16:02:47 +01:00
|
|
|
import pkg/datastore/typedds
|
|
|
|
|
import pkg/questionable/results
|
2025-02-10 16:24:54 +01:00
|
|
|
import pkg/chronicles
|
2025-02-10 16:02:47 +01:00
|
|
|
import pkg/chronos
|
|
|
|
|
import pkg/libp2p
|
|
|
|
|
|
|
|
|
|
import ../types
|
2025-02-10 16:24:54 +01:00
|
|
|
import ../component
|
|
|
|
|
import ../state
|
|
|
|
|
import ../utils/datastoreutils
|
|
|
|
|
import ../utils/asyncdataevent
|
2025-02-10 16:02:47 +01:00
|
|
|
|
|
|
|
|
type
|
2025-02-10 16:24:54 +01:00
|
|
|
NodeEntry = object
|
|
|
|
|
id: Nid
|
|
|
|
|
lastVisit: uint64
|
2025-02-10 16:02:47 +01:00
|
|
|
|
2025-02-10 16:24:54 +01:00
|
|
|
NodeStore* = ref object of Component
|
|
|
|
|
state: State
|
2025-02-10 16:02:47 +01:00
|
|
|
store: TypedDatastore
|
2025-02-10 16:24:54 +01:00
|
|
|
sub: AsyncDataEventSubscription
|
2025-02-10 16:02:47 +01:00
|
|
|
|
|
|
|
|
proc `$`*(entry: NodeEntry): string =
|
|
|
|
|
$entry.id & ":" & $entry.lastVisit
|
|
|
|
|
|
|
|
|
|
proc toBytes*(entry: NodeEntry): seq[byte] =
|
|
|
|
|
var buffer = initProtoBuffer()
|
|
|
|
|
buffer.write(1, $entry.id)
|
|
|
|
|
buffer.write(2, entry.lastVisit)
|
|
|
|
|
buffer.finish()
|
|
|
|
|
return buffer.buffer
|
|
|
|
|
|
|
|
|
|
proc fromBytes*(_: type NodeEntry, data: openArray[byte]): ?!NodeEntry =
|
|
|
|
|
var
|
|
|
|
|
buffer = initProtoBuffer(data)
|
|
|
|
|
idStr: string
|
|
|
|
|
lastVisit: uint64
|
|
|
|
|
|
|
|
|
|
if buffer.getField(1, idStr).isErr:
|
|
|
|
|
return failure("Unable to decode `idStr`")
|
|
|
|
|
|
|
|
|
|
if buffer.getField(2, lastVisit).isErr:
|
|
|
|
|
return failure("Unable to decode `lastVisit`")
|
|
|
|
|
|
|
|
|
|
return success(NodeEntry(id: Nid.fromStr(idStr), lastVisit: lastVisit))
|
2025-02-10 16:24:54 +01:00
|
|
|
|
|
|
|
|
proc processFoundNodes(s: NodeStore, nids: seq[Nid]): Future[?!void] {.async.} =
|
|
|
|
|
# put the nodes in the store.
|
|
|
|
|
# track all new ones, if any, raise newNodes event.
|
|
|
|
|
return success()
|
|
|
|
|
|
|
|
|
|
method start*(s: NodeStore): Future[?!void] {.async.} =
|
|
|
|
|
info "Starting nodestore..."
|
|
|
|
|
|
|
|
|
|
proc onNodesFound(nids: seq[Nid]): Future[?!void] {.async.} =
|
|
|
|
|
return await s.processFoundNodes(nids)
|
|
|
|
|
|
|
|
|
|
s.sub = s.state.events.nodesFound.subscribe(onNodesFound)
|
|
|
|
|
return success()
|
|
|
|
|
|
|
|
|
|
method stop*(s: NodeStore): Future[?!void] {.async.} =
|
|
|
|
|
await s.state.events.nodesFound.unsubscribe(s.sub)
|
|
|
|
|
return success()
|
|
|
|
|
|
|
|
|
|
proc createNodeStore*(state: State): ?!NodeStore =
|
|
|
|
|
without ds =? createTypedDatastore(state.config.dataDir / "nodestore"), err:
|
|
|
|
|
error "Failed to create typed datastore for node store", err = err.msg
|
|
|
|
|
return failure(err)
|
|
|
|
|
|
|
|
|
|
return success(NodeStore(state: state, store: ds))
|