From 7f76586214dc3252b0a37325e0055141e800b1e7 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Sun, 2 Jun 2024 21:21:29 +0200 Subject: [PATCH] Speed up account ledger a little (#2279) `persist` is a hotspot when processing blocks because it is run at least once per transaction and loops over the entire account cache every time. Here, we introduce an extra `dirty` map that keeps track of all accounts that need checking during `persist` which fixes the immediate inefficiency, though probably this could benefit from a more thorough review - we also get rid of the unused clearCache flag - we start with a fresh cache on every fresh vmState. * avoid unnecessary code hash comparisons * avoid unnecessary copies when iterating * use EMPTY_CODE_HASH throughout for code hash comparison --- hive_integration/nodocker/engine/node.nim | 2 +- nimbus/core/executor/process_block.nim | 4 +- nimbus/core/executor/process_transaction.nim | 6 +- nimbus/core/tx_pool/tx_tasks/tx_packer.nim | 12 +- nimbus/core/validate.nim | 2 +- nimbus/db/ledger/accounts_ledger.nim | 114 ++++++++++-------- nimbus/db/ledger/base.nim | 6 +- nimbus/db/state_db/base.nim | 12 +- nimbus/evm/types.nim | 1 - nimbus/sync/protocol/snap/snap_types.nim | 6 +- tests/test_accounts_cache.nim | 22 ++-- tests/test_rpc_experimental_json.nim | 4 +- ...test_rpc_getproofs_track_state_changes.nim | 8 +- tools/common/state_clearing.nim | 6 +- tools/evmstate/evmstate.nim | 2 +- tools/t8n/transition.nim | 2 +- 16 files changed, 106 insertions(+), 103 deletions(-) diff --git a/hive_integration/nodocker/engine/node.nim b/hive_integration/nodocker/engine/node.nim index 42cab8573..b3b0ceace 100644 --- a/hive_integration/nodocker/engine/node.nim +++ b/hive_integration/nodocker/engine/node.nim @@ -74,7 +74,7 @@ proc processBlock( vmState.mutateStateDB: let clearEmptyAccount = vmState.determineFork >= FkSpurious - db.persist(clearEmptyAccount, ClearCache in vmState.flags) + db.persist(clearEmptyAccount) # `applyDeletes = false` # If the trie pruning activated, each of the block will have its own state diff --git a/nimbus/core/executor/process_block.nim b/nimbus/core/executor/process_block.nim index 7ecf8c11a..c9cc0c526 100644 --- a/nimbus/core/executor/process_block.nim +++ b/nimbus/core/executor/process_block.nim @@ -117,8 +117,8 @@ proc procBlkEpilogue(vmState: BaseVMState; vmState.mutateStateDB: if vmState.generateWitness: db.collectWitnessData() - let clearEmptyAccount = vmState.determineFork >= FkSpurious - db.persist(clearEmptyAccount, ClearCache in vmState.flags) + + db.persist(clearEmptyAccount = vmState.determineFork >= FkSpurious) let stateDb = vmState.stateDB if header.stateRoot != stateDb.rootHash: diff --git a/nimbus/core/executor/process_transaction.nim b/nimbus/core/executor/process_transaction.nim index c45da2d08..f431fccd1 100644 --- a/nimbus/core/executor/process_transaction.nim +++ b/nimbus/core/executor/process_transaction.nim @@ -118,9 +118,7 @@ proc processTransactionImpl( if vmState.generateWitness: vmState.stateDB.collectWitnessData() - vmState.stateDB.persist( - clearEmptyAccount = fork >= FkSpurious, - clearCache = false) + vmState.stateDB.persist(clearEmptyAccount = fork >= FkSpurious) return res @@ -157,7 +155,7 @@ proc processBeaconBlockRoot*(vmState: BaseVMState, beaconRoot: Hash256): if res.isError: return err("processBeaconBlockRoot: " & res.error) - statedb.persist(clearEmptyAccount = true, clearCache = false) + statedb.persist(clearEmptyAccount = true) ok() proc processTransaction*( diff --git a/nimbus/core/tx_pool/tx_tasks/tx_packer.nim b/nimbus/core/tx_pool/tx_tasks/tx_packer.nim index e1ec855be..39cba5ce6 100644 --- a/nimbus/core/tx_pool/tx_tasks/tx_packer.nim +++ b/nimbus/core/tx_pool/tx_tasks/tx_packer.nim @@ -71,9 +71,7 @@ proc persist(pst: TxPackerStateRef) ## Smart wrapper if not pst.cleanState: let fork = pst.xp.chain.nextFork - pst.xp.chain.vmState.stateDB.persist( - clearEmptyAccount = fork >= FkSpurious, - clearCache = false) + pst.xp.chain.vmState.stateDB.persist(clearEmptyAccount = fork >= FkSpurious) pst.cleanState = true # ------------------------------------------------------------------------------ @@ -227,9 +225,7 @@ proc vmExecGrabItem(pst: TxPackerStateRef; item: TxItemRef): Result[bool,void] # Commit account state DB vmState.stateDB.commit(accTx) - vmState.stateDB.persist( - clearEmptyAccount = xp.chain.nextFork >= FkSpurious, - clearCache = false) + vmState.stateDB.persist(clearEmptyAccount = xp.chain.nextFork >= FkSpurious) # let midRoot = vmState.stateDB.rootHash -- notused # Finish book-keeping and move item to `packed` bucket @@ -254,9 +250,7 @@ proc vmExecCommit(pst: TxPackerStateRef) if vmState.generateWitness: db.collectWitnessData() # Finish up, then vmState.stateDB.rootHash may be accessed - db.persist( - clearEmptyAccount = xp.chain.nextFork >= FkSpurious, - clearCache = ClearCache in vmState.flags) + db.persist(clearEmptyAccount = xp.chain.nextFork >= FkSpurious) # Update flexi-array, set proper length let nItems = xp.txDB.byStatus.eq(txItemPacked).nItems diff --git a/nimbus/core/validate.nim b/nimbus/core/validate.nim index ef9c3131d..525935c7f 100644 --- a/nimbus/core/validate.nim +++ b/nimbus/core/validate.nim @@ -354,7 +354,7 @@ proc validateTransaction*( # `eth_call` and `eth_estimateGas` # EOA = Externally Owned Account let codeHash = roDB.getCodeHash(sender) - if codeHash != EMPTY_SHA3: + if codeHash != EMPTY_CODE_HASH: return err("invalid tx: sender is not an EOA. sender=$1, codeHash=$2" % [ sender.toHex, codeHash.data.toHex]) diff --git a/nimbus/db/ledger/accounts_ledger.nim b/nimbus/db/ledger/accounts_ledger.nim index 8adbf1540..a0527a798 100644 --- a/nimbus/db/ledger/accounts_ledger.nim +++ b/nimbus/db/ledger/accounts_ledger.nim @@ -80,6 +80,7 @@ type LedgerSavePoint* = ref object parentSavepoint: LedgerSavePoint cache: Table[EthAddress, AccountRef] + dirty: Table[EthAddress, AccountRef] selfDestruct: HashSet[EthAddress] logEntries: seq[Log] accessList: ac_access_list.AccessList @@ -129,6 +130,12 @@ func newCoreDbAccount(address: EthAddress): CoreDbAccount = codeHash: emptyEthAccount.codeHash, storage: CoreDbColRef(nil)) +func resetCoreDbAccount(v: var CoreDbAccount) = + v.nonce = emptyEthAccount.nonce + v.balance = emptyEthAccount.balance + v.codeHash = emptyEthAccount.codeHash + v.storage = nil + template noRlpException(info: static[string]; code: untyped) = try: code @@ -196,6 +203,9 @@ proc commit*(ac: AccountsLedgerRef, sp: LedgerSavePoint) = for k, v in sp.cache: sp.parentSavepoint.cache[k] = v + for k, v in sp.dirty: + sp.parentSavepoint.dirty[k] = v + ac.savePoint.transientStorage.merge(sp.transientStorage) ac.savePoint.accessList.merge(sp.accessList) ac.savePoint.selfDestruct.incl sp.selfDestruct @@ -242,7 +252,7 @@ proc getAccount( # cache the account ac.savePoint.cache[address] = result - + ac.savePoint.dirty[address] = result proc clone(acc: AccountRef, cloneStorage: bool): AccountRef = result = AccountRef( @@ -256,9 +266,9 @@ proc clone(acc: AccountRef, cloneStorage: bool): AccountRef = result.overlayStorage = acc.overlayStorage proc isEmpty(acc: AccountRef): bool = - result = acc.statement.codeHash == EMPTY_SHA3 and + acc.statement.nonce == 0 and acc.statement.balance.isZero and - acc.statement.nonce == 0 + acc.statement.codeHash == EMPTY_CODE_HASH template exists(acc: AccountRef): bool = Alive in acc.flags @@ -294,12 +304,12 @@ proc storageValue( do: result = acc.originalStorageValue(slot, ac) -proc kill(acc: AccountRef, address: EthAddress) = +proc kill(acc: AccountRef) = acc.flags.excl Alive acc.overlayStorage.clear() acc.originalStorage = nil - acc.statement = address.newCoreDbAccount() - acc.code = default(seq[byte]) + acc.statement.resetCoreDbAccount() + acc.code.reset() type PersistMode = enum @@ -324,13 +334,13 @@ proc persistCode(acc: AccountRef, ac: AccountsLedgerRef) = warn logTxt "persistCode()", codeHash=acc.statement.codeHash, error=($$rc.error) -proc persistStorage(acc: AccountRef, ac: AccountsLedgerRef, clearCache: bool) = +proc persistStorage(acc: AccountRef, ac: AccountsLedgerRef) = if acc.overlayStorage.len == 0: # TODO: remove the storage too if we figure out # how to create 'virtual' storage room for each account return - if not clearCache and acc.originalStorage.isNil: + if acc.originalStorage.isNil: acc.originalStorage = newTable[UInt256, UInt256]() # Make sure that there is an account column on the database. This is needed @@ -352,15 +362,13 @@ proc persistStorage(acc: AccountRef, ac: AccountsLedgerRef, clearCache: bool) = if rc.isErr: warn logTxt "persistStorage()", slot, error=($$rc.error) - if not clearCache: - # if we preserve cache, move the overlayStorage - # to originalStorage, related to EIP2200, EIP1283 - for slot, value in acc.overlayStorage: - if value > 0: - acc.originalStorage[slot] = value - else: - acc.originalStorage.del(slot) - acc.overlayStorage.clear() + # move the overlayStorage to originalStorage, related to EIP2200, EIP1283 + for slot, value in acc.overlayStorage: + if value > 0: + acc.originalStorage[slot] = value + else: + acc.originalStorage.del(slot) + acc.overlayStorage.clear() # Changing the storage trie might also change the `storage` descriptor when # the trie changes from empty to exixting or v.v. @@ -378,12 +386,14 @@ proc makeDirty(ac: AccountsLedgerRef, address: EthAddress, cloneStorage = true): if address in ac.savePoint.cache: # it's already in latest savepoint result.flags.incl Dirty + ac.savePoint.dirty[address] = result return # put a copy into latest savepoint result = result.clone(cloneStorage) result.flags.incl Dirty ac.savePoint.cache[address] = result + ac.savePoint.dirty[address] = result proc getCodeHash*(ac: AccountsLedgerRef, address: EthAddress): Hash256 = let acc = ac.getAccount(address, false) @@ -400,24 +410,33 @@ proc getNonce*(ac: AccountsLedgerRef, address: EthAddress): AccountNonce = if acc.isNil: emptyEthAccount.nonce else: acc.statement.nonce +proc getCode(acc: AccountRef, kvt: CoreDxKvtRef): lent seq[byte] = + if CodeLoaded notin acc.flags and CodeChanged notin acc.flags: + if acc.statement.codeHash != EMPTY_CODE_HASH: + var rc = kvt.get(contractHashKey(acc.statement.codeHash).toOpenArray) + if rc.isErr: + warn logTxt "getCode()", codeHash=acc.statement.codeHash, error=($$rc.error) + else: + acc.code = move(rc.value) + acc.flags.incl CodeLoaded + else: + acc.flags.incl CodeLoaded # avoid hash comparisons + + acc.code + proc getCode*(ac: AccountsLedgerRef, address: EthAddress): seq[byte] = let acc = ac.getAccount(address, false) if acc.isNil: return - if CodeLoaded in acc.flags or CodeChanged in acc.flags: - result = acc.code - elif acc.statement.codeHash != EMPTY_CODE_HASH: - let rc = ac.kvt.get(contractHashKey(acc.statement.codeHash).toOpenArray) - if rc.isErr: - warn logTxt "getCode()", codeHash=acc.statement.codeHash, error=($$rc.error) - else: - acc.code = rc.value - acc.flags.incl CodeLoaded - result = acc.code + acc.getCode(ac.kvt) proc getCodeSize*(ac: AccountsLedgerRef, address: EthAddress): int = - ac.getCode(address).len + let acc = ac.getAccount(address, false) + if acc.isNil: + return + + acc.getCode(ac.kvt).len proc getCommittedStorage*(ac: AccountsLedgerRef, address: EthAddress, slot: UInt256): UInt256 = let acc = ac.getAccount(address, false) @@ -436,7 +455,7 @@ proc contractCollision*(ac: AccountsLedgerRef, address: EthAddress): bool = if acc.isNil: return acc.statement.nonce != 0 or - acc.statement.codeHash != EMPTY_SHA3 or + acc.statement.codeHash != EMPTY_CODE_HASH or acc.statement.storage.stateOrVoid != EMPTY_ROOT_HASH proc accountExists*(ac: AccountsLedgerRef, address: EthAddress): bool = @@ -534,7 +553,8 @@ proc deleteAccount*(ac: AccountsLedgerRef, address: EthAddress) = # make sure all savepoints already committed doAssert(ac.savePoint.parentSavepoint.isNil) let acc = ac.getAccount(address) - acc.kill(address) + ac.savePoint.dirty[address] = acc + acc.kill() proc selfDestruct*(ac: AccountsLedgerRef, address: EthAddress) = ac.setBalance(address, 0.u256) @@ -572,13 +592,16 @@ proc deleteEmptyAccount(ac: AccountsLedgerRef, address: EthAddress) = return if not acc.exists: return - acc.kill(address) + + ac.savePoint.dirty[address] = acc + acc.kill() proc clearEmptyAccounts(ac: AccountsLedgerRef) = - for address, acc in ac.savePoint.cache: + # https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md + for acc in ac.savePoint.dirty.values(): if Touched in acc.flags and acc.isEmpty and acc.exists: - acc.kill(address) + acc.kill() # https://github.com/ethereum/EIPs/issues/716 if ac.ripemdSpecial: @@ -586,11 +609,9 @@ proc clearEmptyAccounts(ac: AccountsLedgerRef) = ac.ripemdSpecial = false proc persist*(ac: AccountsLedgerRef, - clearEmptyAccount: bool = false, - clearCache: bool = true) = + clearEmptyAccount: bool = false) = # make sure all savepoint already committed doAssert(ac.savePoint.parentSavepoint.isNil) - var cleanAccounts = initHashSet[EthAddress]() if clearEmptyAccount: ac.clearEmptyAccounts() @@ -598,8 +619,7 @@ proc persist*(ac: AccountsLedgerRef, for address in ac.savePoint.selfDestruct: ac.deleteAccount(address) - for address, acc in ac.savePoint.cache: - assert address == acc.statement.address # debugging only + for acc in ac.savePoint.dirty.values(): # This is a hotspot in block processing case acc.persistMode() of Update: if CodeChanged in acc.flags: @@ -607,25 +627,19 @@ proc persist*(ac: AccountsLedgerRef, if StorageChanged in acc.flags: # storageRoot must be updated first # before persisting account into merkle trie - acc.persistStorage(ac, clearCache) + acc.persistStorage(ac) ac.ledger.merge(acc.statement) of Remove: - ac.ledger.delete address - if not clearCache: - cleanAccounts.incl address + ac.ledger.delete acc.statement.address + ac.savePoint.cache.del acc.statement.address of DoNothing: # dead man tell no tales # remove touched dead account from cache - if not clearCache and Alive notin acc.flags: - cleanAccounts.incl address + if Alive notin acc.flags: + ac.savePoint.cache.del acc.statement.address acc.flags = acc.flags - resetFlags - - if clearCache: - ac.savePoint.cache.clear() - else: - for x in cleanAccounts: - ac.savePoint.cache.del x + ac.savePoint.dirty.clear() ac.savePoint.selfDestruct.clear() diff --git a/nimbus/db/ledger/base.nim b/nimbus/db/ledger/base.nim index c56d47234..ef2fa8ca1 100644 --- a/nimbus/db/ledger/base.nim +++ b/nimbus/db/ledger/base.nim @@ -268,10 +268,10 @@ proc makeMultiKeys*(ldg: LedgerRef): MultiKeysRef = result = ldg.ac.makeMultiKeys() ldg.ifTrackApi: debug apiTxt, api, elapsed -proc persist*(ldg: LedgerRef, clearEmptyAccount = false, clearCache = true) = +proc persist*(ldg: LedgerRef, clearEmptyAccount = false) = ldg.beginTrackApi LdgPersistFn - ldg.ac.persist(clearEmptyAccount, clearCache) - ldg.ifTrackApi: debug apiTxt, api, elapsed, clearEmptyAccount, clearCache + ldg.ac.persist(clearEmptyAccount) + ldg.ifTrackApi: debug apiTxt, api, elapsed, clearEmptyAccount proc ripemdSpecial*(ldg: LedgerRef) = ldg.beginTrackApi LdgRipemdSpecialFn diff --git a/nimbus/db/state_db/base.nim b/nimbus/db/state_db/base.nim index 5d6c8e3f6..b96003efe 100644 --- a/nimbus/db/state_db/base.nim +++ b/nimbus/db/state_db/base.nim @@ -223,7 +223,7 @@ proc getCode*(db: AccountStateDB, address: EthAddress): seq[byte] = proc contractCollision*(db: AccountStateDB, address: EthAddress): bool {.inline.} = db.getNonce(address) != 0 or - db.getCodeHash(address) != EMPTY_SHA3 or + db.getCodeHash(address) != EMPTY_CODE_HASH or db.getStorageRoot(address) != EMPTY_ROOT_HASH proc dumpAccount*(db: AccountStateDB, addressS: string): string = @@ -238,19 +238,19 @@ proc isEmptyAccount*(db: AccountStateDB, address: EthAddress): bool = assert(recordFound.len > 0) let account = rlp.decode(recordFound, Account) - result = account.codeHash == EMPTY_SHA3 and + account.nonce == 0 and account.balance.isZero and - account.nonce == 0 + account.codeHash == EMPTY_CODE_HASH proc isDeadAccount*(db: AccountStateDB, address: EthAddress): bool = let recordFound = db.trie.getAccountBytes(address) if recordFound.len > 0: let account = rlp.decode(recordFound, Account) - result = account.codeHash == EMPTY_SHA3 and + account.nonce == 0 and account.balance.isZero and - account.nonce == 0 + account.codeHash == EMPTY_CODE_HASH else: - result = true + true proc removeEmptyRlpNode(branch: var seq[MptNodeRlpBytes]) = if branch.len() == 1 and branch[0] == emptyRlp: diff --git a/nimbus/evm/types.nim b/nimbus/evm/types.nim index af492eef0..5e3cbfef5 100644 --- a/nimbus/evm/types.nim +++ b/nimbus/evm/types.nim @@ -39,7 +39,6 @@ type VMFlag* = enum ExecutionOK GenerateWitness - ClearCache BlockContext* = object timestamp* : EthTime diff --git a/nimbus/sync/protocol/snap/snap_types.nim b/nimbus/sync/protocol/snap/snap_types.nim index 149f32835..d4023aa48 100644 --- a/nimbus/sync/protocol/snap/snap_types.nim +++ b/nimbus/sync/protocol/snap/snap_types.nim @@ -99,12 +99,12 @@ proc snapRead*( if rlp.blobLen != 0 or not rlp.isBlob: result.codeHash = rlp.read(typeof(result.codeHash)) when strict: - if result.codeHash == EMPTY_SHA3: + if result.codeHash == EMPTY_CODE_HASH: raise newException(RlpTypeMismatch, "EMPTY_SHA3 not encoded as empty string in Snap protocol") else: rlp.skipElem() - result.codeHash = EMPTY_SHA3 + result.codeHash = EMPTY_CODE_HASH proc snapAppend*( writer: var RlpWriter; @@ -121,7 +121,7 @@ proc snapAppend*( writer.append("") else: writer.append(account.storageRoot) - if account.codeHash == EMPTY_SHA3: + if account.codeHash == EMPTY_CODE_HASH: writer.append("") else: writer.append(account.codeHash) diff --git a/tests/test_accounts_cache.nim b/tests/test_accounts_cache.nim index 31b2ac3a3..abec620cc 100644 --- a/tests/test_accounts_cache.nim +++ b/tests/test_accounts_cache.nim @@ -135,7 +135,7 @@ proc runTrial2ok(vmState: BaseVMState; inx: int) = vmState.stateDB.modBalance(eAddr) vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() proc runTrial3(vmState: BaseVMState; inx: int; rollback: bool) = @@ -146,7 +146,7 @@ proc runTrial3(vmState: BaseVMState; inx: int; rollback: bool) = let accTx = vmState.stateDB.beginSavepoint vmState.stateDB.modBalance(eAddr) vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() block: let accTx = vmState.stateDB.beginSavepoint @@ -157,13 +157,13 @@ proc runTrial3(vmState: BaseVMState; inx: int; rollback: bool) = break vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() block: let accTx = vmState.stateDB.beginSavepoint vmState.stateDB.modBalance(eAddr) vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() proc runTrial3crash(vmState: BaseVMState; inx: int; noisy = false) = @@ -177,7 +177,7 @@ proc runTrial3crash(vmState: BaseVMState; inx: int; noisy = false) = let accTx = vmState.stateDB.beginSavepoint vmState.stateDB.modBalance(eAddr) vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() block: let accTx = vmState.stateDB.beginSavepoint @@ -216,7 +216,7 @@ proc runTrial3crash(vmState: BaseVMState; inx: int; noisy = false) = vmState.stateDB.commit(accTx) try: - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() except AssertionDefect as e: if noisy: let msg = e.msg.rsplit($DirSep,1)[^1] @@ -224,7 +224,7 @@ proc runTrial3crash(vmState: BaseVMState; inx: int; noisy = false) = dbTx.dispose() raise e - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() dbTx.commit() @@ -240,13 +240,13 @@ proc runTrial4(vmState: BaseVMState; inx: int; rollback: bool) = let accTx = vmState.stateDB.beginSavepoint vmState.stateDB.modBalance(eAddr) vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() block: let accTx = vmState.stateDB.beginSavepoint vmState.stateDB.modBalance(eAddr) vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() block: let accTx = vmState.stateDB.beginSavepoint @@ -257,7 +257,7 @@ proc runTrial4(vmState: BaseVMState; inx: int; rollback: bool) = break vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() # There must be no dbTx.rollback() here unless `vmState.stateDB` is # discarded and/or re-initialised. @@ -270,7 +270,7 @@ proc runTrial4(vmState: BaseVMState; inx: int; rollback: bool) = let accTx = vmState.stateDB.beginSavepoint vmState.stateDB.modBalance(eAddr) vmState.stateDB.commit(accTx) - vmState.stateDB.persist(clearCache = false) + vmState.stateDB.persist() dbTx.commit() diff --git a/tests/test_rpc_experimental_json.nim b/tests/test_rpc_experimental_json.nim index 71c6a6468..a0d96bb80 100644 --- a/tests/test_rpc_experimental_json.nim +++ b/tests/test_rpc_experimental_json.nim @@ -116,9 +116,9 @@ proc checkAndValidateWitnessAgainstProofs( check stateDB.getBalance(address) == balance check stateDB.getNonce(address) == nonce - if codeHash == ZERO_HASH256 or codeHash == EMPTY_SHA3: + if codeHash == ZERO_HASH256 or codeHash == EMPTY_CODE_HASH: check stateDB.getCode(address).len() == 0 - check stateDB.getCodeHash(address) == EMPTY_SHA3 + check stateDB.getCodeHash(address) == EMPTY_CODE_HASH else: check stateDB.getCodeHash(address) == codeHash diff --git a/tests/test_rpc_getproofs_track_state_changes.nim b/tests/test_rpc_getproofs_track_state_changes.nim index 2988467fc..a8991338a 100644 --- a/tests/test_rpc_getproofs_track_state_changes.nim +++ b/tests/test_rpc_getproofs_track_state_changes.nim @@ -103,11 +103,11 @@ proc updateStateUsingProofsAndCheckStateRoot( stateDB.setCode(address, @[]) stateDB.clearStorage(address) stateDB.deleteAccount(address) - elif (balance == 0 and nonce == 0 and codeHash == EMPTY_SHA3 and storageHash == EMPTY_ROOT_HASH): + elif (balance == 0 and nonce == 0 and codeHash == EMPTY_CODE_HASH and storageHash == EMPTY_ROOT_HASH): # Account exists but is empty: # The account was deleted due to a self destruct or the storage was cleared/set to zero # and the bytecode is empty. - # The RPC API correctly returns codeHash == EMPTY_SHA3 and storageHash == EMPTY_ROOT_HASH + # The RPC API correctly returns codeHash == EMPTY_CODE_HASH and storageHash == EMPTY_ROOT_HASH # in this scenario which is the same behavior implemented by geth. stateDB.setCode(address, @[]) stateDB.clearStorage(address) @@ -123,9 +123,9 @@ proc updateStateUsingProofsAndCheckStateRoot( check stateDB.getBalance(address) == balance check stateDB.getNonce(address) == nonce - if codeHash == ZERO_HASH256 or codeHash == EMPTY_SHA3: + if codeHash == ZERO_HASH256 or codeHash == EMPTY_CODE_HASH: check stateDB.getCode(address).len() == 0 - check stateDB.getCodeHash(address) == EMPTY_SHA3 + check stateDB.getCodeHash(address) == EMPTY_CODE_HASH else: check stateDB.getCodeHash(address) == codeHash diff --git a/tools/common/state_clearing.nim b/tools/common/state_clearing.nim index 771e925fa..3e7bc58c1 100644 --- a/tools/common/state_clearing.nim +++ b/tools/common/state_clearing.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2023 Status Research & Development GmbH +# Copyright (c) 2023-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -38,6 +38,4 @@ proc coinbaseStateClearing*(vmState: BaseVMState, # do not clear cache, we need the cache when constructing # post state - db.persist( - clearEmptyAccount = fork >= FkSpurious, - clearCache = false) + db.persist(clearEmptyAccount = fork >= FkSpurious) diff --git a/tools/evmstate/evmstate.nim b/tools/evmstate/evmstate.nim index 7b2229d80..ad7dfb4ad 100644 --- a/tools/evmstate/evmstate.nim +++ b/tools/evmstate/evmstate.nim @@ -157,7 +157,7 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR vmState.mutateStateDB: setupStateDB(pre, db) - db.persist(clearEmptyAccount = false, clearCache = false) # settle accounts storage + db.persist(clearEmptyAccount = false) # settle accounts storage defer: ctx.verifyResult(vmState) diff --git a/tools/t8n/transition.nim b/tools/t8n/transition.nim index 667c06e5a..81aa91f5a 100644 --- a/tools/t8n/transition.nim +++ b/tools/t8n/transition.nim @@ -481,7 +481,7 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) = vmState.mutateStateDB: db.setupAlloc(ctx.alloc) - db.persist(clearEmptyAccount = false, clearCache = false) + db.persist(clearEmptyAccount = false) let res = exec(ctx, vmState, conf.stateReward, header, conf)