Skip to main content

anvil/eth/
api.rs

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