mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-24 09:48:24 +00:00
Update the beacon and state network content key prefixes (#1950)
This commit is contained in:
parent
ffa8ad2246
commit
dded8643d9
@ -1,4 +1,4 @@
|
|||||||
# Nimbus - Portal Network
|
# Fluffy - Portal Network
|
||||||
# Copyright (c) 2022-2023 Status Research & Development GmbH
|
# Copyright (c) 2022-2023 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||||
@ -30,10 +30,12 @@ const
|
|||||||
|
|
||||||
type
|
type
|
||||||
ContentType* = enum
|
ContentType* = enum
|
||||||
lightClientBootstrap = 0x00
|
# Note: See same note as for state_content.nim
|
||||||
lightClientUpdate = 0x01
|
unused = 0x00
|
||||||
lightClientFinalityUpdate = 0x02
|
lightClientBootstrap = 0x10
|
||||||
lightClientOptimisticUpdate = 0x03
|
lightClientUpdate = 0x11
|
||||||
|
lightClientFinalityUpdate = 0x12
|
||||||
|
lightClientOptimisticUpdate = 0x13
|
||||||
|
|
||||||
# TODO: Consider how we will gossip bootstraps?
|
# TODO: Consider how we will gossip bootstraps?
|
||||||
# In consensus light client operation a node trusts only one bootstrap hash,
|
# In consensus light client operation a node trusts only one bootstrap hash,
|
||||||
@ -59,6 +61,8 @@ type
|
|||||||
|
|
||||||
ContentKey* = object
|
ContentKey* = object
|
||||||
case contentType*: ContentType
|
case contentType*: ContentType
|
||||||
|
of unused:
|
||||||
|
discard
|
||||||
of lightClientBootstrap:
|
of lightClientBootstrap:
|
||||||
lightClientBootstrapKey*: LightClientBootstrapKey
|
lightClientBootstrapKey*: LightClientBootstrapKey
|
||||||
of lightClientUpdate:
|
of lightClientUpdate:
|
||||||
@ -84,8 +88,17 @@ func forkDigestAtEpoch*(
|
|||||||
forkDigests.atEpoch(epoch, cfg)
|
forkDigests.atEpoch(epoch, cfg)
|
||||||
|
|
||||||
func encode*(contentKey: ContentKey): ByteList =
|
func encode*(contentKey: ContentKey): ByteList =
|
||||||
|
doAssert(contentKey.contentType != unused)
|
||||||
ByteList.init(SSZ.encode(contentKey))
|
ByteList.init(SSZ.encode(contentKey))
|
||||||
|
|
||||||
|
proc readSszBytes*(
|
||||||
|
data: openArray[byte], val: var ContentKey) {.raises: [SszError].} =
|
||||||
|
mixin readSszValue
|
||||||
|
if data.len() > 0 and data[0] == ord(unused):
|
||||||
|
raise newException(MalformedSszError, "SSZ selector unused value")
|
||||||
|
|
||||||
|
readSszValue(data, val)
|
||||||
|
|
||||||
func decode*(contentKey: ByteList): Opt[ContentKey] =
|
func decode*(contentKey: ByteList): Opt[ContentKey] =
|
||||||
try:
|
try:
|
||||||
Opt.some(SSZ.decode(contentKey.asSeq(), ContentKey))
|
Opt.some(SSZ.decode(contentKey.asSeq(), ContentKey))
|
||||||
|
@ -253,6 +253,8 @@ proc createGetHandler*(db: BeaconDb): DbGetHandler =
|
|||||||
return Opt.none(seq[byte])
|
return Opt.none(seq[byte])
|
||||||
|
|
||||||
case contentKey.contentType:
|
case contentKey.contentType:
|
||||||
|
of unused:
|
||||||
|
raiseAssert "Should not be used and fail at decoding"
|
||||||
of lightClientBootstrap:
|
of lightClientBootstrap:
|
||||||
db.get(contentId)
|
db.get(contentId)
|
||||||
of lightClientUpdate:
|
of lightClientUpdate:
|
||||||
@ -309,6 +311,8 @@ proc createStoreHandler*(db: BeaconDb): DbStoreHandler =
|
|||||||
return
|
return
|
||||||
|
|
||||||
case contentKey.contentType:
|
case contentKey.contentType:
|
||||||
|
of unused:
|
||||||
|
raiseAssert "Should not be used and fail at decoding"
|
||||||
of lightClientBootstrap:
|
of lightClientBootstrap:
|
||||||
db.put(contentId, content)
|
db.put(contentId, content)
|
||||||
of lightClientUpdate:
|
of lightClientUpdate:
|
||||||
|
@ -192,6 +192,8 @@ proc validateContent(
|
|||||||
return err("Error decoding content key")
|
return err("Error decoding content key")
|
||||||
|
|
||||||
case key.contentType:
|
case key.contentType:
|
||||||
|
of unused:
|
||||||
|
raiseAssert "Should not be used and fail at decoding"
|
||||||
of lightClientBootstrap:
|
of lightClientBootstrap:
|
||||||
let decodingResult = decodeLightClientBootstrapForked(
|
let decodingResult = decodeLightClientBootstrapForked(
|
||||||
n.forkDigests, content)
|
n.forkDigests, content)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Nimbus
|
# Fluffy
|
||||||
# Copyright (c) 2021-2023 Status Research & Development GmbH
|
# Copyright (c) 2021-2023 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||||
@ -23,11 +23,19 @@ type
|
|||||||
Address* = array[20, byte]
|
Address* = array[20, byte]
|
||||||
|
|
||||||
ContentType* = enum
|
ContentType* = enum
|
||||||
accountTrieNode = 0x00
|
# Note: Need to add this unused value as a case object with an enum without
|
||||||
contractStorageTrieNode = 0x01
|
# a 0 valueis not allowed: "low(contentType) must be 0 for discriminant".
|
||||||
accountTrieProof = 0x02
|
# For prefix values that are in the enum gap, the deserialization will fail
|
||||||
contractStorageTrieProof = 0x03
|
# at runtime as is wanted.
|
||||||
contractBytecode = 0x04
|
# In the future it might be possible that this will fail at compile time for
|
||||||
|
# the SSZ Union type, but currently it is allowed in the implementation, and
|
||||||
|
# the SSZ spec is not explicit about disallowing this.
|
||||||
|
unused = 0x00
|
||||||
|
accountTrieNode = 0x20
|
||||||
|
contractStorageTrieNode = 0x21
|
||||||
|
accountTrieProof = 0x22
|
||||||
|
contractStorageTrieProof = 0x23
|
||||||
|
contractBytecode = 0x24
|
||||||
|
|
||||||
AccountTrieNodeKey* = object
|
AccountTrieNodeKey* = object
|
||||||
path*: ByteList
|
path*: ByteList
|
||||||
@ -55,6 +63,8 @@ type
|
|||||||
|
|
||||||
ContentKey* = object
|
ContentKey* = object
|
||||||
case contentType*: ContentType
|
case contentType*: ContentType
|
||||||
|
of unused:
|
||||||
|
discard
|
||||||
of accountTrieNode:
|
of accountTrieNode:
|
||||||
accountTrieNodeKey*: AccountTrieNodeKey
|
accountTrieNodeKey*: AccountTrieNodeKey
|
||||||
of contractStorageTrieNode:
|
of contractStorageTrieNode:
|
||||||
@ -67,8 +77,18 @@ type
|
|||||||
contractBytecodeKey*: ContractBytecodeKey
|
contractBytecodeKey*: ContractBytecodeKey
|
||||||
|
|
||||||
func encode*(contentKey: ContentKey): ByteList =
|
func encode*(contentKey: ContentKey): ByteList =
|
||||||
|
doAssert(contentKey.contentType != unused)
|
||||||
ByteList.init(SSZ.encode(contentKey))
|
ByteList.init(SSZ.encode(contentKey))
|
||||||
|
|
||||||
|
proc readSszBytes*(
|
||||||
|
data: openArray[byte], val: var ContentKey
|
||||||
|
) {.raises: [SszError].} =
|
||||||
|
mixin readSszValue
|
||||||
|
if data.len() > 0 and data[0] == ord(unused):
|
||||||
|
raise newException(MalformedSszError, "SSZ selector is unused value")
|
||||||
|
|
||||||
|
readSszValue(data, val)
|
||||||
|
|
||||||
func decode*(contentKey: ByteList): Opt[ContentKey] =
|
func decode*(contentKey: ByteList): Opt[ContentKey] =
|
||||||
try:
|
try:
|
||||||
Opt.some(SSZ.decode(contentKey.asSeq(), ContentKey))
|
Opt.some(SSZ.decode(contentKey.asSeq(), ContentKey))
|
||||||
@ -84,6 +104,8 @@ template computeContentId*(digestCtxType: type, body: untyped): ContentId =
|
|||||||
|
|
||||||
func toContentId*(contentKey: ContentKey): ContentId =
|
func toContentId*(contentKey: ContentKey): ContentId =
|
||||||
case contentKey.contentType:
|
case contentKey.contentType:
|
||||||
|
of unused:
|
||||||
|
raiseAssert "Should not be used and fail at decoding"
|
||||||
of accountTrieNode: # sha256(path | node_hash)
|
of accountTrieNode: # sha256(path | node_hash)
|
||||||
let key = contentKey.accountTrieNodeKey
|
let key = contentKey.accountTrieNodeKey
|
||||||
computeContentId sha256:
|
computeContentId sha256:
|
||||||
|
@ -281,3 +281,28 @@ suite "Beacon Content Encodings":
|
|||||||
decodeLightClientBootstrapForked(forkDigests, @[]).isErr()
|
decodeLightClientBootstrapForked(forkDigests, @[]).isErr()
|
||||||
decodeLightClientBootstrapForked(forkDigests, encodedTooEarlyFork).isErr()
|
decodeLightClientBootstrapForked(forkDigests, encodedTooEarlyFork).isErr()
|
||||||
decodeLightClientBootstrapForked(forkDigests, encodedUnknownFork).isErr()
|
decodeLightClientBootstrapForked(forkDigests, encodedUnknownFork).isErr()
|
||||||
|
|
||||||
|
suite "Beacon ContentKey Encodings ":
|
||||||
|
test "Invalid prefix - 0 value":
|
||||||
|
let encoded = ByteList.init(@[byte 0x00])
|
||||||
|
let decoded = decode(encoded)
|
||||||
|
|
||||||
|
check decoded.isNone()
|
||||||
|
|
||||||
|
test "Invalid prefix - before valid range":
|
||||||
|
let encoded = ByteList.init(@[byte 0x01])
|
||||||
|
let decoded = decode(encoded)
|
||||||
|
|
||||||
|
check decoded.isNone()
|
||||||
|
|
||||||
|
test "Invalid prefix - after valid range":
|
||||||
|
let encoded = ByteList.init(@[byte 0x14])
|
||||||
|
let decoded = decode(encoded)
|
||||||
|
|
||||||
|
check decoded.isNone()
|
||||||
|
|
||||||
|
test "Invalid key - empty input":
|
||||||
|
let encoded = ByteList.init(@[])
|
||||||
|
let decoded = decode(encoded)
|
||||||
|
|
||||||
|
check decoded.isNone()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Nimbus
|
# Fluffy
|
||||||
# Copyright (c) 2021-2022 Status Research & Development GmbH
|
# Copyright (c) 2021-2023 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||||
# * 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).
|
||||||
@ -31,7 +31,7 @@ suite "State ContentKey Encodings":
|
|||||||
|
|
||||||
# Output
|
# Output
|
||||||
contentKeyHex =
|
contentKeyHex =
|
||||||
"0044000000b8be7903aee73b8f6a59cd44a1f52c62148e1f376c0dfa1f5f773a98666efc2bd1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01020001"
|
"2044000000b8be7903aee73b8f6a59cd44a1f52c62148e1f376c0dfa1f5f773a98666efc2bd1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01020001"
|
||||||
contentId =
|
contentId =
|
||||||
"41237096982860596884042712109427867048220765019203857308279863638242761605893"
|
"41237096982860596884042712109427867048220765019203857308279863638242761605893"
|
||||||
# or
|
# or
|
||||||
@ -67,7 +67,7 @@ suite "State ContentKey Encodings":
|
|||||||
|
|
||||||
# Output
|
# Output
|
||||||
contentKeyHex =
|
contentKeyHex =
|
||||||
"01829bd824b016326a401d083b33d092293333a830580000003e190b68719aecbcb28ed2271014dd25f2aa633184988eb414189ce0899cade5d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01000f0e0c00"
|
"21829bd824b016326a401d083b33d092293333a830580000003e190b68719aecbcb28ed2271014dd25f2aa633184988eb414189ce0899cade5d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01000f0e0c00"
|
||||||
contentId =
|
contentId =
|
||||||
"43529358882110548041037387588279806363134301284609868141745095118932570363585"
|
"43529358882110548041037387588279806363134301284609868141745095118932570363585"
|
||||||
# or
|
# or
|
||||||
@ -100,7 +100,7 @@ suite "State ContentKey Encodings":
|
|||||||
# Output
|
# Output
|
||||||
const
|
const
|
||||||
contentKeyHex =
|
contentKeyHex =
|
||||||
"02829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
"22829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||||
contentId =
|
contentId =
|
||||||
"45301550050471302973396879294932122279426162994178563319590607565171451545101"
|
"45301550050471302973396879294932122279426162994178563319590607565171451545101"
|
||||||
# or
|
# or
|
||||||
@ -135,7 +135,7 @@ suite "State ContentKey Encodings":
|
|||||||
|
|
||||||
# Output
|
# Output
|
||||||
contentKeyHex =
|
contentKeyHex =
|
||||||
"03829bd824b016326a401d083b33d092293333a830c8a6030000000000000000000000000000000000000000000000000000000000d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
"23829bd824b016326a401d083b33d092293333a830c8a6030000000000000000000000000000000000000000000000000000000000d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||||
contentId =
|
contentId =
|
||||||
"80413803151602881485894828440259195604313253842905231566803078625935967002376"
|
"80413803151602881485894828440259195604313253842905231566803078625935967002376"
|
||||||
# or
|
# or
|
||||||
@ -172,7 +172,7 @@ suite "State ContentKey Encodings":
|
|||||||
# Output
|
# Output
|
||||||
const
|
const
|
||||||
contentKeyHex =
|
contentKeyHex =
|
||||||
"04829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
"24829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||||
contentId =
|
contentId =
|
||||||
"9243655320250466575533858917172702581481192615849913473767356296630272634800"
|
"9243655320250466575533858917172702581481192615849913473767356296630272634800"
|
||||||
# or
|
# or
|
||||||
@ -199,3 +199,27 @@ suite "State ContentKey Encodings":
|
|||||||
toContentId(contentKey) == parse(contentId, StUint[256], 10)
|
toContentId(contentKey) == parse(contentId, StUint[256], 10)
|
||||||
# In stint this does BE hex string
|
# In stint this does BE hex string
|
||||||
toContentId(contentKey).toHex() == contentIdHexBE
|
toContentId(contentKey).toHex() == contentIdHexBE
|
||||||
|
|
||||||
|
test "Invalid prefix - 0 value":
|
||||||
|
let encoded = ByteList.init(@[byte 0x00])
|
||||||
|
let decoded = decode(encoded)
|
||||||
|
|
||||||
|
check decoded.isNone()
|
||||||
|
|
||||||
|
test "Invalid prefix - before valid range":
|
||||||
|
let encoded = ByteList.init(@[byte 0x01])
|
||||||
|
let decoded = decode(encoded)
|
||||||
|
|
||||||
|
check decoded.isNone()
|
||||||
|
|
||||||
|
test "Invalid prefix - after valid range":
|
||||||
|
let encoded = ByteList.init(@[byte 0x25])
|
||||||
|
let decoded = decode(encoded)
|
||||||
|
|
||||||
|
check decoded.isNone()
|
||||||
|
|
||||||
|
test "Invalid key - empty input":
|
||||||
|
let encoded = ByteList.init(@[])
|
||||||
|
let decoded = decode(encoded)
|
||||||
|
|
||||||
|
check decoded.isNone()
|
||||||
|
2
vendor/portal-spec-tests
vendored
2
vendor/portal-spec-tests
vendored
@ -1 +1 @@
|
|||||||
Subproject commit ae43c56eabd021406b8afb41f124d63e3cf5adf9
|
Subproject commit eb9edb34eb3ea599a5b14407615cef0e7e48e8b9
|
Loading…
x
Reference in New Issue
Block a user