wrong address ignored
This commit is contained in:
parent
1f76b2e69d
commit
743759a979
|
@ -14,9 +14,10 @@ type
|
||||||
of false:
|
of false:
|
||||||
storageKeys*: MultikeysRef
|
storageKeys*: MultikeysRef
|
||||||
address*: EthAddress
|
address*: EthAddress
|
||||||
|
codeTouched*: bool
|
||||||
|
|
||||||
Multikeys* = object
|
Multikeys* = object
|
||||||
keys: seq[KeyData]
|
keys*: seq[KeyData]
|
||||||
|
|
||||||
MultikeysRef* = ref Multikeys
|
MultikeysRef* = ref Multikeys
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ type
|
||||||
mask*: uint
|
mask*: uint
|
||||||
groups*: array[16, Group]
|
groups*: array[16, Group]
|
||||||
|
|
||||||
AccountKey* = tuple[address: EthAddress, storageKeys: MultikeysRef]
|
AccountKey* = tuple[address: EthAddress, codeTouched: bool, storageKeys: MultikeysRef]
|
||||||
MatchGroup* = tuple[match: bool, group: Group]
|
MatchGroup* = tuple[match: bool, group: Group]
|
||||||
|
|
||||||
func cmpHash(a, b: KeyHash): int =
|
func cmpHash(a, b: KeyHash): int =
|
||||||
|
@ -64,6 +65,7 @@ proc newMultiKeys*(keys: openArray[AccountKey]): MultikeysRef =
|
||||||
storageMode: false,
|
storageMode: false,
|
||||||
hash: keccak(a.address).data,
|
hash: keccak(a.address).data,
|
||||||
address: a.address,
|
address: a.address,
|
||||||
|
codeTouched: a.codeTouched,
|
||||||
storageKeys: a.storageKeys)
|
storageKeys: a.storageKeys)
|
||||||
result.keys.sort(cmpHash)
|
result.keys.sort(cmpHash)
|
||||||
|
|
||||||
|
@ -127,18 +129,13 @@ iterator groups*(m: MultikeysRef, depth: int, n: NibblesSeq, parentGroup: Group)
|
||||||
haveGroup = false
|
haveGroup = false
|
||||||
yield (matchResult, groupResult)
|
yield (matchResult, groupResult)
|
||||||
|
|
||||||
func keyData*(m: MultikeysRef, g: Group): KeyData =
|
iterator keyDatas*(m: MultikeysRef, g: Group): var KeyData =
|
||||||
doAssert(g.first == g.last)
|
|
||||||
result = m.keys[g.first]
|
|
||||||
|
|
||||||
iterator keyDatas*(m: MultikeysRef, g: Group): KeyData =
|
|
||||||
for i in g.first..g.last:
|
for i in g.first..g.last:
|
||||||
yield m.keys[i]
|
yield m.keys[i]
|
||||||
|
|
||||||
iterator addresses*(m :MultikeysRef): EthAddress =
|
|
||||||
for x in m.keys:
|
|
||||||
yield x.address
|
|
||||||
|
|
||||||
iterator storageKeys*(m :MultikeysRef): MultikeysRef =
|
iterator storageKeys*(m :MultikeysRef): MultikeysRef =
|
||||||
for x in m.keys:
|
for x in m.keys:
|
||||||
yield x.storageKeys
|
yield x.storageKeys
|
||||||
|
|
||||||
|
func match*(kd: KeyData, n: NibblesSeq, depth: int): bool {.inline.} =
|
||||||
|
compareNibbles(kd.hash, depth, n)
|
||||||
|
|
|
@ -59,9 +59,6 @@ proc setupStateDB(tester: var Tester, wantedState: JsonNode, stateDB: var Accoun
|
||||||
storageKeys.add(slot.toBytesBE)
|
storageKeys.add(slot.toBytesBE)
|
||||||
stateDB.setStorage(account, slot, fromHex(UInt256, value.getStr))
|
stateDB.setStorage(account, slot, fromHex(UInt256, value.getStr))
|
||||||
|
|
||||||
var sKeys = if storageKeys.len != 0: newMultiKeys(storageKeys) else: MultikeysRef(nil)
|
|
||||||
keys.add((account, sKeys))
|
|
||||||
|
|
||||||
let nonce = accountData{"nonce"}.getHexadecimalInt.AccountNonce
|
let nonce = accountData{"nonce"}.getHexadecimalInt.AccountNonce
|
||||||
let code = accountData{"code"}.getStr.safeHexToSeqByte
|
let code = accountData{"code"}.getStr.safeHexToSeqByte
|
||||||
let balance = UInt256.fromHex accountData{"balance"}.getStr
|
let balance = UInt256.fromHex accountData{"balance"}.getStr
|
||||||
|
@ -70,6 +67,10 @@ proc setupStateDB(tester: var Tester, wantedState: JsonNode, stateDB: var Accoun
|
||||||
stateDB.setCode(account, code)
|
stateDB.setCode(account, code)
|
||||||
stateDB.setBalance(account, balance)
|
stateDB.setBalance(account, balance)
|
||||||
|
|
||||||
|
let sKeys = if storageKeys.len != 0: newMultiKeys(storageKeys) else: MultikeysRef(nil)
|
||||||
|
let codeTouched = code.len > 0
|
||||||
|
keys.add((account, codeTouched, sKeys))
|
||||||
|
|
||||||
tester.keys = newMultiKeys(keys)
|
tester.keys = newMultiKeys(keys)
|
||||||
stateDB.persist()
|
stateDB.persist()
|
||||||
result = stateDB.rootHash
|
result = stateDB.rootHash
|
||||||
|
|
|
@ -8,11 +8,12 @@ import
|
||||||
type
|
type
|
||||||
DB = TrieDatabaseRef
|
DB = TrieDatabaseRef
|
||||||
|
|
||||||
StorageKeys = tuple[hash: Hash256, keys: MultikeysRef]
|
StorageKeys = tuple[storageRoot: Hash256, keys: MultikeysRef]
|
||||||
|
|
||||||
AccountDef = object
|
AccountDef = object
|
||||||
storageKeys: MultiKeysRef
|
storageKeys: MultiKeysRef
|
||||||
account: Account
|
account: Account
|
||||||
|
codeTouched: bool
|
||||||
|
|
||||||
proc randU256(): UInt256 =
|
proc randU256(): UInt256 =
|
||||||
var bytes: array[32, byte]
|
var bytes: array[32, byte]
|
||||||
|
@ -55,13 +56,16 @@ proc randStorage(db: DB): StorageKeys =
|
||||||
proc randAccount(db: DB): AccountDef =
|
proc randAccount(db: DB): AccountDef =
|
||||||
result.account.nonce = randNonce()
|
result.account.nonce = randNonce()
|
||||||
result.account.balance = randU256()
|
result.account.balance = randU256()
|
||||||
|
let z = randStorage(db)
|
||||||
result.account.codeHash = randCode(db)
|
result.account.codeHash = randCode(db)
|
||||||
(result.account.storageRoot, result.storageKeys) = randStorage(db)
|
result.account.storageRoot = z.storageRoot
|
||||||
|
result.storageKeys = z.keys
|
||||||
|
result.codeTouched = rand(0..1) == 0
|
||||||
|
|
||||||
proc randAddress(): EthAddress =
|
proc randAddress(): EthAddress =
|
||||||
discard randomBytes(result.addr, sizeof(result))
|
discard randomBytes(result.addr, sizeof(result))
|
||||||
|
|
||||||
proc runTest(numPairs: int, testStatusIMPL: var TestStatus) =
|
proc runTest(numPairs: int, testStatusIMPL: var TestStatus, useRogueKeys: static[bool] = false) =
|
||||||
var memDB = newMemoryDB()
|
var memDB = newMemoryDB()
|
||||||
var trie = initSecureHexaryTrie(memDB)
|
var trie = initSecureHexaryTrie(memDB)
|
||||||
var addrs = newSeq[AccountKey](numPairs)
|
var addrs = newSeq[AccountKey](numPairs)
|
||||||
|
@ -69,10 +73,15 @@ proc runTest(numPairs: int, testStatusIMPL: var TestStatus) =
|
||||||
|
|
||||||
for i in 0..<numPairs:
|
for i in 0..<numPairs:
|
||||||
let acc = randAccount(memDB)
|
let acc = randAccount(memDB)
|
||||||
addrs[i] = (randAddress(), acc.storageKeys)
|
addrs[i] = (randAddress(), acc.codeTouched, acc.storageKeys)
|
||||||
accs[i] = acc.account
|
accs[i] = acc.account
|
||||||
trie.put(addrs[i].address, rlp.encode(accs[i]))
|
trie.put(addrs[i].address, rlp.encode(accs[i]))
|
||||||
|
|
||||||
|
when useRogueKeys:
|
||||||
|
# rogueAddress should not end up in block witness
|
||||||
|
let rogueAddress = randAddress()
|
||||||
|
addrs.add((rogueAddress, false, MultikeysRef(nil)))
|
||||||
|
|
||||||
var mkeys = newMultiKeys(addrs)
|
var mkeys = newMultiKeys(addrs)
|
||||||
let rootHash = trie.rootHash
|
let rootHash = trie.rootHash
|
||||||
|
|
||||||
|
@ -94,9 +103,19 @@ proc runTest(numPairs: int, testStatusIMPL: var TestStatus) =
|
||||||
let acc = rlp.decode(recordFound, Account)
|
let acc = rlp.decode(recordFound, Account)
|
||||||
check acc == accs[i]
|
check acc == accs[i]
|
||||||
else:
|
else:
|
||||||
debugEcho "BUG IN TREE BUILDER"
|
debugEcho "BUG IN TREE BUILDER ", i
|
||||||
check false
|
check false
|
||||||
|
|
||||||
|
when useRogueKeys:
|
||||||
|
for kd in mkeys.keys:
|
||||||
|
if kd.address == rogueAddress:
|
||||||
|
check kd.visited == false
|
||||||
|
else:
|
||||||
|
check kd.visited == true
|
||||||
|
else:
|
||||||
|
for kd in mkeys.keys:
|
||||||
|
check kd.visited == true
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
suite "random keys block witness roundtrip test":
|
suite "random keys block witness roundtrip test":
|
||||||
randomize()
|
randomize()
|
||||||
|
@ -110,4 +129,7 @@ proc main() =
|
||||||
let rlpBytes = rlp.encode(acc)
|
let rlpBytes = rlp.encode(acc)
|
||||||
check rlpBytes.len > 32
|
check rlpBytes.len > 32
|
||||||
|
|
||||||
|
test "rogue address ignored":
|
||||||
|
runTest(rand(1..30), testStatusIMPL, useRogueKeys = true)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -201,13 +201,18 @@ proc getBranchRecurseAux(wb: var WitnessBuilder, z: var StackElem) =
|
||||||
)
|
)
|
||||||
getBranchRecurseAux(wb, zz)
|
getBranchRecurseAux(wb, zz)
|
||||||
else:
|
else:
|
||||||
let kd = keyData(z.keys, mg.group)
|
# this should be only one match
|
||||||
if z.storageMode:
|
# if there is more than one match
|
||||||
doAssert(kd.storageMode)
|
# it means we encounter a rogue address
|
||||||
writeAccountStorageLeafNode(wb, kd.storageSlot, value.toBytes.decode(UInt256), k, z.node, z.depth)
|
for kd in keyDatas(z.keys, mg.group):
|
||||||
else:
|
if not match(kd, k, z.depth): continue # this is the rogue address
|
||||||
doAssert(not kd.storageMode)
|
kd.visited = true
|
||||||
writeAccountNode(wb, kd.storageKeys, kd.address, value.toBytes.decode(Account), k, z.node, z.depth)
|
if z.storageMode:
|
||||||
|
doAssert(kd.storageMode)
|
||||||
|
writeAccountStorageLeafNode(wb, kd.storageSlot, value.toBytes.decode(UInt256), k, z.node, z.depth)
|
||||||
|
else:
|
||||||
|
doAssert(not kd.storageMode)
|
||||||
|
writeAccountNode(wb, kd.storageKeys, kd.address, value.toBytes.decode(Account), k, z.node, z.depth)
|
||||||
if not match:
|
if not match:
|
||||||
writeHashNode(wb, keccak(z.node).data)
|
writeHashNode(wb, keccak(z.node).data)
|
||||||
of 17:
|
of 17:
|
||||||
|
|
Loading…
Reference in New Issue