Skip to main content

anvil/eth/
api.rs

1use super::{
2    backend::mem::{BlockRequest, DatabaseRef, State, sanitize_simulation_blocks},
3    preserve_simulation_request_fields,
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::ChainNotifications,
13            validate::TransactionValidator,
14        },
15        error::{
16            BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
17        },
18        fees::{
19            FeeDetails, FeeHistoryCache, FeeHistoryCacheItem, MIN_SUGGESTED_PRIORITY_FEE,
20            create_fee_history_cache_item,
21        },
22        macros::node_info,
23        miner::FixedBlockTimeMiner,
24        pool::{
25            Pool,
26            transactions::{
27                PoolTransaction, TransactionOrder, TransactionPriority, TxMarker, to_marker,
28            },
29        },
30        sign::Signer,
31    },
32    filter::{EthFilter, Filters, LogsFilter},
33    mem::transaction_build,
34};
35use alloy_consensus::{
36    Blob, BlockHeader, Transaction, TrieAccount, TxEip4844Variant, TxReceipt,
37    transaction::Recovered,
38};
39use alloy_dyn_abi::TypedData;
40use alloy_eips::{
41    eip2718::Encodable2718,
42    eip7910::{EthConfig, EthForkConfig},
43};
44use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
45use alloy_network::{
46    AnyRpcBlock, AnyRpcHeader, AnyRpcTransaction, BlockResponse, Network,
47    NetworkTransactionBuilder, ReceiptResponse, TransactionBuilder, TransactionBuilder4844,
48    TransactionResponse, eip2718::Decodable2718,
49};
50use alloy_primitives::{
51    Address, B64, B256, Bytes, TxHash, TxKind, U64, U256,
52    map::{HashMap, HashSet},
53};
54use alloy_rpc_types::{
55    AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
56    EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
57    anvil::{
58        ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
59    },
60    erc4337::TransactionConditional,
61    pubsub::TransactionReceiptsParams,
62    request::TransactionRequest,
63    simulate::{MAX_SIMULATE_BLOCKS, SimulatePayload, SimulatedBlock},
64    state::{AccountOverride, EvmOverrides, StateOverride, StateOverridesBuilder},
65    trace::{
66        filter::TraceFilter,
67        geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult},
68        opcode::{BlockOpcodeGas, TransactionOpcodeGas},
69        parity::{
70            LocalizedTransactionTrace, TraceResults, TraceResultsWithTransactionHash, TraceType,
71        },
72    },
73    txpool::{TxpoolContent, TxpoolContentFrom, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
74};
75use alloy_rpc_types_eth::{AccountInfo, Bundle, EthCallResponse, FillTransaction, StateContext};
76use alloy_rpc_types_mev::{EthCallBundle, EthCallBundleResponse};
77use alloy_serde::WithOtherFields;
78use alloy_sol_types::{SolCall, SolValue, sol};
79use anvil_core::{
80    eth::{
81        EthRequest,
82        block::{BlockInfo, canonical_block},
83        transaction::{MaybeImpersonatedTransaction, PendingTransaction},
84    },
85    types::{ReorgOptions, TransactionData},
86};
87use anvil_rpc::{
88    error::{ErrorCode, RpcError},
89    response::ResponseResult,
90};
91use foundry_common::{
92    tempo::{PaymentLaneClassification, PaymentLaneReason, classify_payment_lane},
93    version::{COMMIT_SHA, SEMVER_VERSION},
94};
95use foundry_evm::decode::RevertDecoder;
96use foundry_primitives::{
97    FoundryNetwork, FoundryReceiptEnvelope, FoundryTransactionRequest, FoundryTxEnvelope,
98    FoundryTxReceipt, FoundryTxType, FoundryTypedTx,
99};
100use futures::{
101    StreamExt, TryFutureExt,
102    channel::{mpsc::Receiver, oneshot},
103};
104use parking_lot::RwLock;
105use revm::{
106    context::{BlockEnv, Cfg},
107    context_interface::{
108        block::BlobExcessGasAndPrice,
109        result::{HaltReason, Output},
110    },
111    database::CacheDB,
112    interpreter::{InstructionResult, SuccessOrHalt, return_ok, return_revert},
113    primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
114};
115use std::{sync::Arc, time::Duration};
116use tempo_hardfork::TempoHardfork;
117use tokio::{
118    sync::mpsc::{self, UnboundedReceiver, unbounded_channel},
119    try_join,
120};
121
122/// The client version: `anvil/v{major}.{minor}.{patch}`
123pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
124
125/// The entry point for executing eth api RPC call - The Eth RPC interface.
126///
127/// This type is cheap to clone and can be used concurrently
128pub struct EthApi<N: Network> {
129    /// The transaction pool
130    pool: Arc<Pool<N::TxEnvelope>>,
131    /// Holds all blockchain related data
132    /// In-Memory only for now
133    pub backend: Arc<backend::mem::Backend<N>>,
134    /// Whether this node is mining
135    is_mining: bool,
136    /// available signers
137    signers: Arc<Vec<Box<dyn Signer<N>>>>,
138    /// data required for `eth_feeHistory`
139    fee_history_cache: FeeHistoryCache,
140    /// max number of items kept in fee cache
141    fee_history_limit: u64,
142    /// access to the actual miner
143    ///
144    /// This access is required in order to adjust miner settings based on requests received from
145    /// custom RPC endpoints
146    miner: Miner<N::TxEnvelope>,
147    /// allows to enabled/disable logging
148    logger: LoggingManager,
149    /// Tracks all active filters
150    filters: Filters<N>,
151    /// How transactions are ordered in the pool
152    transaction_order: Arc<RwLock<TransactionOrder>>,
153    /// Whether we're listening for RPC calls
154    net_listening: bool,
155    /// The instance ID. Changes on every reset.
156    instance_id: Arc<RwLock<B256>>,
157}
158
159impl<N: Network> Clone for EthApi<N> {
160    fn clone(&self) -> Self {
161        Self {
162            pool: self.pool.clone(),
163            backend: self.backend.clone(),
164            is_mining: self.is_mining,
165            signers: self.signers.clone(),
166            fee_history_cache: self.fee_history_cache.clone(),
167            fee_history_limit: self.fee_history_limit,
168            miner: self.miner.clone(),
169            logger: self.logger.clone(),
170            filters: self.filters.clone(),
171            transaction_order: self.transaction_order.clone(),
172            net_listening: self.net_listening,
173            instance_id: self.instance_id.clone(),
174        }
175    }
176}
177
178// == impl EthApi<N: Network> generic methods ==
179
180impl<N: Network> EthApi<N> {
181    /// Creates a new instance
182    #[expect(clippy::too_many_arguments)]
183    pub fn new(
184        pool: Arc<Pool<N::TxEnvelope>>,
185        backend: Arc<backend::mem::Backend<N>>,
186        signers: Arc<Vec<Box<dyn Signer<N>>>>,
187        fee_history_cache: FeeHistoryCache,
188        fee_history_limit: u64,
189        miner: Miner<N::TxEnvelope>,
190        logger: LoggingManager,
191        filters: Filters<N>,
192        transactions_order: TransactionOrder,
193    ) -> Self {
194        Self {
195            pool,
196            backend,
197            is_mining: true,
198            signers,
199            fee_history_cache,
200            fee_history_limit,
201            miner,
202            logger,
203            filters,
204            net_listening: true,
205            transaction_order: Arc::new(RwLock::new(transactions_order)),
206            instance_id: Arc::new(RwLock::new(B256::random())),
207        }
208    }
209
210    /// Returns the current gas price
211    pub fn gas_price(&self) -> u128 {
212        if self.backend.is_eip1559() {
213            if self.backend.is_min_priority_fee_enforced() {
214                (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
215            } else {
216                self.backend.base_fee() as u128
217            }
218        } else {
219            self.backend.fees().raw_gas_price()
220        }
221    }
222
223    /// Returns the suggested fee cap.
224    ///
225    /// Returns at least [MIN_SUGGESTED_PRIORITY_FEE]
226    fn lowest_suggestion_tip(&self) -> u128 {
227        let block_number = self.backend.best_number();
228        let cache = self.fee_history_cache.lock();
229        let latest_tip = self
230            .backend
231            .get_block_with_hash(block_number)
232            .and_then(|(_, hash)| cache.get(&block_number).filter(|item| item.block_hash == hash))
233            .and_then(|item| item.rewards.iter().copied().min());
234
235        latest_tip
236            .or_else(|| {
237                cache
238                    .iter()
239                    .filter(|(number, item)| {
240                        self.backend
241                            .get_block_with_hash(**number)
242                            .is_some_and(|(_, hash)| item.block_hash == hash)
243                    })
244                    .flat_map(|(_, item)| item.rewards.iter().copied())
245                    .min()
246            })
247            .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
248            .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
249    }
250
251    /// Returns true if auto mining is enabled, and false.
252    ///
253    /// Handler for ETH RPC call: `anvil_getAutomine`
254    pub fn anvil_get_auto_mine(&self) -> Result<bool> {
255        node_info!("anvil_getAutomine");
256        Ok(self.miner.is_auto_mine())
257    }
258
259    /// Returns the value of mining interval, if set.
260    ///
261    /// Handler for ETH RPC call: `anvil_getIntervalMining`.
262    pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
263        node_info!("anvil_getIntervalMining");
264        Ok(self.miner.get_interval())
265    }
266
267    /// Enables or disables, based on the single boolean argument, the automatic mining of new
268    /// blocks with each new transaction submitted to the network.
269    ///
270    /// Handler for ETH RPC call: `evm_setAutomine`
271    pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
272        node_info!("evm_setAutomine");
273        if self.miner.is_auto_mine() {
274            if enable_automine {
275                return Ok(());
276            }
277            self.miner.set_mining_mode(MiningMode::None);
278        } else if enable_automine {
279            let listener = self.pool.add_ready_listener();
280            let mode = MiningMode::instant(1_000, listener);
281            self.miner.set_mining_mode(mode);
282        }
283        Ok(())
284    }
285
286    /// Sets the mining behavior to interval with the given interval (seconds)
287    ///
288    /// Handler for ETH RPC call: `evm_setIntervalMining`
289    pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
290        node_info!("evm_setIntervalMining");
291        let mining_mode = if secs == 0 {
292            MiningMode::None
293        } else {
294            let block_time = Duration::from_secs(secs);
295
296            // This ensures that memory limits are stricter in interval-mine mode
297            self.backend.update_interval_mine_block_time(block_time);
298
299            MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
300        };
301        self.miner.set_mining_mode(mining_mode);
302        Ok(())
303    }
304
305    /// Removes transactions from the pool
306    ///
307    /// Handler for RPC call: `anvil_dropTransaction`
308    pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
309        node_info!("anvil_dropTransaction");
310        Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
311    }
312
313    /// Removes all transactions from the pool
314    ///
315    /// Handler for RPC call: `anvil_dropAllTransactions`
316    pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
317        node_info!("anvil_dropAllTransactions");
318        self.pool.clear();
319        Ok(())
320    }
321
322    /// Clears all transactions from the pool.
323    ///
324    /// Handler for RPC call: `debug_clearTxpool`
325    pub async fn debug_clear_txpool(&self) -> Result<()> {
326        node_info!("debug_clearTxpool");
327        self.pool.clear();
328        Ok(())
329    }
330
331    pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
332        node_info!("anvil_setChainId");
333        self.backend.set_chain_id(chain_id);
334        Ok(())
335    }
336
337    /// Modifies the balance of an account.
338    ///
339    /// Handler for RPC call: `anvil_setBalance`
340    pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
341        node_info!("anvil_setBalance");
342        self.backend.set_balance(address, balance).await?;
343        Ok(())
344    }
345
346    /// Sets the code of a contract.
347    ///
348    /// Handler for RPC call: `anvil_setCode`
349    pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
350        node_info!("anvil_setCode");
351        self.backend.set_code(address, code).await?;
352        Ok(())
353    }
354
355    /// Sets the nonce of an address.
356    ///
357    /// Handler for RPC call: `anvil_setNonce`
358    pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
359        node_info!("anvil_setNonce");
360        self.backend.set_nonce(address, nonce).await?;
361        Ok(())
362    }
363
364    /// Writes a single slot of the account's storage.
365    ///
366    /// Handler for RPC call: `anvil_setStorageAt`
367    pub async fn anvil_set_storage_at(
368        &self,
369        address: Address,
370        slot: U256,
371        val: B256,
372    ) -> Result<bool> {
373        node_info!("anvil_setStorageAt");
374        self.backend.set_storage_at(address, slot, val).await?;
375        Ok(true)
376    }
377
378    /// Enable or disable logging.
379    ///
380    /// Handler for RPC call: `anvil_setLoggingEnabled`
381    pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
382        node_info!("anvil_setLoggingEnabled");
383        self.logger.set_enabled(enable);
384        Ok(())
385    }
386
387    /// Set the minimum gas price for the node.
388    ///
389    /// Handler for RPC call: `anvil_setMinGasPrice`
390    pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
391        node_info!("anvil_setMinGasPrice");
392        if self.backend.is_eip1559() {
393            return Err(RpcError::invalid_params(
394                "anvil_setMinGasPrice is not supported when EIP-1559 is active",
395            )
396            .into());
397        }
398        self.backend.set_gas_price(gas.saturating_to());
399        Ok(())
400    }
401
402    /// Sets the base fee of the next block.
403    ///
404    /// Handler for RPC call: `anvil_setNextBlockBaseFeePerGas`
405    pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
406        node_info!("anvil_setNextBlockBaseFeePerGas");
407        if !self.backend.is_eip1559() {
408            return Err(RpcError::invalid_params(
409                "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
410            )
411            .into());
412        }
413        self.backend.set_base_fee(basefee.saturating_to());
414        Ok(())
415    }
416
417    /// Sets the coinbase address.
418    ///
419    /// Handler for RPC call: `anvil_setCoinbase`
420    pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
421        node_info!("anvil_setCoinbase");
422        self.backend.set_coinbase(address);
423        Ok(())
424    }
425
426    /// Sets the `prevrandao` value of the next block.
427    ///
428    /// This is a one-shot override: it applies to the next mined block only, after which anvil
429    /// resumes deriving `prevrandao` from the parent hash and block number.
430    ///
431    /// Handler for RPC call: `anvil_setNextBlockPrevRandao`
432    pub async fn anvil_set_next_block_prevrandao(&self, prevrandao: B256) -> Result<()> {
433        node_info!("anvil_setNextBlockPrevRandao");
434        self.backend.set_next_block_prevrandao(prevrandao);
435        Ok(())
436    }
437
438    /// Retrieves the Anvil node configuration params.
439    ///
440    /// Handler for RPC call: `anvil_nodeInfo`
441    pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
442        node_info!("anvil_nodeInfo");
443
444        let evm_env = self.backend.evm_env().read();
445        let fork_config = self.backend.get_fork();
446        let tx_order = self.transaction_order.read();
447        let hard_fork = self.backend.hardfork().name();
448
449        Ok(NodeInfo {
450            current_block_number: self.backend.best_number(),
451            current_block_timestamp: evm_env.block_env.timestamp.saturating_to(),
452            current_block_hash: self.backend.best_hash(),
453            hard_fork,
454            transaction_order: match *tx_order {
455                TransactionOrder::Fifo => "fifo".to_string(),
456                TransactionOrder::Fees => "fees".to_string(),
457            },
458            environment: NodeEnvironment {
459                base_fee: self.backend.base_fee() as u128,
460                chain_id: self.backend.chain_id().to::<u64>(),
461                gas_limit: self.backend.gas_limit(),
462                gas_price: self.gas_price(),
463            },
464            fork_config: fork_config
465                .map(|fork| {
466                    let config = fork.config.read();
467
468                    NodeForkConfig {
469                        fork_url: config.eth_rpc_url().map(|s| s.to_string()),
470                        fork_block_number: Some(config.block_number),
471                        fork_retry_backoff: Some(config.backoff.as_millis()),
472                    }
473                })
474                .unwrap_or_default(),
475            network: self.backend.is_tempo().then(|| "tempo".to_string()),
476        })
477    }
478
479    /// Retrieves metadata about the Anvil instance.
480    ///
481    /// Handler for RPC call: `anvil_metadata`
482    pub async fn anvil_metadata(&self) -> Result<Metadata> {
483        node_info!("anvil_metadata");
484        let fork_config = self.backend.get_fork();
485
486        Ok(Metadata {
487            client_version: CLIENT_VERSION.to_string(),
488            client_semver: Some(SEMVER_VERSION.to_string()),
489            client_commit_sha: Some(COMMIT_SHA.to_string()),
490            chain_id: self.backend.chain_id().to::<u64>(),
491            latest_block_hash: self.backend.best_hash(),
492            latest_block_number: self.backend.best_number(),
493            instance_id: *self.instance_id.read(),
494            forked_network: fork_config.map(|cfg| ForkedNetwork {
495                chain_id: cfg.chain_id(),
496                fork_block_number: cfg.block_number(),
497                fork_block_hash: cfg.block_hash(),
498            }),
499            snapshots: self.backend.list_state_snapshots(),
500        })
501    }
502
503    pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
504        node_info!("anvil_removePoolTransactions");
505        self.pool.remove_transactions_by_address(address);
506        Ok(())
507    }
508
509    /// Snapshot the state of the blockchain at the current block.
510    ///
511    /// Handler for RPC call: `evm_snapshot`
512    pub async fn evm_snapshot(&self) -> Result<U256> {
513        node_info!("evm_snapshot");
514        Ok(self.backend.create_state_snapshot().await)
515    }
516
517    /// Jump forward in time by the given amount of time, in seconds.
518    ///
519    /// Handler for RPC call: `evm_increaseTime`
520    pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
521        node_info!("evm_increaseTime");
522        Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
523    }
524
525    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block
526    ///
527    /// Handler for RPC call: `evm_setNextBlockTimestamp`
528    pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
529        node_info!("evm_setNextBlockTimestamp");
530        self.backend.time().set_next_block_timestamp(seconds)
531    }
532
533    /// Sets the specific timestamp and returns the number of seconds between the given timestamp
534    /// and the current time.
535    ///
536    /// The `timestamp` is in seconds. The `evm_setTime` JSON-RPC method accepts both seconds and
537    /// milliseconds (values above 1e12 are treated as milliseconds); the RPC handler normalises
538    /// the input to seconds before calling this function.
539    ///
540    /// Handler for RPC call: `evm_setTime`
541    pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
542        node_info!("evm_setTime");
543        let now = self.backend.time().current_call_timestamp();
544        self.backend.time().reset(timestamp);
545
546        // number of seconds between the given timestamp and the current time.
547        let offset = timestamp.saturating_sub(now);
548        Ok(offset)
549    }
550
551    /// Set the next block gas limit
552    ///
553    /// Handler for RPC call: `evm_setBlockGasLimit`
554    pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
555        node_info!("evm_setBlockGasLimit");
556        self.backend.set_gas_limit(gas_limit.saturating_to());
557        Ok(true)
558    }
559
560    /// Sets an interval for the block timestamp
561    ///
562    /// Handler for RPC call: `anvil_setBlockTimestampInterval`
563    pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
564        node_info!("anvil_setBlockTimestampInterval");
565        self.backend.time().set_block_timestamp_interval(seconds);
566        Ok(())
567    }
568
569    /// Sets an interval for the block timestamp
570    ///
571    /// Handler for RPC call: `anvil_removeBlockTimestampInterval`
572    pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
573        node_info!("anvil_removeBlockTimestampInterval");
574        Ok(self.backend.time().remove_block_timestamp_interval())
575    }
576
577    /// Sets the backend rpc url
578    ///
579    /// Handler for ETH RPC call: `anvil_setRpcUrl`
580    pub async fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
581        node_info!("anvil_setRpcUrl");
582        if let Some(fork) = self.backend.get_fork() {
583            let urls = vec![url.clone()];
584            let config = fork.config.read().clone();
585            let (new_provider, _) = config.validated_provider_for_urls(&urls).await?;
586
587            let mut config = fork.config.write();
588            config.provider = new_provider;
589            trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url().unwrap_or("none"), url);
590            config.fork_urls = urls;
591        }
592        // Keep node_config in sync so anvil_reset(None) uses the updated URL
593        let mut node_config = self.backend.node_config.write().await;
594        node_config.fork_urls = vec![url];
595        node_config.fork_chain_id = None;
596        Ok(())
597    }
598
599    /// Returns the number of transactions currently pending for inclusion in the next block(s), as
600    /// well as the ones that are being scheduled for future execution only.
601    /// Ref: [Here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status)
602    ///
603    /// Handler for ETH RPC call: `txpool_status`
604    pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
605        node_info!("txpool_status");
606        Ok(self.pool.txpool_status())
607    }
608
609    /// Executes the future on a new blocking task.
610    async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
611    where
612        C: FnOnce(Self) -> F,
613        F: Future<Output = Result<R>> + Send + 'static,
614        R: Send + 'static,
615    {
616        let (tx, rx) = oneshot::channel();
617        let this = self.clone();
618        let f = c(this);
619        tokio::task::spawn_blocking(move || {
620            tokio::runtime::Handle::current().block_on(async move {
621                let res = f.await;
622                let _ = tx.send(res);
623            })
624        });
625        rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
626    }
627
628    /// Updates the `TransactionOrder`
629    pub fn set_transaction_order(&self, order: TransactionOrder) {
630        *self.transaction_order.write() = order;
631    }
632
633    /// Returns the chain ID used for transaction
634    pub fn chain_id(&self) -> u64 {
635        self.backend.chain_id().to::<u64>()
636    }
637
638    /// Returns the configured fork, if any.
639    pub fn get_fork(&self) -> Option<ClientFork> {
640        self.backend.get_fork()
641    }
642
643    /// Returns the current instance's ID.
644    pub fn instance_id(&self) -> B256 {
645        *self.instance_id.read()
646    }
647
648    /// Resets the instance ID.
649    pub fn reset_instance_id(&self) {
650        *self.instance_id.write() = B256::random();
651    }
652
653    /// Returns the first signer that can sign for the given address
654    #[expect(clippy::borrowed_box)]
655    pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer<N>>> {
656        self.signers.iter().find(|signer| signer.is_signer_for(address))
657    }
658
659    /// Returns a new listeners for ready transactions
660    pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
661        self.pool.add_ready_listener()
662    }
663
664    /// Returns true if forked
665    pub fn is_fork(&self) -> bool {
666        self.backend.is_fork()
667    }
668
669    /// Returns the current state root
670    pub async fn state_root(&self) -> Option<B256> {
671        self.backend.get_db().read().await.maybe_state_root()
672    }
673
674    /// Returns true if the `addr` is currently impersonated
675    pub fn is_impersonated(&self, addr: Address) -> bool {
676        self.backend.cheats().is_impersonated(addr)
677    }
678
679    /// Returns a new accessor for certain storage elements
680    pub fn storage_info(&self) -> StorageInfo<N> {
681        StorageInfo::new(Arc::clone(&self.backend))
682    }
683
684    /// Handler for RPC call: `anvil_getBlobByHash`
685    #[allow(clippy::large_stack_frames)]
686    pub fn anvil_get_blob_by_versioned_hash(
687        &self,
688        hash: B256,
689    ) -> Result<Option<alloy_consensus::Blob>> {
690        node_info!("anvil_getBlobByHash");
691        Ok(self.backend.get_blob_by_versioned_hash(hash)?)
692    }
693
694    /// Handler for RPC call: `anvil_getBlobsByBlockId`
695    pub fn anvil_get_blobs_by_block_id(
696        &self,
697        block_id: impl Into<BlockId>,
698        versioned_hashes: Vec<B256>,
699    ) -> Result<Option<Vec<Blob>>> {
700        node_info!("anvil_getBlobsByBlockId");
701        Ok(self.backend.get_blobs_by_block_id(block_id, versioned_hashes)?)
702    }
703
704    /// Returns the genesis time for the Beacon chain
705    ///
706    /// Handler for Beacon API call: `GET /eth/v1/beacon/genesis`
707    pub fn anvil_get_genesis_time(&self) -> Result<u64> {
708        node_info!("anvil_getGenesisTime");
709        Ok(self.backend.genesis_time())
710    }
711
712    /// Reset the fork to a fresh forked state, and optionally update the fork config.
713    ///
714    /// If `forking` is `None` then this will disable forking entirely.
715    ///
716    /// Handler for RPC call: `anvil_reset`
717    pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
718        node_info!("anvil_reset");
719        if let Some(forking) = forking {
720            self.backend.reset_fork(forking).await?;
721        } else {
722            // Reset to a fresh in-memory state
723            self.backend.reset_to_in_mem().await?;
724        }
725        self.reset_instance_id();
726        // Clear pending transactions since they reference the old chain state.
727        self.pool.clear();
728        Ok(())
729    }
730
731    /// Revert the state of the blockchain to a previous snapshot.
732    /// Takes a single parameter, which is the snapshot id to revert to.
733    ///
734    /// Handler for RPC call: `evm_revert`
735    pub async fn evm_revert(&self, id: U256) -> Result<bool> {
736        node_info!("evm_revert");
737        self.backend.revert_state_snapshot(id).await
738    }
739
740    /// Send transactions impersonating specific account and contract addresses.
741    ///
742    /// Handler for ETH RPC call: `anvil_impersonateAccount`
743    pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
744        node_info!("anvil_impersonateAccount");
745        self.backend.impersonate(address);
746        Ok(())
747    }
748
749    /// Stops impersonating an account if previously set with `anvil_impersonateAccount`.
750    ///
751    /// Handler for ETH RPC call: `anvil_stopImpersonatingAccount`
752    pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
753        node_info!("anvil_stopImpersonatingAccount");
754        self.backend.stop_impersonating(address);
755        Ok(())
756    }
757
758    /// If set to true will make every account impersonated
759    ///
760    /// Handler for ETH RPC call: `anvil_autoImpersonateAccount`
761    pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
762        node_info!("anvil_autoImpersonateAccount");
763        self.backend.auto_impersonate_account(enabled);
764        Ok(())
765    }
766
767    /// Registers a new address and signature pair to impersonate.
768    pub async fn anvil_impersonate_signature(
769        &self,
770        signature: Bytes,
771        address: Address,
772    ) -> Result<()> {
773        node_info!("anvil_impersonateSignature");
774        self.backend.impersonate_signature(signature, address).await
775    }
776
777    /// Returns a new block event stream that yields Notifications when a new block was added or
778    /// when logs were removed from the canonical chain due to a reorg
779    pub fn new_block_notifications(&self) -> ChainNotifications {
780        self.backend.new_block_notifications()
781    }
782
783    /// Returns the current client version.
784    ///
785    /// Handler for ETH RPC call: `web3_clientVersion`
786    pub fn client_version(&self) -> Result<String> {
787        node_info!("web3_clientVersion");
788        Ok(CLIENT_VERSION.to_string())
789    }
790
791    /// Returns Keccak-256 (not the standardized SHA3-256) of the given data.
792    ///
793    /// Handler for ETH RPC call: `web3_sha3`
794    pub fn sha3(&self, bytes: Bytes) -> Result<String> {
795        node_info!("web3_sha3");
796        let hash = alloy_primitives::keccak256(bytes.as_ref());
797        Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
798    }
799
800    /// Returns protocol version encoded as a string (quotes are necessary).
801    ///
802    /// Handler for ETH RPC call: `eth_protocolVersion`
803    pub fn protocol_version(&self) -> Result<u64> {
804        node_info!("eth_protocolVersion");
805        Ok(1)
806    }
807
808    /// Returns the number of hashes per second that the node is mining with.
809    ///
810    /// Handler for ETH RPC call: `eth_hashrate`
811    pub fn hashrate(&self) -> Result<U256> {
812        node_info!("eth_hashrate");
813        Ok(U256::ZERO)
814    }
815
816    /// Returns the client coinbase address.
817    ///
818    /// Handler for ETH RPC call: `eth_coinbase`
819    pub fn author(&self) -> Result<Address> {
820        node_info!("eth_coinbase");
821        Ok(self.backend.coinbase())
822    }
823
824    /// Returns true if client is actively mining new blocks.
825    ///
826    /// Handler for ETH RPC call: `eth_mining`
827    pub fn is_mining(&self) -> Result<bool> {
828        node_info!("eth_mining");
829        Ok(self.is_mining)
830    }
831
832    /// Returns the chain ID used for transaction signing at the
833    /// current best block. None is returned if not
834    /// available.
835    ///
836    /// Handler for ETH RPC call: `eth_chainId`
837    pub fn eth_chain_id(&self) -> Result<Option<U64>> {
838        node_info!("eth_chainId");
839        Ok(Some(self.backend.chain_id().to::<U64>()))
840    }
841
842    /// Returns the same as `chain_id`
843    ///
844    /// Handler for ETH RPC call: `eth_networkId`
845    pub fn network_id(&self) -> Result<Option<String>> {
846        node_info!("eth_networkId");
847        let chain_id = self.backend.chain_id().to::<u64>();
848        Ok(Some(format!("{chain_id}")))
849    }
850
851    /// Returns true if client is actively listening for network connections.
852    ///
853    /// Handler for ETH RPC call: `net_listening`
854    pub fn net_listening(&self) -> Result<bool> {
855        node_info!("net_listening");
856        Ok(self.net_listening)
857    }
858
859    /// Returns the current gas price
860    fn eth_gas_price(&self) -> Result<U256> {
861        node_info!("eth_gasPrice");
862        Ok(U256::from(self.gas_price()))
863    }
864
865    /// Returns the base fee for the next block, or null before London.
866    ///
867    /// Handler for ETH RPC call: `eth_baseFee`
868    pub fn base_fee(&self) -> Result<Option<U256>> {
869        node_info!("eth_baseFee");
870        Ok(self.backend.is_eip1559().then(|| U256::from(self.backend.base_fee())))
871    }
872
873    /// Returns the excess blob gas and current blob gas price
874    pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
875        Ok(self.backend.excess_blob_gas_and_price())
876    }
877
878    /// Returns a fee per gas that is an estimate of how much you can pay as a priority fee, or
879    /// 'tip', to get a transaction included in the current block.
880    ///
881    /// Handler for ETH RPC call: `eth_maxPriorityFeePerGas`
882    pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
883        self.max_priority_fee_per_gas()
884    }
885
886    /// Returns the base fee per blob required to send an EIP-4844 tx.
887    ///
888    /// Handler for ETH RPC call: `eth_blobBaseFee`
889    pub fn blob_base_fee(&self) -> Result<U256> {
890        Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
891    }
892
893    /// Returns the block gas limit
894    pub fn gas_limit(&self) -> U256 {
895        U256::from(self.backend.gas_limit())
896    }
897
898    /// Returns the accounts list
899    ///
900    /// Handler for ETH RPC call: `eth_accounts`
901    pub fn accounts(&self) -> Result<Vec<Address>> {
902        node_info!("eth_accounts");
903        let mut unique = HashSet::new();
904        let mut accounts: Vec<Address> = Vec::new();
905        for signer in self.signers.iter() {
906            accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
907        }
908        accounts.extend(
909            self.backend
910                .cheats()
911                .impersonated_accounts()
912                .into_iter()
913                .filter(|acc| unique.insert(*acc)),
914        );
915        Ok(accounts.into_iter().collect())
916    }
917
918    /// Returns the number of most recent block.
919    ///
920    /// Handler for ETH RPC call: `eth_blockNumber`
921    pub fn block_number(&self) -> Result<U256> {
922        node_info!("eth_blockNumber");
923        Ok(U256::from(self.backend.best_number()))
924    }
925
926    /// Returns block with given hash.
927    ///
928    /// Handler for ETH RPC call: `eth_getBlockByHash`
929    pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
930        node_info!("eth_getBlockByHash");
931        self.backend.block_by_hash(hash).await
932    }
933
934    /// Returns block header with given hash.
935    ///
936    /// Handler for ETH RPC call: `eth_getHeaderByHash`
937    pub async fn header_by_hash(
938        &self,
939        hash: B256,
940    ) -> Result<Option<WithOtherFields<AnyRpcHeader>>> {
941        node_info!("eth_getHeaderByHash");
942        Ok(self.backend.block_by_hash(hash).await?.map(|block| {
943            let WithOtherFields { inner: block, other } = block.0;
944            WithOtherFields { inner: block.header, other }
945        }))
946    }
947
948    /// Returns a _full_ block with given hash.
949    ///
950    /// Handler for ETH RPC call: `eth_getBlockByHash`
951    pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
952        node_info!("eth_getBlockByHash");
953        self.backend.block_by_hash_full(hash).await
954    }
955
956    /// Returns the number of transactions in a block with given hash.
957    ///
958    /// Handler for ETH RPC call: `eth_getBlockTransactionCountByHash`
959    pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
960        node_info!("eth_getBlockTransactionCountByHash");
961        let block = self.backend.block_by_hash(hash).await?;
962        let txs = block.map(|b| match b.transactions() {
963            BlockTransactions::Full(txs) => U256::from(txs.len()),
964            BlockTransactions::Hashes(txs) => U256::from(txs.len()),
965            BlockTransactions::Uncle => U256::from(0),
966        });
967        Ok(txs)
968    }
969
970    /// Returns the number of uncles in a block with given hash.
971    ///
972    /// Handler for ETH RPC call: `eth_getUncleCountByBlockHash`
973    pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
974        node_info!("eth_getUncleCountByBlockHash");
975        let block =
976            self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
977        Ok(U256::from(block.uncles.len()))
978    }
979
980    /// Returns the number of uncles in a block with given block number.
981    ///
982    /// Handler for ETH RPC call: `eth_getUncleCountByBlockNumber`
983    pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
984        node_info!("eth_getUncleCountByBlockNumber");
985        let block = self
986            .backend
987            .block_by_number(block_number)
988            .await?
989            .ok_or(BlockchainError::BlockNotFound)?;
990        Ok(U256::from(block.uncles.len()))
991    }
992
993    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
994    ///
995    /// Handler for ETH RPC call: `eth_signTypedData`
996    pub async fn sign_typed_data(
997        &self,
998        _address: Address,
999        _data: serde_json::Value,
1000    ) -> Result<String> {
1001        node_info!("eth_signTypedData");
1002        Err(BlockchainError::RpcUnimplemented)
1003    }
1004
1005    /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).
1006    ///
1007    /// Handler for ETH RPC call: `eth_signTypedData_v3`
1008    pub async fn sign_typed_data_v3(
1009        &self,
1010        _address: Address,
1011        _data: serde_json::Value,
1012    ) -> Result<String> {
1013        node_info!("eth_signTypedData_v3");
1014        Err(BlockchainError::RpcUnimplemented)
1015    }
1016
1017    /// 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.
1018    ///
1019    /// Handler for ETH RPC call: `eth_signTypedData_v4`
1020    pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
1021        node_info!("eth_signTypedData_v4");
1022        let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1023        let signature = signer.sign_typed_data(address, data).await?;
1024        let signature = alloy_primitives::hex::encode(signature.as_bytes());
1025        Ok(format!("0x{signature}"))
1026    }
1027
1028    /// The sign method calculates an Ethereum specific signature
1029    ///
1030    /// Handler for ETH RPC call: `eth_sign`
1031    pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1032        node_info!("eth_sign");
1033        let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1034        let signature =
1035            alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1036        Ok(format!("0x{signature}"))
1037    }
1038
1039    /// Returns transaction at given block hash and index.
1040    ///
1041    /// Handler for ETH RPC call: `eth_getTransactionByBlockHashAndIndex`
1042    pub async fn transaction_by_block_hash_and_index(
1043        &self,
1044        hash: B256,
1045        index: Index,
1046    ) -> Result<Option<AnyRpcTransaction>> {
1047        node_info!("eth_getTransactionByBlockHashAndIndex");
1048        self.backend.transaction_by_block_hash_and_index(hash, index).await
1049    }
1050
1051    /// Returns transaction by given block number and index.
1052    ///
1053    /// Handler for ETH RPC call: `eth_getTransactionByBlockNumberAndIndex`
1054    pub async fn transaction_by_block_number_and_index(
1055        &self,
1056        block: BlockNumber,
1057        idx: Index,
1058    ) -> Result<Option<AnyRpcTransaction>> {
1059        node_info!("eth_getTransactionByBlockNumberAndIndex");
1060        self.backend.transaction_by_block_number_and_index(block, idx).await
1061    }
1062
1063    /// Returns an uncles at given block and index.
1064    ///
1065    /// Handler for ETH RPC call: `eth_getUncleByBlockHashAndIndex`
1066    pub async fn uncle_by_block_hash_and_index(
1067        &self,
1068        block_hash: B256,
1069        idx: Index,
1070    ) -> Result<Option<AnyRpcBlock>> {
1071        node_info!("eth_getUncleByBlockHashAndIndex");
1072        let number =
1073            self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1074        if let Some(fork) = self.get_fork()
1075            && fork.predates_fork_inclusive(number)
1076        {
1077            return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1078        }
1079        // It's impossible to have uncles outside of fork mode
1080        Ok(None)
1081    }
1082
1083    /// Returns an uncles at given block and index.
1084    ///
1085    /// Handler for ETH RPC call: `eth_getUncleByBlockNumberAndIndex`
1086    pub async fn uncle_by_block_number_and_index(
1087        &self,
1088        block_number: BlockNumber,
1089        idx: Index,
1090    ) -> Result<Option<AnyRpcBlock>> {
1091        node_info!("eth_getUncleByBlockNumberAndIndex");
1092        let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1093        if let Some(fork) = self.get_fork()
1094            && fork.predates_fork_inclusive(number)
1095        {
1096            return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1097        }
1098        // It's impossible to have uncles outside of fork mode
1099        Ok(None)
1100    }
1101
1102    /// Returns the hash of the current block, the seedHash, and the boundary condition to be met.
1103    ///
1104    /// Handler for ETH RPC call: `eth_getWork`
1105    pub fn work(&self) -> Result<Work> {
1106        node_info!("eth_getWork");
1107        Err(BlockchainError::RpcUnimplemented)
1108    }
1109
1110    /// Returns the sync status, always be fails.
1111    ///
1112    /// Handler for ETH RPC call: `eth_syncing`
1113    pub fn syncing(&self) -> Result<bool> {
1114        node_info!("eth_syncing");
1115        Ok(false)
1116    }
1117
1118    /// Returns the current configuration of the chain.
1119    /// This is useful for finding out what precompiles and system contracts are available.
1120    ///
1121    /// Note: the activation timestamp is always 0 as the configuration is set at genesis.
1122    /// Note: the `fork_id` is always `0x00000000` as this node does not participate in any forking
1123    /// on the network.
1124    /// Note: the `next` and `last` fields are always `null` as this node does not participate in
1125    /// any forking on the network.
1126    ///
1127    /// Handler for ETH RPC call: `eth_config`
1128    pub fn config(&self) -> Result<EthConfig> {
1129        node_info!("eth_config");
1130        Ok(EthConfig {
1131            current: EthForkConfig {
1132                activation_time: 0,
1133                blob_schedule: self.backend.blob_params(),
1134                chain_id: self.backend.chain_id().to::<u64>(),
1135                fork_id: Bytes::from_static(&[0; 4]),
1136                precompiles: self.backend.precompiles(),
1137                system_contracts: self.backend.system_contracts(),
1138            },
1139            next: None,
1140            last: None,
1141        })
1142    }
1143
1144    /// Used for submitting a proof-of-work solution.
1145    ///
1146    /// Handler for ETH RPC call: `eth_submitWork`
1147    pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1148        node_info!("eth_submitWork");
1149        Err(BlockchainError::RpcUnimplemented)
1150    }
1151
1152    /// Used for submitting mining hashrate.
1153    ///
1154    /// Handler for ETH RPC call: `eth_submitHashrate`
1155    pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1156        node_info!("eth_submitHashrate");
1157        Err(BlockchainError::RpcUnimplemented)
1158    }
1159
1160    /// Introduced in EIP-1559 for getting information on the appropriate priority fee to use.
1161    ///
1162    /// Handler for ETH RPC call: `eth_feeHistory`
1163    pub async fn fee_history(
1164        &self,
1165        block_count: U256,
1166        newest_block: BlockNumber,
1167        reward_percentiles: Vec<f64>,
1168    ) -> Result<FeeHistory>
1169    where
1170        N::ReceiptEnvelope: TxReceipt<Log = alloy_primitives::Log>,
1171    {
1172        node_info!("eth_feeHistory");
1173        // max number of blocks in the requested range
1174
1175        let number = self.backend.convert_block_number(Some(newest_block));
1176
1177        // Snapshot the fork block once so the early return here and the pre-fork split below agree
1178        // on the same value. Reading it a second time lets an `anvil_reset` move the fork between
1179        // the reads: the newest block could clear this early return, then the split treats the
1180        // whole range as pre-fork and tacks on a stray local next-block fee.
1181        let fork = self.get_fork();
1182        let fork_block = fork.as_ref().map(|fork| fork.block_number());
1183
1184        // check if the number predates the fork, if in fork mode
1185        if let (Some(fork), Some(fork_block)) = (fork.as_ref(), fork_block) {
1186            // if we're still at the forked block we don't have any history and can't compute it
1187            // efficiently, instead we fetch it from the fork
1188            if number <= fork_block {
1189                return fork
1190                    .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1191                    .await
1192                    .map_err(BlockchainError::AlloyForkProvider);
1193            }
1194        }
1195
1196        const MAX_BLOCK_COUNT: u64 = 1024u64;
1197        let block_count = block_count.saturating_to::<u64>().min(MAX_BLOCK_COUNT);
1198
1199        // highest and lowest block num in the requested range
1200        let highest = number;
1201        let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1202
1203        // only support ranges that are in cache range
1204        if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1205            return Err(FeeHistoryError::InvalidBlockRange.into());
1206        }
1207
1208        let mut response = FeeHistory {
1209            oldest_block: lowest,
1210            base_fee_per_gas: Vec::new(),
1211            gas_used_ratio: Vec::new(),
1212            reward: Some(Default::default()),
1213            base_fee_per_blob_gas: Default::default(),
1214            blob_gas_used_ratio: Default::default(),
1215        };
1216        let mut rewards = Vec::new();
1217
1218        // The early return above only delegates when the *newest* block predates the fork, but a
1219        // range can dip below the fork block while its newest block is post-fork. Local storage
1220        // has no pre-fork blocks, so resolving them via `backend.get_block` below would fail.
1221        // Serve the pre-fork portion from the fork provider and compute only post-fork locally.
1222        // Reuse the `fork_block` snapshot from above so this split stays consistent with the early
1223        // return; we didn't return, so `fork_block < highest` and only a crossing range splits.
1224        let local_lowest = if let (Some(fork), Some(fork_block)) = (fork.as_ref(), fork_block) {
1225            if lowest <= fork_block {
1226                let count_pre = fork_block - lowest + 1;
1227                let pre = fork
1228                    .fee_history(count_pre, BlockNumber::Number(fork_block), &reward_percentiles)
1229                    .await
1230                    .map_err(BlockchainError::AlloyForkProvider)?;
1231                merge_pre_fork_fee_history(&mut response, &mut rewards, pre, fork_block);
1232                // Compute only post-fork blocks locally; the pre-fork portion is served above.
1233                fork_block + 1
1234            } else {
1235                lowest
1236            }
1237        } else {
1238            lowest
1239        };
1240
1241        {
1242            let storage_info = self.storage_info();
1243            let blob_params = self.backend.blob_params();
1244
1245            // Snapshot the cached entries for the whole range under a single lock. The
1246            // `FeeHistoryService` populates the cache asynchronously and can lag the chain head,
1247            // so some entries may still be missing here.
1248            let cached: Vec<Option<FeeHistoryCacheItem>> = {
1249                let cache = self.fee_history_cache.lock();
1250                (local_lowest..=highest).map(|n| cache.get(&n).cloned()).collect()
1251            };
1252
1253            // Resolve the whole range into concrete items. Cache entries include their block hash
1254            // so a reset or reorg that reuses a block number cannot return data from the old
1255            // canonical chain. Compute misses and stale entries on demand without holding the
1256            // lock. A block that can't be found is a hard error rather than a silently dropped
1257            // entry, so `items` always holds exactly one entry per requested block.
1258            let mut warmed: Vec<(u64, FeeHistoryCacheItem)> = Vec::new();
1259            let mut items: Vec<FeeHistoryCacheItem> = Vec::with_capacity(cached.len());
1260            for (cached_item, n) in cached.into_iter().zip(local_lowest..=highest) {
1261                let hash = self
1262                    .backend
1263                    .block_hash_by_number(n)
1264                    .ok_or(FeeHistoryError::BlockNotFound(BlockNumber::Number(n)))?;
1265                let item = match cached_item {
1266                    Some(item) if item.block_hash == hash => item,
1267                    _ => {
1268                        let block = self
1269                            .backend
1270                            .get_block_by_hash(hash)
1271                            .ok_or(FeeHistoryError::BlockNotFound(BlockNumber::Number(n)))?;
1272                        let header = block.header;
1273                        let (item, block_number) = create_fee_history_cache_item(
1274                            hash,
1275                            &header,
1276                            &storage_info,
1277                            blob_params,
1278                        );
1279                        // The block was found above, but missing stored block/receipts make the
1280                        // helper hand back a zero-filled item. Error out rather than serve
1281                        // synthetic data for a block we already confirmed exists.
1282                        let block_number = block_number
1283                            .ok_or(FeeHistoryError::BlockNotFound(BlockNumber::Number(n)))?;
1284                        warmed.push((block_number, item.clone()));
1285                        item
1286                    }
1287                };
1288                items.push(item);
1289            }
1290
1291            // Warm the cache with the on-demand entries under a single lock, then trim to the
1292            // limit by dropping the oldest blocks so the fallback can't grow the cache unbounded.
1293            if !warmed.is_empty() {
1294                let mut cache = self.fee_history_cache.lock();
1295                for (block_number, item) in warmed {
1296                    cache.insert(block_number, item);
1297                }
1298                while cache.len() as u64 > self.fee_history_limit {
1299                    cache.pop_first();
1300                }
1301            }
1302
1303            for item in items {
1304                response.base_fee_per_gas.push(item.base_fee);
1305                response.base_fee_per_blob_gas.push(item.base_fee_per_blob_gas.unwrap_or(0));
1306                response.blob_gas_used_ratio.push(item.blob_gas_used_ratio);
1307                response.gas_used_ratio.push(item.gas_used_ratio);
1308
1309                // requested percentiles
1310                if !reward_percentiles.is_empty() {
1311                    let mut block_rewards = Vec::new();
1312                    let resolution_per_percentile: f64 = 2.0;
1313                    for p in &reward_percentiles {
1314                        let p = p.clamp(0.0, 100.0);
1315                        let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1316                        let reward = item.rewards.get(index as usize).map_or(0, |r| *r);
1317                        block_rewards.push(reward);
1318                    }
1319                    rewards.push(block_rewards);
1320                }
1321            }
1322        }
1323
1324        response.reward = Some(rewards);
1325
1326        // Both base-fee arrays include the block after the returned range. For a historical
1327        // request, use that block's header; the fee manager tracks the block after the current
1328        // chain head and would therefore append an unrelated value. Prefer an existing child even
1329        // when `highest` was the head at the start of this request, since mining can advance it.
1330        let next_number = highest
1331            .checked_add(1)
1332            .ok_or(FeeHistoryError::BlockNotFound(BlockNumber::Number(highest)))?;
1333        let (next_base_fee, next_blob_base_fee) = self
1334            .backend
1335            .fee_history_next_fees(highest)
1336            .await
1337            .ok_or(FeeHistoryError::BlockNotFound(BlockNumber::Number(next_number)))?;
1338        response.base_fee_per_gas.push(next_base_fee);
1339        response.base_fee_per_blob_gas.push(next_blob_base_fee);
1340
1341        Ok(response)
1342    }
1343
1344    /// Introduced in EIP-1159, a Geth-specific and simplified priority fee oracle.
1345    /// Leverages the already existing fee history cache.
1346    ///
1347    /// Returns a suggestion for a gas tip cap for dynamic fee transactions.
1348    ///
1349    /// Handler for ETH RPC call: `eth_maxPriorityFeePerGas`
1350    pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1351        node_info!("eth_maxPriorityFeePerGas");
1352        Ok(U256::from(self.lowest_suggestion_tip()))
1353    }
1354
1355    /// Returns code by its hash
1356    ///
1357    /// Handler for RPC call: `debug_codeByHash`
1358    pub async fn debug_code_by_hash(
1359        &self,
1360        hash: B256,
1361        block_id: Option<BlockId>,
1362    ) -> Result<Option<Bytes>> {
1363        node_info!("debug_codeByHash");
1364        self.backend.debug_code_by_hash(hash, block_id).await
1365    }
1366
1367    /// Returns the value associated with a key from the database
1368    /// Only supports bytecode lookups.
1369    ///
1370    /// Handler for RPC call: `debug_dbGet`
1371    pub async fn debug_db_get(&self, key: String) -> Result<Option<Bytes>> {
1372        node_info!("debug_dbGet");
1373        self.backend.debug_db_get(key).await
1374    }
1375
1376    /// Handles reth's no-op `debug_getModifiedAccountsByNumber` endpoint.
1377    pub fn debug_get_modified_accounts_by_number(
1378        &self,
1379        _start_number: u64,
1380        _end_number: u64,
1381    ) -> Result<()> {
1382        node_info!("debug_getModifiedAccountsByNumber");
1383        Ok(())
1384    }
1385
1386    /// Handles reth's no-op `debug_freeOSMemory` endpoint.
1387    pub fn debug_free_os_memory(&self) -> Result<()> {
1388        node_info!("debug_freeOSMemory");
1389        Ok(())
1390    }
1391
1392    /// Executes a transaction and returns requested parity trace results.
1393    ///
1394    /// Handler for RPC call: `trace_call`
1395    pub async fn trace_call(
1396        &self,
1397        request: WithOtherFields<TransactionRequest>,
1398        mut trace_types: HashSet<TraceType>,
1399        block_id: Option<BlockId>,
1400    ) -> Result<TraceResults>
1401    where
1402        N: Network<TxEnvelope = FoundryTxEnvelope, ReceiptEnvelope = FoundryReceiptEnvelope>,
1403    {
1404        node_info!("trace_call");
1405        if trace_types.is_empty() {
1406            trace_types.insert(TraceType::Trace);
1407        }
1408
1409        let block_id = block_id.unwrap_or_default();
1410        let block_request = match &block_id {
1411            BlockId::Number(BlockNumber::Pending) => {
1412                let pending_txs = self.pool.ready_transactions().collect();
1413                BlockRequest::Pending(pending_txs)
1414            }
1415            _ => {
1416                let number = self.backend.ensure_block_number(Some(block_id)).await?;
1417                BlockRequest::Number(number)
1418            }
1419        };
1420        let inner = request.as_ref();
1421        let fees = FeeDetails::new(
1422            inner.gas_price,
1423            inner.max_fee_per_gas,
1424            inner.max_priority_fee_per_gas,
1425            inner.max_fee_per_blob_gas,
1426        )?
1427        .or_zero_fees();
1428
1429        self.backend.trace_call(request, fees, trace_types, block_request, block_id).await
1430    }
1431
1432    /// Returns traces for the transaction hash via parity's tracing endpoint
1433    ///
1434    /// Handler for RPC call: `trace_transaction`
1435    pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1436        node_info!("trace_transaction");
1437        self.backend.trace_transaction(tx_hash).await
1438    }
1439
1440    /// Returns traces for the transaction hash via parity's tracing endpoint
1441    ///
1442    /// Handler for RPC call: `trace_block`
1443    pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1444        node_info!("trace_block");
1445        self.backend.trace_block(block).await
1446    }
1447
1448    /// Returns filtered traces over blocks
1449    ///
1450    /// Handler for RPC call: `trace_filter`
1451    pub async fn trace_filter(
1452        &self,
1453        filter: TraceFilter,
1454    ) -> Result<Vec<LocalizedTransactionTrace>> {
1455        node_info!("trace_filter");
1456        self.backend.trace_filter(filter).await
1457    }
1458
1459    /// Returns a transaction trace at a given index.
1460    ///
1461    /// Handler for RPC call: `trace_get`.
1462    pub async fn trace_get(
1463        &self,
1464        hash: B256,
1465        indices: Vec<Index>,
1466    ) -> Result<Option<LocalizedTransactionTrace>> {
1467        node_info!("trace_get");
1468        self.backend.trace_get(hash, indices).await
1469    }
1470
1471    /// Replays all transactions in a block returning the requested traces for each transaction
1472    ///
1473    /// Handler for RPC call: `trace_replayBlockTransactions`
1474    pub async fn trace_replay_block_transactions(
1475        &self,
1476        block: BlockNumber,
1477        trace_types: HashSet<TraceType>,
1478    ) -> Result<Vec<TraceResultsWithTransactionHash>> {
1479        node_info!("trace_replayBlockTransactions");
1480        self.backend.trace_replay_block_transactions(block, trace_types).await
1481    }
1482
1483    /// Replays a transaction returning the requested traces.
1484    ///
1485    /// Handler for RPC call: `trace_replayTransaction`.
1486    pub async fn trace_replay_transaction(
1487        &self,
1488        transaction: B256,
1489        trace_types: HashSet<TraceType>,
1490    ) -> Result<TraceResults> {
1491        node_info!("trace_replayTransaction");
1492        self.backend.trace_replay_transaction(transaction, trace_types).await
1493    }
1494}
1495
1496impl<N: Network<ReceiptEnvelope = FoundryReceiptEnvelope>> EthApi<N> {
1497    /// Returns the current state
1498    pub async fn serialized_state(
1499        &self,
1500        preserve_historical_states: bool,
1501    ) -> Result<SerializableState> {
1502        self.backend.serialized_state(preserve_historical_states).await
1503    }
1504}
1505
1506// == impl EthApi anvil endpoints ==
1507
1508impl EthApi<FoundryNetwork> {
1509    /// Create a buffer that represents all state on the chain, which can be loaded to separate
1510    /// process by calling `anvil_loadState`
1511    ///
1512    /// Handler for RPC call: `anvil_dumpState`
1513    pub async fn anvil_dump_state(
1514        &self,
1515        preserve_historical_states: Option<bool>,
1516    ) -> Result<Bytes> {
1517        node_info!("anvil_dumpState");
1518        self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
1519    }
1520
1521    /// Append chain state buffer to current chain. Will overwrite any conflicting addresses or
1522    /// storage.
1523    ///
1524    /// Handler for RPC call: `anvil_loadState`
1525    pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
1526        node_info!("anvil_loadState");
1527        self.backend.load_state_bytes(buf).await
1528    }
1529
1530    async fn block_request(
1531        &self,
1532        block_number: Option<BlockId>,
1533    ) -> Result<BlockRequest<FoundryTxEnvelope>> {
1534        let block_request = match block_number {
1535            Some(BlockId::Number(BlockNumber::Pending)) => {
1536                let pending_txs = self.pool.ready_transactions().collect();
1537                BlockRequest::Pending(pending_txs)
1538            }
1539            _ => {
1540                let number = self.backend.ensure_block_number(block_number).await?;
1541                BlockRequest::Number(number)
1542            }
1543        };
1544        Ok(block_request)
1545    }
1546
1547    /// Returns account information after replaying a block through a transaction index.
1548    ///
1549    /// Handler for RPC call: `debug_accountInfoAt`.
1550    pub async fn debug_account_info_at(
1551        &self,
1552        block_id: BlockId,
1553        tx_index: Index,
1554        address: Address,
1555    ) -> Result<Option<AccountInfo>> {
1556        node_info!("debug_accountInfoAt");
1557        self.backend.debug_account_info_at(block_id, tx_index, address).await
1558    }
1559
1560    /// Returns opcode gas usage for a transaction.
1561    ///
1562    /// Handler for RPC call: `trace_transactionOpcodeGas`.
1563    pub async fn trace_transaction_opcode_gas(
1564        &self,
1565        tx_hash: B256,
1566    ) -> Result<Option<TransactionOpcodeGas>> {
1567        node_info!("trace_transactionOpcodeGas");
1568        self.backend.trace_transaction_opcode_gas(tx_hash).await
1569    }
1570
1571    /// Returns opcode gas usage for all transactions in a block.
1572    ///
1573    /// Handler for RPC call: `trace_blockOpcodeGas`.
1574    pub async fn trace_block_opcode_gas(
1575        &self,
1576        block_id: BlockId,
1577    ) -> Result<Option<BlockOpcodeGas>> {
1578        node_info!("trace_blockOpcodeGas");
1579        self.backend.trace_block_opcode_gas(block_id).await
1580    }
1581
1582    /// Traces a raw signed transaction without importing it into the mempool.
1583    ///
1584    /// Handler for RPC call: `trace_rawTransaction`.
1585    pub async fn trace_raw_transaction(
1586        &self,
1587        tx: Bytes,
1588        trace_types: HashSet<TraceType>,
1589        block_number: Option<BlockId>,
1590    ) -> Result<TraceResults> {
1591        node_info!("trace_rawTransaction");
1592
1593        let mut data = tx.as_ref();
1594        if data.is_empty() {
1595            return Err(BlockchainError::EmptyRawTransactionData);
1596        }
1597
1598        let transaction = FoundryTxEnvelope::decode_2718(&mut data)
1599            .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1600        self.ensure_typed_transaction_supported(&transaction)?;
1601
1602        let pending_transaction = PendingTransaction::new(transaction)?;
1603        let block_request = self.block_request(block_number).await?;
1604
1605        self.backend
1606            .trace_raw_transaction(pending_transaction, trace_types, Some(block_request))
1607            .await
1608    }
1609
1610    /// Increases the balance of an account.
1611    ///
1612    /// Handler for RPC call: `anvil_addBalance`
1613    pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
1614        node_info!("anvil_addBalance");
1615        let current_balance = self.backend.get_balance(address, None).await?;
1616        self.backend.set_balance(address, current_balance.saturating_add(balance)).await?;
1617        Ok(())
1618    }
1619
1620    /// Rollback the chain to a specific depth.
1621    ///
1622    /// e.g depth = 3
1623    ///     A  -> B  -> C  -> D  -> E
1624    ///     A  -> B
1625    ///
1626    /// Depth specifies the height to rollback the chain back to. Depth must not exceed the current
1627    /// chain height, i.e. can't rollback past the genesis block.
1628    ///
1629    /// Handler for RPC call: `anvil_rollback`
1630    pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
1631        node_info!("anvil_rollback");
1632        let depth = depth.unwrap_or(1);
1633
1634        // Check reorg depth doesn't exceed current chain height
1635        let current_height = self.backend.best_number();
1636        let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
1637            RpcError::invalid_params(format!(
1638                "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
1639            )),
1640        ))?;
1641
1642        // Get the common ancestor block
1643        let common_block =
1644            self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
1645
1646        self.backend.rollback(common_block).await?;
1647        Ok(())
1648    }
1649
1650    /// Estimates the gas usage of the `request` with the state.
1651    ///
1652    /// This will execute the transaction request and find the best gas limit via binary search.
1653    fn do_estimate_gas_with_state(
1654        &self,
1655        request: FoundryTransactionRequest,
1656        state: &dyn DatabaseRef,
1657        block_env: BlockEnv,
1658    ) -> Result<u128> {
1659        let inner = request.as_ref();
1660        let fees = FeeDetails::new(
1661            inner.gas_price,
1662            inner.max_fee_per_gas,
1663            inner.max_priority_fee_per_gas,
1664            inner.max_fee_per_blob_gas,
1665        )?
1666        .or_zero_fees();
1667
1668        // get the highest possible gas limit, either the request's set value or the currently
1669        // configured gas limit
1670        let mut highest_gas_limit = inner.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
1671
1672        // Tempo AA transactions pay fees in ERC-20 tokens, not ETH. Only treat requests as
1673        // Tempo AA in Tempo mode, otherwise `feeToken` should not bypass ETH funds checks.
1674        let is_tempo_aa_tx = self.backend.is_tempo() && request.is_tempo();
1675        let is_tempo_keychain = matches!(
1676            &request,
1677            FoundryTransactionRequest::Tempo(request) if request.key_id.is_some()
1678        );
1679
1680        let gas_price = fees.gas_price.unwrap_or_default();
1681        // Check transfer value before any fast path, and cap gas limit by sender balance when the
1682        // request has a non-zero gas price. Only enforce this for explicit senders: calls without
1683        // `from` historically estimate against the default caller and must not be capped by the
1684        // zero address balance.
1685        if !is_tempo_aa_tx && let Some(from) = inner.from {
1686            let mut available_funds = self.backend.get_balance_with_state(state, from)?;
1687            if let Some(value) = inner.value {
1688                if value > available_funds {
1689                    return Err(InvalidTransactionError::InsufficientFunds.into());
1690                }
1691                // safe: value <= available_funds
1692                available_funds -= value;
1693            }
1694            if gas_price > 0 {
1695                // amount of gas the sender can afford with the `gas_price`
1696                let allowance =
1697                    available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
1698                highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
1699            }
1700        }
1701
1702        // If the request is a simple native token transfer we can optimize
1703        // We assume it's a transfer if we have no input data.
1704        // Skip this optimization for Tempo mode since native ETH transfers are not allowed
1705        // and Tempo AA transactions have higher intrinsic gas costs (~46k).
1706        if !self.backend.is_tempo() {
1707            let to = inner.to.as_ref().and_then(TxKind::to);
1708
1709            // check certain fields to see if the request could be a simple transfer
1710            let maybe_transfer = (inner.input.input().is_none()
1711                || inner.input.input().is_some_and(|data| data.is_empty()))
1712                && inner.authorization_list.is_none()
1713                && inner.access_list.is_none()
1714                && inner.blob_versioned_hashes.is_none();
1715
1716            if maybe_transfer
1717                && highest_gas_limit >= MIN_TRANSACTION_GAS
1718                && let Some(to) = to
1719                && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
1720                && target_code.as_ref().is_empty()
1721            {
1722                return Ok(MIN_TRANSACTION_GAS);
1723            }
1724        }
1725
1726        // execute the call without writing to db
1727        let ethres = self.backend.call_with_state_typed_gas_limit(
1728            &state,
1729            request.clone(),
1730            fees.clone(),
1731            block_env.clone(),
1732            highest_gas_limit as u64,
1733            is_tempo_keychain,
1734        );
1735
1736        let gas_used = match ethres.try_into()? {
1737            GasEstimationCallResult::Success(gas) => Ok(gas),
1738            GasEstimationCallResult::OutOfGas => {
1739                Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
1740            }
1741            GasEstimationCallResult::Revert(output) => {
1742                Err(InvalidTransactionError::Revert(output).into())
1743            }
1744            GasEstimationCallResult::EvmError(err) => {
1745                warn!(target: "node", "estimation failed due to {:?}", err);
1746                Err(BlockchainError::EvmError(err))
1747            }
1748        }?;
1749
1750        // at this point we know the call succeeded but want to find the _best_ (lowest) gas the
1751        // transaction succeeds with. we find this by doing a binary search over the
1752        // possible range NOTE: this is the gas the transaction used, which is less than the
1753        // transaction requires to succeed
1754
1755        // Get the starting lowest gas needed depending on the transaction kind.
1756        let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
1757
1758        // pick a point that's close to the estimated gas
1759        let mut mid_gas_limit =
1760            std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
1761
1762        // Binary search for the ideal gas limit
1763        while (highest_gas_limit - lowest_gas_limit) > 1 {
1764            let ethres = self.backend.call_with_state_typed_gas_limit(
1765                &state,
1766                request.clone(),
1767                fees.clone(),
1768                block_env.clone(),
1769                mid_gas_limit as u64,
1770                is_tempo_keychain,
1771            );
1772
1773            match ethres.try_into()? {
1774                GasEstimationCallResult::Success(_) => {
1775                    // If the transaction succeeded, we can set a ceiling for the highest gas limit
1776                    // at the current midpoint, as spending any more gas would
1777                    // make no sense (as the TX would still succeed).
1778                    highest_gas_limit = mid_gas_limit;
1779                }
1780                GasEstimationCallResult::OutOfGas
1781                | GasEstimationCallResult::Revert(_)
1782                | GasEstimationCallResult::EvmError(_) => {
1783                    // If the transaction failed, we can set a floor for the lowest gas limit at the
1784                    // current midpoint, as spending any less gas would make no
1785                    // sense (as the TX would still revert due to lack of gas).
1786                    //
1787                    // We don't care about the reason here, as we known that transaction is correct
1788                    // as it succeeded earlier
1789                    lowest_gas_limit = mid_gas_limit;
1790                }
1791            };
1792            // new midpoint
1793            mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
1794        }
1795
1796        trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
1797
1798        Ok(highest_gas_limit)
1799    }
1800
1801    /// Executes the [EthRequest] and returns an RPC [ResponseResult].
1802    #[allow(clippy::large_stack_frames)]
1803    pub async fn execute(&self, request: EthRequest) -> ResponseResult {
1804        trace!(target: "rpc::api", "executing eth request");
1805        let response = match request.clone() {
1806            EthRequest::EthProtocolVersion(()) => self.protocol_version().to_rpc_result(),
1807            EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
1808            EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
1809            EthRequest::EthGetAccount(addr, block) => {
1810                self.get_account(addr, block).await.to_rpc_result()
1811            }
1812            EthRequest::EthGetAccountInfo(addr, block) => {
1813                self.get_account_info(addr, block).await.to_rpc_result()
1814            }
1815            EthRequest::EthGetBalance(addr, block) => {
1816                self.balance(addr, block).await.to_rpc_result()
1817            }
1818            EthRequest::EthGetTransactionByHash(hash) => {
1819                self.transaction_by_hash(hash).await.to_rpc_result()
1820            }
1821            EthRequest::EthPendingTransactions(_) => {
1822                self.pending_transactions().await.to_rpc_result()
1823            }
1824            EthRequest::EthSendTransaction(request) => {
1825                self.send_transaction(*request).await.to_rpc_result()
1826            }
1827            EthRequest::EthResend(request, gas_price, gas_limit) => {
1828                self.resend_transaction(*request, gas_price, gas_limit).await.to_rpc_result()
1829            }
1830            EthRequest::EthSendTransactionSync(request) => {
1831                self.send_transaction_sync(*request).await.to_rpc_result()
1832            }
1833            EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
1834            EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
1835            EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
1836            EthRequest::EthHashrate(()) => self.hashrate().to_rpc_result(),
1837            EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
1838            EthRequest::EthBaseFee(_) => self.base_fee().to_rpc_result(),
1839            EthRequest::EthMaxPriorityFeePerGas(_) => {
1840                self.gas_max_priority_fee_per_gas().to_rpc_result()
1841            }
1842            EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
1843            EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
1844            EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
1845            EthRequest::EthCoinbase(()) => self.author().to_rpc_result(),
1846            EthRequest::EthGetStorageAt(addr, slot, block) => {
1847                self.storage_at(addr, slot, block).await.to_rpc_result()
1848            }
1849            EthRequest::EthGetStorageValues(requests, block) => {
1850                self.storage_values(requests, block).await.to_rpc_result()
1851            }
1852            EthRequest::EthGetBlockByHash(hash, full) => {
1853                if full {
1854                    self.block_by_hash_full(hash).await.to_rpc_result()
1855                } else {
1856                    self.block_by_hash(hash).await.to_rpc_result()
1857                }
1858            }
1859            EthRequest::EthGetHeaderByHash(hash) => self.header_by_hash(hash).await.to_rpc_result(),
1860            EthRequest::EthGetBlockByNumber(num, full) => {
1861                if full {
1862                    self.block_by_number_full(num).await.to_rpc_result()
1863                } else {
1864                    self.block_by_number(num).await.to_rpc_result()
1865                }
1866            }
1867            EthRequest::EthGetHeaderByNumber(num) => {
1868                self.header_by_number(num).await.to_rpc_result()
1869            }
1870            EthRequest::EthGetBlockAccessList(block_id) => {
1871                self.block_access_list(block_id).await.to_rpc_result()
1872            }
1873            EthRequest::EthGetBlockAccessListByBlockHash(block_hash) => {
1874                self.block_access_list_by_hash(block_hash).await.to_rpc_result()
1875            }
1876            EthRequest::EthGetBlockAccessListByBlockNumber(block_number) => {
1877                self.block_access_list_by_number(block_number).await.to_rpc_result()
1878            }
1879            EthRequest::EthGetBlockAccessListRaw(block_id) => {
1880                self.block_access_list_raw(block_id).await.to_rpc_result()
1881            }
1882            EthRequest::EthGetTransactionCount(addr, block) => {
1883                self.transaction_count(addr, block).await.to_rpc_result()
1884            }
1885            EthRequest::EthGetTransactionCountByHash(hash) => {
1886                self.block_transaction_count_by_hash(hash).await.to_rpc_result()
1887            }
1888            EthRequest::EthGetTransactionCountByNumber(num) => {
1889                self.block_transaction_count_by_number(num).await.to_rpc_result()
1890            }
1891            EthRequest::EthGetUnclesCountByHash(hash) => {
1892                self.block_uncles_count_by_hash(hash).await.to_rpc_result()
1893            }
1894            EthRequest::EthGetUnclesCountByNumber(num) => {
1895                self.block_uncles_count_by_number(num).await.to_rpc_result()
1896            }
1897            EthRequest::EthGetCodeAt(addr, block) => {
1898                self.get_code(addr, block).await.to_rpc_result()
1899            }
1900            EthRequest::EthGetProof(addr, keys, block) => {
1901                self.get_proof(addr, keys, block).await.to_rpc_result()
1902            }
1903            EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
1904            EthRequest::PersonalSign(content, addr) => {
1905                self.sign(addr, content).await.to_rpc_result()
1906            }
1907            EthRequest::EthSignTransaction(request) => {
1908                self.sign_transaction(*request).await.to_rpc_result()
1909            }
1910            EthRequest::EthSignTypedData(addr, data) => {
1911                self.sign_typed_data(addr, data).await.to_rpc_result()
1912            }
1913            EthRequest::EthSignTypedDataV3(addr, data) => {
1914                self.sign_typed_data_v3(addr, data).await.to_rpc_result()
1915            }
1916            EthRequest::EthSignTypedDataV4(addr, data) => {
1917                self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
1918            }
1919            EthRequest::EthSendRawTransaction(tx) => {
1920                self.send_raw_transaction(tx).await.to_rpc_result()
1921            }
1922            EthRequest::EthSendRawTransactionSync(tx, timeout_ms) => {
1923                self.send_raw_transaction_sync(tx, timeout_ms).await.to_rpc_result()
1924            }
1925            EthRequest::EthSendRawTransactionConditional(tx, condition) => {
1926                self.send_raw_transaction_conditional(tx, condition).await.to_rpc_result()
1927            }
1928            EthRequest::AnvilClassifyTransaction(tx) => {
1929                self.anvil_classify_transaction(tx).to_rpc_result()
1930            }
1931            EthRequest::EthCall(call, block, state_override, block_overrides) => self
1932                .call(call, block, EvmOverrides::new(state_override, block_overrides))
1933                .await
1934                .to_rpc_result(),
1935            EthRequest::EthCallMany(bundles, state_context, state_override) => {
1936                self.call_many(bundles, state_context, state_override).await.to_rpc_result()
1937            }
1938            EthRequest::EthCallBundle(bundle) => self.call_bundle(bundle).await.to_rpc_result(),
1939            EthRequest::EthSimulateV1(simulation, block) => {
1940                self.simulate_v1_raw(simulation, block).await.to_rpc_result()
1941            }
1942            EthRequest::EthCreateAccessList(call, block, state_override) => {
1943                self.create_access_list(call, block, state_override).await.to_rpc_result()
1944            }
1945            EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
1946                .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
1947                .await
1948                .to_rpc_result(),
1949            EthRequest::EthFillTransaction(request) => {
1950                self.fill_transaction(request).await.to_rpc_result()
1951            }
1952            EthRequest::EthGetRawTransactionByHash(hash) => {
1953                self.raw_transaction(hash).await.to_rpc_result()
1954            }
1955            EthRequest::GetBlobByHash(hash) => {
1956                self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
1957            }
1958            EthRequest::GetBlobByTransactionHash(hash) => {
1959                self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
1960            }
1961            EthRequest::GetGenesisTime(()) => self.anvil_get_genesis_time().to_rpc_result(),
1962            EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
1963                self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
1964            }
1965            EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
1966                self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
1967            }
1968            EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
1969                self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
1970            }
1971            EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
1972                self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
1973            }
1974            EthRequest::EthGetTransactionReceipt(tx) => {
1975                self.transaction_receipt(tx).await.to_rpc_result()
1976            }
1977            EthRequest::EthGetBlockReceipts(number) => {
1978                self.block_receipts(number).await.to_rpc_result()
1979            }
1980            EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
1981                self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
1982            }
1983            EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
1984                self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
1985            }
1986            EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
1987            EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
1988            EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
1989            EthRequest::EthConfig(_) => self.config().to_rpc_result(),
1990            EthRequest::EthSubmitWork(nonce, pow, digest) => {
1991                self.submit_work(nonce, pow, digest).to_rpc_result()
1992            }
1993            EthRequest::EthSubmitHashRate(rate, id) => {
1994                self.submit_hashrate(rate, id).to_rpc_result()
1995            }
1996            EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
1997                self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
1998            }
1999            // non eth-standard rpc calls
2000            EthRequest::DebugGetRawTransaction(hash) => {
2001                self.raw_transaction(hash).await.to_rpc_result()
2002            }
2003            EthRequest::DebugGetRawReceipts(block) => {
2004                self.raw_receipts(block).await.to_rpc_result()
2005            }
2006            EthRequest::DebugGetRawTransactions(block) => {
2007                self.raw_transactions(block).await.to_rpc_result()
2008            }
2009            EthRequest::DebugGetRawHeader(block) => self.raw_header(block).await.to_rpc_result(),
2010            EthRequest::DebugGetRawBlock(block) => self.raw_block(block).await.to_rpc_result(),
2011            // non eth-standard rpc calls
2012            EthRequest::DebugClearTxpool(_) => self.debug_clear_txpool().await.to_rpc_result(),
2013            // non eth-standard rpc calls
2014            EthRequest::DebugTraceTransaction(tx, opts) => {
2015                self.debug_trace_transaction(tx, opts).await.to_rpc_result()
2016            }
2017            // non eth-standard rpc calls
2018            EthRequest::DebugTraceCall(tx, block, opts) => {
2019                self.debug_trace_call(tx, block, opts).await.to_rpc_result()
2020            }
2021            EthRequest::DebugCodeByHash(hash, block) => {
2022                self.debug_code_by_hash(hash, block).await.to_rpc_result()
2023            }
2024            EthRequest::DebugDbGet(key) => self.debug_db_get(key).await.to_rpc_result(),
2025            EthRequest::DebugGetModifiedAccountsByNumber(start_number, end_number) => {
2026                self.debug_get_modified_accounts_by_number(start_number, end_number).to_rpc_result()
2027            }
2028            EthRequest::DebugFreeOsMemory(()) => self.debug_free_os_memory().to_rpc_result(),
2029            EthRequest::DebugAccountInfoAt(block_id, tx_index, address) => {
2030                self.debug_account_info_at(block_id, tx_index, address).await.to_rpc_result()
2031            }
2032            EthRequest::DebugTraceBlock(rlp_block, opts) => {
2033                self.debug_trace_block(rlp_block, opts).await.to_rpc_result()
2034            }
2035            EthRequest::DebugTraceBlockByHash(block_hash, opts) => {
2036                self.debug_trace_block_by_hash(block_hash, opts).await.to_rpc_result()
2037            }
2038            EthRequest::DebugTraceBlockByNumber(block_number, opts) => {
2039                self.debug_trace_block_by_number(block_number, opts).await.to_rpc_result()
2040            }
2041            EthRequest::TraceCall(tx, trace_types, block) => {
2042                self.trace_call(tx, trace_types, block).await.to_rpc_result()
2043            }
2044            EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
2045            EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
2046            EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
2047            EthRequest::TraceGet(hash, indices) => {
2048                self.trace_get(hash, indices).await.to_rpc_result()
2049            }
2050            EthRequest::TraceReplayBlockTransactions(block, trace_types) => {
2051                self.trace_replay_block_transactions(block, trace_types).await.to_rpc_result()
2052            }
2053            EthRequest::TraceReplayTransaction(transaction, trace_types) => {
2054                self.trace_replay_transaction(transaction, trace_types).await.to_rpc_result()
2055            }
2056            EthRequest::TraceTransactionOpcodeGas(tx_hash) => {
2057                self.trace_transaction_opcode_gas(tx_hash).await.to_rpc_result()
2058            }
2059            EthRequest::TraceBlockOpcodeGas(block_id) => {
2060                self.trace_block_opcode_gas(block_id).await.to_rpc_result()
2061            }
2062            EthRequest::TraceRawTransaction(tx, trace_types, block_number) => {
2063                self.trace_raw_transaction(tx, trace_types, block_number).await.to_rpc_result()
2064            }
2065            EthRequest::TraceCallMany(calls, block_number) => {
2066                self.trace_call_many(calls, block_number).await.to_rpc_result()
2067            }
2068            EthRequest::ImpersonateAccount(addr) => {
2069                self.anvil_impersonate_account(addr).await.to_rpc_result()
2070            }
2071            EthRequest::StopImpersonatingAccount(addr) => {
2072                self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
2073            }
2074            EthRequest::AutoImpersonateAccount(enable) => {
2075                self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
2076            }
2077            EthRequest::ImpersonateSignature(signature, address) => {
2078                self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
2079            }
2080            EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
2081            EthRequest::Mine(blocks, interval) => {
2082                self.anvil_mine(blocks, interval).await.to_rpc_result()
2083            }
2084            EthRequest::SetAutomine(enabled) => {
2085                self.anvil_set_auto_mine(enabled).await.to_rpc_result()
2086            }
2087            EthRequest::SetIntervalMining(interval) => {
2088                self.anvil_set_interval_mining(interval).to_rpc_result()
2089            }
2090            EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
2091            EthRequest::DropTransaction(tx) => {
2092                self.anvil_drop_transaction(tx).await.to_rpc_result()
2093            }
2094            EthRequest::DropAllTransactions() => {
2095                self.anvil_drop_all_transactions().await.to_rpc_result()
2096            }
2097            EthRequest::Reset(fork) => {
2098                self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
2099            }
2100            EthRequest::SetBalance(addr, val) => {
2101                self.anvil_set_balance(addr, val).await.to_rpc_result()
2102            }
2103            EthRequest::AddBalance(addr, val) => {
2104                self.anvil_add_balance(addr, val).await.to_rpc_result()
2105            }
2106            EthRequest::DealERC20(addr, token_addr, val) => {
2107                self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
2108            }
2109            EthRequest::DealTIP20(addr, token_addr, val) => {
2110                self.anvil_deal_tip20(addr, token_addr, val).await.to_rpc_result()
2111            }
2112            EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
2113                .anvil_set_erc20_allowance(owner, spender, token_addr, val)
2114                .await
2115                .to_rpc_result(),
2116            EthRequest::SetCode(addr, code) => {
2117                self.anvil_set_code(addr, code).await.to_rpc_result()
2118            }
2119            EthRequest::SetNonce(addr, nonce) => {
2120                self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
2121            }
2122            EthRequest::SetStorageAt(addr, slot, val) => {
2123                self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
2124            }
2125            EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
2126            EthRequest::SetNextBlockPrevRandao(prevrandao) => {
2127                self.anvil_set_next_block_prevrandao(prevrandao).await.to_rpc_result()
2128            }
2129            EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
2130            EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
2131            EthRequest::SetMinGasPrice(gas) => {
2132                self.anvil_set_min_gas_price(gas).await.to_rpc_result()
2133            }
2134            EthRequest::SetNextBlockBaseFeePerGas(gas) => {
2135                self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
2136            }
2137            EthRequest::DumpState(preserve_historical_states) => self
2138                .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
2139                .await
2140                .to_rpc_result(),
2141            EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
2142            EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
2143            EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
2144            EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
2145            EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
2146            EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
2147            EthRequest::EvmSetNextBlockTimeStamp(time) => {
2148                if time >= U256::from(u64::MAX) {
2149                    return ResponseResult::Error(RpcError::invalid_params(
2150                        "The timestamp is too big",
2151                    ));
2152                }
2153                let time = time.to::<u64>();
2154                self.evm_set_next_block_timestamp(time).to_rpc_result()
2155            }
2156            EthRequest::EvmSetTime(timestamp) => {
2157                if timestamp >= U256::from(u64::MAX) {
2158                    return ResponseResult::Error(RpcError::invalid_params(
2159                        "The timestamp is too big",
2160                    ));
2161                }
2162                // evm_setTime accepts either seconds or milliseconds for Ganache compatibility.
2163                // Timestamps above 1e12 are interpreted as milliseconds and converted to
2164                // seconds; below that threshold they are treated as seconds directly.
2165                let raw = timestamp.to::<u64>();
2166                let time = if raw > 1_000_000_000_000 {
2167                    Duration::from_millis(raw).as_secs()
2168                } else {
2169                    raw
2170                };
2171                self.evm_set_time(time).to_rpc_result()
2172            }
2173            EthRequest::EvmSetBlockGasLimit(gas_limit) => {
2174                self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
2175            }
2176            EthRequest::EvmSetBlockTimeStampInterval(time) => {
2177                self.evm_set_block_timestamp_interval(time).to_rpc_result()
2178            }
2179            EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
2180                self.evm_remove_block_timestamp_interval().to_rpc_result()
2181            }
2182            EthRequest::EvmMine(mine) => {
2183                self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
2184            }
2185            EthRequest::EvmMineDetailed(mine) => {
2186                self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
2187            }
2188            EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).await.to_rpc_result(),
2189            EthRequest::EthSendUnsignedTransaction(tx) => {
2190                self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
2191            }
2192            EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
2193            EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
2194            EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
2195            EthRequest::EthNewPendingTransactionFilter(full) => {
2196                self.new_pending_transaction_filter(full.unwrap_or(false)).await.to_rpc_result()
2197            }
2198            EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
2199            EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
2200            EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
2201            EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
2202            EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
2203            EthRequest::TxPoolContentFrom(from) => {
2204                self.txpool_content_from(from).await.to_rpc_result()
2205            }
2206            EthRequest::ErigonGetHeaderByNumber(num) => {
2207                self.erigon_get_header_by_number(num).await.to_rpc_result()
2208            }
2209            EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
2210            EthRequest::OtsGetInternalOperations(hash) => {
2211                self.ots_get_internal_operations(hash).await.to_rpc_result()
2212            }
2213            EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
2214            EthRequest::OtsTraceTransaction(hash) => {
2215                self.ots_trace_transaction(hash).await.to_rpc_result()
2216            }
2217            EthRequest::OtsGetTransactionError(hash) => {
2218                self.ots_get_transaction_error(hash).await.to_rpc_result()
2219            }
2220            EthRequest::OtsGetBlockDetails(num) => {
2221                self.ots_get_block_details(num).await.to_rpc_result()
2222            }
2223            EthRequest::OtsGetBlockDetailsByHash(hash) => {
2224                self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
2225            }
2226            EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
2227                self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
2228            }
2229            EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
2230                self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
2231            }
2232            EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
2233                self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
2234            }
2235            EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
2236                self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
2237            }
2238            EthRequest::EthGetTransactionBySenderAndNonce(sender, nonce) => {
2239                self.transaction_by_sender_and_nonce(sender, nonce).await.to_rpc_result()
2240            }
2241            EthRequest::OtsGetContractCreator(address) => {
2242                self.ots_get_contract_creator(address).await.to_rpc_result()
2243            }
2244            EthRequest::RemovePoolTransactions(address) => {
2245                self.anvil_remove_pool_transactions(address).await.to_rpc_result()
2246            }
2247            EthRequest::Reorg(reorg_options) => {
2248                self.anvil_reorg(reorg_options).await.to_rpc_result()
2249            }
2250            EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
2251            EthRequest::SetFeeToken(user, token) => {
2252                self.anvil_set_fee_token(user, token).await.to_rpc_result()
2253            }
2254            EthRequest::SetValidatorFeeToken(validator, token) => {
2255                self.anvil_set_validator_fee_token(validator, token).await.to_rpc_result()
2256            }
2257            EthRequest::SetFeeAmmLiquidity(user_token, validator_token, amount) => self
2258                .anvil_set_fee_amm_liquidity(user_token, validator_token, amount)
2259                .await
2260                .to_rpc_result(),
2261        };
2262
2263        if let ResponseResult::Error(err) = &response {
2264            node_info!("\nRPC request failed:");
2265            node_info!("    Request: {:?}", request);
2266            node_info!("    Error: {}\n", err);
2267        }
2268
2269        response
2270    }
2271
2272    fn sign_request(&self, from: &Address, typed_tx: FoundryTypedTx) -> Result<FoundryTxEnvelope> {
2273        match typed_tx {
2274            #[cfg(feature = "optimism")]
2275            FoundryTypedTx::Deposit(_) => return Ok(typed_tx.into_impersonated()),
2276            _ => {
2277                for signer in self.signers.iter() {
2278                    if signer.accounts().contains(from) {
2279                        return signer.sign_transaction_from(from, typed_tx);
2280                    }
2281                }
2282            }
2283        }
2284        Err(BlockchainError::NoSignerAvailable)
2285    }
2286
2287    async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
2288        match self.pool.get_transaction(hash) {
2289            Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
2290            None => match self.backend.transaction_by_hash(hash).await? {
2291                Some(tx) => Ok(Some(tx.as_ref().encoded_2718().into())),
2292                None => Ok(None),
2293            },
2294        }
2295    }
2296
2297    /// Returns balance of the given account.
2298    ///
2299    /// Handler for ETH RPC call: `eth_getBalance`
2300    pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
2301        node_info!("eth_getBalance");
2302        let block_request = self.block_request(block_number).await?;
2303
2304        // check if the number predates the fork, if in fork mode
2305        if let BlockRequest::Number(number) = block_request
2306            && let Some(fork) = self.get_fork()
2307            && fork.predates_fork(number)
2308        {
2309            return Ok(fork.get_balance(address, number).await?);
2310        }
2311
2312        self.backend.get_balance(address, Some(block_request)).await
2313    }
2314
2315    /// Returns the ethereum account.
2316    ///
2317    /// Handler for ETH RPC call: `eth_getAccount`
2318    pub async fn get_account(
2319        &self,
2320        address: Address,
2321        block_number: Option<BlockId>,
2322    ) -> Result<TrieAccount> {
2323        node_info!("eth_getAccount");
2324        let block_request = self.block_request(block_number).await?;
2325
2326        // check if the number predates the fork, if in fork mode
2327        if let BlockRequest::Number(number) = block_request
2328            && let Some(fork) = self.get_fork()
2329            && fork.predates_fork(number)
2330        {
2331            return Ok(fork.get_account(address, number).await?);
2332        }
2333
2334        self.backend.get_account_at_block(address, Some(block_request)).await
2335    }
2336
2337    /// Returns the account information including balance, nonce, code and storage
2338    ///
2339    /// Note: This isn't support by all providers
2340    pub async fn get_account_info(
2341        &self,
2342        address: Address,
2343        block_number: Option<BlockId>,
2344    ) -> Result<alloy_rpc_types::eth::AccountInfo> {
2345        node_info!("eth_getAccountInfo");
2346
2347        if let Some(fork) = self.get_fork() {
2348            let block_request = self.block_request(block_number).await?;
2349            // check if the number predates the fork, if in fork mode
2350            if let BlockRequest::Number(number) = block_request {
2351                trace!(target: "node", "get_account_info: fork block {}, requested block {number}", fork.block_number());
2352                return if fork.predates_fork(number) {
2353                    // if this predates the fork we need to fetch balance, nonce, code individually
2354                    // because the provider might not support this endpoint
2355                    let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
2356                    let code = fork.get_code(address, number).map_err(BlockchainError::from);
2357                    let nonce = self.get_transaction_count(address, Some(number.into()));
2358                    let (balance, code, nonce) = try_join!(balance, code, nonce)?;
2359
2360                    Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code })
2361                } else {
2362                    // Anvil node is at the same block or higher than the fork block,
2363                    // return account info from backend to reflect current state.
2364                    let account_info = self.backend.get_account(address).await?;
2365                    let code = self.backend.get_code(address, Some(block_request)).await?;
2366                    Ok(alloy_rpc_types::eth::AccountInfo {
2367                        balance: account_info.balance,
2368                        nonce: account_info.nonce,
2369                        code,
2370                    })
2371                };
2372            }
2373        }
2374
2375        let account = self.get_account(address, block_number);
2376        let code = self.get_code(address, block_number);
2377        let (account, code) = try_join!(account, code)?;
2378        Ok(alloy_rpc_types::eth::AccountInfo {
2379            balance: account.balance,
2380            nonce: account.nonce,
2381            code,
2382        })
2383    }
2384    /// Returns content of the storage at given address.
2385    ///
2386    /// Handler for ETH RPC call: `eth_getStorageAt`
2387    pub async fn storage_at(
2388        &self,
2389        address: Address,
2390        index: U256,
2391        block_number: Option<BlockId>,
2392    ) -> Result<B256> {
2393        node_info!("eth_getStorageAt");
2394        let block_request = self.block_request(block_number).await?;
2395
2396        // check if the number predates the fork, if in fork mode
2397        if let BlockRequest::Number(number) = block_request
2398            && let Some(fork) = self.get_fork()
2399            && fork.predates_fork(number)
2400        {
2401            return Ok(B256::from(
2402                fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
2403            ));
2404        }
2405
2406        self.backend.storage_at(address, index, Some(block_request)).await
2407    }
2408
2409    /// Returns storage values for multiple accounts and slots in a single call.
2410    ///
2411    /// Handler for ETH RPC call: `eth_getStorageValues`
2412    pub async fn storage_values(
2413        &self,
2414        requests: HashMap<Address, Vec<B256>>,
2415        block_number: Option<BlockId>,
2416    ) -> Result<HashMap<Address, Vec<B256>>> {
2417        node_info!("eth_getStorageValues");
2418
2419        let total_slots: usize = requests.values().map(|s| s.len()).sum();
2420        if total_slots > 1024 {
2421            return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2422                "total slot count {total_slots} exceeds limit 1024"
2423            ))));
2424        }
2425
2426        let block_request = self.block_request(block_number).await?;
2427
2428        // check if the number predates the fork, if in fork mode
2429        if let BlockRequest::Number(number) = block_request
2430            && let Some(fork) = self.get_fork()
2431            && fork.predates_fork(number)
2432        {
2433            let mut result: HashMap<Address, Vec<B256>> = HashMap::default();
2434            for (address, slots) in requests {
2435                let mut values = Vec::with_capacity(slots.len());
2436                for slot in &slots {
2437                    let val = fork
2438                        .storage_at(address, (*slot).into(), Some(BlockNumber::Number(number)))
2439                        .await?;
2440                    values.push(B256::from(val));
2441                }
2442                result.insert(address, values);
2443            }
2444            return Ok(result);
2445        }
2446
2447        self.backend.storage_values(requests, Some(block_request)).await
2448    }
2449
2450    /// Returns block with given number.
2451    ///
2452    /// Handler for ETH RPC call: `eth_getBlockByNumber`
2453    pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
2454        node_info!("eth_getBlockByNumber");
2455        if number == BlockNumber::Pending {
2456            return Ok(Some(self.pending_block().await));
2457        }
2458
2459        self.backend.block_by_number(number).await
2460    }
2461
2462    /// Returns block header with given number.
2463    ///
2464    /// Handler for ETH RPC call: `eth_getHeaderByNumber`
2465    pub async fn header_by_number(
2466        &self,
2467        number: BlockNumber,
2468    ) -> Result<Option<WithOtherFields<AnyRpcHeader>>> {
2469        node_info!("eth_getHeaderByNumber");
2470        if number == BlockNumber::Pending {
2471            let WithOtherFields { inner: block, other } = self.pending_block().await.0;
2472            return Ok(Some(WithOtherFields { inner: block.header, other }));
2473        }
2474
2475        Ok(self.backend.block_by_number(number).await?.map(|block| {
2476            let WithOtherFields { inner: block, other } = block.0;
2477            WithOtherFields { inner: block.header, other }
2478        }))
2479    }
2480
2481    /// Returns a _full_ block with given number
2482    ///
2483    /// Handler for ETH RPC call: `eth_getBlockByNumber`
2484    pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
2485        node_info!("eth_getBlockByNumber");
2486        if number == BlockNumber::Pending {
2487            return Ok(self.pending_block_full().await);
2488        }
2489        self.backend.block_by_number_full(number).await
2490    }
2491
2492    /// Returns the EIP-7928 block access list for a block.
2493    ///
2494    /// Handler for ETH RPC call: `eth_getBlockAccessList`
2495    pub async fn block_access_list(&self, block_id: BlockId) -> Result<Option<serde_json::Value>> {
2496        node_info!("eth_getBlockAccessList");
2497        let block_request = self.block_request(Some(block_id)).await?;
2498        let BlockRequest::Number(number) = block_request else { return Ok(None) };
2499
2500        if let Some(fork) = self.get_fork()
2501            && fork.predates_fork_inclusive(number)
2502        {
2503            return Ok(fork.block_access_list(block_id).await?);
2504        }
2505
2506        Ok(None)
2507    }
2508
2509    /// Returns the EIP-7928 block access list for a block hash.
2510    ///
2511    /// Handler for ETH RPC call: `eth_getBlockAccessListByBlockHash`
2512    pub async fn block_access_list_by_hash(
2513        &self,
2514        block_hash: B256,
2515    ) -> Result<Option<serde_json::Value>> {
2516        node_info!("eth_getBlockAccessListByBlockHash");
2517        if let Some(fork) = self.get_fork() {
2518            return Ok(fork.block_access_list_by_hash(block_hash).await?);
2519        }
2520        Ok(None)
2521    }
2522
2523    /// Returns the EIP-7928 block access list for a block number.
2524    ///
2525    /// Handler for ETH RPC call: `eth_getBlockAccessListByBlockNumber`
2526    pub async fn block_access_list_by_number(
2527        &self,
2528        block_number: BlockNumber,
2529    ) -> Result<Option<serde_json::Value>> {
2530        node_info!("eth_getBlockAccessListByBlockNumber");
2531        let block_request = self.block_request(Some(BlockId::Number(block_number))).await?;
2532        let BlockRequest::Number(number) = block_request else { return Ok(None) };
2533
2534        if let Some(fork) = self.get_fork()
2535            && fork.predates_fork_inclusive(number)
2536        {
2537            return Ok(fork.block_access_list_by_number(block_number).await?);
2538        }
2539
2540        Ok(None)
2541    }
2542
2543    /// Returns the raw EIP-7928 block access list for a block.
2544    ///
2545    /// Handler for ETH RPC call: `eth_getBlockAccessListRaw`
2546    pub async fn block_access_list_raw(&self, block_id: BlockId) -> Result<Option<Bytes>> {
2547        node_info!("eth_getBlockAccessListRaw");
2548        let block_request = self.block_request(Some(block_id)).await?;
2549        let BlockRequest::Number(number) = block_request else { return Ok(None) };
2550
2551        if let Some(fork) = self.get_fork()
2552            && fork.predates_fork_inclusive(number)
2553        {
2554            return Ok(fork.block_access_list_raw(block_id).await?);
2555        }
2556
2557        Ok(None)
2558    }
2559
2560    /// Returns the number of transactions sent from given address at given time (block number).
2561    ///
2562    /// Also checks the pending transactions if `block_number` is
2563    /// `BlockId::Number(BlockNumber::Pending)`
2564    ///
2565    /// Handler for ETH RPC call: `eth_getTransactionCount`
2566    pub async fn transaction_count(
2567        &self,
2568        address: Address,
2569        block_number: Option<BlockId>,
2570    ) -> Result<U256> {
2571        node_info!("eth_getTransactionCount");
2572        self.get_transaction_count(address, block_number).await.map(U256::from)
2573    }
2574
2575    /// Returns the number of transactions in a block with given block number.
2576    ///
2577    /// Handler for ETH RPC call: `eth_getBlockTransactionCountByNumber`
2578    pub async fn block_transaction_count_by_number(
2579        &self,
2580        block_number: BlockNumber,
2581    ) -> Result<Option<U256>> {
2582        node_info!("eth_getBlockTransactionCountByNumber");
2583        let block_request = self.block_request(Some(block_number.into())).await?;
2584        if let BlockRequest::Pending(txs) = block_request {
2585            let block = self.backend.pending_block(txs).await;
2586            return Ok(Some(U256::from(block.block.body.transactions.len())));
2587        }
2588        let block = self.backend.block_by_number(block_number).await?;
2589        let txs = block.map(|b| match b.transactions() {
2590            BlockTransactions::Full(txs) => U256::from(txs.len()),
2591            BlockTransactions::Hashes(txs) => U256::from(txs.len()),
2592            BlockTransactions::Uncle => U256::from(0),
2593        });
2594        Ok(txs)
2595    }
2596
2597    /// Returns the code at given address at given time (block number).
2598    ///
2599    /// Handler for ETH RPC call: `eth_getCode`
2600    pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
2601        node_info!("eth_getCode");
2602        let block_request = self.block_request(block_number).await?;
2603        // check if the number predates the fork, if in fork mode
2604        if let BlockRequest::Number(number) = block_request
2605            && let Some(fork) = self.get_fork()
2606            && fork.predates_fork(number)
2607        {
2608            return Ok(fork.get_code(address, number).await?);
2609        }
2610        self.backend.get_code(address, Some(block_request)).await
2611    }
2612
2613    /// Returns the account and storage values of the specified account including the Merkle-proof.
2614    /// This call can be used to verify that the data you are pulling from is not tampered with.
2615    ///
2616    /// Handler for ETH RPC call: `eth_getProof`
2617    pub async fn get_proof(
2618        &self,
2619        address: Address,
2620        keys: Vec<B256>,
2621        block_number: Option<BlockId>,
2622    ) -> Result<EIP1186AccountProofResponse> {
2623        node_info!("eth_getProof");
2624        let block_request = self.block_request(block_number).await?;
2625
2626        // If we're in forking mode, or still on the forked block (no blocks mined yet) then we can
2627        // delegate the call.
2628        if let BlockRequest::Number(number) = block_request
2629            && let Some(fork) = self.get_fork()
2630            && fork.predates_fork_inclusive(number)
2631        {
2632            return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
2633        }
2634
2635        let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
2636        Ok(proof)
2637    }
2638
2639    /// Signs a transaction
2640    ///
2641    /// Handler for ETH RPC call: `eth_signTransaction`
2642    pub async fn sign_transaction(
2643        &self,
2644        request: WithOtherFields<TransactionRequest>,
2645    ) -> Result<String> {
2646        node_info!("eth_signTransaction");
2647        let request = self.parse_transaction_request(request)?;
2648
2649        let from = request.from().map(Ok).unwrap_or_else(|| {
2650            self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
2651        })?;
2652
2653        let (nonce, _) = self.request_nonce_for_transaction(&request, from).await?;
2654
2655        let request = self.build_tx_request(request, nonce).await?;
2656
2657        let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
2658        Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
2659    }
2660
2661    /// Sends a transaction
2662    ///
2663    /// Handler for ETH RPC call: `eth_sendTransaction`
2664    pub async fn send_transaction(
2665        &self,
2666        request: WithOtherFields<TransactionRequest>,
2667    ) -> Result<TxHash> {
2668        node_info!("eth_sendTransaction");
2669        let request = self.parse_transaction_request(request)?;
2670
2671        let from = request.from().map(Ok).unwrap_or_else(|| {
2672            self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
2673        })?;
2674        let (nonce, on_chain_nonce) = self.request_nonce_for_transaction(&request, from).await?;
2675
2676        let typed_tx = self.build_tx_request(request, nonce).await?;
2677
2678        // if the sender is currently impersonated we need to "bypass" signing
2679        let pending_transaction = if self.is_impersonated(from) {
2680            let transaction = typed_tx.into_impersonated();
2681            self.ensure_typed_transaction_supported(&transaction)?;
2682            trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
2683            PendingTransaction::with_impersonated(transaction, from)
2684        } else {
2685            let transaction = self.sign_request(&from, typed_tx)?;
2686            self.ensure_typed_transaction_supported(&transaction)?;
2687            PendingTransaction::new(transaction)?
2688        };
2689        // pre-validate
2690        self.backend.validate_pool_transaction(&pending_transaction).await?;
2691
2692        let (requires, provides) = nonce_markers(&pending_transaction, nonce, on_chain_nonce, from);
2693
2694        self.add_pending_transaction(pending_transaction, requires, provides)
2695    }
2696
2697    /// Resends a pending transaction with an updated gas price or gas limit.
2698    ///
2699    /// Handler for ETH RPC call: `eth_resend`
2700    pub async fn resend_transaction(
2701        &self,
2702        request: WithOtherFields<TransactionRequest>,
2703        gas_price: Option<U256>,
2704        gas_limit: Option<U64>,
2705    ) -> Result<TxHash> {
2706        node_info!("eth_resend");
2707        let mut request = self.parse_transaction_request(request)?;
2708
2709        let from = request.from().map(Ok).unwrap_or_else(|| {
2710            self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
2711        })?;
2712        let nonce = request.nonce().ok_or_else(|| {
2713            BlockchainError::InvalidTransactionRequest(
2714                "missing transaction nonce in transaction spec".to_string(),
2715            )
2716        })?;
2717
2718        if !self.pool.contains_sender_nonce(from, nonce) {
2719            return Err(BlockchainError::TransactionNotFound);
2720        }
2721
2722        if let Some(gas_price) = gas_price.filter(|gas_price| !gas_price.is_zero()) {
2723            request.set_gas_price(gas_price.saturating_to());
2724        }
2725
2726        if let Some(gas_limit) = gas_limit.filter(|gas_limit| *gas_limit != U64::ZERO) {
2727            request.set_gas_limit(gas_limit.to());
2728        }
2729
2730        let typed_tx = self.build_tx_request(request, nonce).await?;
2731
2732        let pending_transaction = if self.is_impersonated(from) {
2733            let transaction = typed_tx.into_impersonated();
2734            self.ensure_typed_transaction_supported(&transaction)?;
2735            trace!(target : "node", ?from, "eth_resend: impersonating");
2736            PendingTransaction::with_impersonated(transaction, from)
2737        } else {
2738            let transaction = self.sign_request(&from, typed_tx)?;
2739            self.ensure_typed_transaction_supported(&transaction)?;
2740            PendingTransaction::new(transaction)?
2741        };
2742
2743        self.backend.validate_pool_transaction(&pending_transaction).await?;
2744
2745        let on_chain_nonce = self.backend.current_nonce(from).await?;
2746        let (requires, provides) = nonce_markers(&pending_transaction, nonce, on_chain_nonce, from);
2747
2748        self.add_pending_transaction(pending_transaction, requires, provides)
2749    }
2750
2751    /// Waits for a transaction to be included in a block and returns its receipt (no timeout).
2752    async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
2753        let mut stream = self.new_block_notifications();
2754        // Check if the transaction is already included before listening for new blocks.
2755        if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
2756            return Ok(receipt);
2757        }
2758        while let Some(notification) = stream.next().await {
2759            if let Some(new_block) = notification.as_new_block()
2760                && let Some(block) = self.backend.get_block_by_hash(new_block.hash)
2761                && block.body.transactions.iter().any(|tx| tx.hash() == hash)
2762                && let Some(receipt) = self.backend.transaction_receipt(hash).await?
2763            {
2764                return Ok(receipt);
2765            }
2766        }
2767
2768        Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
2769    }
2770
2771    fn transaction_confirmation_timeout(timeout_ms: Option<u64>) -> Duration {
2772        const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
2773        timeout_ms
2774            .filter(|timeout_ms| *timeout_ms > 0)
2775            .map(Duration::from_millis)
2776            .map(|timeout| timeout.min(TIMEOUT_DURATION))
2777            .unwrap_or(TIMEOUT_DURATION)
2778    }
2779
2780    /// Waits for a transaction to be included in a block and returns its receipt, with timeout.
2781    async fn check_transaction_inclusion(
2782        &self,
2783        hash: TxHash,
2784        timeout_ms: Option<u64>,
2785    ) -> Result<FoundryTxReceipt> {
2786        let timeout_duration = Self::transaction_confirmation_timeout(timeout_ms);
2787        tokio::time::timeout(timeout_duration, self.await_transaction_inclusion(hash))
2788            .await
2789            .unwrap_or_else(|_elapsed| {
2790                Err(BlockchainError::TransactionConfirmationTimeout {
2791                    hash,
2792                    duration: timeout_duration,
2793                })
2794            })
2795    }
2796
2797    /// Sends a transaction and waits for receipt
2798    ///
2799    /// Handler for ETH RPC call: `eth_sendTransactionSync`
2800    pub async fn send_transaction_sync(
2801        &self,
2802        request: WithOtherFields<TransactionRequest>,
2803    ) -> Result<FoundryTxReceipt> {
2804        node_info!("eth_sendTransactionSync");
2805        let hash = self.send_transaction(request).await?;
2806
2807        let receipt = self.check_transaction_inclusion(hash, None).await?;
2808
2809        Ok(receipt)
2810    }
2811
2812    /// Sends signed transaction, returning its hash.
2813    ///
2814    /// Handler for ETH RPC call: `eth_sendRawTransaction`
2815    pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
2816        node_info!("eth_sendRawTransaction");
2817        let mut data = tx.as_ref();
2818        if data.is_empty() {
2819            return Err(BlockchainError::EmptyRawTransactionData);
2820        }
2821
2822        let transaction = FoundryTxEnvelope::decode_2718(&mut data)
2823            .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2824
2825        self.ensure_typed_transaction_supported(&transaction)?;
2826
2827        if self.backend.is_tempo() && TempoHardfork::from(self.backend.hardfork()).is_t5() {
2828            let classification = classify_payment_lane(tx.as_ref());
2829            trace!(target: "node", tx = ?transaction.hash(), ?classification, "classified transaction lane");
2830        }
2831
2832        let pending_transaction = PendingTransaction::new(transaction)?;
2833
2834        // pre-validate
2835        self.backend.validate_pool_transaction(&pending_transaction).await?;
2836
2837        let from = *pending_transaction.sender();
2838        let priority = self.transaction_priority(&pending_transaction.transaction);
2839
2840        // Tempo txs use a 2D nonce system — no sequential ordering by account nonce.
2841        let (requires, provides) = if let Some((requires, provides)) =
2842            tempo_parallel_nonce_markers(&pending_transaction)
2843        {
2844            (requires, provides)
2845        } else {
2846            let on_chain_nonce = self.backend.current_nonce(from).await?;
2847            let nonce = pending_transaction.transaction.nonce();
2848            (required_marker(nonce, on_chain_nonce, from), vec![to_marker(nonce, from)])
2849        };
2850
2851        let pool_transaction =
2852            PoolTransaction { requires, provides, pending_transaction, priority, is_replay: false };
2853
2854        let tx = self.pool.add_transaction(pool_transaction)?;
2855        trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
2856        Ok(*tx.hash())
2857    }
2858
2859    /// Sends a signed transaction with an ignored transaction condition.
2860    ///
2861    /// Handler for ETH RPC call: `eth_sendRawTransactionConditional`
2862    pub async fn send_raw_transaction_conditional(
2863        &self,
2864        tx: Bytes,
2865        _condition: TransactionConditional,
2866    ) -> Result<TxHash> {
2867        node_info!("eth_sendRawTransactionConditional");
2868        self.send_raw_transaction(tx).await
2869    }
2870
2871    /// Classifies a raw transaction with the active Anvil Tempo/T5 payment-lane classifier.
2872    pub fn anvil_classify_transaction(&self, tx: Bytes) -> Result<PaymentLaneClassification> {
2873        node_info!("anvil_classifyTransaction");
2874        let mut data = tx.as_ref();
2875        if data.is_empty() {
2876            return Err(BlockchainError::EmptyRawTransactionData);
2877        }
2878
2879        FoundryTxEnvelope::decode_2718(&mut data)
2880            .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2881
2882        Ok(self.classify_transaction_lane(tx.as_ref()))
2883    }
2884
2885    fn classify_transaction_lane(&self, raw: &[u8]) -> PaymentLaneClassification {
2886        if !self.backend.is_tempo() {
2887            return PaymentLaneClassification::general(PaymentLaneReason::NotTempo);
2888        }
2889
2890        if !TempoHardfork::from(self.backend.hardfork()).is_t5() {
2891            return PaymentLaneClassification::general(PaymentLaneReason::T5NotActive);
2892        }
2893
2894        classify_payment_lane(raw)
2895    }
2896
2897    /// Sends signed transaction, returning its receipt.
2898    ///
2899    /// Handler for ETH RPC call: `eth_sendRawTransactionSync`
2900    pub async fn send_raw_transaction_sync(
2901        &self,
2902        tx: Bytes,
2903        timeout_ms: Option<u64>,
2904    ) -> Result<FoundryTxReceipt> {
2905        node_info!("eth_sendRawTransactionSync");
2906
2907        let hash = self.send_raw_transaction(tx).await?;
2908        let receipt = self.check_transaction_inclusion(hash, timeout_ms).await?;
2909
2910        Ok(receipt)
2911    }
2912
2913    /// Call contract, returning the output data.
2914    ///
2915    /// Handler for ETH RPC call: `eth_call`
2916    pub async fn call(
2917        &self,
2918        request: WithOtherFields<TransactionRequest>,
2919        block_number: Option<BlockId>,
2920        overrides: EvmOverrides,
2921    ) -> Result<Bytes> {
2922        node_info!("eth_call");
2923        let block_request = self.block_request(block_number).await?;
2924        // check if the number predates the fork, if in fork mode
2925        if let BlockRequest::Number(number) = block_request
2926            && let Some(fork) = self.get_fork()
2927            && fork.predates_fork(number)
2928        {
2929            if overrides.has_state() || overrides.has_block() {
2930                return Err(BlockchainError::EvmOverrideError(
2931                    "not available on past forked blocks".to_string(),
2932                ));
2933            }
2934            return Ok(fork.call_raw(&request, Some(number.into())).await?);
2935        }
2936
2937        let fees = FeeDetails::new(
2938            request.gas_price,
2939            request.max_fee_per_gas,
2940            request.max_priority_fee_per_gas,
2941            request.max_fee_per_blob_gas,
2942        )?
2943        .or_zero_fees();
2944        // this can be blocking for a bit, especially in forking mode
2945        // <https://github.com/foundry-rs/foundry/issues/6036>
2946        self.on_blocking_task(|this| async move {
2947            let (exit, out, gas, _) =
2948                this.backend.call(request, fees, Some(block_request), overrides).await?;
2949            trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
2950
2951            ensure_return_ok(exit, &out)
2952        })
2953        .await
2954    }
2955
2956    pub async fn call_many(
2957        &self,
2958        bundles: Vec<Bundle<WithOtherFields<TransactionRequest>>>,
2959        state_context: Option<StateContext>,
2960        state_override: Option<StateOverride>,
2961    ) -> Result<Vec<Vec<EthCallResponse>>> {
2962        node_info!("eth_callMany");
2963        let StateContext { transaction_index, block_number } = state_context.unwrap_or_default();
2964        if transaction_index.is_some_and(|index| index.index().is_some()) {
2965            return Err(BlockchainError::RpcError(RpcError::invalid_params(
2966                "transactionIndex is not supported for eth_callMany yet".to_string(),
2967            )));
2968        }
2969
2970        let block_request = self.block_request(block_number).await?;
2971        if let BlockRequest::Number(number) = block_request
2972            && let Some(fork) = self.get_fork()
2973            && fork.predates_fork(number)
2974        {
2975            return Ok(fork
2976                .call_many(
2977                    bundles,
2978                    Some(StateContext { transaction_index, block_number: Some(number.into()) }),
2979                    state_override,
2980                )
2981                .await?);
2982        }
2983
2984        self.on_blocking_task(|this| async move {
2985            this.backend.call_many(bundles, Some(block_request), state_override).await
2986        })
2987        .await
2988    }
2989
2990    /// Simulates a bundle of signed transactions against the requested state.
2991    ///
2992    /// Handler for ETH RPC call: `eth_callBundle`.
2993    pub async fn call_bundle(&self, bundle: EthCallBundle) -> Result<EthCallBundleResponse> {
2994        node_info!("eth_callBundle");
2995        if bundle.txs.is_empty() {
2996            return Err(BlockchainError::RpcError(RpcError::invalid_params(
2997                "bundle missing txs".to_string(),
2998            )));
2999        }
3000        if bundle.block_number == 0 {
3001            return Err(BlockchainError::RpcError(RpcError::invalid_params(
3002                "bundle missing blockNumber".to_string(),
3003            )));
3004        }
3005
3006        let block_request = self.block_request(Some(bundle.state_block_number.into())).await?;
3007        if let BlockRequest::Number(number) = block_request
3008            && let Some(fork) = self.get_fork()
3009            && fork.predates_fork(number)
3010        {
3011            return Ok(fork.call_bundle(bundle).await?);
3012        }
3013
3014        let transactions = bundle
3015            .txs
3016            .iter()
3017            .map(|raw| {
3018                let mut data = raw.as_ref();
3019                if data.is_empty() {
3020                    return Err(BlockchainError::EmptyRawTransactionData);
3021                }
3022                let transaction = FoundryTxEnvelope::decode_2718(&mut data)
3023                    .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
3024                self.ensure_typed_transaction_supported(&transaction)?;
3025                PendingTransaction::new(transaction).map_err(Into::into)
3026            })
3027            .collect::<Result<Vec<_>>>()?;
3028
3029        self.on_blocking_task(|this| async move {
3030            this.backend.call_bundle(bundle, transactions, Some(block_request)).await
3031        })
3032        .await
3033    }
3034
3035    pub async fn simulate_v1(
3036        &self,
3037        request: SimulatePayload,
3038        block_number: Option<BlockId>,
3039    ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
3040        self.simulate_v1_raw(preserve_simulation_request_fields(request), block_number).await
3041    }
3042
3043    pub(crate) async fn simulate_v1_raw(
3044        &self,
3045        mut request: SimulatePayload<WithOtherFields<TransactionRequest>>,
3046        block_number: Option<BlockId>,
3047    ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
3048        const DEFAULT_BLOCK_INTERVAL_SECS: u64 = 12;
3049
3050        node_info!("eth_simulateV1");
3051        if request.block_state_calls.is_empty() {
3052            return Err(BlockchainError::RpcError(RpcError::invalid_params("empty input")));
3053        }
3054        if request.block_state_calls.len() > MAX_SIMULATE_BLOCKS as usize {
3055            return Err(BlockchainError::RpcError(RpcError {
3056                code: ErrorCode::ServerError(-38026),
3057                message: "too many blocks".into(),
3058                data: None,
3059            }));
3060        }
3061        let block_id = block_number;
3062        let block_request =
3063            self.block_request(block_number).await.map_err(|error| match error {
3064                BlockchainError::BlockOutOfRange(_, _) | BlockchainError::BlockNotFound => {
3065                    BlockchainError::RpcError(RpcError {
3066                        code: ErrorCode::ServerError(-32000),
3067                        message: "header not found".into(),
3068                        data: None,
3069                    })
3070                }
3071                error => error,
3072            })?;
3073        let block_interval = self.backend.time().block_timestamp_interval().unwrap_or_else(|| {
3074            self.miner
3075                .block_interval()
3076                .map(|duration| {
3077                    duration
3078                        .as_secs()
3079                        .saturating_add(u64::from(duration.subsec_nanos() != 0))
3080                        .max(1)
3081                })
3082                .unwrap_or(DEFAULT_BLOCK_INTERVAL_SECS)
3083        });
3084
3085        // check if the number predates the fork, if in fork mode
3086        if let BlockRequest::Number(number) = block_request
3087            && let Some(fork) = self.get_fork()
3088            && fork.predates_fork(number)
3089        {
3090            let block_id = match block_id {
3091                Some(BlockId::Hash(hash)) => BlockId::Hash(hash),
3092                _ => number.into(),
3093            };
3094            let base_block = fork.fetch_block(block_id).await?.ok_or_else(|| {
3095                BlockchainError::RpcError(RpcError {
3096                    code: ErrorCode::ServerError(-32000),
3097                    message: "header not found".into(),
3098                    data: None,
3099                })
3100            })?;
3101            request.block_state_calls = sanitize_simulation_blocks(
3102                request.block_state_calls,
3103                base_block.header.number(),
3104                base_block.header.timestamp(),
3105                block_interval,
3106            )?;
3107            return Ok(fork.simulate_v1(&request, Some(base_block.header.hash.into())).await?);
3108        }
3109
3110        // this can be blocking for a bit, especially in forking mode
3111        // <https://github.com/foundry-rs/foundry/issues/6036>
3112        self.on_blocking_task(|this| async move {
3113            let simulated_blocks =
3114                this.backend.simulate_raw(request, Some(block_request), block_interval).await?;
3115            trace!(target : "node", "Simulate status {:?}", simulated_blocks);
3116
3117            Ok(simulated_blocks)
3118        })
3119        .await
3120    }
3121
3122    /// This method creates an EIP2930 type accessList based on a given Transaction. The accessList
3123    /// contains all storage slots and addresses read and written by the transaction, except for the
3124    /// sender account and the precompiles.
3125    ///
3126    /// It returns list of addresses and storage keys used by the transaction, plus the gas
3127    /// consumed when the access list is added. That is, it gives you the list of addresses and
3128    /// storage keys that will be used by that transaction, plus the gas consumed if the access
3129    /// list is included. Like eth_estimateGas, this is an estimation; the list could change
3130    /// when the transaction is actually mined. Adding an accessList to your transaction does
3131    /// not necessary result in lower gas usage compared to a transaction without an access
3132    /// list.
3133    ///
3134    /// Handler for ETH RPC call: `eth_createAccessList`
3135    pub async fn create_access_list(
3136        &self,
3137        request: WithOtherFields<TransactionRequest>,
3138        block_number: Option<BlockId>,
3139        state_override: Option<StateOverride>,
3140    ) -> Result<AccessListResult> {
3141        node_info!("eth_createAccessList");
3142        let block_request = self.block_request(block_number).await?;
3143        // check if the number predates the fork, if in fork mode
3144        if let BlockRequest::Number(number) = block_request
3145            && let Some(fork) = self.get_fork()
3146            && fork.predates_fork(number)
3147        {
3148            if state_override.is_some() {
3149                return Err(BlockchainError::EvmOverrideError(
3150                    "not available on past forked blocks".to_string(),
3151                ));
3152            }
3153            return Ok(fork.create_access_list_raw(&request, Some(number.into())).await?);
3154        }
3155        let typed_request = self.parse_transaction_request(request.clone())?;
3156
3157        self.backend
3158            .with_database_at(Some(block_request), |state, block_env| {
3159                let mut cache_db = CacheDB::new(state);
3160                if let Some(state_override) = state_override {
3161                    apply_state_overrides(state_override.into_iter().collect(), &mut cache_db)?;
3162                }
3163
3164                let (_, _, _, access_list) = self.backend.build_access_list_with_state(
3165                    &cache_db,
3166                    request.clone(),
3167                    FeeDetails::zero(),
3168                    block_env.clone(),
3169                )?;
3170
3171                // Re-execute with the access list applied to get the post-AL gas usage.
3172                // EVM failures (including reverts) are surfaced in the result's `error`
3173                // field per the execution-apis `eth_createAccessList` spec, so callers
3174                // can still inspect the traced slots when execution fails.
3175                let (exit, _, gas_used, _) = self.backend.call_with_state_typed_access_list(
3176                    &cache_db,
3177                    typed_request,
3178                    FeeDetails::zero(),
3179                    block_env,
3180                    access_list.clone(),
3181                )?;
3182
3183                Ok(AccessListResult {
3184                    access_list,
3185                    gas_used: U256::from(gas_used),
3186                    error: execution_error(exit),
3187                })
3188            })
3189            .await?
3190    }
3191
3192    /// Estimate gas needed for execution of given contract.
3193    /// If no block parameter is given, it will use the pending block by default
3194    ///
3195    /// Handler for ETH RPC call: `eth_estimateGas`
3196    pub async fn estimate_gas(
3197        &self,
3198        request: WithOtherFields<TransactionRequest>,
3199        block_number: Option<BlockId>,
3200        overrides: EvmOverrides,
3201    ) -> Result<U256> {
3202        node_info!("eth_estimateGas");
3203        self.do_estimate_gas(
3204            request,
3205            block_number.or_else(|| Some(BlockNumber::Pending.into())),
3206            overrides,
3207        )
3208        .await
3209        .map(U256::from)
3210    }
3211
3212    /// Fills a transaction request with default values for missing fields.
3213    ///
3214    /// This method populates missing transaction fields like nonce, gas limit,
3215    /// chain ID, and fee parameters with appropriate defaults.
3216    ///
3217    /// Handler for ETH RPC call: `eth_fillTransaction`
3218    pub async fn fill_transaction(
3219        &self,
3220        request: WithOtherFields<TransactionRequest>,
3221    ) -> Result<FillTransaction<AnyRpcTransaction>> {
3222        node_info!("eth_fillTransaction");
3223        let mut request = self.parse_transaction_request(request)?;
3224
3225        let from = match request.from() {
3226            Some(from) => from,
3227            None => self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)?,
3228        };
3229
3230        let nonce = self.request_nonce_for_transaction(&request, from).await?.0;
3231
3232        // Prefill gas limit with estimated gas and bubble up estimation errors directly.
3233        if request.gas_limit().is_none() {
3234            let estimated_gas = self
3235                .do_estimate_gas_typed(request.clone(), Some(BlockNumber::Pending.into()))
3236                .await?;
3237            request.set_gas_limit(estimated_gas as u64);
3238        }
3239
3240        let typed_tx = self.build_tx_request(request, nonce).await?;
3241        let tx = typed_tx.into_impersonated();
3242
3243        let raw = tx.encoded_2718().into();
3244
3245        let mut tx =
3246            transaction_build(None, MaybeImpersonatedTransaction::new(tx), None, None, None);
3247
3248        // Set the correct `from` address (overrides the recovered zero address from dummy
3249        // signature)
3250        tx.0.inner.inner = Recovered::new_unchecked(tx.0.inner.inner.into_inner(), from);
3251
3252        Ok(FillTransaction { raw, tx })
3253    }
3254
3255    /// Handler for RPC call: `anvil_getBlobsByTransactionHash`
3256    pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
3257        node_info!("anvil_getBlobsByTransactionHash");
3258        Ok(self.backend.get_blob_by_tx_hash(hash)?)
3259    }
3260
3261    /// Get transaction by its hash.
3262    ///
3263    /// This will check the storage for a matching transaction, if no transaction exists in storage
3264    /// this will also scan the mempool for a matching pending transaction
3265    ///
3266    /// Handler for ETH RPC call: `eth_getTransactionByHash`
3267    pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
3268        node_info!("eth_getTransactionByHash");
3269        let mut tx =
3270            self.pool.get_transaction(hash).map(|pending| self.build_pool_transaction(pending));
3271        if tx.is_none() {
3272            tx = self.backend.transaction_by_hash(hash).await?
3273        }
3274
3275        Ok(tx)
3276    }
3277
3278    fn build_pool_transaction(
3279        &self,
3280        pending: PendingTransaction<FoundryTxEnvelope>,
3281    ) -> AnyRpcTransaction {
3282        let from = *pending.sender();
3283        let tx = transaction_build(
3284            Some(*pending.hash()),
3285            pending.transaction,
3286            None,
3287            None,
3288            Some(self.backend.base_fee()),
3289        );
3290
3291        let WithOtherFields { inner: mut tx, other } = tx.0;
3292        // we set the from field here explicitly to the set sender of the pending transaction,
3293        // in case the transaction is impersonated.
3294        tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
3295
3296        AnyRpcTransaction(WithOtherFields { inner: tx, other })
3297    }
3298
3299    /// Returns all ready transactions from the local pending pool.
3300    ///
3301    /// Handler for ETH RPC call: `eth_pendingTransactions`
3302    pub async fn pending_transactions(&self) -> Result<Vec<AnyRpcTransaction>> {
3303        node_info!("eth_pendingTransactions");
3304        Ok(self
3305            .pool
3306            .ready_transactions()
3307            .map(|pending| self.build_pool_transaction(pending.pending_transaction.clone()))
3308            .collect())
3309    }
3310
3311    /// Returns the transaction by sender and nonce.
3312    ///
3313    /// This will check the mempool for pending transactions first, then perform a binary search
3314    /// over mined blocks to find the transaction.
3315    ///
3316    /// Handler for ETH RPC call: `eth_getTransactionBySenderAndNonce`
3317    pub async fn transaction_by_sender_and_nonce(
3318        &self,
3319        sender: Address,
3320        nonce: U256,
3321    ) -> Result<Option<AnyRpcTransaction>> {
3322        node_info!("eth_getTransactionBySenderAndNonce");
3323
3324        // check pending txs first
3325        for pending_tx in self.pool.ready_transactions().chain(self.pool.pending_transactions()) {
3326            if U256::from(pending_tx.pending_transaction.nonce()) == nonce
3327                && *pending_tx.pending_transaction.sender() == sender
3328            {
3329                let tx = transaction_build(
3330                    Some(*pending_tx.pending_transaction.hash()),
3331                    pending_tx.pending_transaction.transaction.clone(),
3332                    None,
3333                    None,
3334                    Some(self.backend.base_fee()),
3335                );
3336
3337                let WithOtherFields { inner: mut tx, other } = tx.0;
3338                // we set the from field here explicitly to the set sender of the pending
3339                // transaction, in case the transaction is impersonated.
3340                let from = *pending_tx.pending_transaction.sender();
3341                tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
3342
3343                return Ok(Some(AnyRpcTransaction(WithOtherFields { inner: tx, other })));
3344            }
3345        }
3346
3347        let highest_nonce = self.transaction_count(sender, None).await?.saturating_to::<u64>();
3348        let target_nonce = nonce.saturating_to::<u64>();
3349
3350        // if the nonce is higher or equal to the highest nonce, the transaction doesn't exist
3351        if target_nonce >= highest_nonce {
3352            return Ok(None);
3353        }
3354
3355        // no mined blocks yet
3356        let latest_block = self.backend.best_number();
3357        if latest_block == 0 {
3358            return Ok(None);
3359        }
3360
3361        // binary search for the block containing the transaction
3362        let mut low = 1u64;
3363        let mut high = latest_block;
3364
3365        while low <= high {
3366            let mid = low + (high - low) / 2;
3367            let mid_nonce =
3368                self.transaction_count(sender, Some(mid.into())).await?.saturating_to::<u64>();
3369
3370            if mid_nonce > target_nonce {
3371                high = mid - 1;
3372            } else {
3373                low = mid + 1;
3374            }
3375        }
3376
3377        // search in the target block
3378        let target_block = low;
3379        if target_block <= latest_block
3380            && let Some(txs) =
3381                self.backend.mined_transactions_by_block_number(target_block.into()).await
3382        {
3383            for tx in txs {
3384                if tx.from() == sender && tx.nonce() == target_nonce {
3385                    return Ok(Some(tx));
3386                }
3387            }
3388        }
3389
3390        Ok(None)
3391    }
3392
3393    /// Returns transaction receipt by transaction hash.
3394    ///
3395    /// Handler for ETH RPC call: `eth_getTransactionReceipt`
3396    pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<FoundryTxReceipt>> {
3397        node_info!("eth_getTransactionReceipt");
3398        self.backend.transaction_receipt(hash).await
3399    }
3400
3401    /// Returns block receipts by block number.
3402    ///
3403    /// Handler for ETH RPC call: `eth_getBlockReceipts`
3404    pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<FoundryTxReceipt>>> {
3405        node_info!("eth_getBlockReceipts");
3406        self.backend.block_receipts(number).await
3407    }
3408
3409    /// Returns logs matching given filter object.
3410    ///
3411    /// Handler for ETH RPC call: `eth_getLogs`
3412    pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
3413        node_info!("eth_getLogs");
3414        self.backend.logs(filter).await
3415    }
3416
3417    /// Creates a filter object, based on filter options, to notify when the state changes (logs).
3418    ///
3419    /// Handler for ETH RPC call: `eth_newFilter`
3420    pub async fn new_filter(&self, filter: Filter) -> Result<String> {
3421        node_info!("eth_newFilter");
3422        // all logs that are already available that match the filter if the filter's block range is
3423        // in the past
3424        let historic = if filter.block_option.get_from_block().is_some() {
3425            self.backend.logs(filter.clone()).await?
3426        } else {
3427            vec![]
3428        };
3429        let filter = EthFilter::Logs(Box::new(LogsFilter {
3430            blocks: self.new_block_notifications(),
3431            storage: self.storage_info(),
3432            filter: FilteredParams::new(Some(filter)),
3433            historic: Some(historic),
3434        }));
3435        Ok(self.filters.add_filter(filter).await)
3436    }
3437
3438    /// Creates a filter in the node, to notify when a new block arrives.
3439    ///
3440    /// Handler for ETH RPC call: `eth_newBlockFilter`
3441    pub async fn new_block_filter(&self) -> Result<String> {
3442        node_info!("eth_newBlockFilter");
3443        let filter = EthFilter::Blocks(self.new_block_notifications());
3444        Ok(self.filters.add_filter(filter).await)
3445    }
3446
3447    /// Creates a filter in the node, to notify when new pending transactions arrive.
3448    ///
3449    /// Handler for ETH RPC call: `eth_newPendingTransactionFilter`
3450    pub async fn new_pending_transaction_filter(&self, full: bool) -> Result<String> {
3451        node_info!("eth_newPendingTransactionFilter");
3452        let filter = if full {
3453            EthFilter::FullPendingTransactions(self.full_pending_transactions_filter())
3454        } else {
3455            EthFilter::PendingTransactions(self.new_ready_transactions())
3456        };
3457        Ok(self.filters.add_filter(filter).await)
3458    }
3459
3460    /// Polling method for a filter, which returns an array of logs which occurred since last poll.
3461    ///
3462    /// Handler for ETH RPC call: `eth_getFilterChanges`
3463    pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
3464        node_info!("eth_getFilterChanges");
3465        self.filters.get_filter_changes(id).await
3466    }
3467
3468    /// Returns an array of all logs matching filter with given id.
3469    ///
3470    /// Handler for ETH RPC call: `eth_getFilterLogs`
3471    pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
3472        node_info!("eth_getFilterLogs");
3473        if let Some(filter) = self.filters.get_log_filter(id).await {
3474            self.backend.logs(filter).await
3475        } else {
3476            Err(BlockchainError::FilterNotFound)
3477        }
3478    }
3479
3480    /// Handler for ETH RPC call: `eth_uninstallFilter`
3481    pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
3482        node_info!("eth_uninstallFilter");
3483        Ok(self.filters.uninstall_filter(id).await.is_some())
3484    }
3485
3486    /// Returns EIP-2718 encoded raw transaction
3487    ///
3488    /// Handler for RPC call: `debug_getRawTransaction`
3489    pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
3490        node_info!("debug_getRawTransaction");
3491        self.inner_raw_transaction(hash).await
3492    }
3493
3494    /// Returns EIP-2718 encoded raw receipts for the block.
3495    ///
3496    /// Handler for RPC call: `debug_getRawReceipts`.
3497    pub async fn raw_receipts(&self, block: BlockId) -> Result<Vec<Bytes>> {
3498        node_info!("debug_getRawReceipts");
3499
3500        // In fork mode, serve pre-fork blocks from the upstream provider.
3501        if let BlockRequest::Number(number) = self.block_request(Some(block)).await?
3502            && let Some(fork) = self.get_fork()
3503            && fork.predates_fork_inclusive(number)
3504        {
3505            let receipts = fork.block_receipts(number).await?.unwrap_or_default();
3506            return Ok(receipts
3507                .into_iter()
3508                .map(|receipt| {
3509                    receipt.0.inner.inner.map_logs(|log| log.inner).encoded_2718().into()
3510                })
3511                .collect());
3512        }
3513
3514        let block = self.backend.get_block(block).ok_or(BlockchainError::BlockNotFound)?;
3515        let receipts = self
3516            .backend
3517            .mined_receipts(block.header.hash_slow())
3518            .ok_or(BlockchainError::BlockNotFound)?;
3519        Ok(receipts.into_iter().map(|receipt| receipt.encoded_2718().into()).collect())
3520    }
3521
3522    /// Returns EIP-2718 encoded raw transactions for the block.
3523    ///
3524    /// Handler for RPC call: `debug_getRawTransactions`.
3525    pub async fn raw_transactions(&self, block: BlockId) -> Result<Vec<Bytes>> {
3526        node_info!("debug_getRawTransactions");
3527
3528        if let Some(block) = self.backend.get_block(block) {
3529            return Ok(block
3530                .body
3531                .transactions
3532                .into_iter()
3533                .map(|tx| tx.into_inner().into_canonical().encoded_2718().into())
3534                .collect());
3535        }
3536
3537        // In fork mode, serve pre-fork blocks from the upstream provider. Genuinely unknown or
3538        // out-of-range blocks yield an empty result, mirroring reth; transport errors propagate.
3539        let Some(fork) = self.get_fork() else {
3540            return Ok(Vec::new());
3541        };
3542        let block = match block {
3543            BlockId::Number(BlockNumber::Pending) => None,
3544            BlockId::Number(number) => {
3545                let number = self.backend.convert_block_number(Some(number));
3546                if !fork.predates_fork_inclusive(number) {
3547                    return Ok(Vec::new());
3548                }
3549                fork.block_by_number_full(number).await?
3550            }
3551            BlockId::Hash(hash) => fork
3552                .block_by_hash_full(hash.block_hash)
3553                .await?
3554                .filter(|block| fork.predates_fork_inclusive(block.header().number())),
3555        };
3556        let Some(block) = block else {
3557            return Ok(Vec::new());
3558        };
3559        let BlockTransactions::Full(txs) = block.transactions() else {
3560            return Err(BlockchainError::Internal(
3561                "fork provider returned a non-full block for a full block request".to_string(),
3562            ));
3563        };
3564        Ok(txs.iter().map(|tx| tx.as_ref().encoded_2718().into()).collect())
3565    }
3566
3567    /// Returns RLP encoded raw block header.
3568    ///
3569    /// Handler for RPC call: `debug_getRawHeader`.
3570    pub async fn raw_header(&self, block: BlockId) -> Result<Bytes> {
3571        node_info!("debug_getRawHeader");
3572        let block = self.backend.get_block(block).ok_or(BlockchainError::BlockNotFound)?;
3573        Ok(alloy_rlp::encode(&block.header).into())
3574    }
3575
3576    /// Returns RLP encoded raw block.
3577    ///
3578    /// Handler for RPC call: `debug_getRawBlock`.
3579    pub async fn raw_block(&self, block: BlockId) -> Result<Bytes> {
3580        node_info!("debug_getRawBlock");
3581        let block = self.backend.get_block(block).ok_or(BlockchainError::BlockNotFound)?;
3582        Ok(alloy_rlp::encode(canonical_block(block)).into())
3583    }
3584
3585    /// Returns EIP-2718 encoded raw transaction by block hash and index
3586    ///
3587    /// Handler for RPC call: `eth_getRawTransactionByBlockHashAndIndex`
3588    pub async fn raw_transaction_by_block_hash_and_index(
3589        &self,
3590        block_hash: B256,
3591        index: Index,
3592    ) -> Result<Option<Bytes>> {
3593        node_info!("eth_getRawTransactionByBlockHashAndIndex");
3594        match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
3595            Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
3596            None => Ok(None),
3597        }
3598    }
3599
3600    /// Returns EIP-2718 encoded raw transaction by block number and index
3601    ///
3602    /// Handler for RPC call: `eth_getRawTransactionByBlockNumberAndIndex`
3603    pub async fn raw_transaction_by_block_number_and_index(
3604        &self,
3605        block_number: BlockNumber,
3606        index: Index,
3607    ) -> Result<Option<Bytes>> {
3608        node_info!("eth_getRawTransactionByBlockNumberAndIndex");
3609        match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
3610            Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
3611            None => Ok(None),
3612        }
3613    }
3614
3615    /// Returns traces for the transaction hash for geth's tracing endpoint
3616    ///
3617    /// Handler for RPC call: `debug_traceTransaction`
3618    pub async fn debug_trace_transaction(
3619        &self,
3620        tx_hash: B256,
3621        opts: GethDebugTracingOptions,
3622    ) -> Result<GethTrace> {
3623        node_info!("debug_traceTransaction");
3624        self.backend.debug_trace_transaction(tx_hash, opts).await
3625    }
3626
3627    /// Returns traces for all transactions in an RLP-encoded block.
3628    ///
3629    /// Handler for RPC call: `debug_traceBlock`
3630    pub async fn debug_trace_block(
3631        &self,
3632        rlp_block: Bytes,
3633        opts: GethDebugTracingOptions,
3634    ) -> Result<Vec<TraceResult>> {
3635        node_info!("debug_traceBlock");
3636        self.backend.debug_trace_block(rlp_block, opts).await
3637    }
3638
3639    /// Returns traces for all transactions in a block by hash.
3640    ///
3641    /// Handler for RPC call: `debug_traceBlockByHash`
3642    pub async fn debug_trace_block_by_hash(
3643        &self,
3644        block_hash: B256,
3645        opts: GethDebugTracingOptions,
3646    ) -> Result<Vec<TraceResult>> {
3647        node_info!("debug_traceBlockByHash");
3648        self.backend.debug_trace_block_by_hash(block_hash, opts).await
3649    }
3650
3651    /// Returns traces for all transactions in a block by number.
3652    ///
3653    /// Handler for RPC call: `debug_traceBlockByNumber`
3654    pub async fn debug_trace_block_by_number(
3655        &self,
3656        block_number: BlockNumber,
3657        opts: GethDebugTracingOptions,
3658    ) -> Result<Vec<TraceResult>> {
3659        node_info!("debug_traceBlockByNumber");
3660        self.backend.debug_trace_block_by_number(block_number, opts).await
3661    }
3662
3663    /// Returns traces for the transaction for geth's tracing endpoint
3664    ///
3665    /// Handler for RPC call: `debug_traceCall`
3666    pub async fn debug_trace_call(
3667        &self,
3668        request: WithOtherFields<TransactionRequest>,
3669        block_number: Option<BlockId>,
3670        opts: GethDebugTracingCallOptions,
3671    ) -> Result<GethTrace> {
3672        node_info!("debug_traceCall");
3673        let block_request = self.block_request(block_number).await?;
3674        let fees = FeeDetails::new(
3675            request.gas_price,
3676            request.max_fee_per_gas,
3677            request.max_priority_fee_per_gas,
3678            request.max_fee_per_blob_gas,
3679        )?
3680        .or_zero_fees();
3681
3682        let result: std::result::Result<GethTrace, BlockchainError> =
3683            self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
3684        result
3685    }
3686
3687    /// Traces calls sequentially on top of the same block.
3688    ///
3689    /// Handler for RPC call: `trace_callMany`.
3690    pub async fn trace_call_many(
3691        &self,
3692        calls: Vec<(WithOtherFields<TransactionRequest>, HashSet<TraceType>)>,
3693        block_number: Option<BlockId>,
3694    ) -> Result<Vec<TraceResults>> {
3695        node_info!("trace_callMany");
3696        let block_number = block_number.unwrap_or(BlockId::Number(BlockNumber::Pending));
3697        let block_request = self.block_request(Some(block_number)).await?;
3698
3699        self.backend.trace_call_many(calls, Some(block_request)).await
3700    }
3701}
3702
3703// == impl EthApi anvil endpoints ==
3704
3705impl EthApi<FoundryNetwork> {
3706    /// Mines a series of blocks.
3707    ///
3708    /// Handler for ETH RPC call: `anvil_mine`
3709    pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
3710        node_info!("anvil_mine");
3711        let interval = interval.map(|i| i.saturating_to::<u64>());
3712        let blocks = num_blocks.unwrap_or(U256::from(1));
3713        if blocks.is_zero() {
3714            return Ok(());
3715        }
3716
3717        self.on_blocking_task(|this| async move {
3718            // mine all the blocks
3719            for _ in 0..blocks.saturating_to::<u64>() {
3720                // If we have an interval, jump forwards in time to the "next" timestamp
3721                let pending_increase =
3722                    interval.map(|interval| this.backend.time().apply_time_increase(interval));
3723                if let Err(error) = this.mine_one().await {
3724                    if let Some(pending) = pending_increase {
3725                        this.backend.time().revert_time_increase(pending);
3726                    }
3727                    return Err(error);
3728                }
3729            }
3730            Ok(())
3731        })
3732        .await?;
3733
3734        Ok(())
3735    }
3736
3737    /// Helper function to find the storage slot for an ERC20 function call by testing slots
3738    /// from an access list until one produces the expected result.
3739    ///
3740    /// Rather than trying to reverse-engineer the storage layout, this function uses a
3741    /// "trial and error" approach: try overriding each slot that the function accesses,
3742    /// and see which one actually affects the function's return value.
3743    ///
3744    /// ## Parameters
3745    /// - `token_address`: The ERC20 token contract address
3746    /// - `calldata`: The encoded function call (e.g., `balanceOf(user)` or `allowance(owner,
3747    ///   spender)`)
3748    /// - `expected_value`: The value we want to set (balance or allowance amount)
3749    ///
3750    /// ## Returns
3751    /// The storage slot (B256) that contains the target ERC20 data, or an error if no slot is
3752    /// found.
3753    async fn find_erc20_storage_slot(
3754        &self,
3755        token_address: Address,
3756        calldata: Bytes,
3757        expected_value: U256,
3758    ) -> Result<B256> {
3759        let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
3760
3761        // first collect all the slots that are used by the function call
3762        let access_list_result =
3763            self.create_access_list(WithOtherFields::new(tx.clone()), None, None).await?;
3764        let access_list = access_list_result.access_list;
3765
3766        // iterate over all the accessed slots and try to find the one that contains the
3767        // target value by overriding the slot and checking the function call result
3768        for item in access_list.0 {
3769            if item.address != token_address {
3770                continue;
3771            };
3772            for slot in &item.storage_keys {
3773                let account_override = AccountOverride::default().with_state_diff(std::iter::once(
3774                    (*slot, B256::from(expected_value.to_be_bytes())),
3775                ));
3776
3777                let state_override = StateOverridesBuilder::default()
3778                    .append(token_address, account_override)
3779                    .build();
3780
3781                let evm_override = EvmOverrides::state(Some(state_override));
3782
3783                let Ok(result) =
3784                    self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
3785                else {
3786                    // overriding this slot failed
3787                    continue;
3788                };
3789
3790                let Ok(result_value) = U256::abi_decode(&result) else {
3791                    // response returned something other than a U256
3792                    continue;
3793                };
3794
3795                if result_value == expected_value {
3796                    return Ok(*slot);
3797                }
3798            }
3799        }
3800
3801        Err(BlockchainError::Message("Unable to find storage slot".to_string()))
3802    }
3803
3804    /// Deals ERC20 tokens to a address
3805    ///
3806    /// Handler for RPC call: `anvil_dealERC20`
3807    pub async fn anvil_deal_erc20(
3808        &self,
3809        address: Address,
3810        token_address: Address,
3811        balance: U256,
3812    ) -> Result<()> {
3813        node_info!("anvil_dealERC20");
3814
3815        if self.backend.is_tempo()
3816            && self.backend.try_set_tip20_balance(address, token_address, balance).await?
3817        {
3818            return Ok(());
3819        }
3820
3821        sol! {
3822            #[sol(rpc)]
3823            contract IERC20 {
3824                function balanceOf(address target) external view returns (uint256);
3825            }
3826        }
3827
3828        let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
3829
3830        // Find the storage slot that contains the balance
3831        let slot =
3832            self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
3833                BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
3834            })?;
3835
3836        // Set the storage slot to the desired balance
3837        self.anvil_set_storage_at(
3838            token_address,
3839            U256::from_be_bytes(slot.0),
3840            B256::from(balance.to_be_bytes()),
3841        )
3842        .await?;
3843
3844        Ok(())
3845    }
3846
3847    /// Deals TIP-20 tokens to an address.
3848    ///
3849    /// Handler for RPC call: `anvil_dealTIP20`.
3850    pub async fn anvil_deal_tip20(
3851        &self,
3852        address: Address,
3853        token_address: Address,
3854        balance: U256,
3855    ) -> Result<()> {
3856        node_info!("anvil_dealTIP20");
3857        self.ensure_tempo_mode()?;
3858        self.backend.set_tip20_balance(address, token_address, balance).await?;
3859        Ok(())
3860    }
3861
3862    /// Sets the ERC20 allowance for a spender
3863    ///
3864    /// Handler for RPC call: `anvil_set_erc20_allowance`
3865    pub async fn anvil_set_erc20_allowance(
3866        &self,
3867        owner: Address,
3868        spender: Address,
3869        token_address: Address,
3870        amount: U256,
3871    ) -> Result<()> {
3872        node_info!("anvil_setERC20Allowance");
3873
3874        sol! {
3875            #[sol(rpc)]
3876            contract IERC20 {
3877                function allowance(address owner, address spender) external view returns (uint256);
3878            }
3879        }
3880
3881        let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
3882
3883        // Find the storage slot that contains the allowance
3884        let slot =
3885            self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
3886                BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
3887            })?;
3888
3889        // Set the storage slot to the desired allowance
3890        self.anvil_set_storage_at(
3891            token_address,
3892            U256::from_be_bytes(slot.0),
3893            B256::from(amount.to_be_bytes()),
3894        )
3895        .await?;
3896
3897        Ok(())
3898    }
3899
3900    /// Reorg the chain to a specific depth and mine new blocks back to the canonical height.
3901    ///
3902    /// e.g depth = 3
3903    ///     A  -> B  -> C  -> D  -> E
3904    ///     A  -> B  -> C' -> D' -> E'
3905    ///
3906    /// Depth specifies the height to reorg the chain back to. Depth must not exceed the current
3907    /// chain height, i.e. can't reorg past the genesis block.
3908    ///
3909    /// Optionally supply a list of transaction and block pairs that will populate the reorged
3910    /// blocks. The maximum block number of the pairs must not exceed the specified depth.
3911    ///
3912    /// Handler for RPC call: `anvil_reorg`
3913    pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
3914        node_info!("anvil_reorg");
3915        let depth = options.depth;
3916        let tx_block_pairs = options.tx_block_pairs;
3917
3918        // Check reorg depth doesn't exceed current chain height
3919        let current_height = self.backend.best_number();
3920        let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
3921            RpcError::invalid_params(format!(
3922                "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
3923            )),
3924        ))?;
3925
3926        // Get the common ancestor block
3927        let common_block =
3928            self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
3929
3930        // Convert the transaction requests to pool transactions if they exist, otherwise use empty
3931        // hashmap
3932        let block_pool_txs = if tx_block_pairs.is_empty() {
3933            HashMap::default()
3934        } else {
3935            let mut pairs = tx_block_pairs;
3936
3937            // Check the maximum block supplied number will not exceed the reorged chain height
3938            if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
3939                return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
3940                    "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
3941                    depth - 1
3942                ))));
3943            }
3944
3945            // Sort by block number to make it easier to manage new nonces
3946            pairs.sort_by_key(|a| a.1);
3947
3948            // Manage nonces for each signer
3949            // address -> cumulative nonce
3950            let mut nonces: HashMap<Address, u64> = HashMap::default();
3951
3952            let mut txs: HashMap<u64, Vec<Arc<PoolTransaction<FoundryTxEnvelope>>>> =
3953                HashMap::default();
3954            for pair in pairs {
3955                let (tx_data, block_index) = pair;
3956
3957                let pending = match tx_data {
3958                    TransactionData::Raw(bytes) => {
3959                        let mut data = bytes.as_ref();
3960                        let decoded = FoundryTxEnvelope::decode_2718(&mut data)
3961                            .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
3962                        PendingTransaction::new(decoded)?
3963                    }
3964
3965                    TransactionData::JSON(request) => {
3966                        let from = request.from.map(Ok).unwrap_or_else(|| {
3967                            self.accounts()?
3968                                .first()
3969                                .copied()
3970                                .ok_or(BlockchainError::NoSignerAvailable)
3971                        })?;
3972
3973                        // Get the nonce at the common block
3974                        let curr_nonce = nonces.entry(from).or_insert(
3975                            self.get_transaction_count(
3976                                from,
3977                                Some(common_block.header.number().into()),
3978                            )
3979                            .await?,
3980                        );
3981
3982                        // Build typed transaction request
3983                        let typed_tx = self.build_tx_request(request.into(), *curr_nonce).await?;
3984
3985                        // Increment nonce
3986                        *curr_nonce += 1;
3987
3988                        // Handle signer and convert to pending transaction
3989                        if self.is_impersonated(from) {
3990                            let transaction = typed_tx.into_impersonated();
3991                            self.ensure_typed_transaction_supported(&transaction)?;
3992                            PendingTransaction::with_impersonated(transaction, from)
3993                        } else {
3994                            let transaction = self.sign_request(&from, typed_tx)?;
3995                            self.ensure_typed_transaction_supported(&transaction)?;
3996                            PendingTransaction::new(transaction)?
3997                        }
3998                    }
3999                };
4000
4001                let pooled = PoolTransaction::new(pending).with_replay();
4002                txs.entry(block_index).or_default().push(Arc::new(pooled));
4003            }
4004
4005            txs
4006        };
4007
4008        self.backend.reorg(depth, block_pool_txs, common_block).await?;
4009        Ok(())
4010    }
4011
4012    /// Mine blocks, instantly.
4013    ///
4014    /// Handler for RPC call: `evm_mine`
4015    ///
4016    /// This will mine the blocks regardless of the configured mining mode.
4017    /// **Note**: ganache returns `0x0` here as placeholder for additional meta-data in the future.
4018    pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
4019        node_info!("evm_mine");
4020
4021        self.do_evm_mine(opts).await?;
4022
4023        Ok("0x0".to_string())
4024    }
4025
4026    /// Mine blocks, instantly and return the mined blocks.
4027    ///
4028    /// Handler for RPC call: `evm_mine_detailed`
4029    ///
4030    /// This will mine the blocks regardless of the configured mining mode.
4031    ///
4032    /// **Note**: This behaves exactly as [Self::evm_mine] but returns different output, for
4033    /// compatibility reasons, this is a separate call since `evm_mine` is not an anvil original.
4034    /// and `ganache` may change the `0x0` placeholder.
4035    pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
4036        node_info!("evm_mine_detailed");
4037
4038        let mined_blocks = self.do_evm_mine(opts).await?;
4039
4040        let mut blocks = Vec::with_capacity(mined_blocks as usize);
4041
4042        let latest = self.backend.best_number();
4043        for offset in (0..mined_blocks).rev() {
4044            let block_num = latest - offset;
4045            if let Some(mut block) =
4046                self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
4047            {
4048                let block_txs = match block.transactions_mut() {
4049                    BlockTransactions::Full(txs) => txs,
4050                    BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
4051                };
4052                for tx in block_txs.iter_mut() {
4053                    if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
4054                        && let Some(output) = receipt.out
4055                    {
4056                        // insert revert reason if failure
4057                        if !receipt.inner.as_ref().status()
4058                            && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
4059                        {
4060                            tx.other.insert(
4061                                "revertReason".to_string(),
4062                                serde_json::to_value(reason).expect("Infallible"),
4063                            );
4064                        }
4065                        tx.other.insert(
4066                            "output".to_string(),
4067                            serde_json::to_value(output).expect("Infallible"),
4068                        );
4069                    }
4070                }
4071                block.transactions = BlockTransactions::Full(block_txs.clone());
4072                blocks.push(block);
4073            }
4074        }
4075
4076        Ok(blocks)
4077    }
4078
4079    /// Execute a transaction regardless of signature status
4080    ///
4081    /// Handler for ETH RPC call: `eth_sendUnsignedTransaction`
4082    pub async fn eth_send_unsigned_transaction(
4083        &self,
4084        request: WithOtherFields<TransactionRequest>,
4085    ) -> Result<TxHash> {
4086        node_info!("eth_sendUnsignedTransaction");
4087        let request = self.parse_transaction_request(request)?;
4088        // either use the impersonated account of the request's `from` field
4089        let from = request.from().ok_or(BlockchainError::NoSignerAvailable)?;
4090
4091        let (nonce, on_chain_nonce) = self.request_nonce_for_transaction(&request, from).await?;
4092
4093        let typed_tx = self.build_tx_request(request, nonce).await?;
4094
4095        let transaction = typed_tx.into_impersonated();
4096
4097        self.ensure_typed_transaction_supported(&transaction)?;
4098
4099        let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
4100
4101        // pre-validate
4102        self.backend.validate_pool_transaction(&pending_transaction).await?;
4103
4104        let (requires, provides) = nonce_markers(&pending_transaction, nonce, on_chain_nonce, from);
4105
4106        self.add_pending_transaction(pending_transaction, requires, provides)
4107    }
4108
4109    /// Returns a summary of all the transactions currently pending for inclusion in the next
4110    /// block(s), as well as the ones that are being scheduled for future execution only.
4111    ///
4112    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect) for more details
4113    ///
4114    /// Handler for ETH RPC call: `txpool_inspect`
4115    pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
4116        node_info!("txpool_inspect");
4117        let mut inspect = TxpoolInspect::default();
4118
4119        fn convert(tx: Arc<PoolTransaction<FoundryTxEnvelope>>) -> TxpoolInspectSummary {
4120            let tx = &tx.pending_transaction.transaction;
4121            let to = tx.to();
4122            let gas_price = tx.max_fee_per_gas();
4123            let value = tx.value();
4124            let gas = tx.gas_limit();
4125            TxpoolInspectSummary { to, value, gas, gas_price }
4126        }
4127
4128        // Note: naming differs geth vs anvil:
4129        //
4130        // _Pending transactions_ are transactions that are ready to be processed and included in
4131        // the block. _Queued transactions_ are transactions where the transaction nonce is
4132        // not in sequence. The transaction nonce is an incrementing number for each transaction
4133        // with the same From address.
4134        for pending in self.pool.ready_transactions() {
4135            let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
4136            let key = txpool_transaction_key(&pending.pending_transaction);
4137            entry.insert(key, convert(pending));
4138        }
4139        for queued in self.pool.pending_transactions() {
4140            let entry = inspect.queued.entry(*queued.pending_transaction.sender()).or_default();
4141            let key = txpool_transaction_key(&queued.pending_transaction);
4142            entry.insert(key, convert(queued));
4143        }
4144        Ok(inspect)
4145    }
4146
4147    /// Returns the details of all transactions currently pending for inclusion in the next
4148    /// block(s), as well as the ones that are being scheduled for future execution only.
4149    ///
4150    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content) for more details
4151    ///
4152    /// Handler for ETH RPC call: `txpool_content`
4153    pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
4154        node_info!("txpool_content");
4155        self.build_txpool_content(None)
4156    }
4157
4158    /// Builds the txpool content, optionally filtered to a single sender.
4159    ///
4160    /// When `filter` is `Some`, only transactions from that sender are converted, avoiding the
4161    /// cost of building RPC transactions for unrelated senders.
4162    fn build_txpool_content(
4163        &self,
4164        filter: Option<Address>,
4165    ) -> Result<TxpoolContent<AnyRpcTransaction>> {
4166        let mut content = TxpoolContent::<AnyRpcTransaction>::default();
4167        fn convert(tx: Arc<PoolTransaction<FoundryTxEnvelope>>) -> Result<AnyRpcTransaction> {
4168            let from = *tx.pending_transaction.sender();
4169            let tx = transaction_build(
4170                Some(tx.hash()),
4171                tx.pending_transaction.transaction.clone(),
4172                None,
4173                None,
4174                None,
4175            );
4176
4177            let WithOtherFields { inner: mut tx, other } = tx.0;
4178
4179            // we set the from field here explicitly to the set sender of the pending transaction,
4180            // in case the transaction is impersonated.
4181            tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
4182
4183            let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
4184
4185            Ok(tx)
4186        }
4187
4188        for pending in self.pool.ready_transactions() {
4189            let sender = *pending.pending_transaction.sender();
4190            if filter.is_some_and(|from| from != sender) {
4191                continue;
4192            }
4193            let entry = content.pending.entry(sender).or_default();
4194            let key = txpool_transaction_key(&pending.pending_transaction);
4195            entry.insert(key, convert(pending)?);
4196        }
4197        for queued in self.pool.pending_transactions() {
4198            let sender = *queued.pending_transaction.sender();
4199            if filter.is_some_and(|from| from != sender) {
4200                continue;
4201            }
4202            let entry = content.queued.entry(sender).or_default();
4203            let key = txpool_transaction_key(&queued.pending_transaction);
4204            entry.insert(key, convert(queued)?);
4205        }
4206
4207        Ok(content)
4208    }
4209
4210    /// Returns the details of all transactions currently pending for inclusion in the next
4211    /// block(s), as well as the ones that are being scheduled for future execution only, filtered
4212    /// by sender.
4213    ///
4214    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_contentFrom) for more details
4215    ///
4216    /// Handler for ETH RPC call: `txpool_contentFrom`
4217    pub async fn txpool_content_from(
4218        &self,
4219        from: Address,
4220    ) -> Result<TxpoolContentFrom<AnyRpcTransaction>> {
4221        node_info!("txpool_contentFrom");
4222        let mut content = self.build_txpool_content(Some(from))?;
4223        Ok(content.remove_from(&from))
4224    }
4225}
4226
4227impl EthApi<FoundryNetwork> {
4228    /// Executes the `evm_mine` and returns the number of blocks mined
4229    async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
4230        let mut blocks_to_mine = 1u64;
4231
4232        if let Some(opts) = opts {
4233            let timestamp = match opts {
4234                MineOptions::Timestamp(timestamp) => timestamp,
4235                MineOptions::Options { timestamp, blocks } => {
4236                    if let Some(blocks) = blocks {
4237                        blocks_to_mine = blocks;
4238                    }
4239                    timestamp
4240                }
4241            };
4242            if let Some(timestamp) = timestamp {
4243                // timestamp was explicitly provided to be the next timestamp
4244                self.evm_set_next_block_timestamp(timestamp)?;
4245            }
4246        }
4247
4248        // this can be blocking for a bit, especially in forking mode
4249        // <https://github.com/foundry-rs/foundry/issues/6036>
4250        self.on_blocking_task(|this| async move {
4251            // mine all the blocks
4252            for _ in 0..blocks_to_mine {
4253                this.mine_one().await?;
4254            }
4255            Ok(())
4256        })
4257        .await?;
4258
4259        Ok(blocks_to_mine)
4260    }
4261
4262    async fn do_estimate_gas(
4263        &self,
4264        request: WithOtherFields<TransactionRequest>,
4265        block_number: Option<BlockId>,
4266        overrides: EvmOverrides,
4267    ) -> Result<u128> {
4268        let block_request = self.block_request(block_number).await?;
4269        // check if the number predates the fork, if in fork mode
4270        if let BlockRequest::Number(number) = block_request
4271            && let Some(fork) = self.get_fork()
4272            && fork.predates_fork(number)
4273        {
4274            if overrides.has_state() || overrides.has_block() {
4275                return Err(BlockchainError::EvmOverrideError(
4276                    "not available on past forked blocks".to_string(),
4277                ));
4278            }
4279            return Ok(fork.estimate_gas_raw(&request, Some(number.into())).await?);
4280        }
4281
4282        // this can be blocking for a bit, especially in forking mode
4283        // <https://github.com/foundry-rs/foundry/issues/6036>
4284        self.on_blocking_task(|this| async move {
4285            let request = this.parse_transaction_request(request)?;
4286            this.backend
4287                .with_database_at(Some(block_request), |state, mut block| {
4288                    let mut cache_db = CacheDB::new(state);
4289                    if let Some(state_overrides) = overrides.state {
4290                        apply_state_overrides(
4291                            state_overrides.into_iter().collect(),
4292                            &mut cache_db,
4293                        )?;
4294                    }
4295                    if let Some(block_overrides) = overrides.block {
4296                        cache_db.apply_block_overrides(*block_overrides, &mut block);
4297                    }
4298                    this.do_estimate_gas_with_state(request, &cache_db, block)
4299                })
4300                .await?
4301        })
4302        .await
4303    }
4304
4305    async fn do_estimate_gas_typed(
4306        &self,
4307        request: FoundryTransactionRequest,
4308        block_number: Option<BlockId>,
4309    ) -> Result<u128> {
4310        let block_request = self.block_request(block_number).await?;
4311        self.on_blocking_task(|this| async move {
4312            this.backend
4313                .with_database_at(Some(block_request), |state, block| {
4314                    this.do_estimate_gas_with_state(request, &state, block)
4315                })
4316                .await?
4317        })
4318        .await
4319    }
4320
4321    /// Returns the priority of the transaction based on the current `TransactionOrder`
4322    fn transaction_priority(&self, tx: &FoundryTxEnvelope) -> TransactionPriority {
4323        self.transaction_order.read().priority(tx)
4324    }
4325
4326    /// Returns a listener for pending transactions, yielding full transactions
4327    pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
4328        let (tx, rx) = unbounded_channel();
4329        let mut hashes = self.new_ready_transactions();
4330
4331        let this = self.clone();
4332
4333        tokio::spawn(async move {
4334            while let Some(hash) = hashes.next().await {
4335                if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
4336                    && tx.send(txn).is_err()
4337                {
4338                    break;
4339                }
4340            }
4341        });
4342
4343        rx
4344    }
4345
4346    /// Returns a bounded stream of full pending transactions for poll-based filters.
4347    ///
4348    /// Unlike [`Self::full_pending_transactions`], this applies backpressure via a bounded channel,
4349    /// so an unpolled filter cannot buffer transactions without bound.
4350    pub fn full_pending_transactions_filter(&self) -> mpsc::Receiver<AnyRpcTransaction> {
4351        // Mirror the pool's ready-listener buffer so a full filter is bounded like a hash filter.
4352        let (tx, rx) = mpsc::channel(2048);
4353        let mut hashes = self.new_ready_transactions();
4354        let this = self.clone();
4355
4356        tokio::spawn(async move {
4357            while let Some(hash) = hashes.next().await {
4358                if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
4359                    && tx.send(txn).await.is_err()
4360                {
4361                    break;
4362                }
4363            }
4364        });
4365
4366        rx
4367    }
4368
4369    /// Returns a listener for new block receipts.
4370    pub fn transaction_receipts_subscription(
4371        &self,
4372        filter: TransactionReceiptsParams,
4373    ) -> UnboundedReceiver<Vec<FoundryTxReceipt>> {
4374        let (tx, rx) = unbounded_channel();
4375        let mut blocks = self.new_block_notifications();
4376        let this = self.clone();
4377
4378        tokio::spawn(async move {
4379            // Precompute the hash filter once.
4380            let hash_filter = filter
4381                .transaction_hashes
4382                .filter(|hashes| !hashes.is_empty())
4383                .map(|hashes| hashes.into_iter().collect::<std::collections::HashSet<_>>());
4384
4385            loop {
4386                let notification = tokio::select! {
4387                    biased;
4388                    // Exit when the subscriber unsubscribes, even while awaiting the next block.
4389                    _ = tx.closed() => break,
4390                    maybe_block = blocks.next() => match maybe_block {
4391                        Some(block) => block,
4392                        None => break,
4393                    },
4394                };
4395
4396                let Some(block) = notification.as_new_block() else {
4397                    continue;
4398                };
4399
4400                let receipts = match this.block_receipts(BlockId::Hash(block.hash.into())).await {
4401                    Ok(Some(mut receipts)) => {
4402                        if let Some(hashes) = &hash_filter {
4403                            receipts.retain(|receipt| hashes.contains(&receipt.transaction_hash()));
4404                        }
4405                        receipts
4406                    }
4407                    Ok(None) => continue,
4408                    Err(err) => {
4409                        trace!(target: "node", %err, "failed to build block receipts for subscription");
4410                        continue;
4411                    }
4412                };
4413
4414                if receipts.is_empty() {
4415                    continue;
4416                }
4417
4418                if tx.send(receipts).is_err() {
4419                    break;
4420                }
4421            }
4422        });
4423
4424        rx
4425    }
4426
4427    /// Mines exactly one block
4428    pub async fn mine_one(&self) -> Result<()> {
4429        let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
4430        let outcome = self.backend.mine_block(transactions).await?;
4431
4432        trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
4433        self.pool.on_mined_block(outcome);
4434        Ok(())
4435    }
4436
4437    /// Returns the pending block with tx hashes
4438    async fn pending_block(&self) -> AnyRpcBlock {
4439        let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
4440        let info = self.backend.pending_block(transactions).await;
4441        self.backend.convert_block(info.block)
4442    }
4443
4444    /// Returns the full pending block with `Transaction` objects
4445    async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
4446        let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
4447        let BlockInfo { block, transactions, receipts: _ } =
4448            self.backend.pending_block(transactions).await;
4449
4450        let mut partial_block = self.backend.convert_block(block.clone());
4451
4452        let mut block_transactions = Vec::with_capacity(block.body.transactions.len());
4453        let base_fee = self.backend.base_fee();
4454
4455        for info in transactions {
4456            let tx = block.body.transactions.get(info.transaction_index as usize)?.clone();
4457
4458            let tx = transaction_build(
4459                Some(info.transaction_hash),
4460                tx,
4461                Some(&block),
4462                Some(info),
4463                Some(base_fee),
4464            );
4465            block_transactions.push(tx);
4466        }
4467
4468        partial_block.transactions = BlockTransactions::from(block_transactions);
4469
4470        Some(partial_block)
4471    }
4472
4473    /// Prepares transaction request by filling missing fields using Anvil's API, then attempts
4474    /// to build a [`FoundryTypedTx`].
4475    async fn build_tx_request(
4476        &self,
4477        mut request: FoundryTransactionRequest,
4478        nonce: u64,
4479    ) -> Result<FoundryTypedTx> {
4480        let from = request.from().or(self.accounts()?.first().copied());
4481        if let Some(from) = from {
4482            request.set_from(from);
4483        }
4484
4485        // Fill common fields for all tx types
4486        request.chain_id().is_none().then(|| request.set_chain_id(self.chain_id()));
4487        request.nonce().is_none().then(|| request.set_nonce(nonce));
4488        let is_tempo_batch =
4489            matches!(&request, FoundryTransactionRequest::Tempo(tx) if !tx.calls.is_empty());
4490        if request.kind().is_none() && !is_tempo_batch {
4491            request.set_kind(TxKind::default());
4492        }
4493        if request.gas_limit().is_none() {
4494            let fallback_gas_limit = {
4495                let evm_env = self.backend.evm_env().read();
4496                let block_gas_limit = evm_env.block_env.gas_limit;
4497                if evm_env.cfg_env.tx_gas_limit_cap.is_none() {
4498                    block_gas_limit.min(evm_env.cfg_env().tx_gas_limit_cap())
4499                } else {
4500                    block_gas_limit
4501                }
4502            };
4503            let estimated_gas = self
4504                .do_estimate_gas_typed(request.clone(), None)
4505                .await
4506                .map(|v| v as u64)
4507                .unwrap_or_else(|_| {
4508                    if is_simple_transfer_request(request.as_ref()) {
4509                        MIN_TRANSACTION_GAS as u64
4510                    } else {
4511                        fallback_gas_limit
4512                    }
4513                });
4514            request.set_gas_limit(estimated_gas);
4515        }
4516
4517        // Fill missing tx type specific fields
4518        if let Err((tx_type, _)) = request.missing_keys() {
4519            if matches!(tx_type, FoundryTxType::Legacy | FoundryTxType::Eip2930) {
4520                request.gas_price().is_none().then(|| request.set_gas_price(self.gas_price()));
4521            }
4522            if tx_type == FoundryTxType::Eip2930 {
4523                request
4524                    .access_list()
4525                    .is_none()
4526                    .then(|| request.set_access_list(Default::default()));
4527            }
4528            if matches!(
4529                tx_type,
4530                FoundryTxType::Eip1559
4531                    | FoundryTxType::Eip4844
4532                    | FoundryTxType::Eip7702
4533                    | FoundryTxType::Tempo
4534            ) {
4535                request
4536                    .max_fee_per_gas()
4537                    .is_none()
4538                    .then(|| request.set_max_fee_per_gas(self.gas_price()));
4539                request
4540                    .max_priority_fee_per_gas()
4541                    .is_none()
4542                    .then(|| request.set_max_priority_fee_per_gas(MIN_SUGGESTED_PRIORITY_FEE));
4543            }
4544            if tx_type == FoundryTxType::Eip4844 {
4545                request.as_ref().max_fee_per_blob_gas().is_none().then(|| {
4546                    request.as_mut().set_max_fee_per_blob_gas(
4547                        self.backend.fees().get_next_block_blob_base_fee_per_gas(),
4548                    )
4549                });
4550            }
4551        }
4552
4553        match request
4554            .build_unsigned()
4555            .map_err(|e| BlockchainError::InvalidTransactionRequest(e.to_string()))?
4556        {
4557            FoundryTypedTx::Eip4844(TxEip4844Variant::TxEip4844(_))
4558                if !self.backend.skip_blob_validation(from) =>
4559            {
4560                // If blob validation is not skipped, reject TxEip4844 variant without sidecar.
4561                Err(BlockchainError::FailedToDecodeTransaction)
4562            }
4563            res => Ok(res),
4564        }
4565    }
4566
4567    /// Returns the nonce of the `address` depending on the `block_number`
4568    async fn get_transaction_count(
4569        &self,
4570        address: Address,
4571        block_number: Option<BlockId>,
4572    ) -> Result<u64> {
4573        let block_request = self.block_request(block_number).await?;
4574
4575        if let BlockRequest::Number(number) = block_request
4576            && let Some(fork) = self.get_fork()
4577            && fork.predates_fork(number)
4578        {
4579            return Ok(fork.get_nonce(address, number).await?);
4580        }
4581
4582        self.backend.get_nonce(address, block_request).await
4583    }
4584
4585    /// Returns the nonce for this request
4586    ///
4587    /// This returns a tuple of `(request nonce, highest nonce)`
4588    /// If the nonce field of the `request` is `None` then the tuple will be `(highest nonce,
4589    /// highest nonce)`.
4590    ///
4591    /// This will also check the tx pool for pending transactions from the sender.
4592    async fn request_nonce(
4593        &self,
4594        request: &TransactionRequest,
4595        from: Address,
4596    ) -> Result<(u64, u64)> {
4597        let highest_nonce =
4598            self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
4599        let nonce = request.nonce.unwrap_or(highest_nonce);
4600
4601        Ok((nonce, highest_nonce))
4602    }
4603
4604    /// Adds the given transaction to the pool
4605    fn add_pending_transaction(
4606        &self,
4607        pending_transaction: PendingTransaction<FoundryTxEnvelope>,
4608        requires: Vec<TxMarker>,
4609        provides: Vec<TxMarker>,
4610    ) -> Result<TxHash> {
4611        debug_assert!(requires != provides);
4612        let from = *pending_transaction.sender();
4613        let priority = self.transaction_priority(&pending_transaction.transaction);
4614        let pool_transaction =
4615            PoolTransaction { requires, provides, pending_transaction, priority, is_replay: false };
4616        let tx = self.pool.add_transaction(pool_transaction)?;
4617        trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
4618        Ok(*tx.hash())
4619    }
4620
4621    /// additional validation against hardfork
4622    fn ensure_typed_transaction_supported(&self, tx: &FoundryTxEnvelope) -> Result<()> {
4623        match &tx {
4624            FoundryTxEnvelope::Eip2930(_) => self.backend.ensure_eip2930_active(),
4625            FoundryTxEnvelope::Eip1559(_) => self.backend.ensure_eip1559_active(),
4626            FoundryTxEnvelope::Eip4844(_) => self.backend.ensure_eip4844_active(),
4627            FoundryTxEnvelope::Eip7702(_) => self.backend.ensure_eip7702_active(),
4628            #[cfg(feature = "optimism")]
4629            FoundryTxEnvelope::Deposit(_) => self.backend.ensure_op_deposits_active(),
4630            #[cfg(feature = "optimism")]
4631            FoundryTxEnvelope::PostExec(_) => Err(BlockchainError::InvalidTransactionRequest(
4632                "not implemented for post-exec tx".to_string(),
4633            )),
4634            FoundryTxEnvelope::Legacy(_) => Ok(()),
4635            FoundryTxEnvelope::Tempo(_) => self.backend.ensure_tempo_active(),
4636        }
4637    }
4638
4639    /// Sets the fee token for a user address.
4640    ///
4641    /// Handler for RPC call: `anvil_setFeeToken`
4642    ///
4643    /// Only supported when running in Tempo mode (`--tempo`).
4644    pub async fn anvil_set_fee_token(&self, user: Address, token: Address) -> Result<()> {
4645        node_info!("anvil_setFeeToken");
4646        self.ensure_tempo_mode()?;
4647        self.backend.set_fee_token(user, token).await?;
4648        Ok(())
4649    }
4650
4651    /// Sets the fee token for a validator address.
4652    ///
4653    /// Handler for RPC call: `anvil_setValidatorFeeToken`
4654    ///
4655    /// Only supported when running in Tempo mode (`--tempo`).
4656    pub async fn anvil_set_validator_fee_token(
4657        &self,
4658        validator: Address,
4659        token: Address,
4660    ) -> Result<()> {
4661        node_info!("anvil_setValidatorFeeToken");
4662        self.ensure_tempo_mode()?;
4663        self.backend.set_validator_fee_token(validator, token).await?;
4664        Ok(())
4665    }
4666
4667    /// Mints FeeAMM liquidity for a token pair.
4668    ///
4669    /// Handler for RPC call: `anvil_setFeeAmmLiquidity`
4670    ///
4671    /// Only supported when running in Tempo mode (`--tempo`).
4672    pub async fn anvil_set_fee_amm_liquidity(
4673        &self,
4674        user_token: Address,
4675        validator_token: Address,
4676        amount: U256,
4677    ) -> Result<()> {
4678        node_info!("anvil_setFeeAmmLiquidity");
4679        self.ensure_tempo_mode()?;
4680        self.backend.set_fee_amm_liquidity(user_token, validator_token, amount).await?;
4681        Ok(())
4682    }
4683
4684    /// Ensures anvil runs in Tempo mode (`--tempo`), the RPC method is unavailable otherwise.
4685    fn ensure_tempo_mode(&self) -> Result<()> {
4686        if self.backend.is_tempo() { Ok(()) } else { Err(BlockchainError::RpcUnimplemented) }
4687    }
4688
4689    fn parse_transaction_request(
4690        &self,
4691        request: WithOtherFields<TransactionRequest>,
4692    ) -> Result<FoundryTransactionRequest> {
4693        self.backend.parse_transaction_request(request)
4694    }
4695
4696    async fn request_nonce_for_transaction(
4697        &self,
4698        request: &FoundryTransactionRequest,
4699        from: Address,
4700    ) -> Result<(u64, u64)> {
4701        if let FoundryTransactionRequest::Tempo(request) = request
4702            && let Some(nonce_key) = request.nonce_key.filter(|key| !key.is_zero())
4703        {
4704            if let Some(nonce) = request.nonce() {
4705                return Ok((nonce, 0));
4706            }
4707            let nonce = self.backend.tempo_nonce(from, nonce_key, None).await?;
4708            return Ok((nonce, 0));
4709        }
4710        self.request_nonce(request.as_ref(), from).await
4711    }
4712}
4713
4714fn is_simple_transfer_request(request: &TransactionRequest) -> bool {
4715    request.to.as_ref().and_then(TxKind::to).is_some()
4716        && (request.input.input().is_none()
4717            || request.input.input().is_some_and(|data| data.is_empty()))
4718        && request.authorization_list.is_none()
4719        && request.access_list.is_none()
4720        && request.blob_versioned_hashes.is_none()
4721}
4722
4723fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
4724    if provided_nonce == on_chain_nonce {
4725        return Vec::new();
4726    }
4727    let prev_nonce = provided_nonce.saturating_sub(1);
4728    if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
4729}
4730
4731fn tempo_parallel_nonce_markers(
4732    pending_transaction: &PendingTransaction<FoundryTxEnvelope>,
4733) -> Option<(Vec<TxMarker>, Vec<TxMarker>)> {
4734    // Tempo txs with non-zero nonce_key use a 2D nonce system and should not
4735    // be sequenced by account nonce markers.
4736    pending_transaction
4737        .transaction
4738        .as_ref()
4739        .has_nonzero_tempo_nonce_key()
4740        .then(|| (vec![], vec![pending_transaction.hash().to_vec()]))
4741}
4742
4743/// Returns the pool `(requires, provides)` markers for a transaction, accounting for
4744/// Tempo's 2D nonce system (see [`tempo_parallel_nonce_markers`]).
4745fn nonce_markers(
4746    pending_transaction: &PendingTransaction<FoundryTxEnvelope>,
4747    nonce: u64,
4748    on_chain_nonce: u64,
4749    from: Address,
4750) -> (Vec<TxMarker>, Vec<TxMarker>) {
4751    tempo_parallel_nonce_markers(pending_transaction).unwrap_or_else(|| {
4752        (required_marker(nonce, on_chain_nonce, from), vec![to_marker(nonce, from)])
4753    })
4754}
4755
4756fn txpool_transaction_key(pending_transaction: &PendingTransaction<FoundryTxEnvelope>) -> String {
4757    match pending_transaction.transaction.as_ref() {
4758        FoundryTxEnvelope::Tempo(tx) if !tx.tx().nonce_key.is_zero() => {
4759            let tx = tx.tx();
4760            format!("{}:{}", tx.nonce_key, tx.nonce)
4761        }
4762        _ => pending_transaction.nonce().to_string(),
4763    }
4764}
4765
4766fn convert_transact_out(out: &Option<Output>) -> Bytes {
4767    match out {
4768        None => Default::default(),
4769        Some(Output::Call(out)) => out.to_vec().into(),
4770        Some(Output::Create(out, _)) => out.to_vec().into(),
4771    }
4772}
4773
4774/// Returns an error if the `exit` code is _not_ ok
4775fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
4776    let out = convert_transact_out(out);
4777    match exit {
4778        return_ok!() => Ok(out),
4779        return_revert!() => Err(InvalidTransactionError::Revert(Some(out)).into()),
4780        reason => Err(BlockchainError::EvmError(reason)),
4781    }
4782}
4783
4784/// Maps an EVM exit code to the optional `error` string reported in
4785/// `eth_createAccessList` results.
4786fn execution_error(exit: InstructionResult) -> Option<String> {
4787    match SuccessOrHalt::<HaltReason>::from(exit) {
4788        SuccessOrHalt::Success(_) => None,
4789        SuccessOrHalt::Revert => Some("execution reverted".to_string()),
4790        SuccessOrHalt::Halt(reason) => Some(reason.to_string()),
4791        SuccessOrHalt::FatalExternalError => Some("fatal external error".to_string()),
4792        SuccessOrHalt::Internal(_) => Some("internal EVM error".to_string()),
4793    }
4794}
4795
4796/// Determines the minimum gas needed for a transaction depending on the transaction kind.
4797fn determine_base_gas_by_kind(request: &FoundryTransactionRequest) -> u128 {
4798    let inner = request.as_ref();
4799    let kind = match request {
4800        FoundryTransactionRequest::Tempo(request) => {
4801            request.calls.first().map(|call| call.to).or_else(|| inner.kind())
4802        }
4803        _ => inner.kind(),
4804    };
4805    match kind {
4806        Some(TxKind::Call(_)) => {
4807            MIN_TRANSACTION_GAS
4808                + inner.authorization_list.as_ref().map_or(0, |auths_list| {
4809                    auths_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
4810                })
4811        }
4812        Some(TxKind::Create) => MIN_CREATE_GAS,
4813        // Tighten the gas limit upwards if we don't know the tx kind to avoid deployments failing.
4814        None => MIN_CREATE_GAS,
4815    }
4816}
4817
4818/// Keeps result of a call to revm EVM used for gas estimation
4819enum GasEstimationCallResult {
4820    Success(u128),
4821    OutOfGas,
4822    Revert(Option<Bytes>),
4823    EvmError(InstructionResult),
4824}
4825
4826/// Converts the result of a call to revm EVM into a [`GasEstimationCallResult`].
4827///
4828/// Expected to stay up to date with: <https://github.com/bluealloy/revm/blob/main/crates/interpreter/src/instruction_result.rs>
4829impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
4830    type Error = BlockchainError;
4831
4832    fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
4833        match res {
4834            // Exceptional case: init used too much gas, treated as out of gas error
4835            Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
4836                Ok(Self::OutOfGas)
4837            }
4838            // Tempo intrinsic gas errors come through as Message variants
4839            Err(BlockchainError::Message(ref msg))
4840                if msg.contains("insufficient gas for intrinsic cost") =>
4841            {
4842                Ok(Self::OutOfGas)
4843            }
4844            Err(err) => Err(err),
4845            Ok((exit, output, gas, _)) => match exit {
4846                return_ok!() => Ok(Self::Success(gas)),
4847
4848                // Revert opcodes:
4849                InstructionResult::Revert => {
4850                    Ok(Self::Revert(Some(output.map(|o| o.into_data()).unwrap_or_default())))
4851                }
4852                InstructionResult::CallTooDeep
4853                | InstructionResult::OutOfFunds
4854                | InstructionResult::CreateInitCodeStartingEF00
4855                | InstructionResult::InvalidEOFInitCode
4856                | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
4857
4858                // Out of gas errors:
4859                InstructionResult::OutOfGas
4860                | InstructionResult::MemoryOOG
4861                | InstructionResult::MemoryLimitOOG
4862                | InstructionResult::PrecompileOOG
4863                | InstructionResult::InvalidOperandOOG
4864                | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
4865
4866                // Other errors:
4867                InstructionResult::OpcodeNotFound
4868                | InstructionResult::CallNotAllowedInsideStatic
4869                | InstructionResult::StateChangeDuringStaticCall
4870                | InstructionResult::InvalidFEOpcode
4871                | InstructionResult::InvalidJump
4872                | InstructionResult::NotActivated
4873                | InstructionResult::StackUnderflow
4874                | InstructionResult::StackOverflow
4875                | InstructionResult::OutOfOffset
4876                | InstructionResult::CreateCollision
4877                | InstructionResult::OverflowPayment
4878                | InstructionResult::PrecompileError
4879                | InstructionResult::NonceOverflow
4880                | InstructionResult::CreateContractSizeLimit
4881                | InstructionResult::CreateContractStartingWithEF
4882                | InstructionResult::CreateInitCodeSizeLimit
4883                | InstructionResult::InvalidImmediateEncoding
4884                | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
4885            },
4886        }
4887    }
4888}
4889
4890/// Appends the upstream part of a fee-history range that crosses the fork boundary.
4891fn merge_pre_fork_fee_history(
4892    response: &mut FeeHistory,
4893    rewards: &mut Vec<Vec<u128>>,
4894    pre: FeeHistory,
4895    fork_block: u64,
4896) {
4897    // Upstream may return fewer blocks than requested when its available history starts later.
4898    response.oldest_block = pre.oldest_block;
4899    let count = fork_block.checked_sub(pre.oldest_block).map_or(0, |count| count.saturating_add(1))
4900        as usize;
4901
4902    // Base-fee arrays include a trailing next-block entry. The caller computes that block locally.
4903    response.base_fee_per_gas.extend(pre.base_fee_per_gas.into_iter().take(count));
4904    response.gas_used_ratio.extend(pre.gas_used_ratio.into_iter().take(count));
4905    if let Some(reward) = pre.reward {
4906        rewards.extend(reward.into_iter().take(count));
4907    }
4908
4909    // EIP-4844 fields may be omitted for pre-Cancun blocks. Pad to the actual returned count.
4910    response.base_fee_per_blob_gas.extend(pre.base_fee_per_blob_gas.into_iter().take(count));
4911    response.base_fee_per_blob_gas.resize(count, 0);
4912    response.blob_gas_used_ratio.extend(pre.blob_gas_used_ratio.into_iter().take(count));
4913    response.blob_gas_used_ratio.resize(count, 0.0);
4914}
4915
4916#[cfg(test)]
4917mod tests {
4918    use super::*;
4919    use crate::{NodeConfig, spawn};
4920
4921    // Regression test for <https://github.com/foundry-rs/foundry/issues/13680>.
4922    #[tokio::test(flavor = "multi_thread")]
4923    async fn fee_history_is_complete_when_cache_entries_are_missing() {
4924        let (api, _handle) = spawn(NodeConfig::test()).await;
4925        let count = 10u64;
4926        api.anvil_mine(Some(U256::from(count)), None).await.unwrap();
4927
4928        // Wait until the asynchronous service has consumed all block notifications, then clear
4929        // its cache. With no notifications left to repopulate it, this deterministically exercises
4930        // the RPC handler's fallback for canonical blocks whose cache entries are absent.
4931        tokio::time::timeout(Duration::from_secs(5), async {
4932            loop {
4933                if (1..=count).all(|number| api.fee_history_cache.lock().contains_key(&number)) {
4934                    break;
4935                }
4936                tokio::task::yield_now().await;
4937            }
4938        })
4939        .await
4940        .unwrap();
4941        api.fee_history_cache.lock().clear();
4942
4943        let fee_history =
4944            api.fee_history(U256::from(count), BlockNumber::Latest, vec![50.0]).await.unwrap();
4945
4946        assert_eq!(fee_history.oldest_block, 1);
4947        assert_eq!(fee_history.gas_used_ratio.len(), count as usize);
4948        assert_eq!(fee_history.blob_gas_used_ratio.len(), count as usize);
4949        assert_eq!(fee_history.base_fee_per_gas.len(), count as usize + 1);
4950        assert_eq!(fee_history.base_fee_per_blob_gas.len(), count as usize + 1);
4951        let rewards = fee_history.reward.unwrap();
4952        assert_eq!(rewards.len(), count as usize);
4953        assert!(rewards.iter().all(|reward| reward.len() == 1));
4954    }
4955
4956    #[test]
4957    fn shortened_pre_fork_fee_history_uses_upstream_start() {
4958        let requested_lowest = 4;
4959        let fork_block = 10;
4960        let pre = FeeHistory {
4961            oldest_block: 5,
4962            base_fee_per_gas: vec![1; 7],
4963            gas_used_ratio: vec![0.0; 6],
4964            reward: Some(vec![vec![]; 6]),
4965            base_fee_per_blob_gas: vec![],
4966            blob_gas_used_ratio: vec![],
4967        };
4968
4969        let mut response = FeeHistory { oldest_block: requested_lowest, ..Default::default() };
4970        let mut rewards = Vec::new();
4971
4972        merge_pre_fork_fee_history(&mut response, &mut rewards, pre, fork_block);
4973
4974        assert_eq!(response.oldest_block, 5);
4975        assert_eq!(response.gas_used_ratio.len(), 6);
4976        assert_eq!(response.base_fee_per_gas.len(), 6);
4977        assert_eq!(response.blob_gas_used_ratio.len(), 6);
4978        assert_eq!(response.base_fee_per_blob_gas.len(), 6);
4979        assert_eq!(rewards.len(), 6);
4980    }
4981}