validate the branch of the constructed trie beside validate rootHash

This commit is contained in:
andri lim 2020-05-03 08:11:04 +07:00
parent 6ccb2d65cd
commit 1ef3f60b40
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
4 changed files with 128 additions and 16 deletions

90
stateless/multi_keys.nim Normal file
View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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