nibble encoding update (#2021)

* nibble encoding update

* portal-spec-tests update
This commit is contained in:
Daniel Sobol 2024-02-12 15:39:01 +03:00 committed by GitHub
parent 009caee2dc
commit 35131b6d55
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 24 deletions

View File

@ -19,7 +19,7 @@ import
export ssz_serialization, common_types, hash, results
const
MAX_PACKED_NIBBLES_LEN = 32
MAX_PACKED_NIBBLES_LEN = 33
MAX_UNPACKED_NIBBLES_LEN = 64
MAX_TRIE_NODE_LEN = 1024
@ -44,10 +44,7 @@ type
contractTrieNode = 0x21
contractCode = 0x22
NibblePair* = byte
Nibbles* = object
isOddLength*: bool
packedNibbles*: List[NibblePair, MAX_PACKED_NIBBLES_LEN]
Nibbles* = List[byte, MAX_PACKED_NIBBLES_LEN]
TrieNode* = List[byte, MAX_TRIE_NODE_LEN]
TrieProof* = List[TrieNode, MAX_TRIE_PROOF_LEN]
@ -130,41 +127,53 @@ func toContentId*(contentKey: ContentKey): ContentId =
func packNibbles*(nibbles: seq[byte]): Nibbles =
doAssert(nibbles.len() <= MAX_UNPACKED_NIBBLES_LEN, "Can't pack more than 64 nibbles")
if nibbles.len() == 0:
return Nibbles(@[byte(0x00)])
let
isOddLength = (nibbles.len() %% 2 == 1)
outputLength = (nibbles.len() + 1) div 2
var
output = newSeq[NibblePair]()
output = newSeq[byte]()
highNibble = not isOddLength
currentByte: byte = 0
for nibble in nibbles:
if isOddLength:
currentByte = 0x10
if not isOddLength:
output.add(0x00)
for i, nibble in nibbles:
if highNibble:
currentByte = nibble shl 4
else:
output.add(NibblePair(currentByte or nibble))
output.add(currentByte or nibble)
currentByte = 0
highNibble = not highNibble
Nibbles(isOddLength: isOddLength, packedNibbles: Nibbles.packedNibbles.init(output))
Nibbles(output)
func unpackNibbles*(nibbles: Nibbles): seq[byte] =
doAssert(nibbles.packedNibbles.len() <= MAX_PACKED_NIBBLES_LEN, "Can't unpack more than 32 nibbles")
doAssert(nibbles.len() <= MAX_PACKED_NIBBLES_LEN, "Can't unpack more than 32 nibbles")
var output = newSeq[byte]()
for pair in nibbles.packedNibbles:
for i, pair in nibbles:
if i == 0 and pair == 0x00:
continue
let
first = (pair and 0xF0) shr 4
second = pair and 0x0F
output.add(first)
output.add(second)
if nibbles.isOddLength:
output.delete(0)
if i == 0 and first == 0x01:
output.add(second)
else:
output.add(first)
output.add(second)
output

View File

@ -13,7 +13,7 @@ import
suite "State Content Keys":
const evenNibles = "00050000008679e8ed"
const evenNibles = "008679e8ed"
test "Encode/decode even nibbles":
const
nibbles: seq[byte] = @[8, 6, 7, 9, 14, 8, 14, 13]
@ -26,20 +26,20 @@ suite "State Content Keys":
check encoded.toHex() == evenNibles
check unpackedNibbles == nibbles
const oddNibbles = "0105000000018679e8ed"
const oddNibbles = "138679e8ed"
test "Encode/decode odd nibbles":
const
nibbles: seq[byte] = @[1, 8, 6, 7, 9, 14, 8, 14, 13]
nibbles: seq[byte] = @[3, 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"
const accountTrieNodeKeyEncoded = "20240000006225fcc63b22b80301d9f2582014e450e91f9b329b7cc87ad16894722fff5296008679e8ed"
test "Encode/decode AccountTrieNodeKey":
const
nibbles: seq[byte] = @[8, 6, 7, 9, 14, 8, 14, 13]
@ -58,13 +58,12 @@ suite "State Content Keys":
decoded.contentType == accountTrieNode
decoded.accountTrieNodeKey == AccountTrieNodeKey(path: packedNibbles, nodeHash: nodeHash)
const contractTrieNodeKeyEncoded = "21c02aaa39b223fe8d0a0e5c4f27ead9083c756cc238000000eb43d68008d216e753fef198cf51077f5a89f406d9c244119d1643f0f2b190110005000000405787"
const contractTrieNodeKeyEncoded = "21c02aaa39b223fe8d0a0e5c4f27ead9083c756cc238000000eb43d68008d216e753fef198cf51077f5a89f406d9c244119d1643f0f2b1901100405787"
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