diff --git a/src/gnosis.rs b/src/gnosis.rs index 97ba9a9..e643ef3 100644 --- a/src/gnosis.rs +++ b/src/gnosis.rs @@ -15,6 +15,7 @@ use reth::{ use reth_chainspec::ChainSpec; use reth_errors::BlockValidationError; use reth_evm::{execute::BlockExecutionError, ConfigureEvm}; +use revm_primitives::{Account, AccountInfo, AccountStatus}; pub const SYSTEM_ADDRESS: Address = address!("fffffffffffffffffffffffffffffffffffffffe"); @@ -184,8 +185,30 @@ where }) })?; - // Clean-up post system tx context - state.remove(&SYSTEM_ADDRESS); + // in gnosis aura, system account needs to be included in the state and not removed (despite EIP-158/161, even if empty) + // here we have a generalized check if system account is in state, or needs to be created + + // keeping this generalized, instead of only in block 1 + // (AccountStatus::Touched | AccountStatus::LoadedAsNotExisting) means the account is not in the state + let should_create = state.get(&SYSTEM_ADDRESS).map_or(true, |system_account| { + // true if account not in state (either None, or Touched | LoadedAsNotExisting) + system_account.status == (AccountStatus::Touched | AccountStatus::LoadedAsNotExisting) + }); + + // this check needs to be there in every call, so instead of making it into a function which is called from post_execution, we can just include it in the rewards function + if should_create { + let account = Account { + info: AccountInfo::default(), + storage: Default::default(), + // we force the account to be created by changing the status + status: AccountStatus::Touched | AccountStatus::Created, + }; + state.insert(SYSTEM_ADDRESS, account); + } else { + // clear the system address account from state transitions, else EIP-158/161 (impl in revm) removes it from state + state.remove(&SYSTEM_ADDRESS); + } + state.remove(&evm.block().coinbase); evm.context.evm.db.commit(state); // re-set the previous env