state network test vectors update (#2003)

* state network test vectors update
* nibbles codec
* moving test vectors into portal-spec-tests
* fix copyright year in all_fluffy_tests
This commit is contained in:
Daniel Sobol 2024-02-03 00:12:36 +03:00 committed by GitHub
parent f1e9ca8526
commit 9c53c73173
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 366 additions and 260 deletions

View File

@ -18,6 +18,14 @@ import
export ssz_serialization, common_types, hash, results export ssz_serialization, common_types, hash, results
const
MAX_PACKED_NIBBLES_LEN = 32
MAX_UNPACKED_NIBBLES_LEN = 64
MAX_TRIE_NODE_LEN = 1024
MAX_TRIE_PROOF_LEN = 65
MAX_BYTECODE_LEN = 32768
type type
NodeHash* = KeccakHash NodeHash* = KeccakHash
CodeHash* = KeccakHash CodeHash* = KeccakHash
@ -39,19 +47,12 @@ type
NibblePair* = byte NibblePair* = byte
Nibbles* = object Nibbles* = object
isOddLength*: bool isOddLength*: bool
packedNibbles*: List[NibblePair, 32] packedNibbles*: List[NibblePair, MAX_PACKED_NIBBLES_LEN]
WitnessNode* = List[byte, 1024] TrieNode* = List[byte, MAX_TRIE_NODE_LEN]
Witness* = List[WitnessNode, 1024] TrieProof* = List[TrieNode, MAX_TRIE_PROOF_LEN]
StateWitness* = object Bytecode* = List[byte, MAX_BYTECODE_LEN]
key*: Nibbles
proof*: Witness
StorageWitness* = object
key*: Nibbles
proof*: Witness
stateWitness*: StateWitness
AccountTrieNodeKey* = object AccountTrieNodeKey* = object
path*: Nibbles path*: Nibbles
@ -78,26 +79,27 @@ type
contractCodeKey*: ContractCodeKey contractCodeKey*: ContractCodeKey
AccountTrieNodeOffer* = object AccountTrieNodeOffer* = object
proof*: StateWitness proof*: TrieProof
blockHash*: BlockHash blockHash*: BlockHash
AccountTrieNodeRetrieval* = object AccountTrieNodeRetrieval* = object
node*: WitnessNode node*: TrieNode
ContractTrieNodeOffer* = object ContractTrieNodeOffer* = object
proof*: StorageWitness storageProof*: TrieProof
accountProof*: TrieProof
blockHash*: BlockHash blockHash*: BlockHash
ContractTrieNodeRetrieval* = object ContractTrieNodeRetrieval* = object
node*: WitnessNode node*: TrieNode
ContractCodeOffer* = object ContractCodeOffer* = object
code*: ByteList code*: Bytecode
accountProof*: StateWitness accountProof*: TrieProof
blockHash*: BlockHash blockHash*: BlockHash
ContractCodeRetrieval* = object ContractCodeRetrieval* = object
code*: ByteList code*: Bytecode
func encode*(contentKey: ContentKey): ByteList = func encode*(contentKey: ContentKey): ByteList =
doAssert(contentKey.contentType != unused) doAssert(contentKey.contentType != unused)
@ -125,3 +127,44 @@ func toContentId*(contentKey: ByteList): ContentId =
func toContentId*(contentKey: ContentKey): ContentId = func toContentId*(contentKey: ContentKey): ContentId =
toContentId(encode(contentKey)) toContentId(encode(contentKey))
func packNibbles*(nibbles: seq[byte]): Nibbles =
doAssert(nibbles.len() <= MAX_UNPACKED_NIBBLES_LEN, "Can't pack more than 64 nibbles")
let
isOddLength = (nibbles.len() %% 2 == 1)
outputLength = (nibbles.len() + 1) div 2
var
output = newSeq[NibblePair]()
highNibble = not isOddLength
currentByte: byte = 0
for nibble in nibbles:
if highNibble:
currentByte = nibble shl 4
else:
output.add(NibblePair(currentByte or nibble))
currentByte = 0
highNibble = not highNibble
Nibbles(isOddLength: isOddLength, packedNibbles: Nibbles.packedNibbles.init(output))
func unpackNibbles*(nibbles: Nibbles): seq[byte] =
doAssert(nibbles.packedNibbles.len() <= MAX_PACKED_NIBBLES_LEN, "Can't unpack more than 32 nibbles")
var output = newSeq[byte]()
for pair in nibbles.packedNibbles:
let
first = (pair and 0xF0) shr 4
second = pair and 0x0F
output.add(first)
output.add(second)
if nibbles.isOddLength:
output.delete(0)
output

View File

@ -1,5 +1,5 @@
# Nimbus # Nimbus
# Copyright (c) 2021-2023 Status Research & Development GmbH # Copyright (c) 2021-2024 Status Research & Development GmbH
# Licensed under either of # Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) # * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
@ -9,7 +9,8 @@
import import
./test_portal_wire_protocol, ./test_portal_wire_protocol,
./state_network_tests/test_state_content, ./state_network_tests/test_state_content_keys,
./state_network_tests/test_state_content_values,
./test_state_proof_verification, ./test_state_proof_verification,
./test_accumulator, ./test_accumulator,
./test_history_network, ./test_history_network,

View File

@ -0,0 +1,48 @@
# Fluffy
# Copyright (c) 2023-2024 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).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
../../network/state/state_content
type JsonBlockInfo* = object
number*: uint64
block_hash*: string
state_root*: string
type JsonAccount* = object
nonce*: string
balance*: string
storage_hash*: string
code_hash*: string
type JsonBlock* = object
`block`*: JsonBlockInfo
address*: string
account*: JsonAccount
storage_slot*: string
storage_value*: string
account_proof*: seq[string]
storage_proof*: seq[string]
bytecode*: string
type JsonAccountTrieNode* = object
content_key*: string
content_id*: string
content_value_offer*: string
content_value_retrieval*: string
type JsonContractStorageTtrieNode* = object
content_key*: string
content_id*: string
content_value_offer*: string
content_value_retrieval*: string
type JsonContractBytecode* = object
content_key*: string
content_id*: string
content_value_offer*: string
content_value_retrieval*: string

View File

@ -1,239 +0,0 @@
# Fluffy
# Copyright (c) 2023-2024 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).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
testutils/unittests,
stew/[byteutils, io2],
eth/keys,
../../network/state/state_content
suite "State Content Keys":
const evenNibles = "0005000000123456789abc"
test "Encode/decode even nibbles":
const
packedNibbles = Nibbles.packedNibbles.init(@[NibblePair 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC])
isOddLength = false
let
nibbles = Nibbles(packedNibbles: packedNibbles, isOddLength: isOddLength)
encoded = SSZ.encode(nibbles)
check encoded.toHex() == evenNibles
# echo ">>>", encoded.toHex()
const oddNibbles = "0105000000123456789abc0d"
test "Encode/decode odd nibbles":
const
packedNibbles = Nibbles.packedNibbles.init(@[NibblePair 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0x0D])
isOddLength = true
let
nibbles = Nibbles(packedNibbles: packedNibbles, isOddLength: isOddLength)
encoded = SSZ.encode(nibbles)
check encoded.toHex() == oddNibbles
# echo ">>>", encoded.toHex()
const accountTrieNodeKeyEncoded = "2024000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700005000000123456789abc"
test "Encode/decode AccountTrieNodeKey":
const
packedNibbles = Nibbles.packedNibbles.init(@[NibblePair 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC])
isOddLength = false
nodeHash = NodeHash.fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
let
nibbles = Nibbles(packedNibbles: packedNibbles, isOddLength: isOddLength)
accountTrieNodeKey = AccountTrieNodeKey(path: nibbles, nodeHash: nodeHash)
contentKey = ContentKey(contentType: accountTrieNode, accountTrieNodeKey: accountTrieNodeKey)
encoded = contentKey.encode()
# echo ">>>", $encoded
check $encoded == accountTrieNodeKeyEncoded
let decoded = encoded.decode().valueOr:
raiseAssert "Cannot decode AccountTrieNodeKey"
check:
decoded.contentType == accountTrieNode
decoded.accountTrieNodeKey == AccountTrieNodeKey(path: nibbles, nodeHash: nodeHash)
const contractTrieNodeKeyEncoded = "21000d836201318ec6899a6754069038278074328038000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700005000000123456789abc"
test "Encode/decode ContractTrieNodeKey":
const
address = Address.fromHex("000d836201318ec6899a67540690382780743280")
packedNibbles = Nibbles.packedNibbles.init(@[NibblePair 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC])
isOddLength = false
nodeHash = NodeHash.fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
let
nibbles = Nibbles(packedNibbles: (packedNibbles), isOddLength: isOddLength)
contractTrieNodeKey = ContractTrieNodeKey(address: address, path: nibbles, nodeHash: nodeHash)
contentKey = ContentKey(contentType: contractTrieNode, contractTrieNodeKey: contractTrieNodeKey)
encoded = contentKey.encode()
# echo ">>>", $encoded
check $encoded == contractTrieNodeKeyEncoded
let decoded = encoded.decode().valueOr:
raiseAssert "Cannot decode ContractTrieNodeKey"
check:
decoded.contentType == contractTrieNode
decoded.contractTrieNodeKey == ContractTrieNodeKey(address: address, path: nibbles, nodeHash: nodeHash)
const contractCodeKeyEncoded = "22000d836201318ec6899a67540690382780743280c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
test "Encode/decode ContractCodeKey":
const
address = Address.fromHex("000d836201318ec6899a67540690382780743280")
codeHash = CodeHash.fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
let
contractCodeKey = ContractCodeKey(address: address, codeHash: codeHash)
contentKey = ContentKey(contentType: contractCode, contractCodeKey: contractCodeKey)
encoded = contentKey.encode()
# echo ">>>", $encoded
check $encoded == contractCodeKeyEncoded
let decoded = encoded.decode().valueOr:
raiseAssert "Cannot decode ContractCodeKey"
check:
decoded.contentType == contractCode
decoded.contractCodeKey.address == address
decoded.contractCodeKey.codeHash == codeHash
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()
suite "State Content Values":
const accountTrieNodeOfferEncoded = "24000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa308000000130000000005000000123456789abc04000000010203040506"
test "Encode/decode AccountTrieNodeOffer":
let
blockHash = "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
packedNibbles = @[NibblePair 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]
isOddLength = false
key = Nibbles(packedNibbles: Nibbles.packedNibbles.init(packedNibbles), isOddLength: isOddLength)
witnessNode = WitnessNode(@[byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06])
proof = Witness(@[witnessNode])
accountTrieNodeOffer = AccountTrieNodeOffer(blockHash: BlockHash.fromHex(blockHash), proof: StateWitness(key: key, proof: proof))
encoded = SSZ.encode(accountTrieNodeOffer)
# echo ">>>", encoded.toHex()
check encoded.toHex() == accountTrieNodeOfferEncoded
let decoded = SSZ.decode(encoded, AccountTrieNodeOffer)
check:
decoded.blockHash == BlockHash.fromHex(blockHash)
decoded.proof == StateWitness(key: key, proof: proof)
const accountTrieNodeRetrievalEncoded = "04000000010203040506"
test "Encode/decode AccountTrieNodeRetrieval":
let
witnessNode = WitnessNode(@[byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06])
accountTrieNodeRetrieval = AccountTrieNodeRetrieval(node: witnessNode)
encoded = SSZ.encode(accountTrieNodeRetrieval)
# echo ">>>", encoded.toHex()
check encoded.toHex() == accountTrieNodeRetrievalEncoded
let decoded = SSZ.decode(encoded, AccountTrieNodeRetrieval)
check decoded.node == witnessNode
const contractTrieNodeOfferEncoded = "24000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa30c00000017000000220000000005000000123456789abc040000000102030405060708000000150000000005000000123456789abcdef104000000010203040506070809"
test "Encode/decode ContractTrieNodeOffer":
let
blockHash = "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
contractWitnessKeyPackedNibbles = @[NibblePair 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]
contractWitnessProof = Witness(@[WitnessNode(@[byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07])])
stateWitnessKeyPackedNibbles = @[NibblePair 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF1]
stateWitnessProof = Witness(@[WitnessNode(@[byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09])])
contractTrieNodeOffer = ContractTrieNodeOffer(
blockHash: BlockHash.fromHex(blockHash),
proof: StorageWitness(
key: Nibbles(packedNibbles: Nibbles.packedNibbles.init(contractWitnessKeyPackedNibbles), isOddLength: false),
proof: contractWitnessProof,
stateWitness: StateWitness(
key: Nibbles(packedNibbles: Nibbles.packedNibbles.init(stateWitnessKeyPackedNibbles), isOddLength: false),
proof: stateWitnessProof
)))
encoded = SSZ.encode(contractTrieNodeOffer)
# echo ">>>", encoded.toHex()
check encoded.toHex() == contractTrieNodeOfferEncoded
let decoded = SSZ.decode(encoded, ContractTrieNodeOffer)
check:
decoded.blockHash == BlockHash.fromHex(blockHash)
decoded.proof == StorageWitness(
key: Nibbles(packedNibbles: Nibbles.packedNibbles.init(contractWitnessKeyPackedNibbles), isOddLength: false),
proof: contractWitnessProof,
stateWitness: StateWitness(
key: Nibbles(packedNibbles: Nibbles.packedNibbles.init(stateWitnessKeyPackedNibbles), isOddLength: false),
proof: stateWitnessProof
))
const contractTrieNodeRetrievalEncoded = "04000000010203040506"
test "Encode/decode ContractTrieNodeRetrieval":
let
witnessNode = WitnessNode(@[byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06])
contractTrieNodeRetrieval = ContractTrieNodeRetrieval(node: witnessNode)
encoded = SSZ.encode(contractTrieNodeRetrieval)
# echo ">>>", encoded.toHex()
check encoded.toHex() == contractTrieNodeRetrievalEncoded
let decoded = SSZ.decode(encoded, ContractTrieNodeRetrieval)
check decoded.node == witnessNode
const contractCodeOfferEncoded = "2800000036000000d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3010203040506070809a0a1a2a3a408000000130000000005000000123456789abc04000000010203040506"
test "Encode/decode ContractCodeOffer":
let
code = @[byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4]
blockHash = "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
accountProofKey = Nibbles(packedNibbles: Nibbles.packedNibbles.init(@[NibblePair 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]), isOddLength: false)
accountProofWitness = Witness(@[WitnessNode(@[byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06])])
contractCodeOffer = ContractCodeOffer(
code: ByteList.init(code),
blockHash: BlockHash.fromHex(blockHash),
accountProof: StateWitness(key: accountProofKey, proof: accountProofWitness))
encoded = SSZ.encode(contractCodeOffer)
# echo ">>>", encoded.toHex()
check encoded.toHex() == contractCodeOfferEncoded
let decoded = SSZ.decode(encoded, ContractCodeOffer)
check:
decoded.code == ByteList.init(code)
decoded.blockHash == BlockHash.fromHex(blockHash)
decoded.accountProof == StateWitness(key: accountProofKey, proof: accountProofWitness)
const contractCodeRetrievalEncoded = "04000000010203040506070809a0a1a2a3a4"
test "Encode/decode ContractCodeRetrieval":
let
code = @[byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4]
contractCodeRetrieval = ContractCodeRetrieval(code: ByteList.init(code))
encoded = SSZ.encode(contractCodeRetrieval)
# echo ">>>", encoded.toHex()
check encoded.toHex() == contractCodeRetrievalEncoded
let decoded = SSZ.decode(encoded, ContractCodeRetrieval)
check decoded.code == ByteList.init(code)

View File

@ -0,0 +1,123 @@
# Fluffy
# Copyright (c) 2023-2024 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).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
testutils/unittests,
stew/[byteutils, io2],
eth/keys,
../../network/state/state_content
suite "State Content Keys":
const evenNibles = "00050000008679e8ed"
test "Encode/decode even nibbles":
const
nibbles: seq[byte] = @[8, 6, 7, 9, 14, 8, 14, 13]
packedNibbles = packNibbles(nibbles)
unpackedNibbles = unpackNibbles(packedNibbles)
let
encoded = SSZ.encode(packedNibbles)
check encoded.toHex() == evenNibles
check unpackedNibbles == nibbles
const oddNibbles = "0105000000018679e8ed"
test "Encode/decode odd nibbles":
const
nibbles: seq[byte] = @[1, 8, 6, 7, 9, 14, 8, 14, 13]
packedNibbles = packNibbles(nibbles)
unpackedNibbles = unpackNibbles(packedNibbles)
let
encoded = SSZ.encode(packedNibbles)
check encoded.toHex() == oddNibbles
check unpackedNibbles == nibbles
const accountTrieNodeKeyEncoded = "20240000006225fcc63b22b80301d9f2582014e450e91f9b329b7cc87ad16894722fff529600050000008679e8ed"
test "Encode/decode AccountTrieNodeKey":
const
nibbles: seq[byte] = @[8, 6, 7, 9, 14, 8, 14, 13]
packedNibbles = packNibbles(nibbles)
nodeHash = NodeHash.fromHex("6225fcc63b22b80301d9f2582014e450e91f9b329b7cc87ad16894722fff5296")
let
accountTrieNodeKey = AccountTrieNodeKey(path: packedNibbles, nodeHash: nodeHash)
contentKey = ContentKey(contentType: accountTrieNode, accountTrieNodeKey: accountTrieNodeKey)
encoded = contentKey.encode()
check $encoded == accountTrieNodeKeyEncoded
let decoded = encoded.decode().valueOr:
raiseAssert "Cannot decode AccountTrieNodeKey"
check:
decoded.contentType == accountTrieNode
decoded.accountTrieNodeKey == AccountTrieNodeKey(path: packedNibbles, nodeHash: nodeHash)
const contractTrieNodeKeyEncoded = "21c02aaa39b223fe8d0a0e5c4f27ead9083c756cc238000000eb43d68008d216e753fef198cf51077f5a89f406d9c244119d1643f0f2b190110005000000405787"
test "Encode/decode ContractTrieNodeKey":
const
nibbles: seq[byte] = @[4, 0, 5, 7, 8, 7]
packedNibbles = packNibbles(nibbles)
address = Address.fromHex("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")
isOddLength = false
nodeHash = NodeHash.fromHex("eb43d68008d216e753fef198cf51077f5a89f406d9c244119d1643f0f2b19011")
let
contractTrieNodeKey = ContractTrieNodeKey(address: address, path: packedNibbles, nodeHash: nodeHash)
contentKey = ContentKey(contentType: contractTrieNode, contractTrieNodeKey: contractTrieNodeKey)
encoded = contentKey.encode()
check $encoded == contractTrieNodeKeyEncoded
let decoded = encoded.decode().valueOr:
raiseAssert "Cannot decode ContractTrieNodeKey"
check:
decoded.contentType == contractTrieNode
decoded.contractTrieNodeKey == ContractTrieNodeKey(address: address, path: packedNibbles, nodeHash: nodeHash)
const contractCodeKeyEncoded = "22c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2d0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23"
test "Encode/decode ContractCodeKey":
const
address = Address.fromHex("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")
codeHash = CodeHash.fromHex("d0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23")
let
contractCodeKey = ContractCodeKey(address: address, codeHash: codeHash)
contentKey = ContentKey(contentType: contractCode, contractCodeKey: contractCodeKey)
encoded = contentKey.encode()
check $encoded == contractCodeKeyEncoded
let decoded = encoded.decode().valueOr:
raiseAssert "Cannot decode ContractCodeKey"
check:
decoded.contentType == contractCode
decoded.contractCodeKey.address == address
decoded.contractCodeKey.codeHash == codeHash
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()

View File

@ -0,0 +1,130 @@
# Fluffy
# Copyright (c) 2023-2024 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).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
std/[sugar, sequtils],
testutils/unittests,
stew/[byteutils, io2],
eth/keys,
./helpers,
../../network/state/state_content,
../../eth_data/history_data_json_store
const testVectorDir = "./vendor/portal-spec-tests/tests/mainnet/state/"
suite "State Content Values":
test "Encode/decode AccountTrieNodeOffer":
let
blockContent = readJsonType(testVectorDir & "block.json", JsonBlock).valueOr:
raiseAssert "Cannot read test vector: " & error
accountTrieNode = readJsonType(testVectorDir & "account_trie_node.json", JsonAccountTrieNode).valueOr:
raiseAssert "Cannot read test vector: " & error
blockHash = BlockHash.fromHex(blockContent.`block`.block_hash)
proof = TrieProof.init(blockContent.account_proof.map((hex) => TrieNode.init(hex.hexToSeqByte())))
accountTrieNodeOffer = AccountTrieNodeOffer(blockHash: blockHash, proof: proof)
encoded = SSZ.encode(accountTrieNodeOffer)
expected = accountTrieNode.content_value_offer.hexToSeqByte()
decoded = SSZ.decode(encoded, AccountTrieNodeOffer)
check encoded == expected
check decoded == accountTrieNodeOffer
test "Encode/decode AccountTrieNodeRetrieval":
let
blockContent = readJsonType(testVectorDir & "block.json", JsonBlock).valueOr:
raiseAssert "Cannot read test vector: " & error
accountTrieNode = readJsonType(testVectorDir & "account_trie_node.json", JsonAccountTrieNode).valueOr:
raiseAssert "Cannot read test vector: " & error
node = TrieNode.init(blockContent.account_proof[^1].hexToSeqByte())
accountTrieNodeRetrieval = AccountTrieNodeRetrieval(node: node)
encoded = SSZ.encode(accountTrieNodeRetrieval)
expected = accountTrieNode.content_value_retrieval.hexToSeqByte()
decoded = SSZ.decode(encoded, AccountTrieNodeRetrieval)
check encoded == expected
check decoded == accountTrieNodeRetrieval
test "Encode/decode ContractTrieNodeOffer":
let
blockContent = readJsonType(testVectorDir & "block.json", JsonBlock).valueOr:
raiseAssert "Cannot read test vector: " & error
contractStorageTrieNode = readJsonType(testVectorDir & "contract_storage_trie_node.json", JsonContractStorageTtrieNode).valueOr:
raiseAssert "Cannot read test vector: " & error
blockHash = BlockHash.fromHex(blockContent.`block`.block_hash)
storageProof = TrieProof.init(blockContent.storage_proof.map((hex) => TrieNode.init(hex.hexToSeqByte())))
accountProof = TrieProof.init(blockContent.account_proof.map((hex) => TrieNode.init(hex.hexToSeqByte())))
contractTrieNodeOffer = ContractTrieNodeOffer(
blockHash: blockHash,
storage_proof: storageProof,
account_proof: accountProof)
encoded = SSZ.encode(contractTrieNodeOffer)
expected = contractStorageTrieNode.content_value_offer.hexToSeqByte()
decoded = SSZ.decode(encoded, ContractTrieNodeOffer)
check encoded == expected
check decoded == contractTrieNodeOffer
test "Encode/decode ContractTrieNodeRetrieval":
let
blockContent = readJsonType(testVectorDir & "block.json", JsonBlock).valueOr:
raiseAssert "Cannot read test vector: " & error
contractStorageTrieNode = readJsonType(testVectorDir & "contract_storage_trie_node.json", JsonContractStorageTtrieNode).valueOr:
raiseAssert "Cannot read test vector: " & error
node = TrieNode.init(blockContent.storage_proof[^1].hexToSeqByte())
contractTrieNodeRetrieval = ContractTrieNodeRetrieval(node: node)
encoded = SSZ.encode(contractTrieNodeRetrieval)
expected = contractStorageTrieNode.content_value_retrieval.hexToSeqByte()
decoded = SSZ.decode(encoded, ContractTrieNodeRetrieval)
check encoded == expected
check decoded == contractTrieNodeRetrieval
test "Encode/decode ContractCodeOffer":
let
blockContent = readJsonType(testVectorDir & "block.json", JsonBlock).valueOr:
raiseAssert "Cannot read test vector: " & error
contractBytecode = readJsonType(testVectorDir & "contract_bytecode.json", JsonContractBytecode).valueOr:
raiseAssert "Cannot read test vector: " & error
code = Bytecode.init(blockContent.bytecode.hexToSeqByte())
blockHash = BlockHash.fromHex(blockContent.`block`.block_hash)
accountProof = TrieProof.init(blockContent.account_proof.map((hex) => TrieNode.init(hex.hexToSeqByte())))
contractCodeOffer = ContractCodeOffer(
code: code,
blockHash: blockHash,
accountProof: accountProof)
encoded = SSZ.encode(contractCodeOffer)
expected = contractBytecode.content_value_offer.hexToSeqByte()
decoded = SSZ.decode(encoded, ContractCodeOffer)
check encoded == expected
check decoded == contractCodeOffer
test "Encode/decode ContractCodeRetrieval":
let
blockContent = readJsonType(testVectorDir & "block.json", JsonBlock).valueOr:
raiseAssert "Cannot read test vector: " & error
contractBytecode = readJsonType(testVectorDir & "contract_bytecode.json", JsonContractBytecode).valueOr:
raiseAssert "Cannot read test vector: " & error
code = Bytecode.init(blockContent.bytecode.hexToSeqByte())
contractCodeRetrieval = ContractCodeRetrieval(code: code)
encoded = SSZ.encode(contractCodeRetrieval)
expected = contractBytecode.content_value_retrieval.hexToSeqByte()
decoded = SSZ.decode(encoded, ContractCodeRetrieval)
check encoded == expected
check decoded == contractCodeRetrieval

@ -1 +1 @@
Subproject commit c3f11b8713c3e12be7f517d75cbdbafb9753d1ff Subproject commit e3928b0487ab92ed8323e631728ee3475629757d