mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-13 05:44:40 +00:00
validate the branch of the constructed trie beside validate rootHash
This commit is contained in:
parent
6ccb2d65cd
commit
1ef3f60b40
90
stateless/multi_keys.nim
Normal file
90
stateless/multi_keys.nim
Normal 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()
|
@ -25,11 +25,12 @@ proc isValidBranch(branch: openArray[seq[byte]], rootHash: KeccakHash, key, valu
|
|||||||
result = trie.get(key) == value
|
result = trie.get(key) == value
|
||||||
|
|
||||||
proc testGetBranch(tester: Tester, rootHash: KeccakHash, testStatusIMPL: var TestStatus) =
|
proc testGetBranch(tester: Tester, rootHash: KeccakHash, testStatusIMPL: var TestStatus) =
|
||||||
var trie = initHexaryTrie(tester.memdb, rootHash)
|
var trie = initSecureHexaryTrie(tester.memdb, rootHash)
|
||||||
let flags = {wfEIP170}
|
let flags = {wfEIP170}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for address in tester.address:
|
for address in tester.address:
|
||||||
|
let account = rlp.decode(trie.get(address), Account)
|
||||||
var wb = initWitnessBuilder(tester.memdb, rootHash, flags)
|
var wb = initWitnessBuilder(tester.memdb, rootHash, flags)
|
||||||
var witness = wb.buildWitness(address)
|
var witness = wb.buildWitness(address)
|
||||||
|
|
||||||
@ -42,6 +43,15 @@ proc testGetBranch(tester: Tester, rootHash: KeccakHash, testStatusIMPL: var Tes
|
|||||||
|
|
||||||
var root = tb.buildTree()
|
var root = tb.buildTree()
|
||||||
check root.data == rootHash.data
|
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:
|
except ContractCodeError as e:
|
||||||
debugEcho "CONTRACT CODE ERROR: ", e.msg
|
debugEcho "CONTRACT CODE ERROR: ", e.msg
|
||||||
|
|
||||||
|
@ -51,31 +51,40 @@ proc runTest(numPairs: int) =
|
|||||||
var memDB = newMemoryDB()
|
var memDB = newMemoryDB()
|
||||||
var trie = initSecureHexaryTrie(memDB)
|
var trie = initSecureHexaryTrie(memDB)
|
||||||
var addrs = newSeq[EthAddress](numPairs)
|
var addrs = newSeq[EthAddress](numPairs)
|
||||||
|
var accs = newSeq[Account](numPairs)
|
||||||
|
|
||||||
for i in 0..<numPairs:
|
for i in 0..<numPairs:
|
||||||
addrs[i] = randAddress()
|
addrs[i] = randAddress()
|
||||||
let acc = randAccount(memDB)
|
accs[i] = randAccount(memDB)
|
||||||
trie.put(addrs[i], rlp.encode(acc))
|
trie.put(addrs[i], rlp.encode(accs[i]))
|
||||||
|
|
||||||
let rootHash = trie.rootHash
|
let rootHash = trie.rootHash
|
||||||
|
|
||||||
var wb = initWitnessBuilder(memDB, rootHash, {wfEIP170})
|
for i in 0..<numPairs:
|
||||||
var witness = wb.buildWitness(addrs[0])
|
var wb = initWitnessBuilder(memDB, rootHash, {wfEIP170})
|
||||||
var db = newMemoryDB()
|
var witness = wb.buildWitness(addrs[i])
|
||||||
when defined(useInputStream):
|
var db = newMemoryDB()
|
||||||
var input = memoryInput(witness)
|
when defined(useInputStream):
|
||||||
var tb = initTreeBuilder(input, db, {wfEIP170})
|
var input = memoryInput(witness)
|
||||||
else:
|
var tb = initTreeBuilder(input, db, {wfEIP170})
|
||||||
var tb = initTreeBuilder(witness, db, {wfEIP170})
|
else:
|
||||||
var root = tb.buildTree()
|
var tb = initTreeBuilder(witness, db, {wfEIP170})
|
||||||
debugEcho "root: ", root.data.toHex
|
let root = tb.buildTree()
|
||||||
debugEcho "rootHash: ", rootHash.data.toHex
|
doAssert root.data == rootHash.data
|
||||||
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() =
|
proc main() =
|
||||||
randomize()
|
randomize()
|
||||||
|
|
||||||
for i in 0..<30:
|
for i in 0..<30:
|
||||||
runTest(rand(1..30))
|
runTest(rand(1..30))
|
||||||
|
echo "OK"
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
@ -9,7 +9,7 @@ type
|
|||||||
|
|
||||||
NodeKey = object
|
NodeKey = object
|
||||||
usedBytes: int
|
usedBytes: int
|
||||||
data*: array[32, byte]
|
data: array[32, byte]
|
||||||
|
|
||||||
TreeBuilder = object
|
TreeBuilder = object
|
||||||
when defined(useInputStream):
|
when defined(useInputStream):
|
||||||
@ -47,6 +47,9 @@ else:
|
|||||||
func rootHash*(t: TreeBuilder): KeccakHash {.inline.} =
|
func rootHash*(t: TreeBuilder): KeccakHash {.inline.} =
|
||||||
t.root
|
t.root
|
||||||
|
|
||||||
|
func getDB*(t: TreeBuilder): DB {.inline.} =
|
||||||
|
t.db
|
||||||
|
|
||||||
when defined(useInputStream):
|
when defined(useInputStream):
|
||||||
template readByte(t: var TreeBuilder): byte =
|
template readByte(t: var TreeBuilder): byte =
|
||||||
t.input.read
|
t.input.read
|
||||||
|
Loading…
x
Reference in New Issue
Block a user