Skip to content

Commit 0d08a2f

Browse files
authored
feat(levm): also check cache when querying if account exists (#2489)
**Motivation** Fixes 14 state ef-tests that rely on newly created accounts being treated as existing. **Description** Instead of checking directly on the database, the cache is also queried when determining whether an account exists.
1 parent 793227a commit 0d08a2f

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

crates/vm/levm/src/opcode_handlers/system.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl<'a> VM<'a> {
6464
current_memory_size,
6565
address_was_cold,
6666
account_info.is_empty(),
67-
self.db.store.account_exists(callee),
67+
account_exists(self.db, callee),
6868
value_to_transfer,
6969
gas,
7070
gas_left,
@@ -506,7 +506,7 @@ impl<'a> VM<'a> {
506506
let account_is_empty = if self.env.config.fork >= Fork::SpuriousDragon {
507507
target_account_info.is_empty()
508508
} else {
509-
!self.db.store.account_exists(target_address)
509+
!account_exists(self.db, target_address)
510510
};
511511
current_call_frame.increase_consumed_gas(gas_cost::selfdestruct(
512512
target_account_is_cold,
@@ -560,6 +560,11 @@ impl<'a> VM<'a> {
560560
.selfdestruct_set
561561
.insert(current_call_frame.to);
562562
}
563+
if account_exists(self.db, target_address) && target_account_info.is_empty() {
564+
self.accrued_substate
565+
.touched_accounts
566+
.insert(target_address);
567+
}
563568

564569
Ok(OpcodeResult::Halt)
565570
}

crates/vm/levm/src/utils.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ pub fn eip7702_set_access_code(
544544

545545
// 7. Add PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST gas to the global refund counter if authority exists in the trie.
546546
if cache::is_account_cached(&db.cache, &authority_address)
547-
|| db.store.account_exists(authority_address)
547+
|| account_exists(db, authority_address)
548548
{
549549
let refunded_gas_if_exists = PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST;
550550
refunded_gas = refunded_gas
@@ -718,3 +718,11 @@ pub fn eip7702_get_code(
718718

719719
Ok((true, access_cost, auth_address, authorized_bytecode))
720720
}
721+
722+
/// Checks if a given account exists in the database or cache
723+
pub fn account_exists(db: &mut GeneralizedDatabase, address: Address) -> bool {
724+
match cache::get_account(&db.cache, &address) {
725+
Some(_) => true,
726+
None => db.store.account_exists(address),
727+
}
728+
}

0 commit comments

Comments
 (0)