Skip to main content

anvil/eth/
api.rs

1use super::{
2    backend::mem::{BlockRequest, DatabaseRef, State},
3    sign::build_impersonated,
4};
5use crate::{
6    ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
7    eth::{
8        backend::{
9            self,
10            db::SerializableState,
11            mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
12            notifications::NewBlockNotifications,
13            validate::TransactionValidator,
14        },
15        error::{
16            BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
17        },
18        fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
19        macros::node_info,
20        miner::FixedBlockTimeMiner,
21        pool::{
22            Pool,
23            transactions::{
24                PoolTransaction, TransactionOrder, TransactionPriority, TxMarker, to_marker,
25            },
26        },
27        sign::{self, Signer},
28    },
29    filter::{EthFilter, Filters, LogsFilter},
30    mem::transaction_build,
31};
32use alloy_consensus::{
33    Blob, BlockHeader, Transaction, TrieAccount, TxEip4844Variant, transaction::Recovered,
34};
35use alloy_dyn_abi::TypedData;
36use alloy_eips::{
37    eip2718::Encodable2718,
38    eip7910::{EthConfig, EthForkConfig},
39};
40use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
41use alloy_network::{
42    AnyRpcBlock, AnyRpcTransaction, BlockResponse, Network, ReceiptResponse, TransactionBuilder,
43    TransactionBuilder4844, TransactionResponse, eip2718::Decodable2718,
44};
45use alloy_primitives::{
46    Address, B64, B256, Bytes, TxHash, TxKind, U64, U256,
47    map::{HashMap, HashSet},
48};
49use alloy_rpc_types::{
50    AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
51    EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
52    anvil::{
53        ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
54    },
55    request::TransactionRequest,
56    simulate::{SimulatePayload, SimulatedBlock},
57    state::{AccountOverride, EvmOverrides, StateOverridesBuilder},
58    trace::{
59        filter::TraceFilter,
60        geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
61        parity::{LocalizedTransactionTrace, TraceResultsWithTransactionHash, TraceType},
62    },
63    txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
64};
65use alloy_rpc_types_eth::FillTransaction;
66use alloy_serde::WithOtherFields;
67use alloy_sol_types::{SolCall, SolValue, sol};
68use alloy_transport::TransportErrorKind;
69use anvil_core::{
70    eth::{
71        EthRequest,
72        block::BlockInfo,
73        transaction::{MaybeImpersonatedTransaction, PendingTransaction},
74    },
75    types::{ReorgOptions, TransactionData},
76};
77use anvil_rpc::{error::RpcError, response::ResponseResult};
78use foundry_common::provider::ProviderBuilder;
79use foundry_evm::decode::RevertDecoder;
80use foundry_primitives::{
81    FoundryNetwork, FoundryReceiptEnvelope, FoundryTransactionRequest, FoundryTxEnvelope,
82    FoundryTxReceipt, FoundryTxType, FoundryTypedTx,
83};
84use futures::{
85    StreamExt, TryFutureExt,
86    channel::{mpsc::Receiver, oneshot},
87};
88use parking_lot::RwLock;
89use revm::{
90    context::BlockEnv,
91    context_interface::{block::BlobExcessGasAndPrice, result::Output},
92    database::CacheDB,
93    interpreter::{InstructionResult, return_ok, return_revert},
94    primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
95};
96use std::{sync::Arc, time::Duration};
97use tokio::{
98    sync::mpsc::{UnboundedReceiver, unbounded_channel},
99    try_join,
100};
101
102/// The client version: `anvil/v{major}.{minor}.{patch}`
103pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
104
105/// The entry point for executing eth api RPC call - The Eth RPC interface.
106///
107/// This type is cheap to clone and can be used concurrently
108pub struct EthApi<N: Network> {
109    /// The transaction pool
110    pool: Arc<Pool<N::TxEnvelope>>,
111    /// Holds all blockchain related data
112    /// In-Memory only for now
113    pub backend: Arc<backend::mem::Backend<N>>,
114    /// Whether this node is mining
115    is_mining: bool,
116    /// available signers
117    signers: Arc<Vec<Box<dyn Signer<N>>>>,
118    /// data required for `eth_feeHistory`
119    fee_history_cache: FeeHistoryCache,
120    /// max number of items kept in fee cache
121    fee_history_limit: u64,
122    /// access to the actual miner
123    ///
124    /// This access is required in order to adjust miner settings based on requests received from
125    /// custom RPC endpoints
126    miner: Miner<N::TxEnvelope>,
127    /// allows to enabled/disable logging
128    logger: LoggingManager,
129    /// Tracks all active filters
130    filters: Filters<N>,
131    /// How transactions are ordered in the pool
132    transaction_order: Arc<RwLock<TransactionOrder>>,
133    /// Whether we're listening for RPC calls
134    net_listening: bool,
135    /// The instance ID. Changes on every reset.
136    instance_id: Arc<RwLock<B256>>,
137}
138
139impl<N: Network> Clone for EthApi<N> {
140    fn clone(&self) -> Self {
141        Self {
142            pool: self.pool.clone(),
143            backend: self.backend.clone(),
144            is_mining: self.is_mining,
145            signers: self.signers.clone(),
146            fee_history_cache: self.fee_history_cache.clone(),
147            fee_history_limit: self.fee_history_limit,
148            miner: self.miner.clone(),
149            logger: self.logger.clone(),
150            filters: self.filters.clone(),
151            transaction_order: self.transaction_order.clone(),
152            net_listening: self.net_listening,
153            instance_id: self.instance_id.clone(),
154        }
155    }
156}
157
158// == impl EthApi<N: Network> generic methods ==
159
160impl<N: Network> EthApi<N> {
161    /// Creates a new instance
162    #[expect(clippy::too_many_arguments)]
163    pub fn new(
164        pool: Arc<Pool<N::TxEnvelope>>,
165        backend: Arc<backend::mem::Backend<N>>,
166        signers: Arc<Vec<Box<dyn Signer<N>>>>,
167        fee_history_cache: FeeHistoryCache,
168        fee_history_limit: u64,
169        miner: Miner<N::TxEnvelope>,
170        logger: LoggingManager,
171        filters: Filters<N>,
172        transactions_order: TransactionOrder,
173    ) -> Self {
174        Self {
175            pool,
176            backend,
177            is_mining: true,
178            signers,
179            fee_history_cache,
180            fee_history_limit,
181            miner,
182            logger,
183            filters,
184            net_listening: true,
185            transaction_order: Arc::new(RwLock::new(transactions_order)),
186            instance_id: Arc::new(RwLock::new(B256::random())),
187        }
188    }
189
190    /// Returns the current gas price
191    pub fn gas_price(&self) -> u128 {
192        if self.backend.is_eip1559() {
193            if self.backend.is_min_priority_fee_enforced() {
194                (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
195            } else {
196                self.backend.base_fee() as u128
197            }
198        } else {
199            self.backend.fees().raw_gas_price()
200        }
201    }
202
203    /// Returns the suggested fee cap.
204    ///
205    /// Returns at least [MIN_SUGGESTED_PRIORITY_FEE]
206    fn lowest_suggestion_tip(&self) -> u128 {
207        let block_number = self.backend.best_number();
208        let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
209
210        match latest_cached_block {
211            Some(block) => block.rewards.iter().copied().min(),
212            None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
213        }
214        .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
215        .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
216    }
217
218    /// Returns true if auto mining is enabled, and false.
219    ///
220    /// Handler for ETH RPC call: `anvil_getAutomine`
221    pub fn anvil_get_auto_mine(&self) -> Result<bool> {
222        node_info!("anvil_getAutomine");
223        Ok(self.miner.is_auto_mine())
224    }
225
226    /// Returns the value of mining interval, if set.
227    ///
228    /// Handler for ETH RPC call: `anvil_getIntervalMining`.
229    pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
230        node_info!("anvil_getIntervalMining");
231        Ok(self.miner.get_interval())
232    }
233
234    /// Enables or disables, based on the single boolean argument, the automatic mining of new
235    /// blocks with each new transaction submitted to the network.
236    ///
237    /// Handler for ETH RPC call: `evm_setAutomine`
238    pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
239        node_info!("evm_setAutomine");
240        if self.miner.is_auto_mine() {
241            if enable_automine {
242                return Ok(());
243            }
244            self.miner.set_mining_mode(MiningMode::None);
245        } else if enable_automine {
246            let listener = self.pool.add_ready_listener();
247            let mode = MiningMode::instant(1_000, listener);
248            self.miner.set_mining_mode(mode);
249        }
250        Ok(())
251    }
252
253    /// Sets the mining behavior to interval with the given interval (seconds)
254    ///
255    /// Handler for ETH RPC call: `evm_setIntervalMining`
256    pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
257        node_info!("evm_setIntervalMining");
258        let mining_mode = if secs == 0 {
259            MiningMode::None
260        } else {
261            let block_time = Duration::from_secs(secs);
262
263            // This ensures that memory limits are stricter in interval-mine mode
264            self.backend.update_interval_mine_block_time(block_time);
265
266            MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
267        };
268        self.miner.set_mining_mode(mining_mode);
269        Ok(())
270    }
271
272    /// Removes transactions from the pool
273    ///
274    /// Handler for RPC call: `anvil_dropTransaction`
275    pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
276        node_info!("anvil_dropTransaction");
277        Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
278    }
279
280    /// Removes all transactions from the pool
281    ///
282    /// Handler for RPC call: `anvil_dropAllTransactions`
283    pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
284        node_info!("anvil_dropAllTransactions");
285        self.pool.clear();
286        Ok(())
287    }
288
289    pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
290        node_info!("anvil_setChainId");
291        self.backend.set_chain_id(chain_id);
292        Ok(())
293    }
294
295    /// Modifies the balance of an account.
296    ///
297    /// Handler for RPC call: `anvil_setBalance`
298    pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
299        node_info!("anvil_setBalance");
300        self.backend.set_balance(address, balance).await?;
301        Ok(())
302    }
303
304    /// Sets the code of a contract.
305    ///
306    /// Handler for RPC call: `anvil_setCode`
307    pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
308        node_info!("anvil_setCode");
309        self.backend.set_code(address, code).await?;
310        Ok(())
311    }
312
313    /// Sets the nonce of an address.
314    ///
315    /// Handler for RPC call: `anvil_setNonce`
316    pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
317        node_info!("anvil_setNonce");
318        self.backend.set_nonce(address, nonce).await?;
319        Ok(())
320    }
321
322    /// Writes a single slot of the account's storage.
323    ///
324    /// Handler for RPC call: `anvil_setStorageAt`
325    pub async fn anvil_set_storage_at(
326        &self,
327        address: Address,
328        slot: U256,
329        val: B256,
330    ) -> Result<bool> {
331        node_info!("anvil_setStorageAt");
332        self.backend.set_storage_at(address, slot, val).await?;
333        Ok(true)
334    }
335
336    /// Enable or disable logging.
337    ///
338    /// Handler for RPC call: `anvil_setLoggingEnabled`
339    pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
340        node_info!("anvil_setLoggingEnabled");
341        self.logger.set_enabled(enable);
342        Ok(())
343    }
344
345    /// Set the minimum gas price for the node.
346    ///
347    /// Handler for RPC call: `anvil_setMinGasPrice`
348    pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
349        node_info!("anvil_setMinGasPrice");
350        if self.backend.is_eip1559() {
351            return Err(RpcError::invalid_params(
352                "anvil_setMinGasPrice is not supported when EIP-1559 is active",
353            )
354            .into());
355        }
356        self.backend.set_gas_price(gas.to());
357        Ok(())
358    }
359
360    /// Sets the base fee of the next block.
361    ///
362    /// Handler for RPC call: `anvil_setNextBlockBaseFeePerGas`
363    pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
364        node_info!("anvil_setNextBlockBaseFeePerGas");
365        if !self.backend.is_eip1559() {
366            return Err(RpcError::invalid_params(
367                "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
368            )
369            .into());
370        }
371        self.backend.set_base_fee(basefee.to());
372        Ok(())
373    }
374
375    /// Sets the coinbase address.
376    ///
377    /// Handler for RPC call: `anvil_setCoinbase`
378    pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
379        node_info!("anvil_setCoinbase");
380        self.backend.set_coinbase(address);
381        Ok(())
382    }
383
384    /// Retrieves the Anvil node configuration params.
385    ///
386    /// Handler for RPC call: `anvil_nodeInfo`
387    pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
388        node_info!("anvil_nodeInfo");
389
390        let evm_env = self.backend.evm_env().read();
391        let fork_config = self.backend.get_fork();
392        let tx_order = self.transaction_order.read();
393        let hard_fork = self.backend.hardfork().name();
394
395        Ok(NodeInfo {
396            current_block_number: self.backend.best_number(),
397            current_block_timestamp: evm_env.block_env.timestamp.saturating_to(),
398            current_block_hash: self.backend.best_hash(),
399            hard_fork,
400            transaction_order: match *tx_order {
401                TransactionOrder::Fifo => "fifo".to_string(),
402                TransactionOrder::Fees => "fees".to_string(),
403            },
404            environment: NodeEnvironment {
405                base_fee: self.backend.base_fee() as u128,
406                chain_id: self.backend.chain_id().to::<u64>(),
407                gas_limit: self.backend.gas_limit(),
408                gas_price: self.gas_price(),
409            },
410            fork_config: fork_config
411                .map(|fork| {
412                    let config = fork.config.read();
413
414                    NodeForkConfig {
415                        fork_url: Some(config.eth_rpc_url.clone()),
416                        fork_block_number: Some(config.block_number),
417                        fork_retry_backoff: Some(config.backoff.as_millis()),
418                    }
419                })
420                .unwrap_or_default(),
421            network: self.backend.is_tempo().then(|| "tempo".to_string()),
422        })
423    }
424
425    /// Retrieves metadata about the Anvil instance.
426    ///
427    /// Handler for RPC call: `anvil_metadata`
428    pub async fn anvil_metadata(&self) -> Result<Metadata> {
429        node_info!("anvil_metadata");
430        let fork_config = self.backend.get_fork();
431
432        Ok(Metadata {
433            client_version: CLIENT_VERSION.to_string(),
434            chain_id: self.backend.chain_id().to::<u64>(),
435            latest_block_hash: self.backend.best_hash(),
436            latest_block_number: self.backend.best_number(),
437            instance_id: *self.instance_id.read(),
438            forked_network: fork_config.map(|cfg| ForkedNetwork {
439                chain_id: cfg.chain_id(),
440                fork_block_number: cfg.block_number(),
441                fork_block_hash: cfg.block_hash(),
442            }),
443            snapshots: self.backend.list_state_snapshots(),
444        })
445    }
446
447    pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
448        node_info!("anvil_removePoolTransactions");
449        self.pool.remove_transactions_by_address(address);
450        Ok(())
451    }
452
453    /// Snapshot the state of the blockchain at the current block.
454    ///
455    /// Handler for RPC call: `evm_snapshot`
456    pub async fn evm_snapshot(&self) -> Result<U256> {
457        node_info!("evm_snapshot");
458        Ok(self.backend.create_state_snapshot().await)
459    }
460
461    /// Jump forward in time by the given amount of time, in seconds.
462    ///
463    /// Handler for RPC call: `evm_increaseTime`
464    pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
465        node_info!("evm_increaseTime");
466        Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
467    }
468
469    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block
470    ///
471    /// Handler for RPC call: `evm_setNextBlockTimestamp`
472    pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
473        node_info!("evm_setNextBlockTimestamp");
474        self.backend.time().set_next_block_timestamp(seconds)
475    }
476
477    /// Sets the specific timestamp and returns the number of seconds between the given timestamp
478    /// and the current time.
479    ///
480    /// Handler for RPC call: `evm_setTime`
481    pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
482        node_info!("evm_setTime");
483        let now = self.backend.time().current_call_timestamp();
484        self.backend.time().reset(timestamp);
485
486        // number of seconds between the given timestamp and the current time.
487        let offset = timestamp.saturating_sub(now);
488        Ok(Duration::from_millis(offset).as_secs())
489    }
490
491    /// Set the next block gas limit
492    ///
493    /// Handler for RPC call: `evm_setBlockGasLimit`
494    pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
495        node_info!("evm_setBlockGasLimit");
496        self.backend.set_gas_limit(gas_limit.to());
497        Ok(true)
498    }
499
500    /// Sets an interval for the block timestamp
501    ///
502    /// Handler for RPC call: `anvil_setBlockTimestampInterval`
503    pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
504        node_info!("anvil_setBlockTimestampInterval");
505        self.backend.time().set_block_timestamp_interval(seconds);
506        Ok(())
507    }
508
509    /// Sets an interval for the block timestamp
510    ///
511    /// Handler for RPC call: `anvil_removeBlockTimestampInterval`
512    pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
513        node_info!("anvil_removeBlockTimestampInterval");
514        Ok(self.backend.time().remove_block_timestamp_interval())
515    }
516
517    /// Sets the backend rpc url
518    ///
519    /// Handler for ETH RPC call: `anvil_setRpcUrl`
520    pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
521        node_info!("anvil_setRpcUrl");
522        if let Some(fork) = self.backend.get_fork() {
523            let mut config = fork.config.write();
524            // let interval = config.provider.get_interval();
525            let new_provider = Arc::new(
526                ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
527                    |_| {
528                        TransportErrorKind::custom_str(
529                            format!("Failed to parse invalid url {url}").as_str(),
530                        )
531                    },
532                    // TODO: Add interval
533                )?, // .interval(interval),
534            );
535            config.provider = new_provider;
536            trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
537            config.eth_rpc_url = url;
538        }
539        Ok(())
540    }
541
542    /// Returns the number of transactions currently pending for inclusion in the next block(s), as
543    /// well as the ones that are being scheduled for future execution only.
544    /// Ref: [Here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status)
545    ///
546    /// Handler for ETH RPC call: `txpool_status`
547    pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
548        node_info!("txpool_status");
549        Ok(self.pool.txpool_status())
550    }
551
552    /// Executes the future on a new blocking task.
553    async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
554    where
555        C: FnOnce(Self) -> F,
556        F: Future<Output = Result<R>> + Send + 'static,
557        R: Send + 'static,
558    {
559        let (tx, rx) = oneshot::channel();
560        let this = self.clone();
561        let f = c(this);
562        tokio::task::spawn_blocking(move || {
563            tokio::runtime::Handle::current().block_on(async move {
564                let res = f.await;
565                let _ = tx.send(res);
566            })
567        });
568        rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
569    }
570
571    /// Updates the `TransactionOrder`
572    pub fn set_transaction_order(&self, order: TransactionOrder) {
573        *self.transaction_order.write() = order;
574    }
575
576    /// Returns the chain ID used for transaction
577    pub fn chain_id(&self) -> u64 {
578        self.backend.chain_id().to::<u64>()
579    }
580
581    /// Returns the configured fork, if any.
582    pub fn get_fork(&self) -> Option<ClientFork> {
583        self.backend.get_fork()
584    }
585
586    /// Returns the current instance's ID.
587    pub fn instance_id(&self) -> B256 {
588        *self.instance_id.read()
589    }
590
591    /// Resets the instance ID.
592    pub fn reset_instance_id(&self) {
593        *self.instance_id.write() = B256::random();
594    }
595
596    /// Returns the first signer that can sign for the given address
597    #[expect(clippy::borrowed_box)]
598    pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer<N>>> {
599        self.signers.iter().find(|signer| signer.is_signer_for(address))
600    }
601
602    /// Returns a new listeners for ready transactions
603    pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
604        self.pool.add_ready_listener()
605    }
606
607    /// Returns true if forked
608    pub fn is_fork(&self) -> bool {
609        self.backend.is_fork()
610    }
611
612    /// Returns the current state root
613    pub async fn state_root(&self) -> Option<B256> {
614        self.backend.get_db().read().await.maybe_state_root()
615    }
616
617    /// Returns true if the `addr` is currently impersonated
618    pub fn is_impersonated(&self, addr: Address) -> bool {
619        self.backend.cheats().is_impersonated(addr)
620    }
621
622    /// Returns a new accessor for certain storage elements
623    pub fn storage_info(&self) -> StorageInfo<N> {
624        StorageInfo::new(Arc::clone(&self.backend))
625    }
626
627    /// Handler for RPC call: `anvil_getBlobByHash`
628    pub fn anvil_get_blob_by_versioned_hash(
629        &self,
630        hash: B256,
631    ) -> Result<Option<alloy_consensus::Blob>> {
632        node_info!("anvil_getBlobByHash");
633        Ok(self.backend.get_blob_by_versioned_hash(hash)?)
634    }
635
636    /// Handler for RPC call: `anvil_getBlobsByBlockId`
637    pub fn anvil_get_blobs_by_block_id(
638        &self,
639        block_id: impl Into<BlockId>,
640        versioned_hashes: Vec<B256>,
641    ) -> Result<Option<Vec<Blob>>> {
642        node_info!("anvil_getBlobsByBlockId");
643        Ok(self.backend.get_blobs_by_block_id(block_id, versioned_hashes)?)
644    }
645
646    /// Returns the genesis time for the Beacon chain
647    ///
648    /// Handler for Beacon API call: `GET /eth/v1/beacon/genesis`
649    pub fn anvil_get_genesis_time(&self) -> Result<u64> {
650        node_info!("anvil_getGenesisTime");
651        Ok(self.backend.genesis_time())
652    }
653
654    /// Reset the fork to a fresh forked state, and optionally update the fork config.
655    ///
656    /// If `forking` is `None` then this will disable forking entirely.
657    ///
658    /// Handler for RPC call: `anvil_reset`
659    pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
660        self.reset_instance_id();
661        node_info!("anvil_reset");
662        if let Some(forking) = forking {
663            // if we're resetting the fork we need to reset the instance id
664            self.backend.reset_fork(forking).await?;
665        } else {
666            // Reset to a fresh in-memory state
667            self.backend.reset_to_in_mem().await?;
668        }
669        // Clear pending transactions since they reference the old chain state.
670        self.pool.clear();
671        Ok(())
672    }
673
674    /// Revert the state of the blockchain to a previous snapshot.
675    /// Takes a single parameter, which is the snapshot id to revert to.
676    ///
677    /// Handler for RPC call: `evm_revert`
678    pub async fn evm_revert(&self, id: U256) -> Result<bool> {
679        node_info!("evm_revert");
680        self.backend.revert_state_snapshot(id).await
681    }
682
683    /// Send transactions impersonating specific account and contract addresses.
684    ///
685    /// Handler for ETH RPC call: `anvil_impersonateAccount`
686    pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
687        node_info!("anvil_impersonateAccount");
688        self.backend.impersonate(address);
689        Ok(())
690    }
691
692    /// Stops impersonating an account if previously set with `anvil_impersonateAccount`.
693    ///
694    /// Handler for ETH RPC call: `anvil_stopImpersonatingAccount`
695    pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
696        node_info!("anvil_stopImpersonatingAccount");
697        self.backend.stop_impersonating(address);
698        Ok(())
699    }
700
701    /// If set to true will make every account impersonated
702    ///
703    /// Handler for ETH RPC call: `anvil_autoImpersonateAccount`
704    pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
705        node_info!("anvil_autoImpersonateAccount");
706        self.backend.auto_impersonate_account(enabled);
707        Ok(())
708    }
709
710    /// Registers a new address and signature pair to impersonate.
711    pub async fn anvil_impersonate_signature(
712        &self,
713        signature: Bytes,
714        address: Address,
715    ) -> Result<()> {
716        node_info!("anvil_impersonateSignature");
717        self.backend.impersonate_signature(signature, address).await
718    }
719
720    /// Returns a new block event stream that yields Notifications when a new block was added
721    pub fn new_block_notifications(&self) -> NewBlockNotifications {
722        self.backend.new_block_notifications()
723    }
724
725    /// Returns the current client version.
726    ///
727    /// Handler for ETH RPC call: `web3_clientVersion`
728    pub fn client_version(&self) -> Result<String> {
729        node_info!("web3_clientVersion");
730        Ok(CLIENT_VERSION.to_string())
731    }
732
733    /// Returns Keccak-256 (not the standardized SHA3-256) of the given data.
734    ///
735    /// Handler for ETH RPC call: `web3_sha3`
736    pub fn sha3(&self, bytes: Bytes) -> Result<String> {
737        node_info!("web3_sha3");
738        let hash = alloy_primitives::keccak256(bytes.as_ref());
739        Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
740    }
741
742    /// Returns protocol version encoded as a string (quotes are necessary).
743    ///
744    /// Handler for ETH RPC call: `eth_protocolVersion`
745    pub fn protocol_version(&self) -> Result<u64> {
746        node_info!("eth_protocolVersion");
747        Ok(1)
748    }
749
750    /// Returns the number of hashes per second that the node is mining with.
751    ///
752    /// Handler for ETH RPC call: `eth_hashrate`
753    pub fn hashrate(&self) -> Result<U256> {
754        node_info!("eth_hashrate");
755        Ok(U256::ZERO)
756    }
757
758    /// Returns the client coinbase address.
759    ///
760    /// Handler for ETH RPC call: `eth_coinbase`
761    pub fn author(&self) -> Result<Address> {
762        node_info!("eth_coinbase");
763        Ok(self.backend.coinbase())
764    }
765
766    /// Returns true if client is actively mining new blocks.
767    ///
768    /// Handler for ETH RPC call: `eth_mining`
769    pub fn is_mining(&self) -> Result<bool> {
770        node_info!("eth_mining");
771        Ok(self.is_mining)
772    }
773
774    /// Returns the chain ID used for transaction signing at the
775    /// current best block. None is returned if not
776    /// available.
777    ///
778    /// Handler for ETH RPC call: `eth_chainId`
779    pub fn eth_chain_id(&self) -> Result<Option<U64>> {
780        node_info!("eth_chainId");
781        Ok(Some(self.backend.chain_id().to::<U64>()))
782    }
783
784    /// Returns the same as `chain_id`
785    ///
786    /// Handler for ETH RPC call: `eth_networkId`
787    pub fn network_id(&self) -> Result<Option<String>> {
788        node_info!("eth_networkId");
789        let chain_id = self.backend.chain_id().to::<u64>();
790        Ok(Some(format!("{chain_id}")))
791    }
792
793    /// Returns true if client is actively listening for network connections.
794    ///
795    /// Handler for ETH RPC call: `net_listening`
796    pub fn net_listening(&self) -> Result<bool> {
797        node_info!("net_listening");
798        Ok(self.net_listening)
799    }
800
801    /// Returns the current gas price
802    fn eth_gas_price(&self) -> Result<U256> {
803        node_info!("eth_gasPrice");
804        Ok(U256::from(self.gas_price()))
805    }
806
807    /// Returns the excess blob gas and current blob gas price
808    pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
809        Ok(self.backend.excess_blob_gas_and_price())
810    }
811
812    /// Returns a fee per gas that is an estimate of how much you can pay as a priority fee, or
813    /// 'tip', to get a transaction included in the current block.
814    ///
815    /// Handler for ETH RPC call: `eth_maxPriorityFeePerGas`
816    pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
817        self.max_priority_fee_per_gas()
818    }
819
820    /// Returns the base fee per blob required to send a EIP-4844 tx.
821    ///
822    /// Handler for ETH RPC call: `eth_blobBaseFee`
823    pub fn blob_base_fee(&self) -> Result<U256> {
824        Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
825    }
826
827    /// Returns the block gas limit
828    pub fn gas_limit(&self) -> U256 {
829        U256::from(self.backend.gas_limit())
830    }
831
832    /// Returns the accounts list
833    ///
834    /// Handler for ETH RPC call: `eth_accounts`
835    pub fn accounts(&self) -> Result<Vec<Address>> {
836        node_info!("eth_accounts");
837        let mut unique = HashSet::new();
838        let mut accounts: Vec<Address> = Vec::new();
839        for signer in self.signers.iter() {
840            accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
841        }
842        accounts.extend(
843            self.backend
844                .cheats()
845                .impersonated_accounts()
846                .into_iter()
847                .filter(|acc| unique.insert(*acc)),
848        );
849        Ok(accounts.into_iter().collect())
850    }
851
852    /// Returns the number of most recent block.
853    ///
854    /// Handler for ETH RPC call: `eth_blockNumber`
855    pub fn block_number(&self) -> Result<U256> {
856        node_info!("eth_blockNumber");
857        Ok(U256::from(self.backend.best_number()))
858    }
859
860    /// Returns block with given hash.
861    ///
862    /// Handler for ETH RPC call: `eth_getBlockByHash`
863    pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
864        node_info!("eth_getBlockByHash");
865        self.backend.block_by_hash(hash).await
866    }
867
868    /// Returns a _full_ block with given hash.
869    ///
870    /// Handler for ETH RPC call: `eth_getBlockByHash`
871    pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
872        node_info!("eth_getBlockByHash");
873        self.backend.block_by_hash_full(hash).await
874    }
875
876    /// Returns the number of transactions in a block with given hash.
877    ///
878    /// Handler for ETH RPC call: `eth_getBlockTransactionCountByHash`
879    pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
880        node_info!("eth_getBlockTransactionCountByHash");
881        let block = self.backend.block_by_hash(hash).await?;
882        let txs = block.map(|b| match b.transactions() {
883            BlockTransactions::Full(txs) => U256::from(txs.len()),
884            BlockTransactions::Hashes(txs) => U256::from(txs.len()),
885            BlockTransactions::Uncle => U256::from(0),
886        });
887        Ok(txs)
888    }
889
890    /// Returns the number of uncles in a block with given hash.
891    ///
892    /// Handler for ETH RPC call: `eth_getUncleCountByBlockHash`
893    pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
894        node_info!("eth_getUncleCountByBlockHash");
895        let block =
896            self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
897        Ok(U256::from(block.uncles.len()))
898    }
899
900    /// Returns the number of uncles in a block with given block number.
901    ///
902    /// Handler for ETH RPC call: `eth_getUncleCountByBlockNumber`
903    pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
904        node_info!("eth_getUncleCountByBlockNumber");
905        let block = self
906            .backend
907            .block_by_number(block_number)
908            .await?
909            .ok_or(BlockchainError::BlockNotFound)?;
910        Ok(U256::from(block.uncles.len()))
911    }
912
913    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
914    ///
915    /// Handler for ETH RPC call: `eth_signTypedData`
916    pub async fn sign_typed_data(
917        &self,
918        _address: Address,
919        _data: serde_json::Value,
920    ) -> Result<String> {
921        node_info!("eth_signTypedData");
922        Err(BlockchainError::RpcUnimplemented)
923    }
924
925    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
926    ///
927    /// Handler for ETH RPC call: `eth_signTypedData_v3`
928    pub async fn sign_typed_data_v3(
929        &self,
930        _address: Address,
931        _data: serde_json::Value,
932    ) -> Result<String> {
933        node_info!("eth_signTypedData_v3");
934        Err(BlockchainError::RpcUnimplemented)
935    }
936
937    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md), and includes full support of arrays and recursive data structures.
938    ///
939    /// Handler for ETH RPC call: `eth_signTypedData_v4`
940    pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
941        node_info!("eth_signTypedData_v4");
942        let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
943        let signature = signer.sign_typed_data(address, data).await?;
944        let signature = alloy_primitives::hex::encode(signature.as_bytes());
945        Ok(format!("0x{signature}"))
946    }
947
948    /// The sign method calculates an Ethereum specific signature
949    ///
950    /// Handler for ETH RPC call: `eth_sign`
951    pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
952        node_info!("eth_sign");
953        let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
954        let signature =
955            alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
956        Ok(format!("0x{signature}"))
957    }
958
959    /// Returns transaction at given block hash and index.
960    ///
961    /// Handler for ETH RPC call: `eth_getTransactionByBlockHashAndIndex`
962    pub async fn transaction_by_block_hash_and_index(
963        &self,
964        hash: B256,
965        index: Index,
966    ) -> Result<Option<AnyRpcTransaction>> {
967        node_info!("eth_getTransactionByBlockHashAndIndex");
968        self.backend.transaction_by_block_hash_and_index(hash, index).await
969    }
970
971    /// Returns transaction by given block number and index.
972    ///
973    /// Handler for ETH RPC call: `eth_getTransactionByBlockNumberAndIndex`
974    pub async fn transaction_by_block_number_and_index(
975        &self,
976        block: BlockNumber,
977        idx: Index,
978    ) -> Result<Option<AnyRpcTransaction>> {
979        node_info!("eth_getTransactionByBlockNumberAndIndex");
980        self.backend.transaction_by_block_number_and_index(block, idx).await
981    }
982
983    /// Returns an uncles at given block and index.
984    ///
985    /// Handler for ETH RPC call: `eth_getUncleByBlockHashAndIndex`
986    pub async fn uncle_by_block_hash_and_index(
987        &self,
988        block_hash: B256,
989        idx: Index,
990    ) -> Result<Option<AnyRpcBlock>> {
991        node_info!("eth_getUncleByBlockHashAndIndex");
992        let number =
993            self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
994        if let Some(fork) = self.get_fork()
995            && fork.predates_fork_inclusive(number)
996        {
997            return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
998        }
999        // It's impossible to have uncles outside of fork mode
1000        Ok(None)
1001    }
1002
1003    /// Returns an uncles at given block and index.
1004    ///
1005    /// Handler for ETH RPC call: `eth_getUncleByBlockNumberAndIndex`
1006    pub async fn uncle_by_block_number_and_index(
1007        &self,
1008        block_number: BlockNumber,
1009        idx: Index,
1010    ) -> Result<Option<AnyRpcBlock>> {
1011        node_info!("eth_getUncleByBlockNumberAndIndex");
1012        let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1013        if let Some(fork) = self.get_fork()
1014            && fork.predates_fork_inclusive(number)
1015        {
1016            return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1017        }
1018        // It's impossible to have uncles outside of fork mode
1019        Ok(None)
1020    }
1021
1022    /// Returns the hash of the current block, the seedHash, and the boundary condition to be met.
1023    ///
1024    /// Handler for ETH RPC call: `eth_getWork`
1025    pub fn work(&self) -> Result<Work> {
1026        node_info!("eth_getWork");
1027        Err(BlockchainError::RpcUnimplemented)
1028    }
1029
1030    /// Returns the sync status, always be fails.
1031    ///
1032    /// Handler for ETH RPC call: `eth_syncing`
1033    pub fn syncing(&self) -> Result<bool> {
1034        node_info!("eth_syncing");
1035        Ok(false)
1036    }
1037
1038    /// Returns the current configuration of the chain.
1039    /// This is useful for finding out what precompiles and system contracts are available.
1040    ///
1041    /// Note: the activation timestamp is always 0 as the configuration is set at genesis.
1042    /// Note: the `fork_id` is always `0x00000000` as this node does not participate in any forking
1043    /// on the network.
1044    /// Note: the `next` and `last` fields are always `null` as this node does not participate in
1045    /// any forking on the network.
1046    ///
1047    /// Handler for ETH RPC call: `eth_config`
1048    pub fn config(&self) -> Result<EthConfig> {
1049        node_info!("eth_config");
1050        Ok(EthConfig {
1051            current: EthForkConfig {
1052                activation_time: 0,
1053                blob_schedule: self.backend.blob_params(),
1054                chain_id: self.backend.chain_id().to::<u64>(),
1055                fork_id: Bytes::from_static(&[0; 4]),
1056                precompiles: self.backend.precompiles(),
1057                system_contracts: self.backend.system_contracts(),
1058            },
1059            next: None,
1060            last: None,
1061        })
1062    }
1063
1064    /// Used for submitting a proof-of-work solution.
1065    ///
1066    /// Handler for ETH RPC call: `eth_submitWork`
1067    pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1068        node_info!("eth_submitWork");
1069        Err(BlockchainError::RpcUnimplemented)
1070    }
1071
1072    /// Used for submitting mining hashrate.
1073    ///
1074    /// Handler for ETH RPC call: `eth_submitHashrate`
1075    pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1076        node_info!("eth_submitHashrate");
1077        Err(BlockchainError::RpcUnimplemented)
1078    }
1079
1080    /// Introduced in EIP-1559 for getting information on the appropriate priority fee to use.
1081    ///
1082    /// Handler for ETH RPC call: `eth_feeHistory`
1083    pub async fn fee_history(
1084        &self,
1085        block_count: U256,
1086        newest_block: BlockNumber,
1087        reward_percentiles: Vec<f64>,
1088    ) -> Result<FeeHistory> {
1089        node_info!("eth_feeHistory");
1090        // max number of blocks in the requested range
1091
1092        let current = self.backend.best_number();
1093        let slots_in_an_epoch = 32u64;
1094
1095        let number = match newest_block {
1096            BlockNumber::Latest | BlockNumber::Pending => current,
1097            BlockNumber::Earliest => 0,
1098            BlockNumber::Number(n) => n,
1099            BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1100            BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1101        };
1102
1103        // check if the number predates the fork, if in fork mode
1104        if let Some(fork) = self.get_fork() {
1105            // if we're still at the forked block we don't have any history and can't compute it
1106            // efficiently, instead we fetch it from the fork
1107            if fork.predates_fork_inclusive(number) {
1108                return fork
1109                    .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1110                    .await
1111                    .map_err(BlockchainError::AlloyForkProvider);
1112            }
1113        }
1114
1115        const MAX_BLOCK_COUNT: u64 = 1024u64;
1116        let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1117
1118        // highest and lowest block num in the requested range
1119        let highest = number;
1120        let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1121
1122        // only support ranges that are in cache range
1123        if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1124            return Err(FeeHistoryError::InvalidBlockRange.into());
1125        }
1126
1127        let mut response = FeeHistory {
1128            oldest_block: lowest,
1129            base_fee_per_gas: Vec::new(),
1130            gas_used_ratio: Vec::new(),
1131            reward: Some(Default::default()),
1132            base_fee_per_blob_gas: Default::default(),
1133            blob_gas_used_ratio: Default::default(),
1134        };
1135        let mut rewards = Vec::new();
1136
1137        {
1138            let fee_history = self.fee_history_cache.lock();
1139
1140            // iter over the requested block range
1141            for n in lowest..=highest {
1142                // <https://eips.ethereum.org/EIPS/eip-1559>
1143                if let Some(block) = fee_history.get(&n) {
1144                    response.base_fee_per_gas.push(block.base_fee);
1145                    response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1146                    response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1147                    response.gas_used_ratio.push(block.gas_used_ratio);
1148
1149                    // requested percentiles
1150                    if !reward_percentiles.is_empty() {
1151                        let mut block_rewards = Vec::new();
1152                        let resolution_per_percentile: f64 = 2.0;
1153                        for p in &reward_percentiles {
1154                            let p = p.clamp(0.0, 100.0);
1155                            let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1156                            let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1157                            block_rewards.push(reward);
1158                        }
1159                        rewards.push(block_rewards);
1160                    }
1161                }
1162            }
1163        }
1164
1165        response.reward = Some(rewards);
1166
1167        // add the next block's base fee to the response
1168        // The spec states that `base_fee_per_gas` "[..] includes the next block after the
1169        // newest of the returned range, because this value can be derived from the
1170        // newest block"
1171        response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1172
1173        // Same goes for the `base_fee_per_blob_gas`:
1174        // > [..] includes the next block after the newest of the returned range, because this
1175        // > value can be derived from the newest block.
1176        response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1177
1178        Ok(response)
1179    }
1180
1181    /// Introduced in EIP-1159, a Geth-specific and simplified priority fee oracle.
1182    /// Leverages the already existing fee history cache.
1183    ///
1184    /// Returns a suggestion for a gas tip cap for dynamic fee transactions.
1185    ///
1186    /// Handler for ETH RPC call: `eth_maxPriorityFeePerGas`
1187    pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1188        node_info!("eth_maxPriorityFeePerGas");
1189        Ok(U256::from(self.lowest_suggestion_tip()))
1190    }
1191
1192    /// Returns code by its hash
1193    ///
1194    /// Handler for RPC call: `debug_codeByHash`
1195    pub async fn debug_code_by_hash(
1196        &self,
1197        hash: B256,
1198        block_id: Option<BlockId>,
1199    ) -> Result<Option<Bytes>> {
1200        node_info!("debug_codeByHash");
1201        self.backend.debug_code_by_hash(hash, block_id).await
1202    }
1203
1204    /// Returns the value associated with a key from the database
1205    /// Only supports bytecode lookups.
1206    ///
1207    /// Handler for RPC call: `debug_dbGet`
1208    pub async fn debug_db_get(&self, key: String) -> Result<Option<Bytes>> {
1209        node_info!("debug_dbGet");
1210        self.backend.debug_db_get(key).await
1211    }
1212
1213    /// Returns traces for the transaction hash via parity's tracing endpoint
1214    ///
1215    /// Handler for RPC call: `trace_transaction`
1216    pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1217        node_info!("trace_transaction");
1218        self.backend.trace_transaction(tx_hash).await
1219    }
1220
1221    /// Returns traces for the transaction hash via parity's tracing endpoint
1222    ///
1223    /// Handler for RPC call: `trace_block`
1224    pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1225        node_info!("trace_block");
1226        self.backend.trace_block(block).await
1227    }
1228
1229    /// Returns filtered traces over blocks
1230    ///
1231    /// Handler for RPC call: `trace_filter`
1232    pub async fn trace_filter(
1233        &self,
1234        filter: TraceFilter,
1235    ) -> Result<Vec<LocalizedTransactionTrace>> {
1236        node_info!("trace_filter");
1237        self.backend.trace_filter(filter).await
1238    }
1239
1240    /// Replays all transactions in a block returning the requested traces for each transaction
1241    ///
1242    /// Handler for RPC call: `trace_replayBlockTransactions`
1243    pub async fn trace_replay_block_transactions(
1244        &self,
1245        block: BlockNumber,
1246        trace_types: HashSet<TraceType>,
1247    ) -> Result<Vec<TraceResultsWithTransactionHash>> {
1248        node_info!("trace_replayBlockTransactions");
1249        self.backend.trace_replay_block_transactions(block, trace_types).await
1250    }
1251}
1252
1253impl<N: Network<ReceiptEnvelope = FoundryReceiptEnvelope>> EthApi<N> {
1254    /// Returns the current state
1255    pub async fn serialized_state(
1256        &self,
1257        preserve_historical_states: bool,
1258    ) -> Result<SerializableState> {
1259        self.backend.serialized_state(preserve_historical_states).await
1260    }
1261}
1262
1263// == impl EthApi anvil endpoints ==
1264
1265impl EthApi<FoundryNetwork> {
1266    /// Create a buffer that represents all state on the chain, which can be loaded to separate
1267    /// process by calling `anvil_loadState`
1268    ///
1269    /// Handler for RPC call: `anvil_dumpState`
1270    pub async fn anvil_dump_state(
1271        &self,
1272        preserve_historical_states: Option<bool>,
1273    ) -> Result<Bytes> {
1274        node_info!("anvil_dumpState");
1275        self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
1276    }
1277
1278    /// Append chain state buffer to current chain. Will overwrite any conflicting addresses or
1279    /// storage.
1280    ///
1281    /// Handler for RPC call: `anvil_loadState`
1282    pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
1283        node_info!("anvil_loadState");
1284        self.backend.load_state_bytes(buf).await
1285    }
1286
1287    async fn block_request(
1288        &self,
1289        block_number: Option<BlockId>,
1290    ) -> Result<BlockRequest<FoundryTxEnvelope>> {
1291        let block_request = match block_number {
1292            Some(BlockId::Number(BlockNumber::Pending)) => {
1293                let pending_txs = self.pool.ready_transactions().collect();
1294                BlockRequest::Pending(pending_txs)
1295            }
1296            _ => {
1297                let number = self.backend.ensure_block_number(block_number).await?;
1298                BlockRequest::Number(number)
1299            }
1300        };
1301        Ok(block_request)
1302    }
1303
1304    /// Increases the balance of an account.
1305    ///
1306    /// Handler for RPC call: `anvil_addBalance`
1307    pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
1308        node_info!("anvil_addBalance");
1309        let current_balance = self.backend.get_balance(address, None).await?;
1310        self.backend.set_balance(address, current_balance.saturating_add(balance)).await?;
1311        Ok(())
1312    }
1313
1314    /// Rollback the chain to a specific depth.
1315    ///
1316    /// e.g depth = 3
1317    ///     A  -> B  -> C  -> D  -> E
1318    ///     A  -> B
1319    ///
1320    /// Depth specifies the height to rollback the chain back to. Depth must not exceed the current
1321    /// chain height, i.e. can't rollback past the genesis block.
1322    ///
1323    /// Handler for RPC call: `anvil_rollback`
1324    pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
1325        node_info!("anvil_rollback");
1326        let depth = depth.unwrap_or(1);
1327
1328        // Check reorg depth doesn't exceed current chain height
1329        let current_height = self.backend.best_number();
1330        let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
1331            RpcError::invalid_params(format!(
1332                "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
1333            )),
1334        ))?;
1335
1336        // Get the common ancestor block
1337        let common_block =
1338            self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
1339
1340        self.backend.rollback(common_block).await?;
1341        Ok(())
1342    }
1343
1344    /// Estimates the gas usage of the `request` with the state.
1345    ///
1346    /// This will execute the transaction request and find the best gas limit via binary search.
1347    fn do_estimate_gas_with_state(
1348        &self,
1349        mut request: WithOtherFields<TransactionRequest>,
1350        state: &dyn DatabaseRef,
1351        block_env: BlockEnv,
1352    ) -> Result<u128> {
1353        // If the request is a simple native token transfer we can optimize
1354        // We assume it's a transfer if we have no input data.
1355        // Skip this optimization for Tempo mode since native ETH transfers are not allowed
1356        // and Tempo AA transactions have higher intrinsic gas costs (~46k).
1357        if !self.backend.is_tempo() {
1358            let to = request.to.as_ref().and_then(TxKind::to);
1359
1360            // check certain fields to see if the request could be a simple transfer
1361            let maybe_transfer = (request.input.input().is_none()
1362                || request.input.input().is_some_and(|data| data.is_empty()))
1363                && request.authorization_list.is_none()
1364                && request.access_list.is_none()
1365                && request.blob_versioned_hashes.is_none();
1366
1367            if maybe_transfer
1368                && let Some(to) = to
1369                && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
1370                && target_code.as_ref().is_empty()
1371            {
1372                return Ok(MIN_TRANSACTION_GAS);
1373            }
1374        }
1375
1376        let fees = FeeDetails::new(
1377            request.gas_price,
1378            request.max_fee_per_gas,
1379            request.max_priority_fee_per_gas,
1380            request.max_fee_per_blob_gas,
1381        )?
1382        .or_zero_fees();
1383
1384        // get the highest possible gas limit, either the request's set value or the currently
1385        // configured gas limit
1386        let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
1387
1388        // Tempo AA transactions pay fees in ERC-20 tokens, not ETH
1389        let is_tempo_tx = request.other.get("feeToken").is_some_and(|v| !v.is_null());
1390
1391        let gas_price = fees.gas_price.unwrap_or_default();
1392        // If we have non-zero gas price, cap gas limit by sender balance.
1393        // Skip this check for Tempo transactions which pay with fee tokens, not ETH.
1394        if gas_price > 0
1395            && !is_tempo_tx
1396            && let Some(from) = request.from
1397        {
1398            let mut available_funds = self.backend.get_balance_with_state(state, from)?;
1399            if let Some(value) = request.value {
1400                if value > available_funds {
1401                    return Err(InvalidTransactionError::InsufficientFunds.into());
1402                }
1403                // safe: value < available_funds
1404                available_funds -= value;
1405            }
1406            // amount of gas the sender can afford with the `gas_price`
1407            let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
1408            highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
1409        }
1410
1411        let mut call_to_estimate = request.clone();
1412        call_to_estimate.gas = Some(highest_gas_limit as u64);
1413
1414        // execute the call without writing to db
1415        let ethres =
1416            self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
1417
1418        let gas_used = match ethres.try_into()? {
1419            GasEstimationCallResult::Success(gas) => Ok(gas),
1420            GasEstimationCallResult::OutOfGas => {
1421                Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
1422            }
1423            GasEstimationCallResult::Revert(output) => {
1424                Err(InvalidTransactionError::Revert(output).into())
1425            }
1426            GasEstimationCallResult::EvmError(err) => {
1427                warn!(target: "node", "estimation failed due to {:?}", err);
1428                Err(BlockchainError::EvmError(err))
1429            }
1430        }?;
1431
1432        // at this point we know the call succeeded but want to find the _best_ (lowest) gas the
1433        // transaction succeeds with. we find this by doing a binary search over the
1434        // possible range NOTE: this is the gas the transaction used, which is less than the
1435        // transaction requires to succeed
1436
1437        // Get the starting lowest gas needed depending on the transaction kind.
1438        let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
1439
1440        // pick a point that's close to the estimated gas
1441        let mut mid_gas_limit =
1442            std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
1443
1444        // Binary search for the ideal gas limit
1445        while (highest_gas_limit - lowest_gas_limit) > 1 {
1446            request.gas = Some(mid_gas_limit as u64);
1447            let ethres = self.backend.call_with_state(
1448                &state,
1449                request.clone(),
1450                fees.clone(),
1451                block_env.clone(),
1452            );
1453
1454            match ethres.try_into()? {
1455                GasEstimationCallResult::Success(_) => {
1456                    // If the transaction succeeded, we can set a ceiling for the highest gas limit
1457                    // at the current midpoint, as spending any more gas would
1458                    // make no sense (as the TX would still succeed).
1459                    highest_gas_limit = mid_gas_limit;
1460                }
1461                GasEstimationCallResult::OutOfGas
1462                | GasEstimationCallResult::Revert(_)
1463                | GasEstimationCallResult::EvmError(_) => {
1464                    // If the transaction failed, we can set a floor for the lowest gas limit at the
1465                    // current midpoint, as spending any less gas would make no
1466                    // sense (as the TX would still revert due to lack of gas).
1467                    //
1468                    // We don't care about the reason here, as we known that transaction is correct
1469                    // as it succeeded earlier
1470                    lowest_gas_limit = mid_gas_limit;
1471                }
1472            };
1473            // new midpoint
1474            mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
1475        }
1476
1477        trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
1478
1479        Ok(highest_gas_limit)
1480    }
1481
1482    /// Executes the [EthRequest] and returns an RPC [ResponseResult].
1483    pub async fn execute(&self, request: EthRequest) -> ResponseResult {
1484        trace!(target: "rpc::api", "executing eth request");
1485        let response = match request.clone() {
1486            EthRequest::EthProtocolVersion(()) => self.protocol_version().to_rpc_result(),
1487            EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
1488            EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
1489            EthRequest::EthGetAccount(addr, block) => {
1490                self.get_account(addr, block).await.to_rpc_result()
1491            }
1492            EthRequest::EthGetAccountInfo(addr, block) => {
1493                self.get_account_info(addr, block).await.to_rpc_result()
1494            }
1495            EthRequest::EthGetBalance(addr, block) => {
1496                self.balance(addr, block).await.to_rpc_result()
1497            }
1498            EthRequest::EthGetTransactionByHash(hash) => {
1499                self.transaction_by_hash(hash).await.to_rpc_result()
1500            }
1501            EthRequest::EthSendTransaction(request) => {
1502                self.send_transaction(*request).await.to_rpc_result()
1503            }
1504            EthRequest::EthSendTransactionSync(request) => {
1505                self.send_transaction_sync(*request).await.to_rpc_result()
1506            }
1507            EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
1508            EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
1509            EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
1510            EthRequest::EthHashrate(()) => self.hashrate().to_rpc_result(),
1511            EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
1512            EthRequest::EthMaxPriorityFeePerGas(_) => {
1513                self.gas_max_priority_fee_per_gas().to_rpc_result()
1514            }
1515            EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
1516            EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
1517            EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
1518            EthRequest::EthCoinbase(()) => self.author().to_rpc_result(),
1519            EthRequest::EthGetStorageAt(addr, slot, block) => {
1520                self.storage_at(addr, slot, block).await.to_rpc_result()
1521            }
1522            EthRequest::EthGetStorageValues(requests, block) => {
1523                self.storage_values(requests, block).await.to_rpc_result()
1524            }
1525            EthRequest::EthGetBlockByHash(hash, full) => {
1526                if full {
1527                    self.block_by_hash_full(hash).await.to_rpc_result()
1528                } else {
1529                    self.block_by_hash(hash).await.to_rpc_result()
1530                }
1531            }
1532            EthRequest::EthGetBlockByNumber(num, full) => {
1533                if full {
1534                    self.block_by_number_full(num).await.to_rpc_result()
1535                } else {
1536                    self.block_by_number(num).await.to_rpc_result()
1537                }
1538            }
1539            EthRequest::EthGetTransactionCount(addr, block) => {
1540                self.transaction_count(addr, block).await.to_rpc_result()
1541            }
1542            EthRequest::EthGetTransactionCountByHash(hash) => {
1543                self.block_transaction_count_by_hash(hash).await.to_rpc_result()
1544            }
1545            EthRequest::EthGetTransactionCountByNumber(num) => {
1546                self.block_transaction_count_by_number(num).await.to_rpc_result()
1547            }
1548            EthRequest::EthGetUnclesCountByHash(hash) => {
1549                self.block_uncles_count_by_hash(hash).await.to_rpc_result()
1550            }
1551            EthRequest::EthGetUnclesCountByNumber(num) => {
1552                self.block_uncles_count_by_number(num).await.to_rpc_result()
1553            }
1554            EthRequest::EthGetCodeAt(addr, block) => {
1555                self.get_code(addr, block).await.to_rpc_result()
1556            }
1557            EthRequest::EthGetProof(addr, keys, block) => {
1558                self.get_proof(addr, keys, block).await.to_rpc_result()
1559            }
1560            EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
1561            EthRequest::PersonalSign(content, addr) => {
1562                self.sign(addr, content).await.to_rpc_result()
1563            }
1564            EthRequest::EthSignTransaction(request) => {
1565                self.sign_transaction(*request).await.to_rpc_result()
1566            }
1567            EthRequest::EthSignTypedData(addr, data) => {
1568                self.sign_typed_data(addr, data).await.to_rpc_result()
1569            }
1570            EthRequest::EthSignTypedDataV3(addr, data) => {
1571                self.sign_typed_data_v3(addr, data).await.to_rpc_result()
1572            }
1573            EthRequest::EthSignTypedDataV4(addr, data) => {
1574                self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
1575            }
1576            EthRequest::EthSendRawTransaction(tx) => {
1577                self.send_raw_transaction(tx).await.to_rpc_result()
1578            }
1579            EthRequest::EthSendRawTransactionSync(tx) => {
1580                self.send_raw_transaction_sync(tx).await.to_rpc_result()
1581            }
1582            EthRequest::EthCall(call, block, state_override, block_overrides) => self
1583                .call(call, block, EvmOverrides::new(state_override, block_overrides))
1584                .await
1585                .to_rpc_result(),
1586            EthRequest::EthSimulateV1(simulation, block) => {
1587                self.simulate_v1(simulation, block).await.to_rpc_result()
1588            }
1589            EthRequest::EthCreateAccessList(call, block) => {
1590                self.create_access_list(call, block).await.to_rpc_result()
1591            }
1592            EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
1593                .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
1594                .await
1595                .to_rpc_result(),
1596            EthRequest::EthFillTransaction(request) => {
1597                self.fill_transaction(request).await.to_rpc_result()
1598            }
1599            EthRequest::EthGetRawTransactionByHash(hash) => {
1600                self.raw_transaction(hash).await.to_rpc_result()
1601            }
1602            EthRequest::GetBlobByHash(hash) => {
1603                self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
1604            }
1605            EthRequest::GetBlobByTransactionHash(hash) => {
1606                self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
1607            }
1608            EthRequest::GetGenesisTime(()) => self.anvil_get_genesis_time().to_rpc_result(),
1609            EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
1610                self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
1611            }
1612            EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
1613                self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
1614            }
1615            EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
1616                self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
1617            }
1618            EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
1619                self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
1620            }
1621            EthRequest::EthGetTransactionReceipt(tx) => {
1622                self.transaction_receipt(tx).await.to_rpc_result()
1623            }
1624            EthRequest::EthGetBlockReceipts(number) => {
1625                self.block_receipts(number).await.to_rpc_result()
1626            }
1627            EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
1628                self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
1629            }
1630            EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
1631                self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
1632            }
1633            EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
1634            EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
1635            EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
1636            EthRequest::EthConfig(_) => self.config().to_rpc_result(),
1637            EthRequest::EthSubmitWork(nonce, pow, digest) => {
1638                self.submit_work(nonce, pow, digest).to_rpc_result()
1639            }
1640            EthRequest::EthSubmitHashRate(rate, id) => {
1641                self.submit_hashrate(rate, id).to_rpc_result()
1642            }
1643            EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
1644                self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
1645            }
1646            // non eth-standard rpc calls
1647            EthRequest::DebugGetRawTransaction(hash) => {
1648                self.raw_transaction(hash).await.to_rpc_result()
1649            }
1650            // non eth-standard rpc calls
1651            EthRequest::DebugTraceTransaction(tx, opts) => {
1652                self.debug_trace_transaction(tx, opts).await.to_rpc_result()
1653            }
1654            // non eth-standard rpc calls
1655            EthRequest::DebugTraceCall(tx, block, opts) => {
1656                self.debug_trace_call(tx, block, opts).await.to_rpc_result()
1657            }
1658            EthRequest::DebugCodeByHash(hash, block) => {
1659                self.debug_code_by_hash(hash, block).await.to_rpc_result()
1660            }
1661            EthRequest::DebugDbGet(key) => self.debug_db_get(key).await.to_rpc_result(),
1662            EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
1663            EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
1664            EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
1665            EthRequest::TraceReplayBlockTransactions(block, trace_types) => {
1666                self.trace_replay_block_transactions(block, trace_types).await.to_rpc_result()
1667            }
1668            EthRequest::ImpersonateAccount(addr) => {
1669                self.anvil_impersonate_account(addr).await.to_rpc_result()
1670            }
1671            EthRequest::StopImpersonatingAccount(addr) => {
1672                self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
1673            }
1674            EthRequest::AutoImpersonateAccount(enable) => {
1675                self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
1676            }
1677            EthRequest::ImpersonateSignature(signature, address) => {
1678                self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
1679            }
1680            EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
1681            EthRequest::Mine(blocks, interval) => {
1682                self.anvil_mine(blocks, interval).await.to_rpc_result()
1683            }
1684            EthRequest::SetAutomine(enabled) => {
1685                self.anvil_set_auto_mine(enabled).await.to_rpc_result()
1686            }
1687            EthRequest::SetIntervalMining(interval) => {
1688                self.anvil_set_interval_mining(interval).to_rpc_result()
1689            }
1690            EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
1691            EthRequest::DropTransaction(tx) => {
1692                self.anvil_drop_transaction(tx).await.to_rpc_result()
1693            }
1694            EthRequest::DropAllTransactions() => {
1695                self.anvil_drop_all_transactions().await.to_rpc_result()
1696            }
1697            EthRequest::Reset(fork) => {
1698                self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
1699            }
1700            EthRequest::SetBalance(addr, val) => {
1701                self.anvil_set_balance(addr, val).await.to_rpc_result()
1702            }
1703            EthRequest::AddBalance(addr, val) => {
1704                self.anvil_add_balance(addr, val).await.to_rpc_result()
1705            }
1706            EthRequest::DealERC20(addr, token_addr, val) => {
1707                self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
1708            }
1709            EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
1710                .anvil_set_erc20_allowance(owner, spender, token_addr, val)
1711                .await
1712                .to_rpc_result(),
1713            EthRequest::SetCode(addr, code) => {
1714                self.anvil_set_code(addr, code).await.to_rpc_result()
1715            }
1716            EthRequest::SetNonce(addr, nonce) => {
1717                self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
1718            }
1719            EthRequest::SetStorageAt(addr, slot, val) => {
1720                self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
1721            }
1722            EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
1723            EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
1724            EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
1725            EthRequest::SetMinGasPrice(gas) => {
1726                self.anvil_set_min_gas_price(gas).await.to_rpc_result()
1727            }
1728            EthRequest::SetNextBlockBaseFeePerGas(gas) => {
1729                self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
1730            }
1731            EthRequest::DumpState(preserve_historical_states) => self
1732                .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
1733                .await
1734                .to_rpc_result(),
1735            EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
1736            EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
1737            EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
1738            EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
1739            EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
1740            EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
1741            EthRequest::EvmSetNextBlockTimeStamp(time) => {
1742                if time >= U256::from(u64::MAX) {
1743                    return ResponseResult::Error(RpcError::invalid_params(
1744                        "The timestamp is too big",
1745                    ));
1746                }
1747                let time = time.to::<u64>();
1748                self.evm_set_next_block_timestamp(time).to_rpc_result()
1749            }
1750            EthRequest::EvmSetTime(timestamp) => {
1751                if timestamp >= U256::from(u64::MAX) {
1752                    return ResponseResult::Error(RpcError::invalid_params(
1753                        "The timestamp is too big",
1754                    ));
1755                }
1756                let time = timestamp.to::<u64>();
1757                self.evm_set_time(time).to_rpc_result()
1758            }
1759            EthRequest::EvmSetBlockGasLimit(gas_limit) => {
1760                self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
1761            }
1762            EthRequest::EvmSetBlockTimeStampInterval(time) => {
1763                self.evm_set_block_timestamp_interval(time).to_rpc_result()
1764            }
1765            EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
1766                self.evm_remove_block_timestamp_interval().to_rpc_result()
1767            }
1768            EthRequest::EvmMine(mine) => {
1769                self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
1770            }
1771            EthRequest::EvmMineDetailed(mine) => {
1772                self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
1773            }
1774            EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
1775            EthRequest::EthSendUnsignedTransaction(tx) => {
1776                self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
1777            }
1778            EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
1779            EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
1780            EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
1781            EthRequest::EthNewPendingTransactionFilter(_) => {
1782                self.new_pending_transaction_filter().await.to_rpc_result()
1783            }
1784            EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
1785            EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
1786            EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
1787            EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
1788            EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
1789            EthRequest::ErigonGetHeaderByNumber(num) => {
1790                self.erigon_get_header_by_number(num).await.to_rpc_result()
1791            }
1792            EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
1793            EthRequest::OtsGetInternalOperations(hash) => {
1794                self.ots_get_internal_operations(hash).await.to_rpc_result()
1795            }
1796            EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
1797            EthRequest::OtsTraceTransaction(hash) => {
1798                self.ots_trace_transaction(hash).await.to_rpc_result()
1799            }
1800            EthRequest::OtsGetTransactionError(hash) => {
1801                self.ots_get_transaction_error(hash).await.to_rpc_result()
1802            }
1803            EthRequest::OtsGetBlockDetails(num) => {
1804                self.ots_get_block_details(num).await.to_rpc_result()
1805            }
1806            EthRequest::OtsGetBlockDetailsByHash(hash) => {
1807                self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
1808            }
1809            EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
1810                self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
1811            }
1812            EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
1813                self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
1814            }
1815            EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
1816                self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
1817            }
1818            EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
1819                self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
1820            }
1821            EthRequest::EthGetTransactionBySenderAndNonce(sender, nonce) => {
1822                self.transaction_by_sender_and_nonce(sender, nonce).await.to_rpc_result()
1823            }
1824            EthRequest::OtsGetContractCreator(address) => {
1825                self.ots_get_contract_creator(address).await.to_rpc_result()
1826            }
1827            EthRequest::RemovePoolTransactions(address) => {
1828                self.anvil_remove_pool_transactions(address).await.to_rpc_result()
1829            }
1830            EthRequest::Reorg(reorg_options) => {
1831                self.anvil_reorg(reorg_options).await.to_rpc_result()
1832            }
1833            EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
1834        };
1835
1836        if let ResponseResult::Error(err) = &response {
1837            node_info!("\nRPC request failed:");
1838            node_info!("    Request: {:?}", request);
1839            node_info!("    Error: {}\n", err);
1840        }
1841
1842        response
1843    }
1844
1845    fn sign_request(&self, from: &Address, typed_tx: FoundryTypedTx) -> Result<FoundryTxEnvelope> {
1846        match typed_tx {
1847            FoundryTypedTx::Deposit(_) => return Ok(build_impersonated(typed_tx)),
1848            _ => {
1849                for signer in self.signers.iter() {
1850                    if signer.accounts().contains(from) {
1851                        return signer.sign_transaction_from(from, typed_tx);
1852                    }
1853                }
1854            }
1855        }
1856        Err(BlockchainError::NoSignerAvailable)
1857    }
1858
1859    async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1860        match self.pool.get_transaction(hash) {
1861            Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
1862            None => match self.backend.transaction_by_hash(hash).await? {
1863                Some(tx) => Ok(Some(tx.as_ref().encoded_2718().into())),
1864                None => Ok(None),
1865            },
1866        }
1867    }
1868
1869    /// Returns balance of the given account.
1870    ///
1871    /// Handler for ETH RPC call: `eth_getBalance`
1872    pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
1873        node_info!("eth_getBalance");
1874        let block_request = self.block_request(block_number).await?;
1875
1876        // check if the number predates the fork, if in fork mode
1877        if let BlockRequest::Number(number) = block_request
1878            && let Some(fork) = self.get_fork()
1879            && fork.predates_fork(number)
1880        {
1881            return Ok(fork.get_balance(address, number).await?);
1882        }
1883
1884        self.backend.get_balance(address, Some(block_request)).await
1885    }
1886
1887    /// Returns the ethereum account.
1888    ///
1889    /// Handler for ETH RPC call: `eth_getAccount`
1890    pub async fn get_account(
1891        &self,
1892        address: Address,
1893        block_number: Option<BlockId>,
1894    ) -> Result<TrieAccount> {
1895        node_info!("eth_getAccount");
1896        let block_request = self.block_request(block_number).await?;
1897
1898        // check if the number predates the fork, if in fork mode
1899        if let BlockRequest::Number(number) = block_request
1900            && let Some(fork) = self.get_fork()
1901            && fork.predates_fork(number)
1902        {
1903            return Ok(fork.get_account(address, number).await?);
1904        }
1905
1906        self.backend.get_account_at_block(address, Some(block_request)).await
1907    }
1908
1909    /// Returns the account information including balance, nonce, code and storage
1910    ///
1911    /// Note: This isn't support by all providers
1912    pub async fn get_account_info(
1913        &self,
1914        address: Address,
1915        block_number: Option<BlockId>,
1916    ) -> Result<alloy_rpc_types::eth::AccountInfo> {
1917        node_info!("eth_getAccountInfo");
1918
1919        if let Some(fork) = self.get_fork() {
1920            let block_request = self.block_request(block_number).await?;
1921            // check if the number predates the fork, if in fork mode
1922            if let BlockRequest::Number(number) = block_request {
1923                trace!(target: "node", "get_account_info: fork block {}, requested block {number}", fork.block_number());
1924                return if fork.predates_fork(number) {
1925                    // if this predates the fork we need to fetch balance, nonce, code individually
1926                    // because the provider might not support this endpoint
1927                    let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
1928                    let code = fork.get_code(address, number).map_err(BlockchainError::from);
1929                    let nonce = self.get_transaction_count(address, Some(number.into()));
1930                    let (balance, code, nonce) = try_join!(balance, code, nonce)?;
1931
1932                    Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code })
1933                } else {
1934                    // Anvil node is at the same block or higher than the fork block,
1935                    // return account info from backend to reflect current state.
1936                    let account_info = self.backend.get_account(address).await?;
1937                    let code = self.backend.get_code(address, Some(block_request)).await?;
1938                    Ok(alloy_rpc_types::eth::AccountInfo {
1939                        balance: account_info.balance,
1940                        nonce: account_info.nonce,
1941                        code,
1942                    })
1943                };
1944            }
1945        }
1946
1947        let account = self.get_account(address, block_number);
1948        let code = self.get_code(address, block_number);
1949        let (account, code) = try_join!(account, code)?;
1950        Ok(alloy_rpc_types::eth::AccountInfo {
1951            balance: account.balance,
1952            nonce: account.nonce,
1953            code,
1954        })
1955    }
1956    /// Returns content of the storage at given address.
1957    ///
1958    /// Handler for ETH RPC call: `eth_getStorageAt`
1959    pub async fn storage_at(
1960        &self,
1961        address: Address,
1962        index: U256,
1963        block_number: Option<BlockId>,
1964    ) -> Result<B256> {
1965        node_info!("eth_getStorageAt");
1966        let block_request = self.block_request(block_number).await?;
1967
1968        // check if the number predates the fork, if in fork mode
1969        if let BlockRequest::Number(number) = block_request
1970            && let Some(fork) = self.get_fork()
1971            && fork.predates_fork(number)
1972        {
1973            return Ok(B256::from(
1974                fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
1975            ));
1976        }
1977
1978        self.backend.storage_at(address, index, Some(block_request)).await
1979    }
1980
1981    /// Returns storage values for multiple accounts and slots in a single call.
1982    ///
1983    /// Handler for ETH RPC call: `eth_getStorageValues`
1984    pub async fn storage_values(
1985        &self,
1986        requests: HashMap<Address, Vec<B256>>,
1987        block_number: Option<BlockId>,
1988    ) -> Result<HashMap<Address, Vec<B256>>> {
1989        node_info!("eth_getStorageValues");
1990
1991        let total_slots: usize = requests.values().map(|s| s.len()).sum();
1992        if total_slots > 1024 {
1993            return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
1994                "total slot count {total_slots} exceeds limit 1024"
1995            ))));
1996        }
1997
1998        let block_request = self.block_request(block_number).await?;
1999
2000        // check if the number predates the fork, if in fork mode
2001        if let BlockRequest::Number(number) = block_request
2002            && let Some(fork) = self.get_fork()
2003            && fork.predates_fork(number)
2004        {
2005            let mut result: HashMap<Address, Vec<B256>> = HashMap::default();
2006            for (address, slots) in requests {
2007                let mut values = Vec::with_capacity(slots.len());
2008                for slot in &slots {
2009                    let val = fork
2010                        .storage_at(address, (*slot).into(), Some(BlockNumber::Number(number)))
2011                        .await?;
2012                    values.push(B256::from(val));
2013                }
2014                result.insert(address, values);
2015            }
2016            return Ok(result);
2017        }
2018
2019        self.backend.storage_values(requests, Some(block_request)).await
2020    }
2021
2022    /// Returns block with given number.
2023    ///
2024    /// Handler for ETH RPC call: `eth_getBlockByNumber`
2025    pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
2026        node_info!("eth_getBlockByNumber");
2027        if number == BlockNumber::Pending {
2028            return Ok(Some(self.pending_block().await));
2029        }
2030
2031        self.backend.block_by_number(number).await
2032    }
2033
2034    /// Returns a _full_ block with given number
2035    ///
2036    /// Handler for ETH RPC call: `eth_getBlockByNumber`
2037    pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
2038        node_info!("eth_getBlockByNumber");
2039        if number == BlockNumber::Pending {
2040            return Ok(self.pending_block_full().await);
2041        }
2042        self.backend.block_by_number_full(number).await
2043    }
2044
2045    /// Returns the number of transactions sent from given address at given time (block number).
2046    ///
2047    /// Also checks the pending transactions if `block_number` is
2048    /// `BlockId::Number(BlockNumber::Pending)`
2049    ///
2050    /// Handler for ETH RPC call: `eth_getTransactionCount`
2051    pub async fn transaction_count(
2052        &self,
2053        address: Address,
2054        block_number: Option<BlockId>,
2055    ) -> Result<U256> {
2056        node_info!("eth_getTransactionCount");
2057        self.get_transaction_count(address, block_number).await.map(U256::from)
2058    }
2059
2060    /// Returns the number of transactions in a block with given block number.
2061    ///
2062    /// Handler for ETH RPC call: `eth_getBlockTransactionCountByNumber`
2063    pub async fn block_transaction_count_by_number(
2064        &self,
2065        block_number: BlockNumber,
2066    ) -> Result<Option<U256>> {
2067        node_info!("eth_getBlockTransactionCountByNumber");
2068        let block_request = self.block_request(Some(block_number.into())).await?;
2069        if let BlockRequest::Pending(txs) = block_request {
2070            let block = self.backend.pending_block(txs).await;
2071            return Ok(Some(U256::from(block.block.body.transactions.len())));
2072        }
2073        let block = self.backend.block_by_number(block_number).await?;
2074        let txs = block.map(|b| match b.transactions() {
2075            BlockTransactions::Full(txs) => U256::from(txs.len()),
2076            BlockTransactions::Hashes(txs) => U256::from(txs.len()),
2077            BlockTransactions::Uncle => U256::from(0),
2078        });
2079        Ok(txs)
2080    }
2081
2082    /// Returns the code at given address at given time (block number).
2083    ///
2084    /// Handler for ETH RPC call: `eth_getCode`
2085    pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
2086        node_info!("eth_getCode");
2087        let block_request = self.block_request(block_number).await?;
2088        // check if the number predates the fork, if in fork mode
2089        if let BlockRequest::Number(number) = block_request
2090            && let Some(fork) = self.get_fork()
2091            && fork.predates_fork(number)
2092        {
2093            return Ok(fork.get_code(address, number).await?);
2094        }
2095        self.backend.get_code(address, Some(block_request)).await
2096    }
2097
2098    /// Returns the account and storage values of the specified account including the Merkle-proof.
2099    /// This call can be used to verify that the data you are pulling from is not tampered with.
2100    ///
2101    /// Handler for ETH RPC call: `eth_getProof`
2102    pub async fn get_proof(
2103        &self,
2104        address: Address,
2105        keys: Vec<B256>,
2106        block_number: Option<BlockId>,
2107    ) -> Result<EIP1186AccountProofResponse> {
2108        node_info!("eth_getProof");
2109        let block_request = self.block_request(block_number).await?;
2110
2111        // If we're in forking mode, or still on the forked block (no blocks mined yet) then we can
2112        // delegate the call.
2113        if let BlockRequest::Number(number) = block_request
2114            && let Some(fork) = self.get_fork()
2115            && fork.predates_fork_inclusive(number)
2116        {
2117            return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
2118        }
2119
2120        let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
2121        Ok(proof)
2122    }
2123
2124    /// Signs a transaction
2125    ///
2126    /// Handler for ETH RPC call: `eth_signTransaction`
2127    pub async fn sign_transaction(
2128        &self,
2129        request: WithOtherFields<TransactionRequest>,
2130    ) -> Result<String> {
2131        node_info!("eth_signTransaction");
2132
2133        let from = request.from.map(Ok).unwrap_or_else(|| {
2134            self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
2135        })?;
2136
2137        let (nonce, _) = self.request_nonce(&request, from).await?;
2138
2139        let request = self.build_tx_request(request, nonce).await?;
2140
2141        let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
2142        Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
2143    }
2144
2145    /// Sends a transaction
2146    ///
2147    /// Handler for ETH RPC call: `eth_sendTransaction`
2148    pub async fn send_transaction(
2149        &self,
2150        request: WithOtherFields<TransactionRequest>,
2151    ) -> Result<TxHash> {
2152        node_info!("eth_sendTransaction");
2153
2154        let from = request.from.map(Ok).unwrap_or_else(|| {
2155            self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
2156        })?;
2157        let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2158
2159        let typed_tx = self.build_tx_request(request, nonce).await?;
2160
2161        // if the sender is currently impersonated we need to "bypass" signing
2162        let pending_transaction = if self.is_impersonated(from) {
2163            let transaction = sign::build_impersonated(typed_tx);
2164            self.ensure_typed_transaction_supported(&transaction)?;
2165            trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
2166            PendingTransaction::with_impersonated(transaction, from)
2167        } else {
2168            let transaction = self.sign_request(&from, typed_tx)?;
2169            self.ensure_typed_transaction_supported(&transaction)?;
2170            PendingTransaction::new(transaction)?
2171        };
2172        // pre-validate
2173        self.backend.validate_pool_transaction(&pending_transaction).await?;
2174
2175        let requires = required_marker(nonce, on_chain_nonce, from);
2176        let provides = vec![to_marker(nonce, from)];
2177        debug_assert!(requires != provides);
2178
2179        self.add_pending_transaction(pending_transaction, requires, provides)
2180    }
2181
2182    /// Waits for a transaction to be included in a block and returns its receipt (no timeout).
2183    async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
2184        let mut stream = self.new_block_notifications();
2185        // Check if the transaction is already included before listening for new blocks.
2186        if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
2187            return Ok(receipt);
2188        }
2189        while let Some(notification) = stream.next().await {
2190            if let Some(block) = self.backend.get_block_by_hash(notification.hash)
2191                && block.body.transactions.iter().any(|tx| tx.hash() == hash)
2192                && let Some(receipt) = self.backend.transaction_receipt(hash).await?
2193            {
2194                return Ok(receipt);
2195            }
2196        }
2197
2198        Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
2199    }
2200
2201    /// Waits for a transaction to be included in a block and returns its receipt, with timeout.
2202    async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
2203        const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
2204        tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
2205            .await
2206            .unwrap_or_else(|_elapsed| {
2207                Err(BlockchainError::TransactionConfirmationTimeout {
2208                    hash,
2209                    duration: TIMEOUT_DURATION,
2210                })
2211            })
2212    }
2213
2214    /// Sends a transaction and waits for receipt
2215    ///
2216    /// Handler for ETH RPC call: `eth_sendTransactionSync`
2217    pub async fn send_transaction_sync(
2218        &self,
2219        request: WithOtherFields<TransactionRequest>,
2220    ) -> Result<FoundryTxReceipt> {
2221        node_info!("eth_sendTransactionSync");
2222        let hash = self.send_transaction(request).await?;
2223
2224        let receipt = self.check_transaction_inclusion(hash).await?;
2225
2226        Ok(receipt)
2227    }
2228
2229    /// Sends signed transaction, returning its hash.
2230    ///
2231    /// Handler for ETH RPC call: `eth_sendRawTransaction`
2232    pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
2233        node_info!("eth_sendRawTransaction");
2234        let mut data = tx.as_ref();
2235        if data.is_empty() {
2236            return Err(BlockchainError::EmptyRawTransactionData);
2237        }
2238
2239        let transaction = FoundryTxEnvelope::decode_2718(&mut data)
2240            .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2241
2242        self.ensure_typed_transaction_supported(&transaction)?;
2243
2244        let pending_transaction = PendingTransaction::new(transaction)?;
2245
2246        // pre-validate
2247        self.backend.validate_pool_transaction(&pending_transaction).await?;
2248
2249        let from = *pending_transaction.sender();
2250        let priority = self.transaction_priority(&pending_transaction.transaction);
2251
2252        // Tempo txs use a 2D nonce system — no sequential ordering by account nonce.
2253        let (requires, provides) = if let FoundryTxEnvelope::Tempo(aa_tx) =
2254            pending_transaction.transaction.as_ref()
2255            && !aa_tx.tx().nonce_key.is_zero()
2256        {
2257            (vec![], vec![pending_transaction.hash().to_vec()])
2258        } else {
2259            let on_chain_nonce = self.backend.current_nonce(from).await?;
2260            let nonce = pending_transaction.transaction.nonce();
2261            (required_marker(nonce, on_chain_nonce, from), vec![to_marker(nonce, from)])
2262        };
2263
2264        let pool_transaction =
2265            PoolTransaction { requires, provides, pending_transaction, priority };
2266
2267        let tx = self.pool.add_transaction(pool_transaction)?;
2268        trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
2269        Ok(*tx.hash())
2270    }
2271
2272    /// Sends signed transaction, returning its receipt.
2273    ///
2274    /// Handler for ETH RPC call: `eth_sendRawTransactionSync`
2275    pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<FoundryTxReceipt> {
2276        node_info!("eth_sendRawTransactionSync");
2277
2278        let hash = self.send_raw_transaction(tx).await?;
2279        let receipt = self.check_transaction_inclusion(hash).await?;
2280
2281        Ok(receipt)
2282    }
2283
2284    /// Call contract, returning the output data.
2285    ///
2286    /// Handler for ETH RPC call: `eth_call`
2287    pub async fn call(
2288        &self,
2289        request: WithOtherFields<TransactionRequest>,
2290        block_number: Option<BlockId>,
2291        overrides: EvmOverrides,
2292    ) -> Result<Bytes> {
2293        node_info!("eth_call");
2294        let block_request = self.block_request(block_number).await?;
2295        // check if the number predates the fork, if in fork mode
2296        if let BlockRequest::Number(number) = block_request
2297            && let Some(fork) = self.get_fork()
2298            && fork.predates_fork(number)
2299        {
2300            if overrides.has_state() || overrides.has_block() {
2301                return Err(BlockchainError::EvmOverrideError(
2302                    "not available on past forked blocks".to_string(),
2303                ));
2304            }
2305            return Ok(fork.call(&request, Some(number.into())).await?);
2306        }
2307
2308        let fees = FeeDetails::new(
2309            request.gas_price,
2310            request.max_fee_per_gas,
2311            request.max_priority_fee_per_gas,
2312            request.max_fee_per_blob_gas,
2313        )?
2314        .or_zero_fees();
2315        // this can be blocking for a bit, especially in forking mode
2316        // <https://github.com/foundry-rs/foundry/issues/6036>
2317        self.on_blocking_task(|this| async move {
2318            let (exit, out, gas, _) =
2319                this.backend.call(request, fees, Some(block_request), overrides).await?;
2320            trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
2321
2322            ensure_return_ok(exit, &out)
2323        })
2324        .await
2325    }
2326
2327    pub async fn simulate_v1(
2328        &self,
2329        request: SimulatePayload,
2330        block_number: Option<BlockId>,
2331    ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
2332        node_info!("eth_simulateV1");
2333        let block_request = self.block_request(block_number).await?;
2334        // check if the number predates the fork, if in fork mode
2335        if let BlockRequest::Number(number) = block_request
2336            && let Some(fork) = self.get_fork()
2337            && fork.predates_fork(number)
2338        {
2339            return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
2340        }
2341
2342        // this can be blocking for a bit, especially in forking mode
2343        // <https://github.com/foundry-rs/foundry/issues/6036>
2344        self.on_blocking_task(|this| async move {
2345            let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
2346            trace!(target : "node", "Simulate status {:?}", simulated_blocks);
2347
2348            Ok(simulated_blocks)
2349        })
2350        .await
2351    }
2352
2353    /// This method creates an EIP2930 type accessList based on a given Transaction. The accessList
2354    /// contains all storage slots and addresses read and written by the transaction, except for the
2355    /// sender account and the precompiles.
2356    ///
2357    /// It returns list of addresses and storage keys used by the transaction, plus the gas
2358    /// consumed when the access list is added. That is, it gives you the list of addresses and
2359    /// storage keys that will be used by that transaction, plus the gas consumed if the access
2360    /// list is included. Like eth_estimateGas, this is an estimation; the list could change
2361    /// when the transaction is actually mined. Adding an accessList to your transaction does
2362    /// not necessary result in lower gas usage compared to a transaction without an access
2363    /// list.
2364    ///
2365    /// Handler for ETH RPC call: `eth_createAccessList`
2366    pub async fn create_access_list(
2367        &self,
2368        mut request: WithOtherFields<TransactionRequest>,
2369        block_number: Option<BlockId>,
2370    ) -> Result<AccessListResult> {
2371        node_info!("eth_createAccessList");
2372        let block_request = self.block_request(block_number).await?;
2373        // check if the number predates the fork, if in fork mode
2374        if let BlockRequest::Number(number) = block_request
2375            && let Some(fork) = self.get_fork()
2376            && fork.predates_fork(number)
2377        {
2378            return Ok(fork.create_access_list(&request, Some(number.into())).await?);
2379        }
2380
2381        self.backend
2382            .with_database_at(Some(block_request), |state, block_env| {
2383                let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
2384                    &state,
2385                    request.clone(),
2386                    FeeDetails::zero(),
2387                    block_env.clone(),
2388                )?;
2389                ensure_return_ok(exit, &out)?;
2390
2391                // execute again but with access list set
2392                request.access_list = Some(access_list.clone());
2393
2394                let (exit, out, gas_used, _) =
2395                    self.backend.call_with_state(&state, request, FeeDetails::zero(), block_env)?;
2396                ensure_return_ok(exit, &out)?;
2397
2398                Ok(AccessListResult {
2399                    access_list: AccessList(access_list.0),
2400                    gas_used: U256::from(gas_used),
2401                    error: None,
2402                })
2403            })
2404            .await?
2405    }
2406
2407    /// Estimate gas needed for execution of given contract.
2408    /// If no block parameter is given, it will use the pending block by default
2409    ///
2410    /// Handler for ETH RPC call: `eth_estimateGas`
2411    pub async fn estimate_gas(
2412        &self,
2413        request: WithOtherFields<TransactionRequest>,
2414        block_number: Option<BlockId>,
2415        overrides: EvmOverrides,
2416    ) -> Result<U256> {
2417        node_info!("eth_estimateGas");
2418        self.do_estimate_gas(
2419            request,
2420            block_number.or_else(|| Some(BlockNumber::Pending.into())),
2421            overrides,
2422        )
2423        .await
2424        .map(U256::from)
2425    }
2426
2427    /// Fills a transaction request with default values for missing fields.
2428    ///
2429    /// This method populates missing transaction fields like nonce, gas limit,
2430    /// chain ID, and fee parameters with appropriate defaults.
2431    ///
2432    /// Handler for ETH RPC call: `eth_fillTransaction`
2433    pub async fn fill_transaction(
2434        &self,
2435        mut request: WithOtherFields<TransactionRequest>,
2436    ) -> Result<FillTransaction<AnyRpcTransaction>> {
2437        node_info!("eth_fillTransaction");
2438
2439        let from = match request.as_ref().from() {
2440            Some(from) => from,
2441            None => self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)?,
2442        };
2443
2444        let nonce = if let Some(nonce) = request.as_ref().nonce() {
2445            nonce
2446        } else {
2447            self.request_nonce(&request, from).await?.0
2448        };
2449
2450        // Prefill gas limit with estimated gas, bubble up the error if the gas estimation fails
2451        // This is a workaround to avoid the error being swallowed by the `build_tx_request`
2452        // function
2453        if request.as_ref().gas_limit().is_none() {
2454            let estimated_gas =
2455                self.estimate_gas(request.clone(), None, EvmOverrides::default()).await?;
2456            request.as_mut().set_gas_limit(estimated_gas.to());
2457        }
2458
2459        let typed_tx = self.build_tx_request(request, nonce).await?;
2460        let tx = build_impersonated(typed_tx);
2461
2462        let raw = tx.encoded_2718().into();
2463
2464        let mut tx =
2465            transaction_build(None, MaybeImpersonatedTransaction::new(tx), None, None, None);
2466
2467        // Set the correct `from` address (overrides the recovered zero address from dummy
2468        // signature)
2469        tx.0.inner.inner = Recovered::new_unchecked(tx.0.inner.inner.into_inner(), from);
2470
2471        Ok(FillTransaction { raw, tx })
2472    }
2473
2474    /// Handler for RPC call: `anvil_getBlobsByTransactionHash`
2475    pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
2476        node_info!("anvil_getBlobsByTransactionHash");
2477        Ok(self.backend.get_blob_by_tx_hash(hash)?)
2478    }
2479
2480    /// Get transaction by its hash.
2481    ///
2482    /// This will check the storage for a matching transaction, if no transaction exists in storage
2483    /// this will also scan the mempool for a matching pending transaction
2484    ///
2485    /// Handler for ETH RPC call: `eth_getTransactionByHash`
2486    pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
2487        node_info!("eth_getTransactionByHash");
2488        let mut tx = self.pool.get_transaction(hash).map(|pending| {
2489            let from = *pending.sender();
2490            let tx = transaction_build(
2491                Some(*pending.hash()),
2492                pending.transaction,
2493                None,
2494                None,
2495                Some(self.backend.base_fee()),
2496            );
2497
2498            let WithOtherFields { inner: mut tx, other } = tx.0;
2499            // we set the from field here explicitly to the set sender of the pending transaction,
2500            // in case the transaction is impersonated.
2501            tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2502
2503            AnyRpcTransaction(WithOtherFields { inner: tx, other })
2504        });
2505        if tx.is_none() {
2506            tx = self.backend.transaction_by_hash(hash).await?
2507        }
2508
2509        Ok(tx)
2510    }
2511
2512    /// Returns the transaction by sender and nonce.
2513    ///
2514    /// This will check the mempool for pending transactions first, then perform a binary search
2515    /// over mined blocks to find the transaction.
2516    ///
2517    /// Handler for ETH RPC call: `eth_getTransactionBySenderAndNonce`
2518    pub async fn transaction_by_sender_and_nonce(
2519        &self,
2520        sender: Address,
2521        nonce: U256,
2522    ) -> Result<Option<AnyRpcTransaction>> {
2523        node_info!("eth_getTransactionBySenderAndNonce");
2524
2525        // check pending txs first
2526        for pending_tx in self.pool.ready_transactions().chain(self.pool.pending_transactions()) {
2527            if U256::from(pending_tx.pending_transaction.nonce()) == nonce
2528                && *pending_tx.pending_transaction.sender() == sender
2529            {
2530                let tx = transaction_build(
2531                    Some(*pending_tx.pending_transaction.hash()),
2532                    pending_tx.pending_transaction.transaction.clone(),
2533                    None,
2534                    None,
2535                    Some(self.backend.base_fee()),
2536                );
2537
2538                let WithOtherFields { inner: mut tx, other } = tx.0;
2539                // we set the from field here explicitly to the set sender of the pending
2540                // transaction, in case the transaction is impersonated.
2541                let from = *pending_tx.pending_transaction.sender();
2542                tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2543
2544                return Ok(Some(AnyRpcTransaction(WithOtherFields { inner: tx, other })));
2545            }
2546        }
2547
2548        let highest_nonce = self.transaction_count(sender, None).await?.saturating_to::<u64>();
2549        let target_nonce = nonce.saturating_to::<u64>();
2550
2551        // if the nonce is higher or equal to the highest nonce, the transaction doesn't exist
2552        if target_nonce >= highest_nonce {
2553            return Ok(None);
2554        }
2555
2556        // no mined blocks yet
2557        let latest_block = self.backend.best_number();
2558        if latest_block == 0 {
2559            return Ok(None);
2560        }
2561
2562        // binary search for the block containing the transaction
2563        let mut low = 1u64;
2564        let mut high = latest_block;
2565
2566        while low <= high {
2567            let mid = low + (high - low) / 2;
2568            let mid_nonce =
2569                self.transaction_count(sender, Some(mid.into())).await?.saturating_to::<u64>();
2570
2571            if mid_nonce > target_nonce {
2572                high = mid - 1;
2573            } else {
2574                low = mid + 1;
2575            }
2576        }
2577
2578        // search in the target block
2579        let target_block = low;
2580        if target_block <= latest_block
2581            && let Some(txs) =
2582                self.backend.mined_transactions_by_block_number(target_block.into()).await
2583        {
2584            for tx in txs {
2585                if tx.from() == sender && tx.nonce() == target_nonce {
2586                    return Ok(Some(tx));
2587                }
2588            }
2589        }
2590
2591        Ok(None)
2592    }
2593
2594    /// Returns transaction receipt by transaction hash.
2595    ///
2596    /// Handler for ETH RPC call: `eth_getTransactionReceipt`
2597    pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<FoundryTxReceipt>> {
2598        node_info!("eth_getTransactionReceipt");
2599        self.backend.transaction_receipt(hash).await
2600    }
2601
2602    /// Returns block receipts by block number.
2603    ///
2604    /// Handler for ETH RPC call: `eth_getBlockReceipts`
2605    pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<FoundryTxReceipt>>> {
2606        node_info!("eth_getBlockReceipts");
2607        self.backend.block_receipts(number).await
2608    }
2609
2610    /// Returns logs matching given filter object.
2611    ///
2612    /// Handler for ETH RPC call: `eth_getLogs`
2613    pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
2614        node_info!("eth_getLogs");
2615        self.backend.logs(filter).await
2616    }
2617
2618    /// Creates a filter object, based on filter options, to notify when the state changes (logs).
2619    ///
2620    /// Handler for ETH RPC call: `eth_newFilter`
2621    pub async fn new_filter(&self, filter: Filter) -> Result<String> {
2622        node_info!("eth_newFilter");
2623        // all logs that are already available that match the filter if the filter's block range is
2624        // in the past
2625        let historic = if filter.block_option.get_from_block().is_some() {
2626            self.backend.logs(filter.clone()).await?
2627        } else {
2628            vec![]
2629        };
2630        let filter = EthFilter::Logs(Box::new(LogsFilter {
2631            blocks: self.new_block_notifications(),
2632            storage: self.storage_info(),
2633            filter: FilteredParams::new(Some(filter)),
2634            historic: Some(historic),
2635        }));
2636        Ok(self.filters.add_filter(filter).await)
2637    }
2638
2639    /// Creates a filter in the node, to notify when a new block arrives.
2640    ///
2641    /// Handler for ETH RPC call: `eth_newBlockFilter`
2642    pub async fn new_block_filter(&self) -> Result<String> {
2643        node_info!("eth_newBlockFilter");
2644        let filter = EthFilter::Blocks(self.new_block_notifications());
2645        Ok(self.filters.add_filter(filter).await)
2646    }
2647
2648    /// Creates a filter in the node, to notify when new pending transactions arrive.
2649    ///
2650    /// Handler for ETH RPC call: `eth_newPendingTransactionFilter`
2651    pub async fn new_pending_transaction_filter(&self) -> Result<String> {
2652        node_info!("eth_newPendingTransactionFilter");
2653        let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
2654        Ok(self.filters.add_filter(filter).await)
2655    }
2656
2657    /// Polling method for a filter, which returns an array of logs which occurred since last poll.
2658    ///
2659    /// Handler for ETH RPC call: `eth_getFilterChanges`
2660    pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
2661        node_info!("eth_getFilterChanges");
2662        self.filters.get_filter_changes(id).await
2663    }
2664
2665    /// Returns an array of all logs matching filter with given id.
2666    ///
2667    /// Handler for ETH RPC call: `eth_getFilterLogs`
2668    pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
2669        node_info!("eth_getFilterLogs");
2670        if let Some(filter) = self.filters.get_log_filter(id).await {
2671            self.backend.logs(filter).await
2672        } else {
2673            Err(BlockchainError::FilterNotFound)
2674        }
2675    }
2676
2677    /// Handler for ETH RPC call: `eth_uninstallFilter`
2678    pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
2679        node_info!("eth_uninstallFilter");
2680        Ok(self.filters.uninstall_filter(id).await.is_some())
2681    }
2682
2683    /// Returns EIP-2718 encoded raw transaction
2684    ///
2685    /// Handler for RPC call: `debug_getRawTransaction`
2686    pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
2687        node_info!("debug_getRawTransaction");
2688        self.inner_raw_transaction(hash).await
2689    }
2690
2691    /// Returns EIP-2718 encoded raw transaction by block hash and index
2692    ///
2693    /// Handler for RPC call: `eth_getRawTransactionByBlockHashAndIndex`
2694    pub async fn raw_transaction_by_block_hash_and_index(
2695        &self,
2696        block_hash: B256,
2697        index: Index,
2698    ) -> Result<Option<Bytes>> {
2699        node_info!("eth_getRawTransactionByBlockHashAndIndex");
2700        match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
2701            Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
2702            None => Ok(None),
2703        }
2704    }
2705
2706    /// Returns EIP-2718 encoded raw transaction by block number and index
2707    ///
2708    /// Handler for RPC call: `eth_getRawTransactionByBlockNumberAndIndex`
2709    pub async fn raw_transaction_by_block_number_and_index(
2710        &self,
2711        block_number: BlockNumber,
2712        index: Index,
2713    ) -> Result<Option<Bytes>> {
2714        node_info!("eth_getRawTransactionByBlockNumberAndIndex");
2715        match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
2716            Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
2717            None => Ok(None),
2718        }
2719    }
2720
2721    /// Returns traces for the transaction hash for geth's tracing endpoint
2722    ///
2723    /// Handler for RPC call: `debug_traceTransaction`
2724    pub async fn debug_trace_transaction(
2725        &self,
2726        tx_hash: B256,
2727        opts: GethDebugTracingOptions,
2728    ) -> Result<GethTrace> {
2729        node_info!("debug_traceTransaction");
2730        self.backend.debug_trace_transaction(tx_hash, opts).await
2731    }
2732
2733    /// Returns traces for the transaction for geth's tracing endpoint
2734    ///
2735    /// Handler for RPC call: `debug_traceCall`
2736    pub async fn debug_trace_call(
2737        &self,
2738        request: WithOtherFields<TransactionRequest>,
2739        block_number: Option<BlockId>,
2740        opts: GethDebugTracingCallOptions,
2741    ) -> Result<GethTrace> {
2742        node_info!("debug_traceCall");
2743        let block_request = self.block_request(block_number).await?;
2744        let fees = FeeDetails::new(
2745            request.gas_price,
2746            request.max_fee_per_gas,
2747            request.max_priority_fee_per_gas,
2748            request.max_fee_per_blob_gas,
2749        )?
2750        .or_zero_fees();
2751
2752        let result: std::result::Result<GethTrace, BlockchainError> =
2753            self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
2754        result
2755    }
2756}
2757
2758// == impl EthApi anvil endpoints ==
2759
2760impl EthApi<FoundryNetwork> {
2761    /// Mines a series of blocks.
2762    ///
2763    /// Handler for ETH RPC call: `anvil_mine`
2764    pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
2765        node_info!("anvil_mine");
2766        let interval = interval.map(|i| i.to::<u64>());
2767        let blocks = num_blocks.unwrap_or(U256::from(1));
2768        if blocks.is_zero() {
2769            return Ok(());
2770        }
2771
2772        self.on_blocking_task(|this| async move {
2773            // mine all the blocks
2774            for _ in 0..blocks.to::<u64>() {
2775                // If we have an interval, jump forwards in time to the "next" timestamp
2776                if let Some(interval) = interval {
2777                    this.backend.time().increase_time(interval);
2778                }
2779                this.mine_one().await;
2780            }
2781            Ok(())
2782        })
2783        .await?;
2784
2785        Ok(())
2786    }
2787
2788    /// Helper function to find the storage slot for an ERC20 function call by testing slots
2789    /// from an access list until one produces the expected result.
2790    ///
2791    /// Rather than trying to reverse-engineer the storage layout, this function uses a
2792    /// "trial and error" approach: try overriding each slot that the function accesses,
2793    /// and see which one actually affects the function's return value.
2794    ///
2795    /// ## Parameters
2796    /// - `token_address`: The ERC20 token contract address
2797    /// - `calldata`: The encoded function call (e.g., `balanceOf(user)` or `allowance(owner,
2798    ///   spender)`)
2799    /// - `expected_value`: The value we want to set (balance or allowance amount)
2800    ///
2801    /// ## Returns
2802    /// The storage slot (B256) that contains the target ERC20 data, or an error if no slot is
2803    /// found.
2804    async fn find_erc20_storage_slot(
2805        &self,
2806        token_address: Address,
2807        calldata: Bytes,
2808        expected_value: U256,
2809    ) -> Result<B256> {
2810        let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2811
2812        // first collect all the slots that are used by the function call
2813        let access_list_result =
2814            self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2815        let access_list = access_list_result.access_list;
2816
2817        // iterate over all the accessed slots and try to find the one that contains the
2818        // target value by overriding the slot and checking the function call result
2819        for item in access_list.0 {
2820            if item.address != token_address {
2821                continue;
2822            };
2823            for slot in &item.storage_keys {
2824                let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2825                    (*slot, B256::from(expected_value.to_be_bytes())),
2826                ));
2827
2828                let state_override = StateOverridesBuilder::default()
2829                    .append(token_address, account_override)
2830                    .build();
2831
2832                let evm_override = EvmOverrides::state(Some(state_override));
2833
2834                let Ok(result) =
2835                    self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2836                else {
2837                    // overriding this slot failed
2838                    continue;
2839                };
2840
2841                let Ok(result_value) = U256::abi_decode(&result) else {
2842                    // response returned something other than a U256
2843                    continue;
2844                };
2845
2846                if result_value == expected_value {
2847                    return Ok(*slot);
2848                }
2849            }
2850        }
2851
2852        Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2853    }
2854
2855    /// Deals ERC20 tokens to a address
2856    ///
2857    /// Handler for RPC call: `anvil_dealERC20`
2858    pub async fn anvil_deal_erc20(
2859        &self,
2860        address: Address,
2861        token_address: Address,
2862        balance: U256,
2863    ) -> Result<()> {
2864        node_info!("anvil_dealERC20");
2865
2866        sol! {
2867            #[sol(rpc)]
2868            contract IERC20 {
2869                function balanceOf(address target) external view returns (uint256);
2870            }
2871        }
2872
2873        let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2874
2875        // Find the storage slot that contains the balance
2876        let slot =
2877            self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2878                BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2879            })?;
2880
2881        // Set the storage slot to the desired balance
2882        self.anvil_set_storage_at(
2883            token_address,
2884            U256::from_be_bytes(slot.0),
2885            B256::from(balance.to_be_bytes()),
2886        )
2887        .await?;
2888
2889        Ok(())
2890    }
2891
2892    /// Sets the ERC20 allowance for a spender
2893    ///
2894    /// Handler for RPC call: `anvil_set_erc20_allowance`
2895    pub async fn anvil_set_erc20_allowance(
2896        &self,
2897        owner: Address,
2898        spender: Address,
2899        token_address: Address,
2900        amount: U256,
2901    ) -> Result<()> {
2902        node_info!("anvil_setERC20Allowance");
2903
2904        sol! {
2905            #[sol(rpc)]
2906            contract IERC20 {
2907                function allowance(address owner, address spender) external view returns (uint256);
2908            }
2909        }
2910
2911        let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2912
2913        // Find the storage slot that contains the allowance
2914        let slot =
2915            self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2916                BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2917            })?;
2918
2919        // Set the storage slot to the desired allowance
2920        self.anvil_set_storage_at(
2921            token_address,
2922            U256::from_be_bytes(slot.0),
2923            B256::from(amount.to_be_bytes()),
2924        )
2925        .await?;
2926
2927        Ok(())
2928    }
2929
2930    /// Reorg the chain to a specific depth and mine new blocks back to the canonical height.
2931    ///
2932    /// e.g depth = 3
2933    ///     A  -> B  -> C  -> D  -> E
2934    ///     A  -> B  -> C' -> D' -> E'
2935    ///
2936    /// Depth specifies the height to reorg the chain back to. Depth must not exceed the current
2937    /// chain height, i.e. can't reorg past the genesis block.
2938    ///
2939    /// Optionally supply a list of transaction and block pairs that will populate the reorged
2940    /// blocks. The maximum block number of the pairs must not exceed the specified depth.
2941    ///
2942    /// Handler for RPC call: `anvil_reorg`
2943    pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2944        node_info!("anvil_reorg");
2945        let depth = options.depth;
2946        let tx_block_pairs = options.tx_block_pairs;
2947
2948        // Check reorg depth doesn't exceed current chain height
2949        let current_height = self.backend.best_number();
2950        let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2951            RpcError::invalid_params(format!(
2952                "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2953            )),
2954        ))?;
2955
2956        // Get the common ancestor block
2957        let common_block =
2958            self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2959
2960        // Convert the transaction requests to pool transactions if they exist, otherwise use empty
2961        // hashmap
2962        let block_pool_txs = if tx_block_pairs.is_empty() {
2963            HashMap::default()
2964        } else {
2965            let mut pairs = tx_block_pairs;
2966
2967            // Check the maximum block supplied number will not exceed the reorged chain height
2968            if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2969                return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2970                    "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2971                    depth - 1
2972                ))));
2973            }
2974
2975            // Sort by block number to make it easier to manage new nonces
2976            pairs.sort_by_key(|a| a.1);
2977
2978            // Manage nonces for each signer
2979            // address -> cumulative nonce
2980            let mut nonces: HashMap<Address, u64> = HashMap::default();
2981
2982            let mut txs: HashMap<u64, Vec<Arc<PoolTransaction<FoundryTxEnvelope>>>> =
2983                HashMap::default();
2984            for pair in pairs {
2985                let (tx_data, block_index) = pair;
2986
2987                let pending = match tx_data {
2988                    TransactionData::Raw(bytes) => {
2989                        let mut data = bytes.as_ref();
2990                        let decoded = FoundryTxEnvelope::decode_2718(&mut data)
2991                            .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2992                        PendingTransaction::new(decoded)?
2993                    }
2994
2995                    TransactionData::JSON(request) => {
2996                        let from = request.from.map(Ok).unwrap_or_else(|| {
2997                            self.accounts()?
2998                                .first()
2999                                .copied()
3000                                .ok_or(BlockchainError::NoSignerAvailable)
3001                        })?;
3002
3003                        // Get the nonce at the common block
3004                        let curr_nonce = nonces.entry(from).or_insert(
3005                            self.get_transaction_count(
3006                                from,
3007                                Some(common_block.header.number().into()),
3008                            )
3009                            .await?,
3010                        );
3011
3012                        // Build typed transaction request
3013                        let typed_tx = self.build_tx_request(request.into(), *curr_nonce).await?;
3014
3015                        // Increment nonce
3016                        *curr_nonce += 1;
3017
3018                        // Handle signer and convert to pending transaction
3019                        if self.is_impersonated(from) {
3020                            let transaction = sign::build_impersonated(typed_tx);
3021                            self.ensure_typed_transaction_supported(&transaction)?;
3022                            PendingTransaction::with_impersonated(transaction, from)
3023                        } else {
3024                            let transaction = self.sign_request(&from, typed_tx)?;
3025                            self.ensure_typed_transaction_supported(&transaction)?;
3026                            PendingTransaction::new(transaction)?
3027                        }
3028                    }
3029                };
3030
3031                let pooled = PoolTransaction::new(pending);
3032                txs.entry(block_index).or_default().push(Arc::new(pooled));
3033            }
3034
3035            txs
3036        };
3037
3038        self.backend.reorg(depth, block_pool_txs, common_block).await?;
3039        Ok(())
3040    }
3041
3042    /// Mine blocks, instantly.
3043    ///
3044    /// Handler for RPC call: `evm_mine`
3045    ///
3046    /// This will mine the blocks regardless of the configured mining mode.
3047    /// **Note**: ganache returns `0x0` here as placeholder for additional meta-data in the future.
3048    pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
3049        node_info!("evm_mine");
3050
3051        self.do_evm_mine(opts).await?;
3052
3053        Ok("0x0".to_string())
3054    }
3055
3056    /// Mine blocks, instantly and return the mined blocks.
3057    ///
3058    /// Handler for RPC call: `evm_mine_detailed`
3059    ///
3060    /// This will mine the blocks regardless of the configured mining mode.
3061    ///
3062    /// **Note**: This behaves exactly as [Self::evm_mine] but returns different output, for
3063    /// compatibility reasons, this is a separate call since `evm_mine` is not an anvil original.
3064    /// and `ganache` may change the `0x0` placeholder.
3065    pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
3066        node_info!("evm_mine_detailed");
3067
3068        let mined_blocks = self.do_evm_mine(opts).await?;
3069
3070        let mut blocks = Vec::with_capacity(mined_blocks as usize);
3071
3072        let latest = self.backend.best_number();
3073        for offset in (0..mined_blocks).rev() {
3074            let block_num = latest - offset;
3075            if let Some(mut block) =
3076                self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
3077            {
3078                let block_txs = match block.transactions_mut() {
3079                    BlockTransactions::Full(txs) => txs,
3080                    BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
3081                };
3082                for tx in block_txs.iter_mut() {
3083                    if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
3084                        && let Some(output) = receipt.out
3085                    {
3086                        // insert revert reason if failure
3087                        if !receipt.inner.as_ref().status()
3088                            && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
3089                        {
3090                            tx.other.insert(
3091                                "revertReason".to_string(),
3092                                serde_json::to_value(reason).expect("Infallible"),
3093                            );
3094                        }
3095                        tx.other.insert(
3096                            "output".to_string(),
3097                            serde_json::to_value(output).expect("Infallible"),
3098                        );
3099                    }
3100                }
3101                block.transactions = BlockTransactions::Full(block_txs.clone());
3102                blocks.push(block);
3103            }
3104        }
3105
3106        Ok(blocks)
3107    }
3108
3109    /// Execute a transaction regardless of signature status
3110    ///
3111    /// Handler for ETH RPC call: `eth_sendUnsignedTransaction`
3112    pub async fn eth_send_unsigned_transaction(
3113        &self,
3114        request: WithOtherFields<TransactionRequest>,
3115    ) -> Result<TxHash> {
3116        node_info!("eth_sendUnsignedTransaction");
3117        // either use the impersonated account of the request's `from` field
3118        let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
3119
3120        let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
3121
3122        let typed_tx = self.build_tx_request(request, nonce).await?;
3123
3124        let transaction = sign::build_impersonated(typed_tx);
3125
3126        self.ensure_typed_transaction_supported(&transaction)?;
3127
3128        let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
3129
3130        // pre-validate
3131        self.backend.validate_pool_transaction(&pending_transaction).await?;
3132
3133        let requires = required_marker(nonce, on_chain_nonce, from);
3134        let provides = vec![to_marker(nonce, from)];
3135
3136        self.add_pending_transaction(pending_transaction, requires, provides)
3137    }
3138
3139    /// Returns a summary of all the transactions currently pending for inclusion in the next
3140    /// block(s), as well as the ones that are being scheduled for future execution only.
3141    ///
3142    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect) for more details
3143    ///
3144    /// Handler for ETH RPC call: `txpool_inspect`
3145    pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
3146        node_info!("txpool_inspect");
3147        let mut inspect = TxpoolInspect::default();
3148
3149        fn convert(tx: Arc<PoolTransaction<FoundryTxEnvelope>>) -> TxpoolInspectSummary {
3150            let tx = &tx.pending_transaction.transaction;
3151            let to = tx.to();
3152            let gas_price = tx.max_fee_per_gas();
3153            let value = tx.value();
3154            let gas = tx.gas_limit();
3155            TxpoolInspectSummary { to, value, gas, gas_price }
3156        }
3157
3158        // Note: naming differs geth vs anvil:
3159        //
3160        // _Pending transactions_ are transactions that are ready to be processed and included in
3161        // the block. _Queued transactions_ are transactions where the transaction nonce is
3162        // not in sequence. The transaction nonce is an incrementing number for each transaction
3163        // with the same From address.
3164        for pending in self.pool.ready_transactions() {
3165            let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
3166            let key = pending.pending_transaction.nonce().to_string();
3167            entry.insert(key, convert(pending));
3168        }
3169        for queued in self.pool.pending_transactions() {
3170            let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
3171            let key = queued.pending_transaction.nonce().to_string();
3172            entry.insert(key, convert(queued));
3173        }
3174        Ok(inspect)
3175    }
3176
3177    /// Returns the details of all transactions currently pending for inclusion in the next
3178    /// block(s), as well as the ones that are being scheduled for future execution only.
3179    ///
3180    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content) for more details
3181    ///
3182    /// Handler for ETH RPC call: `txpool_inspect`
3183    pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
3184        node_info!("txpool_content");
3185        let mut content = TxpoolContent::<AnyRpcTransaction>::default();
3186        fn convert(tx: Arc<PoolTransaction<FoundryTxEnvelope>>) -> Result<AnyRpcTransaction> {
3187            let from = *tx.pending_transaction.sender();
3188            let tx = transaction_build(
3189                Some(tx.hash()),
3190                tx.pending_transaction.transaction.clone(),
3191                None,
3192                None,
3193                None,
3194            );
3195
3196            let WithOtherFields { inner: mut tx, other } = tx.0;
3197
3198            // we set the from field here explicitly to the set sender of the pending transaction,
3199            // in case the transaction is impersonated.
3200            tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
3201
3202            let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
3203
3204            Ok(tx)
3205        }
3206
3207        for pending in self.pool.ready_transactions() {
3208            let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
3209            let key = pending.pending_transaction.nonce().to_string();
3210            entry.insert(key, convert(pending)?);
3211        }
3212        for queued in self.pool.pending_transactions() {
3213            let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
3214            let key = queued.pending_transaction.nonce().to_string();
3215            entry.insert(key, convert(queued)?);
3216        }
3217
3218        Ok(content)
3219    }
3220}
3221
3222impl EthApi<FoundryNetwork> {
3223    /// Executes the `evm_mine` and returns the number of blocks mined
3224    async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
3225        let mut blocks_to_mine = 1u64;
3226
3227        if let Some(opts) = opts {
3228            let timestamp = match opts {
3229                MineOptions::Timestamp(timestamp) => timestamp,
3230                MineOptions::Options { timestamp, blocks } => {
3231                    if let Some(blocks) = blocks {
3232                        blocks_to_mine = blocks;
3233                    }
3234                    timestamp
3235                }
3236            };
3237            if let Some(timestamp) = timestamp {
3238                // timestamp was explicitly provided to be the next timestamp
3239                self.evm_set_next_block_timestamp(timestamp)?;
3240            }
3241        }
3242
3243        // this can be blocking for a bit, especially in forking mode
3244        // <https://github.com/foundry-rs/foundry/issues/6036>
3245        self.on_blocking_task(|this| async move {
3246            // mine all the blocks
3247            for _ in 0..blocks_to_mine {
3248                this.mine_one().await;
3249            }
3250            Ok(())
3251        })
3252        .await?;
3253
3254        Ok(blocks_to_mine)
3255    }
3256
3257    async fn do_estimate_gas(
3258        &self,
3259        request: WithOtherFields<TransactionRequest>,
3260        block_number: Option<BlockId>,
3261        overrides: EvmOverrides,
3262    ) -> Result<u128> {
3263        let block_request = self.block_request(block_number).await?;
3264        // check if the number predates the fork, if in fork mode
3265        if let BlockRequest::Number(number) = block_request
3266            && let Some(fork) = self.get_fork()
3267            && fork.predates_fork(number)
3268        {
3269            if overrides.has_state() || overrides.has_block() {
3270                return Err(BlockchainError::EvmOverrideError(
3271                    "not available on past forked blocks".to_string(),
3272                ));
3273            }
3274            return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
3275        }
3276
3277        // this can be blocking for a bit, especially in forking mode
3278        // <https://github.com/foundry-rs/foundry/issues/6036>
3279        self.on_blocking_task(|this| async move {
3280            this.backend
3281                .with_database_at(Some(block_request), |state, mut block| {
3282                    let mut cache_db = CacheDB::new(state);
3283                    if let Some(state_overrides) = overrides.state {
3284                        apply_state_overrides(
3285                            state_overrides.into_iter().collect(),
3286                            &mut cache_db,
3287                        )?;
3288                    }
3289                    if let Some(block_overrides) = overrides.block {
3290                        cache_db.apply_block_overrides(*block_overrides, &mut block);
3291                    }
3292                    this.do_estimate_gas_with_state(request, &cache_db, block)
3293                })
3294                .await?
3295        })
3296        .await
3297    }
3298
3299    /// Returns the priority of the transaction based on the current `TransactionOrder`
3300    fn transaction_priority(&self, tx: &FoundryTxEnvelope) -> TransactionPriority {
3301        self.transaction_order.read().priority(tx)
3302    }
3303
3304    /// Returns a listener for pending transactions, yielding full transactions
3305    pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3306        let (tx, rx) = unbounded_channel();
3307        let mut hashes = self.new_ready_transactions();
3308
3309        let this = self.clone();
3310
3311        tokio::spawn(async move {
3312            while let Some(hash) = hashes.next().await {
3313                if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3314                    && tx.send(txn).is_err()
3315                {
3316                    break;
3317                }
3318            }
3319        });
3320
3321        rx
3322    }
3323
3324    /// Mines exactly one block
3325    pub async fn mine_one(&self) {
3326        let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3327        let outcome = self.backend.mine_block(transactions).await;
3328
3329        trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3330        self.pool.on_mined_block(outcome);
3331    }
3332
3333    /// Returns the pending block with tx hashes
3334    async fn pending_block(&self) -> AnyRpcBlock {
3335        let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3336        let info = self.backend.pending_block(transactions).await;
3337        self.backend.convert_block(info.block)
3338    }
3339
3340    /// Returns the full pending block with `Transaction` objects
3341    async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3342        let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3343        let BlockInfo { block, transactions, receipts: _ } =
3344            self.backend.pending_block(transactions).await;
3345
3346        let mut partial_block = self.backend.convert_block(block.clone());
3347
3348        let mut block_transactions = Vec::with_capacity(block.body.transactions.len());
3349        let base_fee = self.backend.base_fee();
3350
3351        for info in transactions {
3352            let tx = block.body.transactions.get(info.transaction_index as usize)?.clone();
3353
3354            let tx = transaction_build(
3355                Some(info.transaction_hash),
3356                tx,
3357                Some(&block),
3358                Some(info),
3359                Some(base_fee),
3360            );
3361            block_transactions.push(tx);
3362        }
3363
3364        partial_block.transactions = BlockTransactions::from(block_transactions);
3365
3366        Some(partial_block)
3367    }
3368
3369    /// Prepares transaction request by filling missing fields using Anvil's API, then attempts
3370    /// to build a [`FoundryTypedTx`].
3371    async fn build_tx_request(
3372        &self,
3373        request: WithOtherFields<TransactionRequest>,
3374        nonce: u64,
3375    ) -> Result<FoundryTypedTx> {
3376        let mut request = Into::<FoundryTransactionRequest>::into(request);
3377        let from = request.from().or(self.accounts()?.first().copied());
3378
3379        // Fill common fields for all tx types
3380        request.chain_id().is_none().then(|| request.set_chain_id(self.chain_id()));
3381        request.nonce().is_none().then(|| request.set_nonce(nonce));
3382        request.kind().is_none().then(|| request.set_kind(TxKind::default()));
3383        if request.gas_limit().is_none() {
3384            request.set_gas_limit(
3385                self.do_estimate_gas(
3386                    request.as_ref().clone().into(),
3387                    None,
3388                    EvmOverrides::default(),
3389                )
3390                .await
3391                .map(|v| v as u64)
3392                .unwrap_or(self.backend.gas_limit()),
3393            );
3394        }
3395
3396        // Fill missing tx type specific fields
3397        if let Err((tx_type, _)) = request.missing_keys() {
3398            if matches!(tx_type, FoundryTxType::Legacy | FoundryTxType::Eip2930) {
3399                request.gas_price().is_none().then(|| request.set_gas_price(self.gas_price()));
3400            }
3401            if tx_type == FoundryTxType::Eip2930 {
3402                request
3403                    .access_list()
3404                    .is_none()
3405                    .then(|| request.set_access_list(Default::default()));
3406            }
3407            if matches!(
3408                tx_type,
3409                FoundryTxType::Eip1559
3410                    | FoundryTxType::Eip4844
3411                    | FoundryTxType::Eip7702
3412                    | FoundryTxType::Tempo
3413            ) {
3414                request
3415                    .max_fee_per_gas()
3416                    .is_none()
3417                    .then(|| request.set_max_fee_per_gas(self.gas_price()));
3418                request
3419                    .max_priority_fee_per_gas()
3420                    .is_none()
3421                    .then(|| request.set_max_priority_fee_per_gas(MIN_SUGGESTED_PRIORITY_FEE));
3422            }
3423            if tx_type == FoundryTxType::Eip4844 {
3424                request.as_ref().max_fee_per_blob_gas().is_none().then(|| {
3425                    request.as_mut().set_max_fee_per_blob_gas(
3426                        self.backend.fees().get_next_block_blob_base_fee_per_gas(),
3427                    )
3428                });
3429            }
3430        }
3431
3432        match request
3433            .build_unsigned()
3434            .map_err(|e| BlockchainError::InvalidTransactionRequest(e.to_string()))?
3435        {
3436            FoundryTypedTx::Eip4844(TxEip4844Variant::TxEip4844(_))
3437                if !self.backend.skip_blob_validation(from) =>
3438            {
3439                // If blob validation is not skipped, reject TxEip4844 variant without sidecar.
3440                Err(BlockchainError::FailedToDecodeTransaction)
3441            }
3442            res => Ok(res),
3443        }
3444    }
3445
3446    /// Returns the nonce of the `address` depending on the `block_number`
3447    async fn get_transaction_count(
3448        &self,
3449        address: Address,
3450        block_number: Option<BlockId>,
3451    ) -> Result<u64> {
3452        let block_request = self.block_request(block_number).await?;
3453
3454        if let BlockRequest::Number(number) = block_request
3455            && let Some(fork) = self.get_fork()
3456            && fork.predates_fork(number)
3457        {
3458            return Ok(fork.get_nonce(address, number).await?);
3459        }
3460
3461        self.backend.get_nonce(address, block_request).await
3462    }
3463
3464    /// Returns the nonce for this request
3465    ///
3466    /// This returns a tuple of `(request nonce, highest nonce)`
3467    /// If the nonce field of the `request` is `None` then the tuple will be `(highest nonce,
3468    /// highest nonce)`.
3469    ///
3470    /// This will also check the tx pool for pending transactions from the sender.
3471    async fn request_nonce(
3472        &self,
3473        request: &TransactionRequest,
3474        from: Address,
3475    ) -> Result<(u64, u64)> {
3476        let highest_nonce =
3477            self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3478        let nonce = request.nonce.unwrap_or(highest_nonce);
3479
3480        Ok((nonce, highest_nonce))
3481    }
3482
3483    /// Adds the given transaction to the pool
3484    fn add_pending_transaction(
3485        &self,
3486        pending_transaction: PendingTransaction<FoundryTxEnvelope>,
3487        requires: Vec<TxMarker>,
3488        provides: Vec<TxMarker>,
3489    ) -> Result<TxHash> {
3490        let from = *pending_transaction.sender();
3491        let priority = self.transaction_priority(&pending_transaction.transaction);
3492        let pool_transaction =
3493            PoolTransaction { requires, provides, pending_transaction, priority };
3494        let tx = self.pool.add_transaction(pool_transaction)?;
3495        trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3496        Ok(*tx.hash())
3497    }
3498
3499    /// additional validation against hardfork
3500    fn ensure_typed_transaction_supported(&self, tx: &FoundryTxEnvelope) -> Result<()> {
3501        match &tx {
3502            FoundryTxEnvelope::Eip2930(_) => self.backend.ensure_eip2930_active(),
3503            FoundryTxEnvelope::Eip1559(_) => self.backend.ensure_eip1559_active(),
3504            FoundryTxEnvelope::Eip4844(_) => self.backend.ensure_eip4844_active(),
3505            FoundryTxEnvelope::Eip7702(_) => self.backend.ensure_eip7702_active(),
3506            FoundryTxEnvelope::Deposit(_) => self.backend.ensure_op_deposits_active(),
3507            FoundryTxEnvelope::Legacy(_) => Ok(()),
3508            FoundryTxEnvelope::Tempo(_) => self.backend.ensure_tempo_active(),
3509        }
3510    }
3511}
3512
3513fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3514    if provided_nonce == on_chain_nonce {
3515        return Vec::new();
3516    }
3517    let prev_nonce = provided_nonce.saturating_sub(1);
3518    if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3519}
3520
3521fn convert_transact_out(out: &Option<Output>) -> Bytes {
3522    match out {
3523        None => Default::default(),
3524        Some(Output::Call(out)) => out.to_vec().into(),
3525        Some(Output::Create(out, _)) => out.to_vec().into(),
3526    }
3527}
3528
3529/// Returns an error if the `exit` code is _not_ ok
3530fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3531    let out = convert_transact_out(out);
3532    match exit {
3533        return_ok!() => Ok(out),
3534        return_revert!() => Err(InvalidTransactionError::Revert(Some(out)).into()),
3535        reason => Err(BlockchainError::EvmError(reason)),
3536    }
3537}
3538
3539/// Determines the minimum gas needed for a transaction depending on the transaction kind.
3540fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3541    match request.kind() {
3542        Some(TxKind::Call(_)) => {
3543            MIN_TRANSACTION_GAS
3544                + request.inner().authorization_list.as_ref().map_or(0, |auths_list| {
3545                    auths_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3546                })
3547        }
3548        Some(TxKind::Create) => MIN_CREATE_GAS,
3549        // Tighten the gas limit upwards if we don't know the tx kind to avoid deployments failing.
3550        None => MIN_CREATE_GAS,
3551    }
3552}
3553
3554/// Keeps result of a call to revm EVM used for gas estimation
3555enum GasEstimationCallResult {
3556    Success(u128),
3557    OutOfGas,
3558    Revert(Option<Bytes>),
3559    EvmError(InstructionResult),
3560}
3561
3562/// Converts the result of a call to revm EVM into a [`GasEstimationCallResult`].
3563///
3564/// Expected to stay up to date with: <https://github.com/bluealloy/revm/blob/main/crates/interpreter/src/instruction_result.rs>
3565impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3566    type Error = BlockchainError;
3567
3568    fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3569        match res {
3570            // Exceptional case: init used too much gas, treated as out of gas error
3571            Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3572                Ok(Self::OutOfGas)
3573            }
3574            // Tempo intrinsic gas errors come through as Message variants
3575            Err(BlockchainError::Message(ref msg))
3576                if msg.contains("insufficient gas for intrinsic cost") =>
3577            {
3578                Ok(Self::OutOfGas)
3579            }
3580            Err(err) => Err(err),
3581            Ok((exit, output, gas, _)) => match exit {
3582                return_ok!() => Ok(Self::Success(gas)),
3583
3584                // Revert opcodes:
3585                InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3586                InstructionResult::CallTooDeep
3587                | InstructionResult::OutOfFunds
3588                | InstructionResult::CreateInitCodeStartingEF00
3589                | InstructionResult::InvalidEOFInitCode
3590                | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3591
3592                // Out of gas errors:
3593                InstructionResult::OutOfGas
3594                | InstructionResult::MemoryOOG
3595                | InstructionResult::MemoryLimitOOG
3596                | InstructionResult::PrecompileOOG
3597                | InstructionResult::InvalidOperandOOG
3598                | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3599
3600                // Other errors:
3601                InstructionResult::OpcodeNotFound
3602                | InstructionResult::CallNotAllowedInsideStatic
3603                | InstructionResult::StateChangeDuringStaticCall
3604                | InstructionResult::InvalidFEOpcode
3605                | InstructionResult::InvalidJump
3606                | InstructionResult::NotActivated
3607                | InstructionResult::StackUnderflow
3608                | InstructionResult::StackOverflow
3609                | InstructionResult::OutOfOffset
3610                | InstructionResult::CreateCollision
3611                | InstructionResult::OverflowPayment
3612                | InstructionResult::PrecompileError
3613                | InstructionResult::NonceOverflow
3614                | InstructionResult::CreateContractSizeLimit
3615                | InstructionResult::CreateContractStartingWithEF
3616                | InstructionResult::CreateInitCodeSizeLimit
3617                | InstructionResult::InvalidImmediateEncoding
3618                | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3619            },
3620        }
3621    }
3622}