Skip to main content

anvil/eth/
api.rs

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