2021-09-03 08:57:19 +00:00
|
|
|
import
|
|
|
|
std/[options, sugar],
|
2021-09-22 15:07:14 +00:00
|
|
|
stew/[results, byteutils],
|
2021-09-23 12:26:41 +00:00
|
|
|
eth/p2p/discoveryv5/[protocol, node, enr],
|
2021-09-22 15:07:14 +00:00
|
|
|
../wire/portal_protocol,
|
|
|
|
./state_content
|
|
|
|
|
|
|
|
const
|
|
|
|
StateProtocolId* = "portal:state".toBytes()
|
2021-09-03 08:57:19 +00:00
|
|
|
|
2021-09-13 13:56:44 +00:00
|
|
|
# TODO expose function in domain specific way i.e operating od state network
|
|
|
|
# objects i.e nodes, tries, hashes
|
2021-09-22 15:07:14 +00:00
|
|
|
type StateNetwork* = ref object
|
2021-09-03 08:57:19 +00:00
|
|
|
portalProtocol*: PortalProtocol
|
2021-09-22 15:07:14 +00:00
|
|
|
storage: ContentStorage
|
2021-09-03 08:57:19 +00:00
|
|
|
|
|
|
|
proc getHandler(storage: ContentStorage): ContentHandler =
|
2021-09-22 15:07:14 +00:00
|
|
|
return (proc (contentKey: state_content.ByteList): ContentResult =
|
2021-09-03 08:57:19 +00:00
|
|
|
let maybeContent = storage.getContent(contentKey)
|
|
|
|
if (maybeContent.isSome()):
|
|
|
|
ContentResult(kind: ContentFound, content: maybeContent.unsafeGet())
|
|
|
|
else:
|
|
|
|
ContentResult(kind: ContentMissing, contentId: toContentId(contentKey)))
|
|
|
|
|
|
|
|
# Further improvements which may be necessary:
|
|
|
|
# 1. Return proper domain types instead of bytes
|
|
|
|
# 2. First check if item is in storage instead of doing lookup
|
|
|
|
# 3. Put item into storage (if in radius) after succesful lookup
|
2021-09-22 15:07:14 +00:00
|
|
|
proc getContent*(p: StateNetwork, key: ContentKey):
|
2021-09-13 13:56:44 +00:00
|
|
|
Future[Option[seq[byte]]] {.async.} =
|
2021-09-03 08:57:19 +00:00
|
|
|
let keyAsBytes = encodeKeyAsList(key)
|
|
|
|
let id = contentIdAsUint256(toContentId(keyAsBytes))
|
|
|
|
let result = await p.portalProtocol.contentLookup(keyAsBytes, id)
|
2021-09-13 13:56:44 +00:00
|
|
|
# for now returning bytes, ultimatly it would be nice to return proper domain
|
|
|
|
# types from here
|
2021-09-03 08:57:19 +00:00
|
|
|
return result.map(x => x.asSeq())
|
|
|
|
|
2021-09-22 15:07:14 +00:00
|
|
|
proc new*(T: type StateNetwork, baseProtocol: protocol.Protocol,
|
2021-09-23 12:26:41 +00:00
|
|
|
storage: ContentStorage , dataRadius = UInt256.high(),
|
|
|
|
bootstrapRecords: openarray[Record] = []): T =
|
2021-09-22 15:07:14 +00:00
|
|
|
let portalProtocol = PortalProtocol.new(
|
2021-09-23 12:26:41 +00:00
|
|
|
baseProtocol, StateProtocolId, getHandler(storage), dataRadius,
|
|
|
|
bootstrapRecords)
|
2021-09-13 13:56:44 +00:00
|
|
|
|
2021-09-22 15:07:14 +00:00
|
|
|
return StateNetwork(portalProtocol: portalProtocol, storage: storage)
|
2021-09-03 08:57:19 +00:00
|
|
|
|
2021-09-22 15:07:14 +00:00
|
|
|
proc start*(p: StateNetwork) =
|
2021-09-03 08:57:19 +00:00
|
|
|
p.portalProtocol.start()
|
|
|
|
|
2021-09-22 15:07:14 +00:00
|
|
|
proc stop*(p: StateNetwork) =
|
2021-09-03 08:57:19 +00:00
|
|
|
p.portalProtocol.stop()
|