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