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