Skip to content

Commit

Permalink
feat: support eip-7610
Browse files Browse the repository at this point in the history
  • Loading branch information
hai-rise committed Oct 19, 2024
1 parent 4e28b87 commit f133e3d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
21 changes: 21 additions & 0 deletions crates/primitives/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ pub trait Database {
/// Get account code by its hash.
fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error>;

/// Get if the account already has storage (to support EIP-7610)
fn has_storage(&mut self, _address: Address) -> Result<bool, Self::Error> {
// This is a good default value (no storage for collision) as only a hash collision
// could trigger EIP-7610. A proper implementation can check the account's storage
// hash, etc.
Ok(false)
}

/// Get storage value of address at index.
fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error>;

Expand Down Expand Up @@ -49,6 +57,14 @@ pub trait DatabaseRef {
/// Get account code by its hash.
fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error>;

/// Get if the account already has storage (to support EIP-7610)
fn has_storage_ref(&self, _address: Address) -> Result<bool, Self::Error> {
// This is a good default value (no storage for collision) as only a hash collision
// could trigger EIP-7610. A proper implementation can check the account's storage
// hash, etc.
Ok(false)
}

/// Get storage value of address at index.
fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error>;

Expand Down Expand Up @@ -80,6 +96,11 @@ impl<T: DatabaseRef> Database for WrapDatabaseRef<T> {
self.0.code_by_hash_ref(code_hash)
}

#[inline]
fn has_storage(&mut self, address: Address) -> Result<bool, Self::Error> {
self.0.has_storage_ref(address)
}

#[inline]
fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
self.0.storage_ref(address, index)
Expand Down
14 changes: 14 additions & 0 deletions crates/revm/src/context/evm_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,17 @@ impl<DB: Database> EvmContext<DB> {
// warm load account.
self.load_account(created_address)?;

// This only check with the pre-execution state. Can storage be cleared after load?
let address_has_storage = self
.db
.has_storage(created_address)
.map_err(EVMError::Database)?;

// create account, transfer funds and make the journal checkpoint.
let checkpoint = match self.journaled_state.create_account_checkpoint(
inputs.caller,
created_address,
address_has_storage,
inputs.value,
spec_id,
) {
Expand Down Expand Up @@ -432,10 +439,17 @@ impl<DB: Database> EvmContext<DB> {
// Load account so it needs to be marked as warm for access list.
self.load_account(created_address)?;

// This only check with the pre-execution state. Can storage be cleared after load?
let address_has_storage = self
.db
.has_storage(created_address)
.map_err(EVMError::Database)?;

// create account, transfer funds and make the journal checkpoint.
let checkpoint = match self.journaled_state.create_account_checkpoint(
inputs.caller,
created_address,
address_has_storage,
inputs.value,
spec_id,
) {
Expand Down
10 changes: 6 additions & 4 deletions crates/revm/src/journaled_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ impl JournaledState {
&mut self,
caller: Address,
address: Address,
address_has_storage: bool,
balance: U256,
spec_id: SpecId,
) -> Result<JournalCheckpoint, InstructionResult> {
Expand All @@ -271,10 +272,11 @@ impl JournaledState {
let last_journal = self.journal.last_mut().unwrap();

// New account can be created if:
// Bytecode is not empty.
// Nonce is not zero
// Account is not precompile.
if account.info.code_hash != KECCAK_EMPTY || account.info.nonce != 0 {
// Bytecode is empty.
// Nonce is zero.
// Storage is empty.
if account.info.code_hash != KECCAK_EMPTY || account.info.nonce != 0 || address_has_storage
{
self.checkpoint_revert(checkpoint);
return Err(InstructionResult::CreateCollision);
}
Expand Down

0 comments on commit f133e3d

Please sign in to comment.