validate the branch of the constructed trie beside validate rootHash
This commit is contained in:
parent
6ccb2d65cd
commit
1ef3f60b40
|
@ -0,0 +1,90 @@
|
|||
import eth/common, eth/trie/db, tables, algorithm, stew/byteutils
|
||||
|
||||
type
|
||||
KeyHash = array[32, byte]
|
||||
|
||||
Multikeys = object
|
||||
hash: seq[KeyHash]
|
||||
|
||||
Group = object
|
||||
a, b: int
|
||||
|
||||
proc toHash(x: string): KeyHash =
|
||||
let len = min(x.len, 32)
|
||||
for i in 0..<len:
|
||||
result[i] = x[i].byte
|
||||
|
||||
proc `$`(x: KeyHash): string =
|
||||
result = newString(x.len)
|
||||
for i, c in x:
|
||||
result[i] = c.char
|
||||
|
||||
let keys = [
|
||||
"abcdefghijklmnopqrstuv",
|
||||
"abcj34-09u3209u0jhfn93",
|
||||
"couynnm3mm,op312u0jnnm",
|
||||
"bad03he0823hhhf0hn1032",
|
||||
"abcdefghon0384hr0h3240",
|
||||
"baiju-94i-j2nh-9jdjlwk",
|
||||
"bai2222-9ur34nonf08hn3"
|
||||
]
|
||||
|
||||
|
||||
proc cmpHash(a, b: KeyHash): int =
|
||||
var i = 0
|
||||
var m = min(a.len, b.len)
|
||||
while i < m:
|
||||
result = a[i].int - b[i].int
|
||||
if result != 0: return
|
||||
inc(i)
|
||||
result = a.len - b.len
|
||||
|
||||
proc nextGroup(m: Multikeys, c: int, g: Group): Group =
|
||||
result.a = g.b + 1
|
||||
var head = m.hash[result.a][c]
|
||||
let last = m.hash.len - 1
|
||||
for i in result.a..<m.hash.len:
|
||||
if m.hash[i][c] != head:
|
||||
result.b = i - 1
|
||||
break
|
||||
elif i == last:
|
||||
result.b = last
|
||||
|
||||
proc lastGroup(a: Group, g: Group): bool =
|
||||
g.b == a.b
|
||||
|
||||
proc main() =
|
||||
var m: Multikeys
|
||||
for x in keys:
|
||||
m.hash.add toHash(x)
|
||||
|
||||
m.hash.sort(cmpHash)
|
||||
|
||||
for x in m.hash:
|
||||
echo x
|
||||
|
||||
var a = Group(a: 0, b: m.hash.len - 1)
|
||||
var c = 0
|
||||
var g = Group(a: a.a-1, b: a.a-1)
|
||||
while not a.lastGroup(g):
|
||||
g = m.nextGroup(c, g)
|
||||
echo g
|
||||
|
||||
echo "---"
|
||||
c = 2
|
||||
var b = Group(a: 3, b: 5)
|
||||
g = Group(a: b.a-1, b: b.a-1)
|
||||
while not b.lastGroup(g):
|
||||
g = m.nextGroup(c, g)
|
||||
echo g
|
||||
|
||||
|
||||
echo "---"
|
||||
c = 2
|
||||
b = Group(a: 6, b: 6)
|
||||
g = Group(a: b.a-1, b: b.a-1)
|
||||
while not b.lastGroup(g):
|
||||
g = m.nextGroup(c, g)
|
||||
echo g
|
||||
|
||||
main()
|
|
@ -25,11 +25,12 @@ proc isValidBranch(branch: openArray[seq[byte]], rootHash: KeccakHash, key, valu
|
|||
result = trie.get(key) == value
|
||||
|
||||
proc testGetBranch(tester: Tester, rootHash: KeccakHash, testStatusIMPL: var TestStatus) =
|
||||
var trie = initHexaryTrie(tester.memdb, rootHash)
|
||||
var trie = initSecureHexaryTrie(tester.memdb, rootHash)
|
||||
let flags = {wfEIP170}
|
||||
|
||||
try:
|
||||
for address in tester.address:
|
||||
let account = rlp.decode(trie.get(address), Account)
|
||||
var wb = initWitnessBuilder(tester.memdb, rootHash, flags)
|
||||
var witness = wb.buildWitness(address)
|
||||
|
||||
|
@ -42,6 +43,15 @@ proc testGetBranch(tester: Tester, rootHash: KeccakHash, testStatusIMPL: var Tes
|
|||
|
||||
var root = tb.buildTree()
|
||||
check root.data == rootHash.data
|
||||
|
||||
let newTrie = initSecureHexaryTrie(tb.getDB(), root)
|
||||
let recordFound = newTrie.get(address)
|
||||
if recordFound.len > 0:
|
||||
let acc = rlp.decode(recordFound, Account)
|
||||
doAssert acc == account
|
||||
else:
|
||||
doAssert(false, "BUG IN TREE BUILDER")
|
||||
|
||||
except ContractCodeError as e:
|
||||
debugEcho "CONTRACT CODE ERROR: ", e.msg
|
||||
|
||||
|
|
|
@ -51,31 +51,40 @@ proc runTest(numPairs: int) =
|
|||
var memDB = newMemoryDB()
|
||||
var trie = initSecureHexaryTrie(memDB)
|
||||
var addrs = newSeq[EthAddress](numPairs)
|
||||
var accs = newSeq[Account](numPairs)
|
||||
|
||||
for i in 0..<numPairs:
|
||||
addrs[i] = randAddress()
|
||||
let acc = randAccount(memDB)
|
||||
trie.put(addrs[i], rlp.encode(acc))
|
||||
accs[i] = randAccount(memDB)
|
||||
trie.put(addrs[i], rlp.encode(accs[i]))
|
||||
|
||||
let rootHash = trie.rootHash
|
||||
|
||||
var wb = initWitnessBuilder(memDB, rootHash, {wfEIP170})
|
||||
var witness = wb.buildWitness(addrs[0])
|
||||
var db = newMemoryDB()
|
||||
when defined(useInputStream):
|
||||
var input = memoryInput(witness)
|
||||
var tb = initTreeBuilder(input, db, {wfEIP170})
|
||||
else:
|
||||
var tb = initTreeBuilder(witness, db, {wfEIP170})
|
||||
var root = tb.buildTree()
|
||||
debugEcho "root: ", root.data.toHex
|
||||
debugEcho "rootHash: ", rootHash.data.toHex
|
||||
doAssert root.data == rootHash.data
|
||||
for i in 0..<numPairs:
|
||||
var wb = initWitnessBuilder(memDB, rootHash, {wfEIP170})
|
||||
var witness = wb.buildWitness(addrs[i])
|
||||
var db = newMemoryDB()
|
||||
when defined(useInputStream):
|
||||
var input = memoryInput(witness)
|
||||
var tb = initTreeBuilder(input, db, {wfEIP170})
|
||||
else:
|
||||
var tb = initTreeBuilder(witness, db, {wfEIP170})
|
||||
let root = tb.buildTree()
|
||||
doAssert root.data == rootHash.data
|
||||
|
||||
let newTrie = initSecureHexaryTrie(tb.getDB(), root)
|
||||
let recordFound = newTrie.get(addrs[i])
|
||||
if recordFound.len > 0:
|
||||
let acc = rlp.decode(recordFound, Account)
|
||||
doAssert acc == accs[i]
|
||||
else:
|
||||
doAssert(false, "BUG IN TREE BUILDER")
|
||||
|
||||
proc main() =
|
||||
randomize()
|
||||
|
||||
for i in 0..<30:
|
||||
runTest(rand(1..30))
|
||||
echo "OK"
|
||||
|
||||
main()
|
||||
|
|
|
@ -9,7 +9,7 @@ type
|
|||
|
||||
NodeKey = object
|
||||
usedBytes: int
|
||||
data*: array[32, byte]
|
||||
data: array[32, byte]
|
||||
|
||||
TreeBuilder = object
|
||||
when defined(useInputStream):
|
||||
|
@ -47,6 +47,9 @@ else:
|
|||
func rootHash*(t: TreeBuilder): KeccakHash {.inline.} =
|
||||
t.root
|
||||
|
||||
func getDB*(t: TreeBuilder): DB {.inline.} =
|
||||
t.db
|
||||
|
||||
when defined(useInputStream):
|
||||
template readByte(t: var TreeBuilder): byte =
|
||||
t.input.read
|
||||
|
|
Loading…
Reference in New Issue