implement witness header encoding decoding and implement buildForest
This commit is contained in:
parent
90c2ede43b
commit
fdb750f67e
|
@ -40,7 +40,7 @@ proc testGetBranch(tester: Tester, rootHash: KeccakHash, testStatusIMPL: var Tes
|
|||
else:
|
||||
var tb = initTreeBuilder(witness, db, flags)
|
||||
|
||||
var root = tb.treeNode()
|
||||
var root = tb.buildTree()
|
||||
check root.data == rootHash.data
|
||||
except ContractCodeError as e:
|
||||
debugEcho "CONTRACT CODE ERROR: ", e.msg
|
||||
|
|
|
@ -67,7 +67,7 @@ proc runTest(numPairs: int) =
|
|||
var tb = initTreeBuilder(input, db, {wfEIP170})
|
||||
else:
|
||||
var tb = initTreeBuilder(witness, db, {wfEIP170})
|
||||
var root = tb.treeNode()
|
||||
var root = tb.buildTree()
|
||||
debugEcho "root: ", root.data.toHex
|
||||
debugEcho "rootHash: ", rootHash.data.toHex
|
||||
doAssert root.data == rootHash.data
|
||||
|
|
|
@ -60,6 +60,8 @@ when defined(useInputStream):
|
|||
template read(t: var TreeBuilder, len: int): auto =
|
||||
t.input.read(len)
|
||||
|
||||
template readable(t: var TreeBuilder): bool =
|
||||
t.input.readable
|
||||
else:
|
||||
template readByte(t: var TreeBuilder): byte =
|
||||
let pos = t.pos
|
||||
|
@ -69,9 +71,8 @@ else:
|
|||
template len(t: TreeBuilder): int =
|
||||
t.input.len
|
||||
|
||||
template peek(t: TreeBuilder): byte =
|
||||
t.input.peek
|
||||
t.input[t.pos]
|
||||
template readable(t: var TreeBuilder): bool =
|
||||
t.pos < t.input.len
|
||||
|
||||
template read(t: var TreeBuilder, len: int): auto =
|
||||
let pos = t.pos
|
||||
|
@ -115,8 +116,43 @@ proc extensionNode(t: var TreeBuilder, depth: int, storageMode: bool): NodeKey
|
|||
proc accountNode(t: var TreeBuilder, depth: int): NodeKey
|
||||
proc accountStorageLeafNode(t: var TreeBuilder, depth: int): NodeKey
|
||||
proc hashNode(t: var TreeBuilder): NodeKey
|
||||
proc treeNode(t: var TreeBuilder, depth: int = 0, storageMode = false): NodeKey
|
||||
|
||||
proc treeNode*(t: var TreeBuilder, depth: int = 0, storageMode = false): NodeKey =
|
||||
proc buildTree*(t: var TreeBuilder): KeccakHash =
|
||||
let version = t.readByte().int
|
||||
if version != BlockWitnessVersion.int:
|
||||
raise newException(ParsingError, "Wrong block witness version")
|
||||
|
||||
# one or more trees
|
||||
|
||||
# we only parse one tree here
|
||||
let metadataType = t.readByte().int
|
||||
if metadataType != MetadataNothing.int:
|
||||
raise newException(ParsingError, "This tree builder support no metadata")
|
||||
|
||||
var res = treeNode(t)
|
||||
if res.usedBytes != 32:
|
||||
raise newException(ParsingError, "Buildtree should produce hash")
|
||||
|
||||
result.data = res.data
|
||||
|
||||
proc buildForest*(t: var TreeBuilder): seq[KeccakHash] =
|
||||
let version = t.readByte().int
|
||||
if version != BlockWitnessVersion.int:
|
||||
raise newException(ParsingError, "Wrong block witness version")
|
||||
|
||||
while t.readable:
|
||||
let metadataType = t.readByte().int
|
||||
if metadataType != MetadataNothing.int:
|
||||
raise newException(ParsingError, "This tree builder support no metadata")
|
||||
|
||||
var res = treeNode(t)
|
||||
if res.usedBytes != 32:
|
||||
raise newException(ParsingError, "Buildtree should produce hash")
|
||||
|
||||
result.add KeccakHash(data: res.data)
|
||||
|
||||
proc treeNode(t: var TreeBuilder, depth: int = 0, storageMode = false): NodeKey =
|
||||
assert(depth < 64)
|
||||
let nodeType = TrieNodeType(t.readByte)
|
||||
|
||||
|
|
|
@ -244,8 +244,17 @@ proc getBranchRecurseAux(wb: var WitnessBuilder, node: openArray[byte], path: Ni
|
|||
raise newException(CorruptedTrieDatabase,
|
||||
"HexaryTrie node with an unexpected number of children")
|
||||
|
||||
proc buildWitness*(wb: var WitnessBuilder; address: EthAddress): seq[byte] =
|
||||
proc buildWitness*(wb: var WitnessBuilder; address: EthAddress, withVersion: bool = true): seq[byte] =
|
||||
# witness version
|
||||
wb.output.append(BlockWitnessVersion.byte)
|
||||
|
||||
# one or more trees
|
||||
|
||||
# we only output one tree
|
||||
wb.output.append(MetadataNothing.byte)
|
||||
let key = keccak(address)
|
||||
var node = wb.db.get(wb.root.data)
|
||||
getBranchRecurseAux(wb, node, initNibbleRange(key.data), 0, false)
|
||||
|
||||
# result
|
||||
result = wb.output.getOutput(seq[byte])
|
||||
|
|
|
@ -15,9 +15,14 @@ type
|
|||
wfNoFlag
|
||||
wfEIP170 # fork >= Spurious Dragon
|
||||
|
||||
MetadataType* = enum
|
||||
MetadataNothing
|
||||
MetadataSomething
|
||||
|
||||
WitnessFlags* = set[WitnessFlag]
|
||||
|
||||
ContractCodeError* = object of ValueError
|
||||
ParsingError* = object of ValueError
|
||||
|
||||
const
|
||||
StorageLeafNodeType* = AccountNodeType
|
||||
|
@ -33,6 +38,5 @@ func branchMaskBitIsSet*(x: uint, i: int): bool {.inline.} =
|
|||
|
||||
func constructBranchMask*(b1, b2: byte): uint {.inline.} =
|
||||
result = uint(b1) shl 8 or uint(b2)
|
||||
if countOnes(result) < 2:
|
||||
debugEcho "MASK: ", result
|
||||
assert(countOnes(result) > 1)
|
||||
if countOnes(result) < 2 or ((result and (not 0x1FFFF'u)) != 0):
|
||||
raise newException(ParsingError, "Invalid branch mask pattern")
|
||||
|
|
Loading…
Reference in New Issue