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-28 17:58:41 +00:00
|
|
|
../../content_db,
|
2021-09-22 15:07:14 +00:00
|
|
|
../wire/portal_protocol,
|
2021-10-05 19:16:33 +00:00
|
|
|
./state_content,
|
|
|
|
./custom_distance
|
2021-09-22 15:07:14 +00:00
|
|
|
|
|
|
|
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-28 17:58:41 +00:00
|
|
|
contentDB*: ContentDB
|
2021-09-03 08:57:19 +00:00
|
|
|
|
2021-09-28 17:58:41 +00:00
|
|
|
proc getHandler(contentDB: ContentDB): ContentHandler =
|
2021-09-22 15:07:14 +00:00
|
|
|
return (proc (contentKey: state_content.ByteList): ContentResult =
|
2021-09-28 17:58:41 +00:00
|
|
|
let contentId = toContentId(contentKey)
|
|
|
|
let maybeContent = contentDB.get(contentId)
|
2021-09-03 08:57:19 +00:00
|
|
|
if (maybeContent.isSome()):
|
|
|
|
ContentResult(kind: ContentFound, content: maybeContent.unsafeGet())
|
|
|
|
else:
|
2021-09-28 17:58:41 +00:00
|
|
|
ContentResult(kind: ContentMissing, contentId: contentId))
|
2021-09-03 08:57:19 +00:00
|
|
|
|
|
|
|
# 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-24 09:22:07 +00:00
|
|
|
let
|
|
|
|
keyEncoded = encode(key)
|
|
|
|
id = toContentId(keyEncoded)
|
|
|
|
content = await p.portalProtocol.contentLookup(keyEncoded, id)
|
|
|
|
# for now returning bytes, ultimately it would be nice to return proper domain
|
2021-09-13 13:56:44 +00:00
|
|
|
# types from here
|
2021-09-24 09:22:07 +00:00
|
|
|
return content.map(x => x.asSeq())
|
2021-09-03 08:57:19 +00:00
|
|
|
|
2021-09-22 15:07:14 +00:00
|
|
|
proc new*(T: type StateNetwork, baseProtocol: protocol.Protocol,
|
2021-09-28 17:58:41 +00:00
|
|
|
contentDB: ContentDB , dataRadius = UInt256.high(),
|
2021-09-23 12:26:41 +00:00
|
|
|
bootstrapRecords: openarray[Record] = []): T =
|
2021-09-22 15:07:14 +00:00
|
|
|
let portalProtocol = PortalProtocol.new(
|
2021-09-28 17:58:41 +00:00
|
|
|
baseProtocol, StateProtocolId, getHandler(contentDB), dataRadius,
|
2021-10-05 19:16:33 +00:00
|
|
|
bootstrapRecords, customDistanceCalculator)
|
2021-09-13 13:56:44 +00:00
|
|
|
|
2021-09-28 17:58:41 +00:00
|
|
|
return StateNetwork(portalProtocol: portalProtocol, contentDB: contentDB)
|
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()
|