From 02816ce06fbbcc0b09f7cebe93091bb5bd9ef52a Mon Sep 17 00:00:00 2001 From: Derek Cofausper <256792747+decofe@users.noreply.github.com> Date: Tue, 3 Mar 2026 22:56:28 -0800 Subject: [PATCH] refactor(rpc): use native PrecompilesMap::move_precompiles in simulate (#22761) Co-authored-by: Matthias Seitz <19890894+mattsse@users.noreply.github.com> --- crates/rpc/rpc-eth-types/src/simulate.rs | 63 ++---------------------- 1 file changed, 5 insertions(+), 58 deletions(-) diff --git a/crates/rpc/rpc-eth-types/src/simulate.rs b/crates/rpc/rpc-eth-types/src/simulate.rs index 87c175e470..269abce89f 100644 --- a/crates/rpc/rpc-eth-types/src/simulate.rs +++ b/crates/rpc/rpc-eth-types/src/simulate.rs @@ -97,12 +97,6 @@ pub enum EthSimulateError { /// Max init code size exceeded. #[error("max initcode size exceeded")] MaxInitCodeSizeExceeded, - /// `MovePrecompileToAddress` referenced itself in replacement. - #[error("MovePrecompileToAddress referenced itself")] - PrecompileSelfReference, - /// Multiple `MovePrecompileToAddress` referencing the same address. - #[error("Multiple MovePrecompileToAddress referencing the same address")] - PrecompileDuplicateAddress, /// Attempted to move a non-precompile address. #[error("account {0} is not a precompile")] NotAPrecompile(Address), @@ -120,8 +114,6 @@ impl EthSimulateError { Self::BlockGasLimitExceeded => -38015, Self::BlockNumberInvalid { .. } => -38020, Self::BlockTimestampInvalid { .. } => -38021, - Self::PrecompileSelfReference => -38022, - Self::PrecompileDuplicateAddress => -38023, Self::SenderNotEOA => -38024, Self::MaxInitCodeSizeExceeded => -38025, Self::GasLimitReached => -38026, @@ -141,29 +133,10 @@ impl ToRpcError for EthSimulateError { /// This function processes `movePrecompileToAddress` entries from the state overrides and /// moves precompiles from their original addresses to new addresses. The original address /// is cleared (precompile removed) and the precompile is installed at the destination address. -/// -/// # Validation -/// -/// - The source address must be a precompile (exists in the precompiles map) -/// - Moving multiple precompiles to the same destination is allowed -/// - Self-references (moving to the same address) are not explicitly forbidden here since that -/// would be a no-op -/// -/// # Arguments -/// -/// * `state_overrides` - The state overrides containing potential `movePrecompileToAddress` entries -/// * `precompiles` - Mutable reference to the EVM's precompiles map -/// -/// # Returns -/// -/// Returns `Ok(())` on success, or an `EthSimulateError::NotAPrecompile` if a source address -/// is not a precompile. pub fn apply_precompile_overrides( state_overrides: &StateOverride, precompiles: &mut PrecompilesMap, ) -> Result<(), EthSimulateError> { - use alloy_evm::precompiles::DynPrecompile; - let moves: Vec<_> = state_overrides .iter() .filter_map(|(source, account_override)| { @@ -171,37 +144,11 @@ pub fn apply_precompile_overrides( }) .collect(); - if moves.is_empty() { - return Ok(()); - } - - for (source, _) in &moves { - if precompiles.get(source).is_none() { - return Err(EthSimulateError::NotAPrecompile(*source)); - } - } - - let mut extracted: Vec<(Address, Address, DynPrecompile)> = Vec::with_capacity(moves.len()); - - for (source, dest) in moves { - if source == dest { - continue; - } - - let mut found_precompile: Option = None; - precompiles.apply_precompile(&source, |existing| { - found_precompile = existing; - None - }); - - if let Some(precompile) = found_precompile { - extracted.push((source, dest, precompile)); - } - } - - for (_, dest, precompile) in extracted { - precompiles.apply_precompile(&dest, |_| Some(precompile)); - } + precompiles.move_precompiles(moves).map_err( + |alloy_evm::precompiles::MovePrecompileError::NotAPrecompile(addr)| { + EthSimulateError::NotAPrecompile(addr) + }, + )?; Ok(()) }