mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-11 21:04:11 +00:00
Add SSZ Unions through case objects (#882)
* Add SSZ Unions through case objects * Add connection id content response test and improve other test vectors * Implement content keys and ids for state network as per spec Content keys case object is used so that it can be serialized and deserialized as an SSZ Union. * Let message Union in Portal wire protocol start at 0 as per new spec
This commit is contained in:
parent
414fdafab9
commit
bdbd8e4c87
@ -13,3 +13,4 @@ import
|
|||||||
type
|
type
|
||||||
ByteList* = List[byte, 2048]
|
ByteList* = List[byte, 2048]
|
||||||
Bytes2* = array[2, byte]
|
Bytes2* = array[2, byte]
|
||||||
|
Bytes32* = array[32, byte]
|
||||||
|
@ -5,78 +5,124 @@
|
|||||||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
# https://github.com/ethereum/stateless-ethereum-specs/blob/master/state-network.md#content
|
# As per spec:
|
||||||
|
# https://github.com/ethereum/portal-network-specs/blob/master/state-network.md#content-keys-and-content-ids
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
std/options,
|
std/options,
|
||||||
nimcrypto/[sha2, hash], stew/objects, stint,
|
nimcrypto/[hash, sha2, keccak], stew/objects, stint,
|
||||||
ssz_serialization,
|
ssz_serialization,
|
||||||
../../common/common_types
|
../../common/common_types
|
||||||
|
|
||||||
export ssz_serialization, common_types
|
export ssz_serialization, common_types
|
||||||
|
|
||||||
type
|
type
|
||||||
ContentType* = enum
|
|
||||||
Account = 0x01
|
|
||||||
ContractStorage = 0x02
|
|
||||||
ContractBytecode = 0x03
|
|
||||||
|
|
||||||
NetworkId* = uint16
|
|
||||||
|
|
||||||
NodeHash* = MDigest[32 * 8] # keccak256
|
NodeHash* = MDigest[32 * 8] # keccak256
|
||||||
|
|
||||||
CodeHash* = MDigest[32 * 8] # keccak256
|
CodeHash* = MDigest[32 * 8] # keccak256
|
||||||
|
|
||||||
Address* = array[20, byte]
|
Address* = array[20, byte]
|
||||||
|
|
||||||
ContentKey* = object
|
ContentType* = enum
|
||||||
networkId*: NetworkId
|
accountTrieNode = 0x00
|
||||||
contentType*: ContentType
|
contractStorageTrieNode = 0x01
|
||||||
# TODO: How shall we deal with the different ContentKey structures?
|
accountTrieProof = 0x02
|
||||||
# Lets start with just node hashes for now.
|
contractStorageTrieProof = 0x03
|
||||||
# address: Address
|
contractBytecode = 0x04
|
||||||
# triePath: ByteList
|
|
||||||
|
AccountTrieNodeKey* = object
|
||||||
|
path*: ByteList
|
||||||
nodeHash*: NodeHash
|
nodeHash*: NodeHash
|
||||||
|
stateRoot*: Bytes32
|
||||||
|
|
||||||
|
ContractStorageTrieNodeKey* = object
|
||||||
|
address*: Address
|
||||||
|
path*: ByteList
|
||||||
|
nodeHash*: NodeHash
|
||||||
|
stateRoot*: Bytes32
|
||||||
|
|
||||||
|
AccountTrieProofKey* = object
|
||||||
|
address*: Address
|
||||||
|
stateRoot*: Bytes32
|
||||||
|
|
||||||
|
ContractStorageTrieProofKey* = object
|
||||||
|
address*: Address
|
||||||
|
slot*: UInt256
|
||||||
|
stateRoot*: Bytes32
|
||||||
|
|
||||||
|
ContractBytecodeKey* = object
|
||||||
|
address*: Address
|
||||||
|
codeHash*: CodeHash
|
||||||
|
|
||||||
|
ContentKey* = object
|
||||||
|
case contentType*: ContentType
|
||||||
|
of accountTrieNode:
|
||||||
|
accountTrieNodeKey*: AccountTrieNodeKey
|
||||||
|
of contractStorageTrieNode:
|
||||||
|
contractStorageTrieNodeKey*: ContractStorageTrieNodeKey
|
||||||
|
of accountTrieProof:
|
||||||
|
accountTrieProofKey*: AccountTrieProofKey
|
||||||
|
of contractStorageTrieProof:
|
||||||
|
contractStorageTrieProofKey*: ContractStorageTrieProofKey
|
||||||
|
of contractBytecode:
|
||||||
|
contractBytecodeKey*: ContractBytecodeKey
|
||||||
|
|
||||||
ContentId* = Uint256
|
ContentId* = Uint256
|
||||||
|
|
||||||
KeccakHash* = MDigest[32 * 8] # could also import from either eth common types or trie defs
|
|
||||||
|
|
||||||
template toSszType*(x: ContentType): uint8 =
|
|
||||||
uint8(x)
|
|
||||||
|
|
||||||
template toSszType*(x: auto): auto =
|
|
||||||
x
|
|
||||||
|
|
||||||
func fromSszBytes*(T: type ContentType, data: openArray[byte]):
|
|
||||||
T {.raises: [MalformedSszError, Defect].} =
|
|
||||||
if data.len != sizeof(uint8):
|
|
||||||
raiseIncorrectSize T
|
|
||||||
|
|
||||||
var contentType: T
|
|
||||||
if not checkedEnumAssign(contentType, data[0]):
|
|
||||||
raiseIncorrectSize T
|
|
||||||
|
|
||||||
contentType
|
|
||||||
|
|
||||||
func encode*(contentKey: ContentKey): ByteList =
|
func encode*(contentKey: ContentKey): ByteList =
|
||||||
ByteList.init(SSZ.encode(contentKey))
|
ByteList.init(SSZ.encode(contentKey))
|
||||||
|
|
||||||
# TODO consider if more powerfull error handling is necessary here.
|
|
||||||
func decode*(contentKey: ByteList): Option[ContentKey] =
|
func decode*(contentKey: ByteList): Option[ContentKey] =
|
||||||
try:
|
try:
|
||||||
some(SSZ.decode(contentKey.asSeq(), ContentKey))
|
some(SSZ.decode(contentKey.asSeq(), ContentKey))
|
||||||
except SszError:
|
except SszError:
|
||||||
return none[ContentKey]()
|
return none[ContentKey]()
|
||||||
|
|
||||||
func toContentId*(contentKey: ByteList): ContentId =
|
template computeContentId*(digestCtxType: type, body: untyped): ContentId =
|
||||||
# TODO: Hash function to be defined, sha256 used now, might be confusing
|
var h {.inject.}: digestCtxType
|
||||||
# with keccak256 that is used for the actual nodes:
|
init(h)
|
||||||
# https://github.com/ethereum/stateless-ethereum-specs/blob/master/state-network.md#content
|
body
|
||||||
let idHash = sha2.sha_256.digest(contentKey.asSeq())
|
let idHash = finish(h)
|
||||||
readUintBE[256](idHash.data)
|
readUintBE[256](idHash.data)
|
||||||
|
|
||||||
func toContentId*(contentKey: ContentKey): ContentId =
|
proc toContentId*(contentKey: ContentKey): ContentId =
|
||||||
toContentId(encode(contentKey))
|
case contentKey.contentType:
|
||||||
|
of accountTrieNode: # sha256(path | node_hash)
|
||||||
|
let key = contentKey.accountTrieNodeKey
|
||||||
|
computeContentId sha256:
|
||||||
|
h.update(key.path.asSeq())
|
||||||
|
h.update(key.nodeHash.data)
|
||||||
|
of contractStorageTrieNode: # sha256(address | path | node_hash)
|
||||||
|
let key = contentKey.contractStorageTrieNodeKey
|
||||||
|
computeContentId sha256:
|
||||||
|
h.update(key.address)
|
||||||
|
h.update(key.path.asSeq())
|
||||||
|
h.update(key.nodeHash.data)
|
||||||
|
of accountTrieProof: # keccak(address)
|
||||||
|
let key = contentKey.accountTrieProofKey
|
||||||
|
computeContentId keccak256:
|
||||||
|
h.update(key.address)
|
||||||
|
of contractStorageTrieProof: # (keccak(address) + keccak(slot)) % 2**256
|
||||||
|
# TODO: Why is keccak run on slot, when it can be used directly?
|
||||||
|
# Also, value to LE or BE? Not mentioned in specification.
|
||||||
|
let key = contentKey.contractStorageTrieProofKey
|
||||||
|
let n1 =
|
||||||
|
block: computeContentId keccak256:
|
||||||
|
h.update(key.address)
|
||||||
|
let n2 =
|
||||||
|
block: computeContentId keccak256:
|
||||||
|
h.update(toBytesLE(key.slot))
|
||||||
|
|
||||||
|
n1 + n2 # uint256 will wrap arround, practically applying the modulo 256
|
||||||
|
of contractBytecode: # sha256(address | code_hash)
|
||||||
|
let key = contentKey.contractBytecodeKey
|
||||||
|
computeContentId sha256:
|
||||||
|
h.update(key.address)
|
||||||
|
h.update(key.codeHash.data)
|
||||||
|
|
||||||
|
proc toContentId*(contentKey: ByteList): Option[ContentId] =
|
||||||
|
let key = decode(contentKey)
|
||||||
|
if key.isSome():
|
||||||
|
some(key.get().toContentId())
|
||||||
|
else:
|
||||||
|
none(ContentId)
|
||||||
|
@ -24,17 +24,20 @@ type StateNetwork* = ref object
|
|||||||
proc getHandler(contentDB: ContentDB): ContentHandler =
|
proc getHandler(contentDB: ContentDB): ContentHandler =
|
||||||
return (proc (contentKey: state_content.ByteList): ContentResult =
|
return (proc (contentKey: state_content.ByteList): ContentResult =
|
||||||
let contentId = toContentId(contentKey)
|
let contentId = toContentId(contentKey)
|
||||||
let maybeContent = contentDB.get(contentId)
|
if contentId.isSome():
|
||||||
if (maybeContent.isSome()):
|
let maybeContent = contentDB.get(contentId.get())
|
||||||
ContentResult(kind: ContentFound, content: maybeContent.unsafeGet())
|
if (maybeContent.isSome()):
|
||||||
|
ContentResult(kind: ContentFound, content: maybeContent.unsafeGet())
|
||||||
|
else:
|
||||||
|
ContentResult(kind: ContentMissing, contentId: contentId.get())
|
||||||
else:
|
else:
|
||||||
ContentResult(kind: ContentMissing, contentId: contentId))
|
ContentResult(kind: ContentKeyValidationFailure, error: ""))
|
||||||
|
|
||||||
proc getContent*(n: StateNetwork, key: ContentKey):
|
proc getContent*(n: StateNetwork, key: ContentKey):
|
||||||
Future[Option[seq[byte]]] {.async.} =
|
Future[Option[seq[byte]]] {.async.} =
|
||||||
let
|
let
|
||||||
keyEncoded = encode(key)
|
keyEncoded = encode(key)
|
||||||
contentId = toContentId(keyEncoded)
|
contentId = toContentId(key)
|
||||||
|
|
||||||
let nodeId = n.portalProtocol.localNode.id
|
let nodeId = n.portalProtocol.localNode.id
|
||||||
|
|
||||||
|
@ -30,16 +30,19 @@ type
|
|||||||
dataRadius*: UInt256
|
dataRadius*: UInt256
|
||||||
|
|
||||||
MessageKind* = enum
|
MessageKind* = enum
|
||||||
unused = 0x00
|
ping = 0x00
|
||||||
|
pong = 0x01
|
||||||
|
findnode = 0x02
|
||||||
|
nodes = 0x03
|
||||||
|
findcontent = 0x04
|
||||||
|
content = 0x05
|
||||||
|
offer = 0x06
|
||||||
|
accept = 0x07
|
||||||
|
|
||||||
ping = 0x01
|
ContentMessageType* = enum
|
||||||
pong = 0x02
|
connectionIdType = 0x00
|
||||||
findnode = 0x03
|
contentType = 0x01
|
||||||
nodes = 0x04
|
enrsType = 0x02
|
||||||
findcontent = 0x05
|
|
||||||
content = 0x06
|
|
||||||
offer = 0x07
|
|
||||||
accept = 0x08
|
|
||||||
|
|
||||||
PingMessage* = object
|
PingMessage* = object
|
||||||
enrSeq*: uint64
|
enrSeq*: uint64
|
||||||
@ -60,11 +63,14 @@ type
|
|||||||
FindContentMessage* = object
|
FindContentMessage* = object
|
||||||
contentKey*: ByteList
|
contentKey*: ByteList
|
||||||
|
|
||||||
# TODO: Must become an SSZ Union
|
|
||||||
ContentMessage* = object
|
ContentMessage* = object
|
||||||
connectionId*: Bytes2
|
case contentMessageType*: ContentMessageType
|
||||||
content*: ByteList
|
of connectionIdType:
|
||||||
enrs*: List[ByteList, 32]
|
connectionId*: Bytes2
|
||||||
|
of contentType:
|
||||||
|
content*: ByteList
|
||||||
|
of enrsType:
|
||||||
|
enrs*: List[ByteList, 32]
|
||||||
|
|
||||||
OfferMessage* = object
|
OfferMessage* = object
|
||||||
contentKeys*: ContentKeysList
|
contentKeys*: ContentKeysList
|
||||||
@ -73,7 +79,6 @@ type
|
|||||||
connectionId*: Bytes2
|
connectionId*: Bytes2
|
||||||
contentKeys*: ContentKeysBitList
|
contentKeys*: ContentKeysBitList
|
||||||
|
|
||||||
# TODO: Needs to become an SSZ Union
|
|
||||||
Message* = object
|
Message* = object
|
||||||
case kind*: MessageKind
|
case kind*: MessageKind
|
||||||
of ping:
|
of ping:
|
||||||
@ -81,7 +86,7 @@ type
|
|||||||
of pong:
|
of pong:
|
||||||
pong*: PongMessage
|
pong*: PongMessage
|
||||||
of findnode:
|
of findnode:
|
||||||
findNode*: FindNodeMessage
|
findnode*: FindNodeMessage
|
||||||
of nodes:
|
of nodes:
|
||||||
nodes*: NodesMessage
|
nodes*: NodesMessage
|
||||||
of findcontent:
|
of findcontent:
|
||||||
@ -92,8 +97,6 @@ type
|
|||||||
offer*: OfferMessage
|
offer*: OfferMessage
|
||||||
of accept:
|
of accept:
|
||||||
accept*: AcceptMessage
|
accept*: AcceptMessage
|
||||||
else:
|
|
||||||
discard
|
|
||||||
|
|
||||||
SomeMessage* =
|
SomeMessage* =
|
||||||
PingMessage or PongMessage or
|
PingMessage or PongMessage or
|
||||||
@ -104,7 +107,7 @@ type
|
|||||||
template messageKind*(T: typedesc[SomeMessage]): MessageKind =
|
template messageKind*(T: typedesc[SomeMessage]): MessageKind =
|
||||||
when T is PingMessage: ping
|
when T is PingMessage: ping
|
||||||
elif T is PongMessage: pong
|
elif T is PongMessage: pong
|
||||||
elif T is FindNodeMessage: findNode
|
elif T is FindNodeMessage: findnode
|
||||||
elif T is NodesMessage: nodes
|
elif T is NodesMessage: nodes
|
||||||
elif T is FindContentMessage: findcontent
|
elif T is FindContentMessage: findcontent
|
||||||
elif T is ContentMessage: content
|
elif T is ContentMessage: content
|
||||||
@ -122,42 +125,24 @@ func fromSszBytes*(T: type UInt256, data: openArray[byte]):
|
|||||||
T.fromBytesLE(data)
|
T.fromBytesLE(data)
|
||||||
|
|
||||||
proc encodeMessage*[T: SomeMessage](m: T): seq[byte] =
|
proc encodeMessage*[T: SomeMessage](m: T): seq[byte] =
|
||||||
ord(messageKind(T)).byte & SSZ.encode(m)
|
# TODO: Could/should be macro'd away,
|
||||||
|
# or we just use SSZ.encode(Message) directly
|
||||||
|
when T is PingMessage: SSZ.encode(Message(kind: ping, ping: m))
|
||||||
|
elif T is PongMessage: SSZ.encode(Message(kind: pong, pong: m))
|
||||||
|
elif T is FindNodeMessage: SSZ.encode(Message(kind: findnode, findnode: m))
|
||||||
|
elif T is NodesMessage: SSZ.encode(Message(kind: nodes, nodes: m))
|
||||||
|
elif T is FindContentMessage: SSZ.encode(Message(kind: findcontent, findcontent: m))
|
||||||
|
elif T is ContentMessage: SSZ.encode(Message(kind: content, content: m))
|
||||||
|
elif T is OfferMessage: SSZ.encode(Message(kind: offer, offer: m))
|
||||||
|
elif T is AcceptMessage: SSZ.encode(Message(kind: accept, accept: m))
|
||||||
|
|
||||||
proc decodeMessage*(body: openarray[byte]): Result[Message, cstring] =
|
proc decodeMessage*(body: openarray[byte]): Result[Message, cstring] =
|
||||||
# Decodes to the specific `Message` type.
|
|
||||||
if body.len < 1:
|
|
||||||
return err("No message data, peer might not support this talk protocol")
|
|
||||||
|
|
||||||
var kind: MessageKind
|
|
||||||
if not checkedEnumAssign(kind, body[0]):
|
|
||||||
return err("Invalid message type")
|
|
||||||
|
|
||||||
var message = Message(kind: kind)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
case kind
|
if body.len < 1: # TODO: This check should probably move a layer down
|
||||||
of unused: return err("Invalid message type")
|
return err("No message data, peer might not support this talk protocol")
|
||||||
of ping:
|
ok(SSZ.decode(body, Message))
|
||||||
message.ping = SSZ.decode(body.toOpenArray(1, body.high), PingMessage)
|
|
||||||
of pong:
|
|
||||||
message.pong = SSZ.decode(body.toOpenArray(1, body.high), PongMessage)
|
|
||||||
of findNode:
|
|
||||||
message.findNode = SSZ.decode(body.toOpenArray(1, body.high), FindNodeMessage)
|
|
||||||
of nodes:
|
|
||||||
message.nodes = SSZ.decode(body.toOpenArray(1, body.high), NodesMessage)
|
|
||||||
of findcontent:
|
|
||||||
message.findcontent = SSZ.decode(body.toOpenArray(1, body.high), FindContentMessage)
|
|
||||||
of content:
|
|
||||||
message.content = SSZ.decode(body.toOpenArray(1, body.high), ContentMessage)
|
|
||||||
of offer:
|
|
||||||
message.offer = SSZ.decode(body.toOpenArray(1, body.high), OfferMessage)
|
|
||||||
of accept:
|
|
||||||
message.accept = SSZ.decode(body.toOpenArray(1, body.high), AcceptMessage)
|
|
||||||
except SszError:
|
except SszError:
|
||||||
return err("Invalid message encoding")
|
err("Invalid message encoding")
|
||||||
|
|
||||||
ok(message)
|
|
||||||
|
|
||||||
template innerMessage[T: SomeMessage](message: Message, expected: MessageKind): Option[T] =
|
template innerMessage[T: SomeMessage](message: Message, expected: MessageKind): Option[T] =
|
||||||
if (message.kind == expected):
|
if (message.kind == expected):
|
||||||
|
@ -137,26 +137,25 @@ proc handleFindContent(p: PortalProtocol, fc: FindContentMessage): seq[byte] =
|
|||||||
# TODO: Need to provide uTP connectionId when content is too large for a
|
# TODO: Need to provide uTP connectionId when content is too large for a
|
||||||
# single response.
|
# single response.
|
||||||
let content = contentHandlingResult.content
|
let content = contentHandlingResult.content
|
||||||
let enrs = List[ByteList, 32](@[]) # Empty enrs when payload is send
|
|
||||||
encodeMessage(ContentMessage(
|
encodeMessage(ContentMessage(
|
||||||
enrs: enrs, content: ByteList(content)))
|
contentMessageType: contentType, content: ByteList(content)))
|
||||||
of ContentMissing:
|
of ContentMissing:
|
||||||
let
|
let
|
||||||
contentId = contentHandlingResult.contentId
|
contentId = contentHandlingResult.contentId
|
||||||
closestNodes = p.routingTable.neighbours(
|
closestNodes = p.routingTable.neighbours(
|
||||||
NodeId(contentId), seenOnly = true)
|
NodeId(contentId), seenOnly = true)
|
||||||
content = ByteList(@[]) # Empty payload when enrs are send
|
|
||||||
enrs =
|
enrs =
|
||||||
closestNodes.map(proc(x: Node): ByteList = ByteList(x.record.raw))
|
closestNodes.map(proc(x: Node): ByteList = ByteList(x.record.raw))
|
||||||
encodeMessage(ContentMessage(
|
encodeMessage(ContentMessage(
|
||||||
enrs: List[ByteList, 32](List(enrs)), content: content))
|
contentMessageType: enrsType, enrs: List[ByteList, 32](List(enrs))))
|
||||||
|
|
||||||
of ContentKeyValidationFailure:
|
of ContentKeyValidationFailure:
|
||||||
# Return empty response when content key validation fails
|
# Return empty content response when content key validation fails
|
||||||
|
# TODO: Better would be to return no message at all, or we need to add a
|
||||||
|
# None type or so.
|
||||||
let content = ByteList(@[])
|
let content = ByteList(@[])
|
||||||
let enrs = List[ByteList, 32](@[]) # Empty enrs when payload is send
|
|
||||||
encodeMessage(ContentMessage(
|
encodeMessage(ContentMessage(
|
||||||
enrs: enrs, content: content))
|
contentMessageType: contentType, content: content))
|
||||||
|
|
||||||
proc handleOffer(p: PortalProtocol, a: OfferMessage): seq[byte] =
|
proc handleOffer(p: PortalProtocol, a: OfferMessage): seq[byte] =
|
||||||
let
|
let
|
||||||
@ -203,8 +202,9 @@ proc messageHandler*(protocol: TalkProtocol, request: seq[byte],
|
|||||||
of MessageKind.offer:
|
of MessageKind.offer:
|
||||||
p.handleOffer(message.offer)
|
p.handleOffer(message.offer)
|
||||||
else:
|
else:
|
||||||
# This shouldn't occur as the 0 case is already covered in `decodedMessage`
|
# This would mean a that Portal wire response message is being send over a
|
||||||
debug "Packet decoding error: Invalid message type"
|
# discv5 talkreq message.
|
||||||
|
debug "Invalid Portal wire message type over talkreq", kind = message.kind
|
||||||
@[]
|
@[]
|
||||||
else:
|
else:
|
||||||
debug "Packet decoding error", error = decoded.error, srcId, srcUdpAddress
|
debug "Packet decoding error", error = decoded.error, srcId, srcUdpAddress
|
||||||
@ -388,7 +388,14 @@ proc lookup*(p: PortalProtocol, target: NodeId): Future[seq[Node]] {.async.} =
|
|||||||
|
|
||||||
proc handleFoundContentMessage(p: PortalProtocol, m: ContentMessage,
|
proc handleFoundContentMessage(p: PortalProtocol, m: ContentMessage,
|
||||||
dst: Node, nodes: var seq[Node]): LookupResult =
|
dst: Node, nodes: var seq[Node]): LookupResult =
|
||||||
if (m.enrs.len() != 0 and m.content.len() == 0):
|
case m.contentMessageType:
|
||||||
|
of connectionIdType:
|
||||||
|
# TODO: We'd have to get the data through uTP, or wrap some proc around
|
||||||
|
# this call that does that.
|
||||||
|
LookupResult(kind: Content)
|
||||||
|
of contentType:
|
||||||
|
LookupResult(kind: Content, content: m.content)
|
||||||
|
of enrsType:
|
||||||
let records = recordsFromBytes(m.enrs)
|
let records = recordsFromBytes(m.enrs)
|
||||||
let verifiedNodes = verifyNodesRecords(records, dst, EnrsResultLimit)
|
let verifiedNodes = verifyNodesRecords(records, dst, EnrsResultLimit)
|
||||||
nodes.add(verifiedNodes)
|
nodes.add(verifiedNodes)
|
||||||
@ -397,16 +404,7 @@ proc handleFoundContentMessage(p: PortalProtocol, m: ContentMessage,
|
|||||||
# Attempt to add all nodes discovered
|
# Attempt to add all nodes discovered
|
||||||
discard p.routingTable.addNode(n)
|
discard p.routingTable.addNode(n)
|
||||||
|
|
||||||
return LookupResult(kind: Nodes, nodes: nodes)
|
LookupResult(kind: Nodes, nodes: nodes)
|
||||||
elif (m.content.len() != 0 and m.enrs.len() == 0):
|
|
||||||
return LookupResult(kind: Content, content: m.content)
|
|
||||||
elif ((m.content.len() != 0 and m.enrs.len() != 0)):
|
|
||||||
# Both content and enrs are filled, which means protocol breach. For now
|
|
||||||
# just logging offending node to quickly identify it
|
|
||||||
warn "Invalid foundcontent response form node ", uri = toURI(dst.record)
|
|
||||||
return LookupResult(kind: Nodes, nodes: nodes)
|
|
||||||
else:
|
|
||||||
return LookupResult(kind: Nodes, nodes: nodes)
|
|
||||||
|
|
||||||
proc contentLookupWorker(p: PortalProtocol, destNode: Node, target: ByteList):
|
proc contentLookupWorker(p: PortalProtocol, destNode: Node, target: ByteList):
|
||||||
Future[LookupResult] {.async.} =
|
Future[LookupResult] {.async.} =
|
||||||
|
@ -13,8 +13,8 @@ import
|
|||||||
|
|
||||||
suite "Portal Wire Protocol Message Encodings":
|
suite "Portal Wire Protocol Message Encodings":
|
||||||
test "Ping Request":
|
test "Ping Request":
|
||||||
var dataRadius: UInt256
|
|
||||||
let
|
let
|
||||||
|
dataRadius = UInt256.high() - 1 # Full radius - 1
|
||||||
enrSeq = 1'u64
|
enrSeq = 1'u64
|
||||||
# Can be any custom payload, testing with just dataRadius here.
|
# Can be any custom payload, testing with just dataRadius here.
|
||||||
customPayload = ByteList(SSZ.encode(CustomPayload(dataRadius: dataRadius)))
|
customPayload = ByteList(SSZ.encode(CustomPayload(dataRadius: dataRadius)))
|
||||||
@ -22,7 +22,7 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
|
|
||||||
let encoded = encodeMessage(p)
|
let encoded = encodeMessage(p)
|
||||||
check encoded.toHex ==
|
check encoded.toHex ==
|
||||||
"0101000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000"
|
"0001000000000000000c000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
|
|
||||||
@ -33,8 +33,8 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
message.ping.customPayload == customPayload
|
message.ping.customPayload == customPayload
|
||||||
|
|
||||||
test "Pong Response":
|
test "Pong Response":
|
||||||
var dataRadius: UInt256
|
|
||||||
let
|
let
|
||||||
|
dataRadius = UInt256.high() div 2.stuint(256) # Radius of half the UInt256
|
||||||
enrSeq = 1'u64
|
enrSeq = 1'u64
|
||||||
# Can be any custom payload, testing with just dataRadius here.
|
# Can be any custom payload, testing with just dataRadius here.
|
||||||
customPayload = ByteList(SSZ.encode(CustomPayload(dataRadius: dataRadius)))
|
customPayload = ByteList(SSZ.encode(CustomPayload(dataRadius: dataRadius)))
|
||||||
@ -42,7 +42,7 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
|
|
||||||
let encoded = encodeMessage(p)
|
let encoded = encodeMessage(p)
|
||||||
check encoded.toHex ==
|
check encoded.toHex ==
|
||||||
"0201000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000"
|
"0101000000000000000c000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
|
|
||||||
@ -54,11 +54,11 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
|
|
||||||
test "FindNode Request":
|
test "FindNode Request":
|
||||||
let
|
let
|
||||||
distances = List[uint16, 256](@[0x0100'u16])
|
distances = List[uint16, 256](@[0x0100'u16, 0x00ff'u16])
|
||||||
fn = FindNodeMessage(distances: distances)
|
fn = FindNodeMessage(distances: distances)
|
||||||
|
|
||||||
let encoded = encodeMessage(fn)
|
let encoded = encodeMessage(fn)
|
||||||
check encoded.toHex == "03040000000001"
|
check encoded.toHex == "02040000000001ff00"
|
||||||
|
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
@ -68,13 +68,13 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
message.kind == findnode
|
message.kind == findnode
|
||||||
message.findnode.distances == distances
|
message.findnode.distances == distances
|
||||||
|
|
||||||
test "Nodes Response - empty":
|
test "Nodes Response - empty enr list":
|
||||||
let
|
let
|
||||||
total = 0x1'u8
|
total = 0x1'u8
|
||||||
n = NodesMessage(total: total)
|
n = NodesMessage(total: total)
|
||||||
|
|
||||||
let encoded = encodeMessage(n)
|
let encoded = encodeMessage(n)
|
||||||
check encoded.toHex == "040105000000"
|
check encoded.toHex == "030105000000"
|
||||||
|
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
@ -85,7 +85,7 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
message.nodes.total == total
|
message.nodes.total == total
|
||||||
message.nodes.enrs.len() == 0
|
message.nodes.enrs.len() == 0
|
||||||
|
|
||||||
test "Nodes Response - enr":
|
test "Nodes Response - enrs":
|
||||||
var e1, e2: Record
|
var e1, e2: Record
|
||||||
check:
|
check:
|
||||||
e1.fromURI("enr:-HW4QBzimRxkmT18hMKaAL3IcZF1UcfTMPyi3Q1pxwZZbcZVRI8DC5infUAB_UauARLOJtYTxaagKoGmIjzQxO2qUygBgmlkgnY0iXNlY3AyNTZrMaEDymNMrg1JrLQB2KTGtv6MVbcNEVv0AHacwUAPMljNMTg")
|
e1.fromURI("enr:-HW4QBzimRxkmT18hMKaAL3IcZF1UcfTMPyi3Q1pxwZZbcZVRI8DC5infUAB_UauARLOJtYTxaagKoGmIjzQxO2qUygBgmlkgnY0iXNlY3AyNTZrMaEDymNMrg1JrLQB2KTGtv6MVbcNEVv0AHacwUAPMljNMTg")
|
||||||
@ -96,7 +96,7 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
n = NodesMessage(total: total, enrs: List[ByteList, 32](@[ByteList(e1.raw), ByteList(e2.raw)]))
|
n = NodesMessage(total: total, enrs: List[ByteList, 32](@[ByteList(e1.raw), ByteList(e2.raw)]))
|
||||||
|
|
||||||
let encoded = encodeMessage(n)
|
let encoded = encodeMessage(n)
|
||||||
check encoded.toHex == "040105000000080000007f000000f875b8401ce2991c64993d7c84c29a00bdc871917551c7d330fca2dd0d69c706596dc655448f030b98a77d4001fd46ae0112ce26d613c5a6a02a81a6223cd0c4edaa53280182696482763489736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138f875b840d7f1c39e376297f81d7297758c64cb37dcc5c3beea9f57f7ce9695d7d5a67553417d719539d6ae4b445946de4d99e680eb8063f29485b555d45b7df16a1850130182696482763489736563703235366b31a1030e2cb74241c0c4fc8e8166f1a79a05d5b0dd95813a74b094529f317d5c39d235"
|
check encoded.toHex == "030105000000080000007f000000f875b8401ce2991c64993d7c84c29a00bdc871917551c7d330fca2dd0d69c706596dc655448f030b98a77d4001fd46ae0112ce26d613c5a6a02a81a6223cd0c4edaa53280182696482763489736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138f875b840d7f1c39e376297f81d7297758c64cb37dcc5c3beea9f57f7ce9695d7d5a67553417d719539d6ae4b445946de4d99e680eb8063f29485b555d45b7df16a1850130182696482763489736563703235366b31a1030e2cb74241c0c4fc8e8166f1a79a05d5b0dd95813a74b094529f317d5c39d235"
|
||||||
|
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
@ -110,12 +110,13 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
message.nodes.enrs[1] == ByteList(e2.raw)
|
message.nodes.enrs[1] == ByteList(e2.raw)
|
||||||
|
|
||||||
test "FindContent Request":
|
test "FindContent Request":
|
||||||
|
const contentKeyString = "0x706f7274616c"
|
||||||
let
|
let
|
||||||
contentEncoded = ByteList.init(@[1'u8])
|
contentKey = ByteList.init(hexToSeqByte(contentKeyString))
|
||||||
fn = FindContentMessage(contentKey: contentEncoded)
|
fc = FindContentMessage(contentKey: contentKey)
|
||||||
|
|
||||||
let encoded = encodeMessage(fn)
|
let encoded = encodeMessage(fc)
|
||||||
check encoded.toHex == "050400000001"
|
check encoded.toHex == "0404000000706f7274616c"
|
||||||
|
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
@ -123,16 +124,16 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
let message = decoded.get()
|
let message = decoded.get()
|
||||||
check:
|
check:
|
||||||
message.kind == findcontent
|
message.kind == findcontent
|
||||||
message.findcontent.contentKey == contentEncoded
|
message.findcontent.contentKey == contentKey
|
||||||
|
|
||||||
test "Content Response - payload":
|
test "Content Response - connection id":
|
||||||
let
|
let
|
||||||
enrs = List[ByteList, 32](@[])
|
connectionId = Bytes2([byte 0x01, 0x02])
|
||||||
content = ByteList(@[byte 0x01, 0x02, 0x03])
|
c = ContentMessage(
|
||||||
n = ContentMessage(enrs: enrs, content: content)
|
contentMessageType: connectionIdType, connectionId: connectionId)
|
||||||
|
|
||||||
let encoded = encodeMessage(n)
|
let encoded = encodeMessage(c)
|
||||||
check encoded.toHex == "0600000a0000000d000000010203"
|
check encoded.toHex == "05000102"
|
||||||
|
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
@ -140,7 +141,25 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
let message = decoded.get()
|
let message = decoded.get()
|
||||||
check:
|
check:
|
||||||
message.kind == MessageKind.content
|
message.kind == MessageKind.content
|
||||||
message.content.enrs.len() == 0
|
message.content.contentMessageType == connectionIdType
|
||||||
|
message.content.connectionId == connectionId
|
||||||
|
|
||||||
|
test "Content Response - content payload":
|
||||||
|
const contentString = "0x7468652063616b652069732061206c6965"
|
||||||
|
let
|
||||||
|
content = ByteList(hexToSeqByte(contentString))
|
||||||
|
c = ContentMessage(contentMessageType: contentType, content: content)
|
||||||
|
|
||||||
|
let encoded = encodeMessage(c)
|
||||||
|
check encoded.toHex == "05017468652063616b652069732061206c6965"
|
||||||
|
|
||||||
|
let decoded = decodeMessage(encoded)
|
||||||
|
check decoded.isOk()
|
||||||
|
|
||||||
|
let message = decoded.get()
|
||||||
|
check:
|
||||||
|
message.kind == MessageKind.content
|
||||||
|
message.content.contentMessageType == contentType
|
||||||
message.content.content == content
|
message.content.content == content
|
||||||
|
|
||||||
test "Content Response - enrs":
|
test "Content Response - enrs":
|
||||||
@ -151,11 +170,10 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
|
|
||||||
let
|
let
|
||||||
enrs = List[ByteList, 32](@[ByteList(e1.raw), ByteList(e2.raw)])
|
enrs = List[ByteList, 32](@[ByteList(e1.raw), ByteList(e2.raw)])
|
||||||
content = ByteList(@[])
|
c = ContentMessage(contentMessageType: enrsType, enrs: enrs)
|
||||||
n = ContentMessage(enrs: enrs, content: content)
|
|
||||||
|
|
||||||
let encoded = encodeMessage(n)
|
let encoded = encodeMessage(c)
|
||||||
check encoded.toHex == "0600000a0000000a000000080000007f000000f875b8401ce2991c64993d7c84c29a00bdc871917551c7d330fca2dd0d69c706596dc655448f030b98a77d4001fd46ae0112ce26d613c5a6a02a81a6223cd0c4edaa53280182696482763489736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138f875b840d7f1c39e376297f81d7297758c64cb37dcc5c3beea9f57f7ce9695d7d5a67553417d719539d6ae4b445946de4d99e680eb8063f29485b555d45b7df16a1850130182696482763489736563703235366b31a1030e2cb74241c0c4fc8e8166f1a79a05d5b0dd95813a74b094529f317d5c39d235"
|
check encoded.toHex == "0502080000007f000000f875b8401ce2991c64993d7c84c29a00bdc871917551c7d330fca2dd0d69c706596dc655448f030b98a77d4001fd46ae0112ce26d613c5a6a02a81a6223cd0c4edaa53280182696482763489736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138f875b840d7f1c39e376297f81d7297758c64cb37dcc5c3beea9f57f7ce9695d7d5a67553417d719539d6ae4b445946de4d99e680eb8063f29485b555d45b7df16a1850130182696482763489736563703235366b31a1030e2cb74241c0c4fc8e8166f1a79a05d5b0dd95813a74b094529f317d5c39d235"
|
||||||
|
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
@ -163,18 +181,18 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
let message = decoded.get()
|
let message = decoded.get()
|
||||||
check:
|
check:
|
||||||
message.kind == MessageKind.content
|
message.kind == MessageKind.content
|
||||||
|
message.content.contentMessageType == enrsType
|
||||||
message.content.enrs.len() == 2
|
message.content.enrs.len() == 2
|
||||||
message.content.enrs[0] == ByteList(e1.raw)
|
message.content.enrs[0] == ByteList(e1.raw)
|
||||||
message.content.enrs[1] == ByteList(e2.raw)
|
message.content.enrs[1] == ByteList(e2.raw)
|
||||||
message.content.content == content
|
|
||||||
|
|
||||||
test "Offer Request":
|
test "Offer Request":
|
||||||
let
|
let
|
||||||
contentKeys = ContentKeysList(List(@[ByteList(@[byte 0x01, 0x02, 0x03])]))
|
contentKeys = ContentKeysList(List(@[ByteList(@[byte 0x01, 0x02, 0x03])]))
|
||||||
am = OfferMessage(contentKeys: contentKeys)
|
o = OfferMessage(contentKeys: contentKeys)
|
||||||
|
|
||||||
let encoded = encodeMessage(am)
|
let encoded = encodeMessage(o)
|
||||||
check encoded.toHex == "070400000004000000010203"
|
check encoded.toHex == "060400000004000000010203"
|
||||||
|
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
@ -185,14 +203,14 @@ suite "Portal Wire Protocol Message Encodings":
|
|||||||
message.offer.contentKeys == contentKeys
|
message.offer.contentKeys == contentKeys
|
||||||
|
|
||||||
test "Accept Response":
|
test "Accept Response":
|
||||||
|
var contentKeys = ContentKeysBitList.init(8)
|
||||||
|
contentKeys.setBit(0)
|
||||||
let
|
let
|
||||||
connectionId = Bytes2([byte 0x01, 0x02])
|
connectionId = Bytes2([byte 0x01, 0x02])
|
||||||
contentKeys = ContentKeysBitList.init(8)
|
a = AcceptMessage(connectionId: connectionId, contentKeys: contentKeys)
|
||||||
n = AcceptMessage(connectionId: connectionId,
|
|
||||||
contentKeys: contentKeys)
|
|
||||||
|
|
||||||
let encoded = encodeMessage(n)
|
let encoded = encodeMessage(a)
|
||||||
check encoded.toHex == "080102060000000001"
|
check encoded.toHex == "070102060000000101"
|
||||||
|
|
||||||
let decoded = decodeMessage(encoded)
|
let decoded = decodeMessage(encoded)
|
||||||
check decoded.isOk()
|
check decoded.isOk()
|
||||||
|
@ -133,7 +133,6 @@ procSuite "Portal Wire Protocol Tests":
|
|||||||
check:
|
check:
|
||||||
content.isOk()
|
content.isOk()
|
||||||
content.get().enrs.len() == 1
|
content.get().enrs.len() == 1
|
||||||
content.get().content.len() == 0
|
|
||||||
|
|
||||||
await test.stopTest()
|
await test.stopTest()
|
||||||
|
|
||||||
|
@ -59,10 +59,10 @@ procSuite "State Content Network":
|
|||||||
copyMem(nodeHash.data.addr, unsafeAddr k[0], sizeof(nodeHash.data))
|
copyMem(nodeHash.data.addr, unsafeAddr k[0], sizeof(nodeHash.data))
|
||||||
|
|
||||||
let
|
let
|
||||||
|
# TODO: add stateRoot, and path eventually
|
||||||
|
accountTrieNodeKey = AccountTrieNodeKey(nodeHash: nodeHash)
|
||||||
contentKey = ContentKey(
|
contentKey = ContentKey(
|
||||||
networkId: 0'u16,
|
contentType: accountTrieNode, accountTrieNodeKey: accountTrieNodeKey)
|
||||||
contentType: state_content.ContentType.Account,
|
|
||||||
nodeHash: nodeHash)
|
|
||||||
contentId = toContentId(contentKey)
|
contentId = toContentId(contentKey)
|
||||||
|
|
||||||
proto1.contentDB.put(contentId, v)
|
proto1.contentDB.put(contentId, v)
|
||||||
@ -72,10 +72,10 @@ procSuite "State Content Network":
|
|||||||
copyMem(nodeHash.data.addr, unsafeAddr key[0], sizeof(nodeHash.data))
|
copyMem(nodeHash.data.addr, unsafeAddr key[0], sizeof(nodeHash.data))
|
||||||
|
|
||||||
let
|
let
|
||||||
|
accountTrieNodeKey = AccountTrieNodeKey(nodeHash: nodeHash)
|
||||||
contentKey = ContentKey(
|
contentKey = ContentKey(
|
||||||
networkId: 0'u16,
|
contentType: accountTrieNode, accountTrieNodeKey: accountTrieNodeKey)
|
||||||
contentType: state_content.ContentType.Account,
|
contentId = toContentId(contentKey)
|
||||||
nodeHash: nodeHash)
|
|
||||||
|
|
||||||
# Note: GetContent and thus the lookup here is not really needed, as we
|
# Note: GetContent and thus the lookup here is not really needed, as we
|
||||||
# only have to request data to one node.
|
# only have to request data to one node.
|
||||||
@ -102,12 +102,10 @@ procSuite "State Content Network":
|
|||||||
node3 = initDiscoveryNode(
|
node3 = initDiscoveryNode(
|
||||||
rng, PrivateKey.random(rng[]), localAddress(20304))
|
rng, PrivateKey.random(rng[]), localAddress(20304))
|
||||||
|
|
||||||
|
|
||||||
proto1 = StateNetwork.new(node1, ContentDB.new("", inMemory = true))
|
proto1 = StateNetwork.new(node1, ContentDB.new("", inMemory = true))
|
||||||
proto2 = StateNetwork.new(node2, ContentDB.new("", inMemory = true))
|
proto2 = StateNetwork.new(node2, ContentDB.new("", inMemory = true))
|
||||||
proto3 = StateNetwork.new(node3, ContentDB.new("", inMemory = true))
|
proto3 = StateNetwork.new(node3, ContentDB.new("", inMemory = true))
|
||||||
|
|
||||||
|
|
||||||
# Node1 knows about Node2, and Node2 knows about Node3 which hold all content
|
# Node1 knows about Node2, and Node2 knows about Node3 which hold all content
|
||||||
check proto1.portalProtocol.addNode(node2.localNode) == Added
|
check proto1.portalProtocol.addNode(node2.localNode) == Added
|
||||||
check proto2.portalProtocol.addNode(node3.localNode) == Added
|
check proto2.portalProtocol.addNode(node3.localNode) == Added
|
||||||
@ -122,10 +120,9 @@ procSuite "State Content Network":
|
|||||||
copyMem(nodeHash.data.addr, unsafeAddr k[0], sizeof(nodeHash.data))
|
copyMem(nodeHash.data.addr, unsafeAddr k[0], sizeof(nodeHash.data))
|
||||||
|
|
||||||
let
|
let
|
||||||
|
accountTrieNodeKey = AccountTrieNodeKey(nodeHash: nodeHash)
|
||||||
contentKey = ContentKey(
|
contentKey = ContentKey(
|
||||||
networkId: 0'u16,
|
contentType: accountTrieNode, accountTrieNodeKey: accountTrieNodeKey)
|
||||||
contentType: state_content.ContentType.Account,
|
|
||||||
nodeHash: nodeHash)
|
|
||||||
contentId = toContentId(contentKey)
|
contentId = toContentId(contentKey)
|
||||||
|
|
||||||
proto2.contentDB.put(contentId, v)
|
proto2.contentDB.put(contentId, v)
|
||||||
@ -138,10 +135,10 @@ procSuite "State Content Network":
|
|||||||
let firstKey = keys[0]
|
let firstKey = keys[0]
|
||||||
copyMem(nodeHash.data.addr, unsafeAddr firstKey[0], sizeof(nodeHash.data))
|
copyMem(nodeHash.data.addr, unsafeAddr firstKey[0], sizeof(nodeHash.data))
|
||||||
|
|
||||||
let contentKey = ContentKey(
|
let
|
||||||
networkId: 0'u16,
|
accountTrieNodeKey = AccountTrieNodeKey(nodeHash: nodeHash)
|
||||||
contentType: state_content.ContentType.Account,
|
contentKey = ContentKey(
|
||||||
nodeHash: nodeHash)
|
contentType: accountTrieNode, accountTrieNodeKey: accountTrieNodeKey)
|
||||||
|
|
||||||
let foundContent = await proto1.getContent(contentKey)
|
let foundContent = await proto1.getContent(contentKey)
|
||||||
|
|
||||||
|
@ -162,7 +162,12 @@ proc testHandler(contentKey: state_content.ByteList): ContentResult =
|
|||||||
# Note: We don't incorperate storage in this tool so we always return
|
# Note: We don't incorperate storage in this tool so we always return
|
||||||
# missing content. For now we are using the state network derivation but it
|
# missing content. For now we are using the state network derivation but it
|
||||||
# could be selective based on the network the tool is used for.
|
# could be selective based on the network the tool is used for.
|
||||||
ContentResult(kind: ContentMissing, contentId: toContentId(contentKey))
|
let contentId = toContentId(contentKey)
|
||||||
|
if contentId.isSome():
|
||||||
|
ContentResult(kind: ContentMissing, contentId: contentId.get())
|
||||||
|
else:
|
||||||
|
ContentResult(kind: ContentKeyValidationFailure,
|
||||||
|
error: "Failed decoding content key")
|
||||||
|
|
||||||
proc run(config: DiscoveryConf) =
|
proc run(config: DiscoveryConf) =
|
||||||
let
|
let
|
||||||
|
2
vendor/nim-ssz-serialization
vendored
2
vendor/nim-ssz-serialization
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 5d65b20d6b56265902e5c9b6a2be4d1c2fd6427e
|
Subproject commit 1f07d6500aa708321aefd1a209aaba05b9ea80a8
|
Loading…
x
Reference in New Issue
Block a user