deals with touched/not touched account code

This commit is contained in:
andri lim 2020-05-05 15:21:39 +07:00
parent 743759a979
commit 37db9a55ee
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
4 changed files with 31 additions and 15 deletions

View File

@ -31,9 +31,9 @@ proc testGetBranch(tester: Tester, rootHash: KeccakHash, testStatusIMPL: var Tes
check root.data == rootHash.data
let newTrie = initSecureHexaryTrie(tb.getDB(), root)
for address in tester.keys.addresses:
let account = rlp.decode(trie.get(address), Account)
let recordFound = newTrie.get(address)
for kd in tester.keys.keys:
let account = rlp.decode(trie.get(kd.address), Account)
let recordFound = newTrie.get(kd.address)
if recordFound.len > 0:
let acc = rlp.decode(recordFound, Account)
doAssert acc == account

View File

@ -332,10 +332,11 @@ proc accountNode(t: var TreeBuilder, depth: int): NodeKey =
nonce: UInt256.fromBytesBE(t.read(32), false).truncate(AccountNonce)
)
if accountType == SimpleAccountType:
case accountType
of SimpleAccountType:
acc.codeHash = blankStringHash
acc.storageRoot = emptyRlpHash
else:
of ExtendedAccountType:
let codeLen = t.safeReadU32()
if wfEIP170 in t.flags and codeLen > EIP170_CODE_SIZE_LIMIT:
raise newException(ContractCodeError, "code len exceed EIP170 code size limit")
@ -348,6 +349,15 @@ proc accountNode(t: var TreeBuilder, depth: int): NodeKey =
let storageRoot = t.treeNode(0, storageMode = true)
doAssert(storageRoot.usedBytes == 32)
acc.storageRoot.data = storageRoot.data
of CodeUntouched:
# TODO: should we check it is a hashNode ?
let codeHash = t.treeNode(depth)
doAssert(codeHash.usedBytes == 32)
acc.codeHash.data = codeHash.data
let storageRoot = t.treeNode(0, storageMode = true)
doAssert(storageRoot.usedBytes == 32)
acc.storageRoot.data = storageRoot.data
r.append rlp.encode(acc)

View File

@ -107,8 +107,8 @@ proc writeHashNode(wb: var WitnessBuilder, node: openArray[byte]) =
proc getBranchRecurseAux(wb: var WitnessBuilder, z: var StackElem) {.raises: [ContractCodeError, IOError, Defect, CatchableError, Exception].}
proc writeAccountNode(wb: var WitnessBuilder, storageKeys: MultikeysRef, address: EthAddress,
acc: Account, nibbles: NibblesSeq, node: openArray[byte], depth: int) {.raises: [ContractCodeError, IOError, Defect, CatchableError, Exception].} =
proc writeAccountNode(wb: var WitnessBuilder, kd: KeyData, acc: Account, nibbles: NibblesSeq,
node: openArray[byte], depth: int) {.raises: [ContractCodeError, IOError, Defect, CatchableError, Exception].} =
# write type
wb.output.append(AccountNodeType.byte)
@ -121,17 +121,22 @@ proc writeAccountNode(wb: var WitnessBuilder, storageKeys: MultikeysRef, address
wb.output.append(depth.byte)
doAssert(nibbles.len == 64 - depth)
let accountType = if acc.codeHash == blankStringHash and acc.storageRoot == emptyRlpHash: SimpleAccountType
var accountType = if acc.codeHash == blankStringHash and acc.storageRoot == emptyRlpHash: SimpleAccountType
else: ExtendedAccountType
if not kd.codeTouched:
accountType = CodeUntouched
wb.output.append(accountType.byte)
wb.writeNibbles(nibbles, false)
wb.output.append(address)
wb.output.append(kd.address)
wb.output.append(acc.balance.toBytesBE)
wb.output.append(acc.nonce.u256.toBytesBE)
if accountType == ExtendedAccountType:
if acc.codeHash != blankStringHash:
if accountType != SimpleAccountType:
if not kd.codeTouched:
wb.writeHashNode(acc.codeHash.data)
elif acc.codeHash != blankStringHash:
let code = get(wb.db, contractHashKey(acc.codeHash).toOpenArray)
if wfEIP170 in wb.flags and code.len > EIP170_CODE_SIZE_LIMIT:
raise newException(ContractCodeError, "code len exceed EIP170 code size limit")
@ -140,14 +145,14 @@ proc writeAccountNode(wb: var WitnessBuilder, storageKeys: MultikeysRef, address
else:
wb.writeU32(0'u32)
if storageKeys.isNil:
if kd.storageKeys.isNil:
# we have storage but not touched by EVM
wb.writeHashNode(acc.storageRoot.data)
elif acc.storageRoot != emptyRlpHash:
var zz = StackElem(
node: wb.db.get(acc.storageRoot.data),
parentGroup: storageKeys.initGroup(),
keys: storageKeys,
parentGroup: kd.storageKeys.initGroup(),
keys: kd.storageKeys,
depth: 0, # reset depth
storageMode: true # switch to storage mode
)
@ -212,7 +217,7 @@ proc getBranchRecurseAux(wb: var WitnessBuilder, z: var StackElem) =
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)
writeAccountNode(wb, kd, value.toBytes.decode(Account), k, z.node, z.depth)
if not match:
writeHashNode(wb, keccak(z.node).data)
of 17:

View File

@ -10,6 +10,7 @@ type
AccountType* = enum
SimpleAccountType
ExtendedAccountType
CodeUntouched
WitnessFlag* = enum
wfNoFlag