Skip to main content

anvil/eth/
api.rs

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