fix json_from_tree

This commit is contained in:
andri lim 2020-05-07 22:12:34 +07:00
parent 36c93aacb1
commit 798de46ca7
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
2 changed files with 51 additions and 48 deletions

View File

@ -215,71 +215,74 @@ proc getBranchRecurse(wb: var WitnessBuilder, z: var StackElem) =
case nodeRlp.listLen case nodeRlp.listLen
of 2: of 2:
let (isLeaf, k) = nodeRlp.extensionNodeKey let (isLeaf, k) = nodeRlp.extensionNodeKey
var match = false let mg = groups(z.keys, z.depth, k, z.parentGroup)
# only zero or one group can match the path
# but if there is a match, it can be in any position if not mg.match:
# 1st, 2nd, or max 3rd position # return immediately if there is no match
# recursion will go deeper depend on the common-prefix length nibbles writeHashNode(wb, keccak(z.node).data)
for mg in groups(z.keys, z.depth, k, z.parentGroup): return
if not mg.match: continue
doAssert(match == false) # should be only one match
match = true
let value = nodeRlp.listElem(1) let value = nodeRlp.listElem(1)
if not isLeaf: if not isLeaf:
# ExtensionNodeType # recursion will go deeper depend on the common-prefix length nibbles
writeExtensionNode(wb, k, z.depth, z.node) writeExtensionNode(wb, k, z.depth, z.node)
var zz = StackElem( var zz = StackElem(
node: value.getNode, node: value.getNode,
parentGroup: mg.group, parentGroup: mg.group,
keys: z.keys, keys: z.keys,
depth: z.depth + k.len, depth: z.depth + k.len, # increase the depth by k.len
storageMode: z.storageMode storageMode: z.storageMode
) )
getBranchRecurse(wb, zz) getBranchRecurse(wb, zz)
else: return
# this should be only one match
# if there is more than one match # there should be only one match
# it means we encounter an invalid address let kd = z.keys.visitMatch(mg, z.depth, k)
for kd in keyDatas(z.keys, mg.group):
if not match(kd, k, z.depth): continue # skip the invalid address
kd.visited = true
if z.storageMode: if z.storageMode:
doAssert(kd.storageMode) doAssert(kd.storageMode)
writeAccountStorageLeafNode(wb, kd.storageSlot, value.toBytes.decode(UInt256), k, z.node, z.depth) writeAccountStorageLeafNode(wb, kd.storageSlot, value.toBytes.decode(UInt256), k, z.node, z.depth)
else: else:
doAssert(not kd.storageMode) doAssert(not kd.storageMode)
writeAccountNode(wb, kd, value.toBytes.decode(Account), k, z.node, z.depth) writeAccountNode(wb, kd, value.toBytes.decode(Account), k, z.node, z.depth)
if not match:
writeHashNode(wb, keccak(z.node).data)
of 17: of 17:
let branchMask = rlpListToBitmask(nodeRlp) let branchMask = rlpListToBitmask(nodeRlp)
writeBranchNode(wb, branchMask, z.depth, z.node) writeBranchNode(wb, branchMask, z.depth, z.node)
let path = groups(z.keys, z.parentGroup, z.depth)
# if there is a match in any branch elem # if there is a match in any branch elem
# 1st to 16th, the recursion will go deeper # 1st to 16th, the recursion will go deeper
# by one nibble # by one nibble
let notLeaf = z.depth != 63 # path.len == 0 doAssert(z.depth != 64) # notLeaf or path.len == 0
for i in 0..<16:
if not branchMask.branchMaskBitIsSet(i): continue let path = groups(z.keys, z.parentGroup, z.depth)
var branch = nodeRlp.listElem(i) for i in nonEmpty(branchMask):
if notLeaf and branchMaskBitIsSet(path.mask, i): let branch = nodeRlp.listElem(i)
if branchMaskBitIsSet(path.mask, i):
# it is a match between multikeys and Branch Node elem
var zz = StackElem( var zz = StackElem(
node: branch.getNode, node: branch.getNode,
parentGroup: path.groups[i], parentGroup: path.groups[i],
keys: z.keys, keys: z.keys,
depth: z.depth + 1, depth: z.depth + 1, # increase the depth by one
storageMode: z.storageMode storageMode: z.storageMode
) )
getBranchRecurse(wb, zz) getBranchRecurse(wb, zz)
else: continue
if branch.isList: if branch.isList:
# short node appear in yellow paper
# but never in the actual ethereum state trie
# an rlp encoded ethereum account will have length > 32 bytes
# block witness spec silent about this
doAssert(false, "Short node should not exist in block witness") doAssert(false, "Short node should not exist in block witness")
else: else:
# this is a potential branch for multiproof # if branch elem not empty and not a match, emit hash
writeHashNode(wb, branch.expectHash) writeHashNode(wb, branch.expectHash)
# 17th elem should always empty # 17th elem should always empty
# 17th elem appear in yellow paper but never in
# the actual ethereum state trie
# the 17th elem also not included in block witness spec
doAssert branchMask.branchMaskBitIsSet(16) == false doAssert branchMask.branchMaskBitIsSet(16) == false
else: else:
raise newException(CorruptedTrieDatabase, raise newException(CorruptedTrieDatabase,

View File

@ -82,7 +82,7 @@ proc runGenerator(numPairs, numSlots: int): string =
result = wb.buildWitness(mkeys) result = wb.buildWitness(mkeys)
proc writeHelp() = proc writeHelp() =
echo "jsoin_witness_gen output --pairs:val --slots:val -s:val -p:val" echo "json_witness_gen output --pairs:val --slots:val -s:val -p:val"
proc main() = proc main() =
var filename: string var filename: string