wrong address ignored

This commit is contained in:
andri lim 2020-05-05 15:05:17 +07:00
parent 1f76b2e69d
commit 743759a979
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
4 changed files with 51 additions and 26 deletions

View File

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

View File

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

View File

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

View File

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