Skip to content

Commit a0277cd

Browse files
authored
Fix aristo proof verification - handle embedded trie nodes (#3583)
* Add test which reproduces embedded trie node scenario. * Implement fix.
1 parent 7e28787 commit a0277cd

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

execution_chain/db/aristo/aristo_proof.nim

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,12 @@ proc makeMultiProof*(
199199

200200
ok()
201201

202+
template rlpNodeToBytes(node: Rlp): seq[byte] =
203+
if node.isList():
204+
node.rawData.toSeq()
205+
else:
206+
node.toBytes()
207+
202208
proc trackRlpNodes(
203209
chain: openArray[seq[byte]];
204210
nextIndex: int;
@@ -233,14 +239,14 @@ proc trackRlpNodes(
233239
of 2:
234240
let (isLeaf, segm) = NibblesBuf.fromHexPrefix rlpNode.listElem(0).toBytes
235241
nChewOff = sharedPrefixLen(path, segm)
236-
link = rlpNode.listElem(1).toBytes # link or payload
242+
link = rlpNode.listElem(1).rlpNodeToBytes() # link or payload
237243
if isLeaf:
238244
if nChewOff == path.len:
239245
return ok(link)
240246
return err(PartTrkLeafPfxMismatch)
241247
of 17:
242248
nChewOff = 1
243-
link = rlpNode.listElem(path[0].int).toBytes
249+
link = rlpNode.listElem(path[0].int).rlpNodeToBytes()
244250
else:
245251
return err(PartTrkGarbledNode)
246252

@@ -292,14 +298,14 @@ proc trackRlpNodes(
292298
of 2:
293299
let (isLeaf, segm) = NibblesBuf.fromHexPrefix rlpNode.listElem(0).toBytes
294300
nChewOff = sharedPrefixLen(path, segm)
295-
link = rlpNode.listElem(1).toBytes # link or payload
301+
link = rlpNode.listElem(1).rlpNodeToBytes() # link or payload
296302
if isLeaf:
297303
if nChewOff == path.len:
298304
return ok(link)
299305
return err(PartTrkLeafPfxMismatch)
300306
of 17:
301307
nChewOff = 1
302-
link = rlpNode.listElem(path[0].int).toBytes
308+
link = rlpNode.listElem(path[0].int).rlpNodeToBytes()
303309
else:
304310
return err(PartTrkGarbledNode)
305311

tests/test_aristo_proof.nim

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ import
1414
unittest2,
1515
stint,
1616
results,
17+
eth/rlp,
1718
stew/byteutils,
1819
eth/common/hashes,
1920
eth/trie/[hexary, db, trie_defs],
2021
../execution_chain/db/aristo/aristo_proof
2122

2223
template getBytes(i: int): seq[byte] =
23-
@(u256(i).toBytesBE())
24+
rlp.encode(u256(i))
2425

2526
func toNodesTable(proofNodes: openArray[seq[byte]]): Table[Hash32, seq[byte]] =
2627
var nodes: Table[Hash32, seq[byte]]
@@ -29,7 +30,7 @@ func toNodesTable(proofNodes: openArray[seq[byte]]): Table[Hash32, seq[byte]] =
2930
nodes
3031

3132
suite "Aristo proof verification":
32-
const numValues = 1000
33+
const numValues = 10000
3334

3435
setup:
3536
let db = newMemoryDB()
@@ -151,6 +152,41 @@ suite "Aristo proof verification":
151152
check:
152153
leafValue.isNone()
153154

155+
# By using a small value (1 in this case) and storing a large number of keys
156+
# this test reproduces the scenario where leaf trie nodes get embedded into
157+
# the parent node because the len of the rlp encoded node is less than 32.
158+
test "Validate proof for existing value - embedded leafs":
159+
const
160+
iterations = 100000
161+
leaf = getBytes(1)
162+
163+
for i in 1..iterations:
164+
let
165+
indexBytes = getBytes(i)
166+
key = keccak256(indexBytes)
167+
value = indexBytes
168+
trie.put(key.data, leaf)
169+
170+
for i in 1..iterations:
171+
let
172+
indexBytes = getBytes(i)
173+
key = keccak256(indexBytes)
174+
value = indexBytes
175+
root = trie.rootHash()
176+
proof = trie.getBranch(key.data)
177+
178+
block:
179+
let leafValue = verifyProof(proof, root, key).expect("valid proof")
180+
check:
181+
leafValue.isSome()
182+
leafValue.get() == leaf
183+
184+
block:
185+
let leafValue = verifyProof(toNodesTable(proof), root, key).expect("valid proof")
186+
check:
187+
leafValue.isSome()
188+
leafValue.get() == leaf
189+
154190
# The following test cases were copied from the Rust hexary trie implementation.
155191
# See here: https://github.com/citahub/cita_trie/blob/master/src/tests/mod.rs#L554
156192
test "Validate proof for empty trie":

0 commit comments

Comments
 (0)