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
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||
@ -30,10 +30,12 @@ const
|
||||
|
||||
type
|
||||
ContentType* = enum
|
||||
lightClientBootstrap = 0x00
|
||||
lightClientUpdate = 0x01
|
||||
lightClientFinalityUpdate = 0x02
|
||||
lightClientOptimisticUpdate = 0x03
|
||||
# Note: See same note as for state_content.nim
|
||||
unused = 0x00
|
||||
lightClientBootstrap = 0x10
|
||||
lightClientUpdate = 0x11
|
||||
lightClientFinalityUpdate = 0x12
|
||||
lightClientOptimisticUpdate = 0x13
|
||||
|
||||
# TODO: Consider how we will gossip bootstraps?
|
||||
# In consensus light client operation a node trusts only one bootstrap hash,
|
||||
@ -59,6 +61,8 @@ type
|
||||
|
||||
ContentKey* = object
|
||||
case contentType*: ContentType
|
||||
of unused:
|
||||
discard
|
||||
of lightClientBootstrap:
|
||||
lightClientBootstrapKey*: LightClientBootstrapKey
|
||||
of lightClientUpdate:
|
||||
@ -84,8 +88,17 @@ func forkDigestAtEpoch*(
|
||||
forkDigests.atEpoch(epoch, cfg)
|
||||
|
||||
func encode*(contentKey: ContentKey): ByteList =
|
||||
doAssert(contentKey.contentType != unused)
|
||||
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] =
|
||||
try:
|
||||
Opt.some(SSZ.decode(contentKey.asSeq(), ContentKey))
|
||||
|
@ -253,6 +253,8 @@ proc createGetHandler*(db: BeaconDb): DbGetHandler =
|
||||
return Opt.none(seq[byte])
|
||||
|
||||
case contentKey.contentType:
|
||||
of unused:
|
||||
raiseAssert "Should not be used and fail at decoding"
|
||||
of lightClientBootstrap:
|
||||
db.get(contentId)
|
||||
of lightClientUpdate:
|
||||
@ -309,6 +311,8 @@ proc createStoreHandler*(db: BeaconDb): DbStoreHandler =
|
||||
return
|
||||
|
||||
case contentKey.contentType:
|
||||
of unused:
|
||||
raiseAssert "Should not be used and fail at decoding"
|
||||
of lightClientBootstrap:
|
||||
db.put(contentId, content)
|
||||
of lightClientUpdate:
|
||||
|
@ -192,6 +192,8 @@ proc validateContent(
|
||||
return err("Error decoding content key")
|
||||
|
||||
case key.contentType:
|
||||
of unused:
|
||||
raiseAssert "Should not be used and fail at decoding"
|
||||
of lightClientBootstrap:
|
||||
let decodingResult = decodeLightClientBootstrapForked(
|
||||
n.forkDigests, content)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Nimbus
|
||||
# Fluffy
|
||||
# Copyright (c) 2021-2023 Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||
@ -23,11 +23,19 @@ type
|
||||
Address* = array[20, byte]
|
||||
|
||||
ContentType* = enum
|
||||
accountTrieNode = 0x00
|
||||
contractStorageTrieNode = 0x01
|
||||
accountTrieProof = 0x02
|
||||
contractStorageTrieProof = 0x03
|
||||
contractBytecode = 0x04
|
||||
# Note: Need to add this unused value as a case object with an enum without
|
||||
# a 0 valueis not allowed: "low(contentType) must be 0 for discriminant".
|
||||
# For prefix values that are in the enum gap, the deserialization will fail
|
||||
# at runtime as is wanted.
|
||||
# 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
|
||||
path*: ByteList
|
||||
@ -55,6 +63,8 @@ type
|
||||
|
||||
ContentKey* = object
|
||||
case contentType*: ContentType
|
||||
of unused:
|
||||
discard
|
||||
of accountTrieNode:
|
||||
accountTrieNodeKey*: AccountTrieNodeKey
|
||||
of contractStorageTrieNode:
|
||||
@ -67,8 +77,18 @@ type
|
||||
contractBytecodeKey*: ContractBytecodeKey
|
||||
|
||||
func encode*(contentKey: ContentKey): ByteList =
|
||||
doAssert(contentKey.contentType != unused)
|
||||
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] =
|
||||
try:
|
||||
Opt.some(SSZ.decode(contentKey.asSeq(), ContentKey))
|
||||
@ -84,6 +104,8 @@ template computeContentId*(digestCtxType: type, body: untyped): ContentId =
|
||||
|
||||
func toContentId*(contentKey: ContentKey): ContentId =
|
||||
case contentKey.contentType:
|
||||
of unused:
|
||||
raiseAssert "Should not be used and fail at decoding"
|
||||
of accountTrieNode: # sha256(path | node_hash)
|
||||
let key = contentKey.accountTrieNodeKey
|
||||
computeContentId sha256:
|
||||
|
@ -281,3 +281,28 @@ suite "Beacon Content Encodings":
|
||||
decodeLightClientBootstrapForked(forkDigests, @[]).isErr()
|
||||
decodeLightClientBootstrapForked(forkDigests, encodedTooEarlyFork).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
|
||||
# Copyright (c) 2021-2022 Status Research & Development GmbH
|
||||
# Fluffy
|
||||
# Copyright (c) 2021-2023 Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * 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).
|
||||
@ -31,7 +31,7 @@ suite "State ContentKey Encodings":
|
||||
|
||||
# Output
|
||||
contentKeyHex =
|
||||
"0044000000b8be7903aee73b8f6a59cd44a1f52c62148e1f376c0dfa1f5f773a98666efc2bd1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01020001"
|
||||
"2044000000b8be7903aee73b8f6a59cd44a1f52c62148e1f376c0dfa1f5f773a98666efc2bd1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01020001"
|
||||
contentId =
|
||||
"41237096982860596884042712109427867048220765019203857308279863638242761605893"
|
||||
# or
|
||||
@ -67,7 +67,7 @@ suite "State ContentKey Encodings":
|
||||
|
||||
# Output
|
||||
contentKeyHex =
|
||||
"01829bd824b016326a401d083b33d092293333a830580000003e190b68719aecbcb28ed2271014dd25f2aa633184988eb414189ce0899cade5d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01000f0e0c00"
|
||||
"21829bd824b016326a401d083b33d092293333a830580000003e190b68719aecbcb28ed2271014dd25f2aa633184988eb414189ce0899cade5d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01000f0e0c00"
|
||||
contentId =
|
||||
"43529358882110548041037387588279806363134301284609868141745095118932570363585"
|
||||
# or
|
||||
@ -100,7 +100,7 @@ suite "State ContentKey Encodings":
|
||||
# Output
|
||||
const
|
||||
contentKeyHex =
|
||||
"02829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||
"22829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||
contentId =
|
||||
"45301550050471302973396879294932122279426162994178563319590607565171451545101"
|
||||
# or
|
||||
@ -135,7 +135,7 @@ suite "State ContentKey Encodings":
|
||||
|
||||
# Output
|
||||
contentKeyHex =
|
||||
"03829bd824b016326a401d083b33d092293333a830c8a6030000000000000000000000000000000000000000000000000000000000d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||
"23829bd824b016326a401d083b33d092293333a830c8a6030000000000000000000000000000000000000000000000000000000000d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||
contentId =
|
||||
"80413803151602881485894828440259195604313253842905231566803078625935967002376"
|
||||
# or
|
||||
@ -172,7 +172,7 @@ suite "State ContentKey Encodings":
|
||||
# Output
|
||||
const
|
||||
contentKeyHex =
|
||||
"04829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||
"24829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"
|
||||
contentId =
|
||||
"9243655320250466575533858917172702581481192615849913473767356296630272634800"
|
||||
# or
|
||||
@ -199,3 +199,27 @@ suite "State ContentKey Encodings":
|
||||
toContentId(contentKey) == parse(contentId, StUint[256], 10)
|
||||
# In stint this does BE hex string
|
||||
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