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::{
33 Account, Blob, Transaction,
34 transaction::{Recovered, eip4844::TxEip4844Variant},
35};
36use alloy_dyn_abi::TypedData;
37use alloy_eips::{
38 eip2718::Encodable2718,
39 eip4844::BlobTransactionSidecar,
40 eip7910::{EthConfig, EthForkConfig},
41};
42use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
43use alloy_network::{
44 AnyRpcBlock, AnyRpcTransaction, BlockResponse, TransactionBuilder, TransactionBuilder4844,
45 TransactionResponse, eip2718::Decodable2718,
46};
47use alloy_primitives::{
48 Address, B64, B256, Bytes, Signature, TxHash, TxKind, U64, U256,
49 map::{HashMap, HashSet},
50};
51use alloy_rpc_types::{
52 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
53 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
54 anvil::{
55 ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
56 },
57 request::TransactionRequest,
58 simulate::{SimulatePayload, SimulatedBlock},
59 state::{AccountOverride, EvmOverrides, StateOverridesBuilder},
60 trace::{
61 filter::TraceFilter,
62 geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
63 parity::LocalizedTransactionTrace,
64 },
65 txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
66};
67use alloy_rpc_types_eth::FillTransaction;
68use alloy_serde::WithOtherFields;
69use alloy_sol_types::{SolCall, SolValue, sol};
70use alloy_transport::TransportErrorKind;
71use anvil_core::{
72 eth::{
73 EthRequest,
74 block::BlockInfo,
75 transaction::{
76 MaybeImpersonatedTransaction, PendingTransaction, ReceiptResponse,
77 transaction_request_to_typed,
78 },
79 wallet::WalletCapabilities,
80 },
81 types::{ReorgOptions, TransactionData},
82};
83use anvil_rpc::{error::RpcError, response::ResponseResult};
84use foundry_common::provider::ProviderBuilder;
85use foundry_evm::decode::RevertDecoder;
86use foundry_primitives::{FoundryTxEnvelope, FoundryTypedTx};
87use futures::{
88 StreamExt, TryFutureExt,
89 channel::{mpsc::Receiver, oneshot},
90};
91use parking_lot::RwLock;
92use revm::{
93 context::BlockEnv,
94 context_interface::{block::BlobExcessGasAndPrice, result::Output},
95 database::CacheDB,
96 interpreter::{InstructionResult, return_ok, return_revert},
97 primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
98};
99use std::{sync::Arc, time::Duration};
100use tokio::{
101 sync::mpsc::{UnboundedReceiver, unbounded_channel},
102 try_join,
103};
104
105pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
107
108#[derive(Clone)]
112pub struct EthApi {
113 pool: Arc<Pool>,
115 pub backend: Arc<backend::mem::Backend>,
118 is_mining: bool,
120 signers: Arc<Vec<Box<dyn Signer>>>,
122 fee_history_cache: FeeHistoryCache,
124 fee_history_limit: u64,
126 miner: Miner,
131 logger: LoggingManager,
133 filters: Filters,
135 transaction_order: Arc<RwLock<TransactionOrder>>,
137 net_listening: bool,
139 instance_id: Arc<RwLock<B256>>,
141}
142
143impl EthApi {
144 #[expect(clippy::too_many_arguments)]
146 pub fn new(
147 pool: Arc<Pool>,
148 backend: Arc<backend::mem::Backend>,
149 signers: Arc<Vec<Box<dyn Signer>>>,
150 fee_history_cache: FeeHistoryCache,
151 fee_history_limit: u64,
152 miner: Miner,
153 logger: LoggingManager,
154 filters: Filters,
155 transactions_order: TransactionOrder,
156 ) -> Self {
157 Self {
158 pool,
159 backend,
160 is_mining: true,
161 signers,
162 fee_history_cache,
163 fee_history_limit,
164 miner,
165 logger,
166 filters,
167 net_listening: true,
168 transaction_order: Arc::new(RwLock::new(transactions_order)),
169 instance_id: Arc::new(RwLock::new(B256::random())),
170 }
171 }
172
173 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
175 trace!(target: "rpc::api", "executing eth request");
176 let response = match request.clone() {
177 EthRequest::EthProtocolVersion(()) => self.protocol_version().to_rpc_result(),
178 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
179 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
180 EthRequest::EthGetAccount(addr, block) => {
181 self.get_account(addr, block).await.to_rpc_result()
182 }
183 EthRequest::EthGetAccountInfo(addr, block) => {
184 self.get_account_info(addr, block).await.to_rpc_result()
185 }
186 EthRequest::EthGetBalance(addr, block) => {
187 self.balance(addr, block).await.to_rpc_result()
188 }
189 EthRequest::EthGetTransactionByHash(hash) => {
190 self.transaction_by_hash(hash).await.to_rpc_result()
191 }
192 EthRequest::EthSendTransaction(request) => {
193 self.send_transaction(*request).await.to_rpc_result()
194 }
195 EthRequest::EthSendTransactionSync(request) => {
196 self.send_transaction_sync(*request).await.to_rpc_result()
197 }
198 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
199 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
200 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
201 EthRequest::EthHashrate(()) => self.hashrate().to_rpc_result(),
202 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
203 EthRequest::EthMaxPriorityFeePerGas(_) => {
204 self.gas_max_priority_fee_per_gas().to_rpc_result()
205 }
206 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
207 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
208 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
209 EthRequest::EthCoinbase(()) => self.author().to_rpc_result(),
210 EthRequest::EthGetStorageAt(addr, slot, block) => {
211 self.storage_at(addr, slot, block).await.to_rpc_result()
212 }
213 EthRequest::EthGetBlockByHash(hash, full) => {
214 if full {
215 self.block_by_hash_full(hash).await.to_rpc_result()
216 } else {
217 self.block_by_hash(hash).await.to_rpc_result()
218 }
219 }
220 EthRequest::EthGetBlockByNumber(num, full) => {
221 if full {
222 self.block_by_number_full(num).await.to_rpc_result()
223 } else {
224 self.block_by_number(num).await.to_rpc_result()
225 }
226 }
227 EthRequest::EthGetTransactionCount(addr, block) => {
228 self.transaction_count(addr, block).await.to_rpc_result()
229 }
230 EthRequest::EthGetTransactionCountByHash(hash) => {
231 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
232 }
233 EthRequest::EthGetTransactionCountByNumber(num) => {
234 self.block_transaction_count_by_number(num).await.to_rpc_result()
235 }
236 EthRequest::EthGetUnclesCountByHash(hash) => {
237 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
238 }
239 EthRequest::EthGetUnclesCountByNumber(num) => {
240 self.block_uncles_count_by_number(num).await.to_rpc_result()
241 }
242 EthRequest::EthGetCodeAt(addr, block) => {
243 self.get_code(addr, block).await.to_rpc_result()
244 }
245 EthRequest::EthGetProof(addr, keys, block) => {
246 self.get_proof(addr, keys, block).await.to_rpc_result()
247 }
248 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
249 EthRequest::PersonalSign(content, addr) => {
250 self.sign(addr, content).await.to_rpc_result()
251 }
252 EthRequest::EthSignTransaction(request) => {
253 self.sign_transaction(*request).await.to_rpc_result()
254 }
255 EthRequest::EthSignTypedData(addr, data) => {
256 self.sign_typed_data(addr, data).await.to_rpc_result()
257 }
258 EthRequest::EthSignTypedDataV3(addr, data) => {
259 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
260 }
261 EthRequest::EthSignTypedDataV4(addr, data) => {
262 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
263 }
264 EthRequest::EthSendRawTransaction(tx) => {
265 self.send_raw_transaction(tx).await.to_rpc_result()
266 }
267 EthRequest::EthSendRawTransactionSync(tx) => {
268 self.send_raw_transaction_sync(tx).await.to_rpc_result()
269 }
270 EthRequest::EthCall(call, block, state_override, block_overrides) => self
271 .call(call, block, EvmOverrides::new(state_override, block_overrides))
272 .await
273 .to_rpc_result(),
274 EthRequest::EthSimulateV1(simulation, block) => {
275 self.simulate_v1(simulation, block).await.to_rpc_result()
276 }
277 EthRequest::EthCreateAccessList(call, block) => {
278 self.create_access_list(call, block).await.to_rpc_result()
279 }
280 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
281 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
282 .await
283 .to_rpc_result(),
284 EthRequest::EthFillTransaction(request) => {
285 self.fill_transaction(request).await.to_rpc_result()
286 }
287 EthRequest::EthGetRawTransactionByHash(hash) => {
288 self.raw_transaction(hash).await.to_rpc_result()
289 }
290 EthRequest::GetBlobByHash(hash) => {
291 self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
292 }
293 EthRequest::GetBlobByTransactionHash(hash) => {
294 self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
295 }
296 EthRequest::GetBlobSidecarsByBlockId(block_id) => {
297 self.anvil_get_blob_sidecars_by_block_id(block_id).to_rpc_result()
298 }
299 EthRequest::GetGenesisTime(()) => self.anvil_get_genesis_time().to_rpc_result(),
300 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
301 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
302 }
303 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
304 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
305 }
306 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
307 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
308 }
309 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
310 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
311 }
312 EthRequest::EthGetTransactionReceipt(tx) => {
313 self.transaction_receipt(tx).await.to_rpc_result()
314 }
315 EthRequest::EthGetBlockReceipts(number) => {
316 self.block_receipts(number).await.to_rpc_result()
317 }
318 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
319 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
320 }
321 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
322 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
323 }
324 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
325 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
326 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
327 EthRequest::EthConfig(_) => self.config().to_rpc_result(),
328 EthRequest::EthSubmitWork(nonce, pow, digest) => {
329 self.submit_work(nonce, pow, digest).to_rpc_result()
330 }
331 EthRequest::EthSubmitHashRate(rate, id) => {
332 self.submit_hashrate(rate, id).to_rpc_result()
333 }
334 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
335 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
336 }
337 EthRequest::DebugGetRawTransaction(hash) => {
339 self.raw_transaction(hash).await.to_rpc_result()
340 }
341 EthRequest::DebugTraceTransaction(tx, opts) => {
343 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
344 }
345 EthRequest::DebugTraceCall(tx, block, opts) => {
347 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
348 }
349 EthRequest::DebugCodeByHash(hash, block) => {
350 self.debug_code_by_hash(hash, block).await.to_rpc_result()
351 }
352 EthRequest::DebugDbGet(key) => self.debug_db_get(key).await.to_rpc_result(),
353 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
354 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
355 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
356 EthRequest::ImpersonateAccount(addr) => {
357 self.anvil_impersonate_account(addr).await.to_rpc_result()
358 }
359 EthRequest::StopImpersonatingAccount(addr) => {
360 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
361 }
362 EthRequest::AutoImpersonateAccount(enable) => {
363 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
364 }
365 EthRequest::ImpersonateSignature(signature, address) => {
366 self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
367 }
368 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
369 EthRequest::Mine(blocks, interval) => {
370 self.anvil_mine(blocks, interval).await.to_rpc_result()
371 }
372 EthRequest::SetAutomine(enabled) => {
373 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
374 }
375 EthRequest::SetIntervalMining(interval) => {
376 self.anvil_set_interval_mining(interval).to_rpc_result()
377 }
378 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
379 EthRequest::DropTransaction(tx) => {
380 self.anvil_drop_transaction(tx).await.to_rpc_result()
381 }
382 EthRequest::DropAllTransactions() => {
383 self.anvil_drop_all_transactions().await.to_rpc_result()
384 }
385 EthRequest::Reset(fork) => {
386 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
387 }
388 EthRequest::SetBalance(addr, val) => {
389 self.anvil_set_balance(addr, val).await.to_rpc_result()
390 }
391 EthRequest::AddBalance(addr, val) => {
392 self.anvil_add_balance(addr, val).await.to_rpc_result()
393 }
394 EthRequest::DealERC20(addr, token_addr, val) => {
395 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
396 }
397 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
398 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
399 .await
400 .to_rpc_result(),
401 EthRequest::SetCode(addr, code) => {
402 self.anvil_set_code(addr, code).await.to_rpc_result()
403 }
404 EthRequest::SetNonce(addr, nonce) => {
405 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
406 }
407 EthRequest::SetStorageAt(addr, slot, val) => {
408 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
409 }
410 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
411 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
412 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
413 EthRequest::SetMinGasPrice(gas) => {
414 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
415 }
416 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
417 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
418 }
419 EthRequest::DumpState(preserve_historical_states) => self
420 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
421 .await
422 .to_rpc_result(),
423 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
424 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
425 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
426 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
427 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
428 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
429 EthRequest::EvmSetNextBlockTimeStamp(time) => {
430 if time >= U256::from(u64::MAX) {
431 return ResponseResult::Error(RpcError::invalid_params(
432 "The timestamp is too big",
433 ));
434 }
435 let time = time.to::<u64>();
436 self.evm_set_next_block_timestamp(time).to_rpc_result()
437 }
438 EthRequest::EvmSetTime(timestamp) => {
439 if timestamp >= U256::from(u64::MAX) {
440 return ResponseResult::Error(RpcError::invalid_params(
441 "The timestamp is too big",
442 ));
443 }
444 let time = timestamp.to::<u64>();
445 self.evm_set_time(time).to_rpc_result()
446 }
447 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
448 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
449 }
450 EthRequest::EvmSetBlockTimeStampInterval(time) => {
451 self.evm_set_block_timestamp_interval(time).to_rpc_result()
452 }
453 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
454 self.evm_remove_block_timestamp_interval().to_rpc_result()
455 }
456 EthRequest::EvmMine(mine) => {
457 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
458 }
459 EthRequest::EvmMineDetailed(mine) => {
460 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
461 }
462 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
463 EthRequest::EthSendUnsignedTransaction(tx) => {
464 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
465 }
466 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
467 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
468 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
469 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
470 EthRequest::EthNewPendingTransactionFilter(_) => {
471 self.new_pending_transaction_filter().await.to_rpc_result()
472 }
473 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
474 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
475 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
476 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
477 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
478 EthRequest::ErigonGetHeaderByNumber(num) => {
479 self.erigon_get_header_by_number(num).await.to_rpc_result()
480 }
481 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
482 EthRequest::OtsGetInternalOperations(hash) => {
483 self.ots_get_internal_operations(hash).await.to_rpc_result()
484 }
485 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
486 EthRequest::OtsTraceTransaction(hash) => {
487 self.ots_trace_transaction(hash).await.to_rpc_result()
488 }
489 EthRequest::OtsGetTransactionError(hash) => {
490 self.ots_get_transaction_error(hash).await.to_rpc_result()
491 }
492 EthRequest::OtsGetBlockDetails(num) => {
493 self.ots_get_block_details(num).await.to_rpc_result()
494 }
495 EthRequest::OtsGetBlockDetailsByHash(hash) => {
496 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
497 }
498 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
499 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
500 }
501 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
502 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
503 }
504 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
505 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
506 }
507 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
508 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
509 }
510 EthRequest::EthGetTransactionBySenderAndNonce(sender, nonce) => {
511 self.transaction_by_sender_and_nonce(sender, nonce).await.to_rpc_result()
512 }
513 EthRequest::OtsGetContractCreator(address) => {
514 self.ots_get_contract_creator(address).await.to_rpc_result()
515 }
516 EthRequest::RemovePoolTransactions(address) => {
517 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
518 }
519 EthRequest::Reorg(reorg_options) => {
520 self.anvil_reorg(reorg_options).await.to_rpc_result()
521 }
522 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
523 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
524 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
525 EthRequest::AnvilSetExecutor(executor_pk) => {
526 self.anvil_set_executor(executor_pk).to_rpc_result()
527 }
528 };
529
530 if let ResponseResult::Error(err) = &response {
531 node_info!("\nRPC request failed:");
532 node_info!(" Request: {:?}", request);
533 node_info!(" Error: {}\n", err);
534 }
535
536 response
537 }
538
539 fn sign_request(&self, from: &Address, request: FoundryTypedTx) -> Result<FoundryTxEnvelope> {
540 match request {
541 FoundryTypedTx::Deposit(_) => {
542 let nil_signature = Signature::from_scalars_and_parity(
543 B256::with_last_byte(1),
544 B256::with_last_byte(1),
545 false,
546 );
547 return build_typed_transaction(request, nil_signature);
548 }
549 _ => {
550 for signer in self.signers.iter() {
551 if signer.accounts().contains(from) {
552 let signature = signer.sign_transaction(request.clone(), from)?;
553 return build_typed_transaction(request, signature);
554 }
555 }
556 }
557 }
558 Err(BlockchainError::NoSignerAvailable)
559 }
560
561 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
562 let block_request = match block_number {
563 Some(BlockId::Number(BlockNumber::Pending)) => {
564 let pending_txs = self.pool.ready_transactions().collect();
565 BlockRequest::Pending(pending_txs)
566 }
567 _ => {
568 let number = self.backend.ensure_block_number(block_number).await?;
569 BlockRequest::Number(number)
570 }
571 };
572 Ok(block_request)
573 }
574
575 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
576 match self.pool.get_transaction(hash) {
577 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
578 None => match self.backend.transaction_by_hash(hash).await? {
579 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
580 None => Ok(None),
581 },
582 }
583 }
584
585 pub fn client_version(&self) -> Result<String> {
589 node_info!("web3_clientVersion");
590 Ok(CLIENT_VERSION.to_string())
591 }
592
593 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
597 node_info!("web3_sha3");
598 let hash = alloy_primitives::keccak256(bytes.as_ref());
599 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
600 }
601
602 pub fn protocol_version(&self) -> Result<u64> {
606 node_info!("eth_protocolVersion");
607 Ok(1)
608 }
609
610 pub fn hashrate(&self) -> Result<U256> {
614 node_info!("eth_hashrate");
615 Ok(U256::ZERO)
616 }
617
618 pub fn author(&self) -> Result<Address> {
622 node_info!("eth_coinbase");
623 Ok(self.backend.coinbase())
624 }
625
626 pub fn is_mining(&self) -> Result<bool> {
630 node_info!("eth_mining");
631 Ok(self.is_mining)
632 }
633
634 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
640 node_info!("eth_chainId");
641 Ok(Some(self.backend.chain_id().to::<U64>()))
642 }
643
644 pub fn network_id(&self) -> Result<Option<String>> {
648 node_info!("eth_networkId");
649 let chain_id = self.backend.chain_id().to::<u64>();
650 Ok(Some(format!("{chain_id}")))
651 }
652
653 pub fn net_listening(&self) -> Result<bool> {
657 node_info!("net_listening");
658 Ok(self.net_listening)
659 }
660
661 fn eth_gas_price(&self) -> Result<U256> {
663 node_info!("eth_gasPrice");
664 Ok(U256::from(self.gas_price()))
665 }
666
667 pub fn gas_price(&self) -> u128 {
669 if self.backend.is_eip1559() {
670 if self.backend.is_min_priority_fee_enforced() {
671 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
672 } else {
673 self.backend.base_fee() as u128
674 }
675 } else {
676 self.backend.fees().raw_gas_price()
677 }
678 }
679
680 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
682 Ok(self.backend.excess_blob_gas_and_price())
683 }
684
685 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
690 self.max_priority_fee_per_gas()
691 }
692
693 pub fn blob_base_fee(&self) -> Result<U256> {
697 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
698 }
699
700 pub fn gas_limit(&self) -> U256 {
702 U256::from(self.backend.gas_limit())
703 }
704
705 pub fn accounts(&self) -> Result<Vec<Address>> {
709 node_info!("eth_accounts");
710 let mut unique = HashSet::new();
711 let mut accounts: Vec<Address> = Vec::new();
712 for signer in self.signers.iter() {
713 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
714 }
715 accounts.extend(
716 self.backend
717 .cheats()
718 .impersonated_accounts()
719 .into_iter()
720 .filter(|acc| unique.insert(*acc)),
721 );
722 Ok(accounts.into_iter().collect())
723 }
724
725 pub fn block_number(&self) -> Result<U256> {
729 node_info!("eth_blockNumber");
730 Ok(U256::from(self.backend.best_number()))
731 }
732
733 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
737 node_info!("eth_getBalance");
738 let block_request = self.block_request(block_number).await?;
739
740 if let BlockRequest::Number(number) = block_request
742 && let Some(fork) = self.get_fork()
743 && fork.predates_fork(number)
744 {
745 return Ok(fork.get_balance(address, number).await?);
746 }
747
748 self.backend.get_balance(address, Some(block_request)).await
749 }
750
751 pub async fn get_account(
755 &self,
756 address: Address,
757 block_number: Option<BlockId>,
758 ) -> Result<Account> {
759 node_info!("eth_getAccount");
760 let block_request = self.block_request(block_number).await?;
761
762 if let BlockRequest::Number(number) = block_request
764 && let Some(fork) = self.get_fork()
765 && fork.predates_fork(number)
766 {
767 return Ok(fork.get_account(address, number).await?);
768 }
769
770 self.backend.get_account_at_block(address, Some(block_request)).await
771 }
772
773 pub async fn get_account_info(
777 &self,
778 address: Address,
779 block_number: Option<BlockId>,
780 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
781 node_info!("eth_getAccountInfo");
782
783 if let Some(fork) = self.get_fork() {
784 let block_request = self.block_request(block_number).await?;
785 if let BlockRequest::Number(number) = block_request {
787 trace!(target: "node", "get_account_info: fork block {}, requested block {number}", fork.block_number());
788 return if fork.predates_fork(number) {
789 let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
792 let code = fork.get_code(address, number).map_err(BlockchainError::from);
793 let nonce = self.get_transaction_count(address, Some(number.into()));
794 let (balance, code, nonce) = try_join!(balance, code, nonce)?;
795
796 Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code })
797 } else {
798 let account_info = self.backend.get_account(address).await?;
801 let code = self.backend.get_code(address, Some(block_request)).await?;
802 Ok(alloy_rpc_types::eth::AccountInfo {
803 balance: account_info.balance,
804 nonce: account_info.nonce,
805 code,
806 })
807 };
808 }
809 }
810
811 let account = self.get_account(address, block_number);
812 let code = self.get_code(address, block_number);
813 let (account, code) = try_join!(account, code)?;
814 Ok(alloy_rpc_types::eth::AccountInfo {
815 balance: account.balance,
816 nonce: account.nonce,
817 code,
818 })
819 }
820 pub async fn storage_at(
824 &self,
825 address: Address,
826 index: U256,
827 block_number: Option<BlockId>,
828 ) -> Result<B256> {
829 node_info!("eth_getStorageAt");
830 let block_request = self.block_request(block_number).await?;
831
832 if let BlockRequest::Number(number) = block_request
834 && let Some(fork) = self.get_fork()
835 && fork.predates_fork(number)
836 {
837 return Ok(B256::from(
838 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
839 ));
840 }
841
842 self.backend.storage_at(address, index, Some(block_request)).await
843 }
844
845 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
849 node_info!("eth_getBlockByHash");
850 self.backend.block_by_hash(hash).await
851 }
852
853 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
857 node_info!("eth_getBlockByHash");
858 self.backend.block_by_hash_full(hash).await
859 }
860
861 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
865 node_info!("eth_getBlockByNumber");
866 if number == BlockNumber::Pending {
867 return Ok(Some(self.pending_block().await));
868 }
869
870 self.backend.block_by_number(number).await
871 }
872
873 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
877 node_info!("eth_getBlockByNumber");
878 if number == BlockNumber::Pending {
879 return Ok(self.pending_block_full().await);
880 }
881 self.backend.block_by_number_full(number).await
882 }
883
884 pub async fn transaction_count(
891 &self,
892 address: Address,
893 block_number: Option<BlockId>,
894 ) -> Result<U256> {
895 node_info!("eth_getTransactionCount");
896 self.get_transaction_count(address, block_number).await.map(U256::from)
897 }
898
899 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
903 node_info!("eth_getBlockTransactionCountByHash");
904 let block = self.backend.block_by_hash(hash).await?;
905 let txs = block.map(|b| match b.transactions() {
906 BlockTransactions::Full(txs) => U256::from(txs.len()),
907 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
908 BlockTransactions::Uncle => U256::from(0),
909 });
910 Ok(txs)
911 }
912
913 pub async fn block_transaction_count_by_number(
917 &self,
918 block_number: BlockNumber,
919 ) -> Result<Option<U256>> {
920 node_info!("eth_getBlockTransactionCountByNumber");
921 let block_request = self.block_request(Some(block_number.into())).await?;
922 if let BlockRequest::Pending(txs) = block_request {
923 let block = self.backend.pending_block(txs).await;
924 return Ok(Some(U256::from(block.block.body.transactions.len())));
925 }
926 let block = self.backend.block_by_number(block_number).await?;
927 let txs = block.map(|b| match b.transactions() {
928 BlockTransactions::Full(txs) => U256::from(txs.len()),
929 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
930 BlockTransactions::Uncle => U256::from(0),
931 });
932 Ok(txs)
933 }
934
935 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
939 node_info!("eth_getUncleCountByBlockHash");
940 let block =
941 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
942 Ok(U256::from(block.uncles.len()))
943 }
944
945 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
949 node_info!("eth_getUncleCountByBlockNumber");
950 let block = self
951 .backend
952 .block_by_number(block_number)
953 .await?
954 .ok_or(BlockchainError::BlockNotFound)?;
955 Ok(U256::from(block.uncles.len()))
956 }
957
958 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
962 node_info!("eth_getCode");
963 let block_request = self.block_request(block_number).await?;
964 if let BlockRequest::Number(number) = block_request
966 && let Some(fork) = self.get_fork()
967 && fork.predates_fork(number)
968 {
969 return Ok(fork.get_code(address, number).await?);
970 }
971 self.backend.get_code(address, Some(block_request)).await
972 }
973
974 pub async fn get_proof(
979 &self,
980 address: Address,
981 keys: Vec<B256>,
982 block_number: Option<BlockId>,
983 ) -> Result<EIP1186AccountProofResponse> {
984 node_info!("eth_getProof");
985 let block_request = self.block_request(block_number).await?;
986
987 if let BlockRequest::Number(number) = block_request
990 && let Some(fork) = self.get_fork()
991 && fork.predates_fork_inclusive(number)
992 {
993 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
994 }
995
996 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
997 Ok(proof)
998 }
999
1000 pub async fn sign_typed_data(
1004 &self,
1005 _address: Address,
1006 _data: serde_json::Value,
1007 ) -> Result<String> {
1008 node_info!("eth_signTypedData");
1009 Err(BlockchainError::RpcUnimplemented)
1010 }
1011
1012 pub async fn sign_typed_data_v3(
1016 &self,
1017 _address: Address,
1018 _data: serde_json::Value,
1019 ) -> Result<String> {
1020 node_info!("eth_signTypedData_v3");
1021 Err(BlockchainError::RpcUnimplemented)
1022 }
1023
1024 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
1028 node_info!("eth_signTypedData_v4");
1029 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1030 let signature = signer.sign_typed_data(address, data).await?;
1031 let signature = alloy_primitives::hex::encode(signature.as_bytes());
1032 Ok(format!("0x{signature}"))
1033 }
1034
1035 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1039 node_info!("eth_sign");
1040 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1041 let signature =
1042 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1043 Ok(format!("0x{signature}"))
1044 }
1045
1046 pub async fn sign_transaction(
1050 &self,
1051 mut request: WithOtherFields<TransactionRequest>,
1052 ) -> Result<String> {
1053 node_info!("eth_signTransaction");
1054
1055 let from = request.from.map(Ok).unwrap_or_else(|| {
1056 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1057 })?;
1058
1059 let (nonce, _) = self.request_nonce(&request, from).await?;
1060
1061 if request.gas.is_none() {
1062 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1064 {
1065 request.gas = Some(gas.to());
1066 }
1067 }
1068
1069 let request = self.build_typed_tx_request(request, nonce)?;
1070
1071 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1072 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1073 }
1074
1075 pub async fn send_transaction(
1079 &self,
1080 mut request: WithOtherFields<TransactionRequest>,
1081 ) -> Result<TxHash> {
1082 node_info!("eth_sendTransaction");
1083
1084 let from = request.from.map(Ok).unwrap_or_else(|| {
1085 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1086 })?;
1087 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1088
1089 if request.gas.is_none() {
1090 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1092 {
1093 request.gas = Some(gas.to());
1094 }
1095 }
1096
1097 let request = self.build_typed_tx_request(request, nonce)?;
1098
1099 let pending_transaction = if self.is_impersonated(from) {
1101 let bypass_signature = self.impersonated_signature(&request);
1102 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1103 self.ensure_typed_transaction_supported(&transaction)?;
1104 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1105 PendingTransaction::with_impersonated(transaction, from)
1106 } else {
1107 let transaction = self.sign_request(&from, request)?;
1108 self.ensure_typed_transaction_supported(&transaction)?;
1109 PendingTransaction::new(transaction)?
1110 };
1111 self.backend.validate_pool_transaction(&pending_transaction).await?;
1113
1114 let requires = required_marker(nonce, on_chain_nonce, from);
1115 let provides = vec![to_marker(nonce, from)];
1116 debug_assert!(requires != provides);
1117
1118 self.add_pending_transaction(pending_transaction, requires, provides)
1119 }
1120
1121 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1123 let mut stream = self.new_block_notifications();
1124 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1126 return Ok(receipt);
1127 }
1128 while let Some(notification) = stream.next().await {
1129 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1130 && block.body.transactions.iter().any(|tx| tx.hash() == hash)
1131 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1132 {
1133 return Ok(receipt);
1134 }
1135 }
1136
1137 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1138 }
1139
1140 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1142 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1143 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1144 .await
1145 .unwrap_or_else(|_elapsed| {
1146 Err(BlockchainError::TransactionConfirmationTimeout {
1147 hash,
1148 duration: TIMEOUT_DURATION,
1149 })
1150 })
1151 }
1152
1153 pub async fn send_transaction_sync(
1157 &self,
1158 request: WithOtherFields<TransactionRequest>,
1159 ) -> Result<ReceiptResponse> {
1160 node_info!("eth_sendTransactionSync");
1161 let hash = self.send_transaction(request).await?;
1162
1163 let receipt = self.check_transaction_inclusion(hash).await?;
1164
1165 Ok(ReceiptResponse::from(receipt))
1166 }
1167
1168 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1172 node_info!("eth_sendRawTransaction");
1173 let mut data = tx.as_ref();
1174 if data.is_empty() {
1175 return Err(BlockchainError::EmptyRawTransactionData);
1176 }
1177
1178 let transaction = FoundryTxEnvelope::decode_2718(&mut data)
1179 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1180
1181 self.ensure_typed_transaction_supported(&transaction)?;
1182
1183 let pending_transaction = PendingTransaction::new(transaction)?;
1184
1185 self.backend.validate_pool_transaction(&pending_transaction).await?;
1187
1188 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1189 let from = *pending_transaction.sender();
1190 let nonce = pending_transaction.transaction.nonce();
1191 let requires = required_marker(nonce, on_chain_nonce, from);
1192
1193 let priority = self.transaction_priority(&pending_transaction.transaction);
1194 let pool_transaction = PoolTransaction {
1195 requires,
1196 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1197 pending_transaction,
1198 priority,
1199 };
1200
1201 let tx = self.pool.add_transaction(pool_transaction)?;
1202 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1203 Ok(*tx.hash())
1204 }
1205
1206 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<ReceiptResponse> {
1210 node_info!("eth_sendRawTransactionSync");
1211
1212 let hash = self.send_raw_transaction(tx).await?;
1213 let receipt = self.check_transaction_inclusion(hash).await?;
1214
1215 Ok(ReceiptResponse::from(receipt))
1216 }
1217
1218 pub async fn call(
1222 &self,
1223 request: WithOtherFields<TransactionRequest>,
1224 block_number: Option<BlockId>,
1225 overrides: EvmOverrides,
1226 ) -> Result<Bytes> {
1227 node_info!("eth_call");
1228 let block_request = self.block_request(block_number).await?;
1229 if let BlockRequest::Number(number) = block_request
1231 && let Some(fork) = self.get_fork()
1232 && fork.predates_fork(number)
1233 {
1234 if overrides.has_state() || overrides.has_block() {
1235 return Err(BlockchainError::EvmOverrideError(
1236 "not available on past forked blocks".to_string(),
1237 ));
1238 }
1239 return Ok(fork.call(&request, Some(number.into())).await?);
1240 }
1241
1242 let fees = FeeDetails::new(
1243 request.gas_price,
1244 request.max_fee_per_gas,
1245 request.max_priority_fee_per_gas,
1246 request.max_fee_per_blob_gas,
1247 )?
1248 .or_zero_fees();
1249 self.on_blocking_task(|this| async move {
1252 let (exit, out, gas, _) =
1253 this.backend.call(request, fees, Some(block_request), overrides).await?;
1254 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1255
1256 ensure_return_ok(exit, &out)
1257 })
1258 .await
1259 }
1260
1261 pub async fn simulate_v1(
1262 &self,
1263 request: SimulatePayload,
1264 block_number: Option<BlockId>,
1265 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1266 node_info!("eth_simulateV1");
1267 let block_request = self.block_request(block_number).await?;
1268 if let BlockRequest::Number(number) = block_request
1270 && let Some(fork) = self.get_fork()
1271 && fork.predates_fork(number)
1272 {
1273 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1274 }
1275
1276 self.on_blocking_task(|this| async move {
1279 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1280 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1281
1282 Ok(simulated_blocks)
1283 })
1284 .await
1285 }
1286
1287 pub async fn create_access_list(
1301 &self,
1302 mut request: WithOtherFields<TransactionRequest>,
1303 block_number: Option<BlockId>,
1304 ) -> Result<AccessListResult> {
1305 node_info!("eth_createAccessList");
1306 let block_request = self.block_request(block_number).await?;
1307 if let BlockRequest::Number(number) = block_request
1309 && let Some(fork) = self.get_fork()
1310 && fork.predates_fork(number)
1311 {
1312 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1313 }
1314
1315 self.backend
1316 .with_database_at(Some(block_request), |state, block_env| {
1317 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1318 &state,
1319 request.clone(),
1320 FeeDetails::zero(),
1321 block_env.clone(),
1322 )?;
1323 ensure_return_ok(exit, &out)?;
1324
1325 request.access_list = Some(access_list.clone());
1327
1328 let (exit, out, gas_used, _) = self.backend.call_with_state(
1329 &state,
1330 request.clone(),
1331 FeeDetails::zero(),
1332 block_env,
1333 )?;
1334 ensure_return_ok(exit, &out)?;
1335
1336 Ok(AccessListResult {
1337 access_list: AccessList(access_list.0),
1338 gas_used: U256::from(gas_used),
1339 error: None,
1340 })
1341 })
1342 .await?
1343 }
1344
1345 pub async fn estimate_gas(
1350 &self,
1351 request: WithOtherFields<TransactionRequest>,
1352 block_number: Option<BlockId>,
1353 overrides: EvmOverrides,
1354 ) -> Result<U256> {
1355 node_info!("eth_estimateGas");
1356 self.do_estimate_gas(
1357 request,
1358 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1359 overrides,
1360 )
1361 .await
1362 .map(U256::from)
1363 }
1364
1365 pub async fn fill_transaction(
1372 &self,
1373 mut request: WithOtherFields<TransactionRequest>,
1374 ) -> Result<FillTransaction<AnyRpcTransaction>> {
1375 node_info!("eth_fillTransaction");
1376
1377 let from = match request.as_ref().from() {
1378 Some(from) => from,
1379 None => self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)?,
1380 };
1381
1382 let nonce = if let Some(nonce) = request.as_ref().nonce() {
1383 nonce
1384 } else {
1385 self.request_nonce(&request, from).await?.0
1386 };
1387
1388 if request.as_ref().has_eip4844_fields()
1389 && request.as_ref().max_fee_per_blob_gas().is_none()
1390 {
1391 let blob_fee = self.backend.fees().get_next_block_blob_base_fee_per_gas();
1393 request.as_mut().set_max_fee_per_blob_gas(blob_fee);
1394 }
1395
1396 if request.as_ref().blob_sidecar().is_some()
1397 && request.as_ref().blob_versioned_hashes.is_none()
1398 {
1399 request.as_mut().populate_blob_hashes();
1400 }
1401
1402 if request.as_ref().gas_limit().is_none() {
1403 let estimated_gas = self
1404 .estimate_gas(request.clone(), Some(BlockId::latest()), EvmOverrides::default())
1405 .await?;
1406 request.as_mut().set_gas_limit(estimated_gas.to());
1407 }
1408
1409 if request.as_ref().gas_price().is_none() {
1410 let tip = if let Some(tip) = request.as_ref().max_priority_fee_per_gas() {
1411 tip
1412 } else {
1413 let tip = self.lowest_suggestion_tip();
1414 request.as_mut().set_max_priority_fee_per_gas(tip);
1415 tip
1416 };
1417 if request.as_ref().max_fee_per_gas().is_none() {
1418 request.as_mut().set_max_fee_per_gas(self.gas_price() + tip);
1419 }
1420 }
1421
1422 let typed_tx = self.build_typed_tx_request(request, nonce)?;
1423 let tx = build_typed_transaction(
1424 typed_tx,
1425 Signature::new(Default::default(), Default::default(), false),
1426 )?;
1427
1428 let raw = tx.encoded_2718().to_vec().into();
1429
1430 let mut tx =
1431 transaction_build(None, MaybeImpersonatedTransaction::new(tx), None, None, None);
1432
1433 tx.0.inner.inner = Recovered::new_unchecked(tx.0.inner.inner.into_inner(), from);
1436
1437 Ok(FillTransaction { raw, tx })
1438 }
1439
1440 pub fn anvil_get_blob_by_versioned_hash(
1442 &self,
1443 hash: B256,
1444 ) -> Result<Option<alloy_consensus::Blob>> {
1445 node_info!("anvil_getBlobByHash");
1446 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1447 }
1448
1449 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1451 node_info!("anvil_getBlobsByTransactionHash");
1452 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1453 }
1454
1455 pub fn anvil_get_blobs_by_block_id(
1457 &self,
1458 block_id: impl Into<BlockId>,
1459 versioned_hashes: Vec<B256>,
1460 ) -> Result<Option<Vec<Blob>>> {
1461 node_info!("anvil_getBlobsByBlockId");
1462 Ok(self.backend.get_blobs_by_block_id(block_id, versioned_hashes)?)
1463 }
1464
1465 pub fn anvil_get_blob_sidecars_by_block_id(
1467 &self,
1468 block_id: BlockId,
1469 ) -> Result<Option<BlobTransactionSidecar>> {
1470 node_info!("anvil_getBlobSidecarsByBlockId");
1471 Ok(self.backend.get_blob_sidecars_by_block_id(block_id)?)
1472 }
1473
1474 pub fn anvil_get_genesis_time(&self) -> Result<u64> {
1478 node_info!("anvil_getGenesisTime");
1479 Ok(self.backend.genesis_time())
1480 }
1481
1482 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1489 node_info!("eth_getTransactionByHash");
1490 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1491 let from = *pending.sender();
1492 let tx = transaction_build(
1493 Some(*pending.hash()),
1494 pending.transaction,
1495 None,
1496 None,
1497 Some(self.backend.base_fee()),
1498 );
1499
1500 let WithOtherFields { inner: mut tx, other } = tx.0;
1501 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1504
1505 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1506 });
1507 if tx.is_none() {
1508 tx = self.backend.transaction_by_hash(hash).await?
1509 }
1510
1511 Ok(tx)
1512 }
1513
1514 pub async fn transaction_by_block_hash_and_index(
1518 &self,
1519 hash: B256,
1520 index: Index,
1521 ) -> Result<Option<AnyRpcTransaction>> {
1522 node_info!("eth_getTransactionByBlockHashAndIndex");
1523 self.backend.transaction_by_block_hash_and_index(hash, index).await
1524 }
1525
1526 pub async fn transaction_by_block_number_and_index(
1530 &self,
1531 block: BlockNumber,
1532 idx: Index,
1533 ) -> Result<Option<AnyRpcTransaction>> {
1534 node_info!("eth_getTransactionByBlockNumberAndIndex");
1535 self.backend.transaction_by_block_number_and_index(block, idx).await
1536 }
1537
1538 pub async fn transaction_by_sender_and_nonce(
1545 &self,
1546 sender: Address,
1547 nonce: U256,
1548 ) -> Result<Option<AnyRpcTransaction>> {
1549 node_info!("eth_getTransactionBySenderAndNonce");
1550
1551 for pending_tx in self.pool.ready_transactions().chain(self.pool.pending_transactions()) {
1553 if U256::from(pending_tx.pending_transaction.nonce()) == nonce
1554 && *pending_tx.pending_transaction.sender() == sender
1555 {
1556 let tx = transaction_build(
1557 Some(*pending_tx.pending_transaction.hash()),
1558 pending_tx.pending_transaction.transaction.clone(),
1559 None,
1560 None,
1561 Some(self.backend.base_fee()),
1562 );
1563
1564 let WithOtherFields { inner: mut tx, other } = tx.0;
1565 let from = *pending_tx.pending_transaction.sender();
1568 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1569
1570 return Ok(Some(AnyRpcTransaction(WithOtherFields { inner: tx, other })));
1571 }
1572 }
1573
1574 let highest_nonce = self.transaction_count(sender, None).await?.saturating_to::<u64>();
1575 let target_nonce = nonce.saturating_to::<u64>();
1576
1577 if target_nonce >= highest_nonce {
1579 return Ok(None);
1580 }
1581
1582 let latest_block = self.backend.best_number();
1584 if latest_block == 0 {
1585 return Ok(None);
1586 }
1587
1588 let mut low = 1u64;
1590 let mut high = latest_block;
1591
1592 while low <= high {
1593 let mid = low + (high - low) / 2;
1594 let mid_nonce =
1595 self.transaction_count(sender, Some(mid.into())).await?.saturating_to::<u64>();
1596
1597 if mid_nonce > target_nonce {
1598 high = mid - 1;
1599 } else {
1600 low = mid + 1;
1601 }
1602 }
1603
1604 let target_block = low;
1606 if target_block <= latest_block
1607 && let Some(txs) =
1608 self.backend.mined_transactions_by_block_number(target_block.into()).await
1609 {
1610 for tx in txs {
1611 if tx.from() == sender
1612 && tx.nonce() == target_nonce
1613 && let Some(mined_tx) = self.backend.transaction_by_hash(tx.tx_hash()).await?
1614 {
1615 return Ok(Some(mined_tx));
1616 }
1617 }
1618 }
1619
1620 Ok(None)
1621 }
1622
1623 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1627 node_info!("eth_getTransactionReceipt");
1628 self.backend.transaction_receipt(hash).await
1629 }
1630
1631 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1635 node_info!("eth_getBlockReceipts");
1636 self.backend.block_receipts(number).await
1637 }
1638
1639 pub async fn uncle_by_block_hash_and_index(
1643 &self,
1644 block_hash: B256,
1645 idx: Index,
1646 ) -> Result<Option<AnyRpcBlock>> {
1647 node_info!("eth_getUncleByBlockHashAndIndex");
1648 let number =
1649 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1650 if let Some(fork) = self.get_fork()
1651 && fork.predates_fork_inclusive(number)
1652 {
1653 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1654 }
1655 Ok(None)
1657 }
1658
1659 pub async fn uncle_by_block_number_and_index(
1663 &self,
1664 block_number: BlockNumber,
1665 idx: Index,
1666 ) -> Result<Option<AnyRpcBlock>> {
1667 node_info!("eth_getUncleByBlockNumberAndIndex");
1668 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1669 if let Some(fork) = self.get_fork()
1670 && fork.predates_fork_inclusive(number)
1671 {
1672 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1673 }
1674 Ok(None)
1676 }
1677
1678 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1682 node_info!("eth_getLogs");
1683 self.backend.logs(filter).await
1684 }
1685
1686 pub fn work(&self) -> Result<Work> {
1690 node_info!("eth_getWork");
1691 Err(BlockchainError::RpcUnimplemented)
1692 }
1693
1694 pub fn syncing(&self) -> Result<bool> {
1698 node_info!("eth_syncing");
1699 Ok(false)
1700 }
1701
1702 pub fn config(&self) -> Result<EthConfig> {
1713 node_info!("eth_config");
1714 Ok(EthConfig {
1715 current: EthForkConfig {
1716 activation_time: 0,
1717 blob_schedule: self.backend.blob_params(),
1718 chain_id: self.backend.env().read().evm_env.cfg_env.chain_id,
1719 fork_id: Bytes::from_static(&[0; 4]),
1720 precompiles: self.backend.precompiles(),
1721 system_contracts: self.backend.system_contracts(),
1722 },
1723 next: None,
1724 last: None,
1725 })
1726 }
1727
1728 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1732 node_info!("eth_submitWork");
1733 Err(BlockchainError::RpcUnimplemented)
1734 }
1735
1736 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1740 node_info!("eth_submitHashrate");
1741 Err(BlockchainError::RpcUnimplemented)
1742 }
1743
1744 pub async fn fee_history(
1748 &self,
1749 block_count: U256,
1750 newest_block: BlockNumber,
1751 reward_percentiles: Vec<f64>,
1752 ) -> Result<FeeHistory> {
1753 node_info!("eth_feeHistory");
1754 let current = self.backend.best_number();
1757 let slots_in_an_epoch = 32u64;
1758
1759 let number = match newest_block {
1760 BlockNumber::Latest | BlockNumber::Pending => current,
1761 BlockNumber::Earliest => 0,
1762 BlockNumber::Number(n) => n,
1763 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1764 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1765 };
1766
1767 if let Some(fork) = self.get_fork() {
1769 if fork.predates_fork_inclusive(number) {
1772 return fork
1773 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1774 .await
1775 .map_err(BlockchainError::AlloyForkProvider);
1776 }
1777 }
1778
1779 const MAX_BLOCK_COUNT: u64 = 1024u64;
1780 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1781
1782 let highest = number;
1784 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1785
1786 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1788 return Err(FeeHistoryError::InvalidBlockRange.into());
1789 }
1790
1791 let mut response = FeeHistory {
1792 oldest_block: lowest,
1793 base_fee_per_gas: Vec::new(),
1794 gas_used_ratio: Vec::new(),
1795 reward: Some(Default::default()),
1796 base_fee_per_blob_gas: Default::default(),
1797 blob_gas_used_ratio: Default::default(),
1798 };
1799 let mut rewards = Vec::new();
1800
1801 {
1802 let fee_history = self.fee_history_cache.lock();
1803
1804 for n in lowest..=highest {
1806 if let Some(block) = fee_history.get(&n) {
1808 response.base_fee_per_gas.push(block.base_fee);
1809 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1810 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1811 response.gas_used_ratio.push(block.gas_used_ratio);
1812
1813 if !reward_percentiles.is_empty() {
1815 let mut block_rewards = Vec::new();
1816 let resolution_per_percentile: f64 = 2.0;
1817 for p in &reward_percentiles {
1818 let p = p.clamp(0.0, 100.0);
1819 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1820 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1821 block_rewards.push(reward);
1822 }
1823 rewards.push(block_rewards);
1824 }
1825 }
1826 }
1827 }
1828
1829 response.reward = Some(rewards);
1830
1831 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1836
1837 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1841
1842 Ok(response)
1843 }
1844
1845 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1852 node_info!("eth_maxPriorityFeePerGas");
1853 Ok(U256::from(self.lowest_suggestion_tip()))
1854 }
1855
1856 fn lowest_suggestion_tip(&self) -> u128 {
1860 let block_number = self.backend.best_number();
1861 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1862
1863 match latest_cached_block {
1864 Some(block) => block.rewards.iter().copied().min(),
1865 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1866 }
1867 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1868 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1869 }
1870
1871 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1875 node_info!("eth_newFilter");
1876 let historic = if filter.block_option.get_from_block().is_some() {
1879 self.backend.logs(filter.clone()).await?
1880 } else {
1881 vec![]
1882 };
1883 let filter = EthFilter::Logs(Box::new(LogsFilter {
1884 blocks: self.new_block_notifications(),
1885 storage: self.storage_info(),
1886 filter: FilteredParams::new(Some(filter)),
1887 historic: Some(historic),
1888 }));
1889 Ok(self.filters.add_filter(filter).await)
1890 }
1891
1892 pub async fn new_block_filter(&self) -> Result<String> {
1896 node_info!("eth_newBlockFilter");
1897 let filter = EthFilter::Blocks(self.new_block_notifications());
1898 Ok(self.filters.add_filter(filter).await)
1899 }
1900
1901 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1905 node_info!("eth_newPendingTransactionFilter");
1906 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1907 Ok(self.filters.add_filter(filter).await)
1908 }
1909
1910 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1914 node_info!("eth_getFilterChanges");
1915 self.filters.get_filter_changes(id).await
1916 }
1917
1918 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1922 node_info!("eth_getFilterLogs");
1923 if let Some(filter) = self.filters.get_log_filter(id).await {
1924 self.backend.logs(filter).await
1925 } else {
1926 Ok(Vec::new())
1927 }
1928 }
1929
1930 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1932 node_info!("eth_uninstallFilter");
1933 Ok(self.filters.uninstall_filter(id).await.is_some())
1934 }
1935
1936 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1940 node_info!("debug_getRawTransaction");
1941 self.inner_raw_transaction(hash).await
1942 }
1943
1944 pub async fn raw_transaction_by_block_hash_and_index(
1948 &self,
1949 block_hash: B256,
1950 index: Index,
1951 ) -> Result<Option<Bytes>> {
1952 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1953 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1954 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1955 None => Ok(None),
1956 }
1957 }
1958
1959 pub async fn raw_transaction_by_block_number_and_index(
1963 &self,
1964 block_number: BlockNumber,
1965 index: Index,
1966 ) -> Result<Option<Bytes>> {
1967 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1968 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1969 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1970 None => Ok(None),
1971 }
1972 }
1973
1974 pub async fn debug_trace_transaction(
1978 &self,
1979 tx_hash: B256,
1980 opts: GethDebugTracingOptions,
1981 ) -> Result<GethTrace> {
1982 node_info!("debug_traceTransaction");
1983 self.backend.debug_trace_transaction(tx_hash, opts).await
1984 }
1985
1986 pub async fn debug_trace_call(
1990 &self,
1991 request: WithOtherFields<TransactionRequest>,
1992 block_number: Option<BlockId>,
1993 opts: GethDebugTracingCallOptions,
1994 ) -> Result<GethTrace> {
1995 node_info!("debug_traceCall");
1996 let block_request = self.block_request(block_number).await?;
1997 let fees = FeeDetails::new(
1998 request.gas_price,
1999 request.max_fee_per_gas,
2000 request.max_priority_fee_per_gas,
2001 request.max_fee_per_blob_gas,
2002 )?
2003 .or_zero_fees();
2004
2005 let result: std::result::Result<GethTrace, BlockchainError> =
2006 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
2007 result
2008 }
2009
2010 pub async fn debug_code_by_hash(
2014 &self,
2015 hash: B256,
2016 block_id: Option<BlockId>,
2017 ) -> Result<Option<Bytes>> {
2018 node_info!("debug_codeByHash");
2019 self.backend.debug_code_by_hash(hash, block_id).await
2020 }
2021
2022 pub async fn debug_db_get(&self, key: String) -> Result<Option<Bytes>> {
2027 node_info!("debug_dbGet");
2028 self.backend.debug_db_get(key).await
2029 }
2030
2031 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
2035 node_info!("trace_transaction");
2036 self.backend.trace_transaction(tx_hash).await
2037 }
2038
2039 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
2043 node_info!("trace_block");
2044 self.backend.trace_block(block).await
2045 }
2046
2047 pub async fn trace_filter(
2051 &self,
2052 filter: TraceFilter,
2053 ) -> Result<Vec<LocalizedTransactionTrace>> {
2054 node_info!("trace_filter");
2055 self.backend.trace_filter(filter).await
2056 }
2057}
2058
2059impl EthApi {
2062 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
2066 node_info!("anvil_impersonateAccount");
2067 self.backend.impersonate(address);
2068 Ok(())
2069 }
2070
2071 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
2075 node_info!("anvil_stopImpersonatingAccount");
2076 self.backend.stop_impersonating(address);
2077 Ok(())
2078 }
2079
2080 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
2084 node_info!("anvil_autoImpersonateAccount");
2085 self.backend.auto_impersonate_account(enabled);
2086 Ok(())
2087 }
2088
2089 pub async fn anvil_impersonate_signature(
2091 &self,
2092 signature: Bytes,
2093 address: Address,
2094 ) -> Result<()> {
2095 node_info!("anvil_impersonateSignature");
2096 self.backend.impersonate_signature(signature, address).await
2097 }
2098
2099 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
2103 node_info!("anvil_getAutomine");
2104 Ok(self.miner.is_auto_mine())
2105 }
2106
2107 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
2111 node_info!("anvil_getIntervalMining");
2112 Ok(self.miner.get_interval())
2113 }
2114
2115 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
2120 node_info!("evm_setAutomine");
2121 if self.miner.is_auto_mine() {
2122 if enable_automine {
2123 return Ok(());
2124 }
2125 self.miner.set_mining_mode(MiningMode::None);
2126 } else if enable_automine {
2127 let listener = self.pool.add_ready_listener();
2128 let mode = MiningMode::instant(1_000, listener);
2129 self.miner.set_mining_mode(mode);
2130 }
2131 Ok(())
2132 }
2133
2134 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
2138 node_info!("anvil_mine");
2139 let interval = interval.map(|i| i.to::<u64>());
2140 let blocks = num_blocks.unwrap_or(U256::from(1));
2141 if blocks.is_zero() {
2142 return Ok(());
2143 }
2144
2145 self.on_blocking_task(|this| async move {
2146 for _ in 0..blocks.to::<u64>() {
2148 if let Some(interval) = interval {
2150 this.backend.time().increase_time(interval);
2151 }
2152 this.mine_one().await;
2153 }
2154 Ok(())
2155 })
2156 .await?;
2157
2158 Ok(())
2159 }
2160
2161 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
2165 node_info!("evm_setIntervalMining");
2166 let mining_mode = if secs == 0 {
2167 MiningMode::None
2168 } else {
2169 let block_time = Duration::from_secs(secs);
2170
2171 self.backend.update_interval_mine_block_time(block_time);
2173
2174 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
2175 };
2176 self.miner.set_mining_mode(mining_mode);
2177 Ok(())
2178 }
2179
2180 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
2184 node_info!("anvil_dropTransaction");
2185 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
2186 }
2187
2188 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
2192 node_info!("anvil_dropAllTransactions");
2193 self.pool.clear();
2194 Ok(())
2195 }
2196
2197 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
2203 self.reset_instance_id();
2204 node_info!("anvil_reset");
2205 if let Some(forking) = forking {
2206 self.backend.reset_fork(forking).await
2208 } else {
2209 self.backend.reset_to_in_mem().await
2212 }
2213 }
2214
2215 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
2216 node_info!("anvil_setChainId");
2217 self.backend.set_chain_id(chain_id);
2218 Ok(())
2219 }
2220
2221 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
2225 node_info!("anvil_setBalance");
2226 self.backend.set_balance(address, balance).await?;
2227 Ok(())
2228 }
2229
2230 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
2234 node_info!("anvil_addBalance");
2235 let current_balance = self.backend.get_balance(address, None).await?;
2236 self.backend.set_balance(address, current_balance + balance).await?;
2237 Ok(())
2238 }
2239
2240 async fn find_erc20_storage_slot(
2257 &self,
2258 token_address: Address,
2259 calldata: Bytes,
2260 expected_value: U256,
2261 ) -> Result<B256> {
2262 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2263
2264 let access_list_result =
2266 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2267 let access_list = access_list_result.access_list;
2268
2269 for item in access_list.0 {
2272 if item.address != token_address {
2273 continue;
2274 };
2275 for slot in &item.storage_keys {
2276 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2277 (*slot, B256::from(expected_value.to_be_bytes())),
2278 ));
2279
2280 let state_override = StateOverridesBuilder::default()
2281 .append(token_address, account_override)
2282 .build();
2283
2284 let evm_override = EvmOverrides::state(Some(state_override));
2285
2286 let Ok(result) =
2287 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2288 else {
2289 continue;
2291 };
2292
2293 let Ok(result_value) = U256::abi_decode(&result) else {
2294 continue;
2296 };
2297
2298 if result_value == expected_value {
2299 return Ok(*slot);
2300 }
2301 }
2302 }
2303
2304 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2305 }
2306
2307 pub async fn anvil_deal_erc20(
2311 &self,
2312 address: Address,
2313 token_address: Address,
2314 balance: U256,
2315 ) -> Result<()> {
2316 node_info!("anvil_dealERC20");
2317
2318 sol! {
2319 #[sol(rpc)]
2320 contract IERC20 {
2321 function balanceOf(address target) external view returns (uint256);
2322 }
2323 }
2324
2325 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2326
2327 let slot =
2329 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2330 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2331 })?;
2332
2333 self.anvil_set_storage_at(
2335 token_address,
2336 U256::from_be_bytes(slot.0),
2337 B256::from(balance.to_be_bytes()),
2338 )
2339 .await?;
2340
2341 Ok(())
2342 }
2343
2344 pub async fn anvil_set_erc20_allowance(
2348 &self,
2349 owner: Address,
2350 spender: Address,
2351 token_address: Address,
2352 amount: U256,
2353 ) -> Result<()> {
2354 node_info!("anvil_setERC20Allowance");
2355
2356 sol! {
2357 #[sol(rpc)]
2358 contract IERC20 {
2359 function allowance(address owner, address spender) external view returns (uint256);
2360 }
2361 }
2362
2363 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2364
2365 let slot =
2367 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2368 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2369 })?;
2370
2371 self.anvil_set_storage_at(
2373 token_address,
2374 U256::from_be_bytes(slot.0),
2375 B256::from(amount.to_be_bytes()),
2376 )
2377 .await?;
2378
2379 Ok(())
2380 }
2381
2382 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2386 node_info!("anvil_setCode");
2387 self.backend.set_code(address, code).await?;
2388 Ok(())
2389 }
2390
2391 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2395 node_info!("anvil_setNonce");
2396 self.backend.set_nonce(address, nonce).await?;
2397 Ok(())
2398 }
2399
2400 pub async fn anvil_set_storage_at(
2404 &self,
2405 address: Address,
2406 slot: U256,
2407 val: B256,
2408 ) -> Result<bool> {
2409 node_info!("anvil_setStorageAt");
2410 self.backend.set_storage_at(address, slot, val).await?;
2411 Ok(true)
2412 }
2413
2414 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2418 node_info!("anvil_setLoggingEnabled");
2419 self.logger.set_enabled(enable);
2420 Ok(())
2421 }
2422
2423 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2427 node_info!("anvil_setMinGasPrice");
2428 if self.backend.is_eip1559() {
2429 return Err(RpcError::invalid_params(
2430 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2431 )
2432 .into());
2433 }
2434 self.backend.set_gas_price(gas.to());
2435 Ok(())
2436 }
2437
2438 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2442 node_info!("anvil_setNextBlockBaseFeePerGas");
2443 if !self.backend.is_eip1559() {
2444 return Err(RpcError::invalid_params(
2445 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2446 )
2447 .into());
2448 }
2449 self.backend.set_base_fee(basefee.to());
2450 Ok(())
2451 }
2452
2453 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2457 node_info!("anvil_setCoinbase");
2458 self.backend.set_coinbase(address);
2459 Ok(())
2460 }
2461
2462 pub async fn anvil_dump_state(
2467 &self,
2468 preserve_historical_states: Option<bool>,
2469 ) -> Result<Bytes> {
2470 node_info!("anvil_dumpState");
2471 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2472 }
2473
2474 pub async fn serialized_state(
2476 &self,
2477 preserve_historical_states: bool,
2478 ) -> Result<SerializableState> {
2479 self.backend.serialized_state(preserve_historical_states).await
2480 }
2481
2482 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2487 node_info!("anvil_loadState");
2488 self.backend.load_state_bytes(buf).await
2489 }
2490
2491 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2495 node_info!("anvil_nodeInfo");
2496
2497 let env = self.backend.env().read();
2498 let fork_config = self.backend.get_fork();
2499 let tx_order = self.transaction_order.read();
2500 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2501
2502 Ok(NodeInfo {
2503 current_block_number: self.backend.best_number(),
2504 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2505 current_block_hash: self.backend.best_hash(),
2506 hard_fork: hard_fork.to_string(),
2507 transaction_order: match *tx_order {
2508 TransactionOrder::Fifo => "fifo".to_string(),
2509 TransactionOrder::Fees => "fees".to_string(),
2510 },
2511 environment: NodeEnvironment {
2512 base_fee: self.backend.base_fee() as u128,
2513 chain_id: self.backend.chain_id().to::<u64>(),
2514 gas_limit: self.backend.gas_limit(),
2515 gas_price: self.gas_price(),
2516 },
2517 fork_config: fork_config
2518 .map(|fork| {
2519 let config = fork.config.read();
2520
2521 NodeForkConfig {
2522 fork_url: Some(config.eth_rpc_url.clone()),
2523 fork_block_number: Some(config.block_number),
2524 fork_retry_backoff: Some(config.backoff.as_millis()),
2525 }
2526 })
2527 .unwrap_or_default(),
2528 })
2529 }
2530
2531 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2535 node_info!("anvil_metadata");
2536 let fork_config = self.backend.get_fork();
2537
2538 Ok(Metadata {
2539 client_version: CLIENT_VERSION.to_string(),
2540 chain_id: self.backend.chain_id().to::<u64>(),
2541 latest_block_hash: self.backend.best_hash(),
2542 latest_block_number: self.backend.best_number(),
2543 instance_id: *self.instance_id.read(),
2544 forked_network: fork_config.map(|cfg| ForkedNetwork {
2545 chain_id: cfg.chain_id(),
2546 fork_block_number: cfg.block_number(),
2547 fork_block_hash: cfg.block_hash(),
2548 }),
2549 snapshots: self.backend.list_state_snapshots(),
2550 })
2551 }
2552
2553 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2554 node_info!("anvil_removePoolTransactions");
2555 self.pool.remove_transactions_by_address(address);
2556 Ok(())
2557 }
2558
2559 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2573 node_info!("anvil_reorg");
2574 let depth = options.depth;
2575 let tx_block_pairs = options.tx_block_pairs;
2576
2577 let current_height = self.backend.best_number();
2579 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2580 RpcError::invalid_params(format!(
2581 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2582 )),
2583 ))?;
2584
2585 let common_block =
2587 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2588
2589 let block_pool_txs = if tx_block_pairs.is_empty() {
2592 HashMap::default()
2593 } else {
2594 let mut pairs = tx_block_pairs;
2595
2596 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2598 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2599 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2600 depth - 1
2601 ))));
2602 }
2603
2604 pairs.sort_by_key(|a| a.1);
2606
2607 let mut nonces: HashMap<Address, u64> = HashMap::default();
2610
2611 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2612 for pair in pairs {
2613 let (tx_data, block_index) = pair;
2614
2615 let pending = match tx_data {
2616 TransactionData::Raw(bytes) => {
2617 let mut data = bytes.as_ref();
2618 let decoded = FoundryTxEnvelope::decode_2718(&mut data)
2619 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2620 PendingTransaction::new(decoded)?
2621 }
2622
2623 TransactionData::JSON(req) => {
2624 let mut tx_req = WithOtherFields::new(req);
2625 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2626 self.accounts()?
2627 .first()
2628 .copied()
2629 .ok_or(BlockchainError::NoSignerAvailable)
2630 })?;
2631
2632 let curr_nonce = nonces.entry(from).or_insert(
2634 self.get_transaction_count(
2635 from,
2636 Some(common_block.header.number.into()),
2637 )
2638 .await?,
2639 );
2640
2641 if tx_req.gas.is_none()
2643 && let Ok(gas) = self
2644 .estimate_gas(tx_req.clone(), None, EvmOverrides::default())
2645 .await
2646 {
2647 tx_req.gas = Some(gas.to());
2648 }
2649
2650 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2652
2653 *curr_nonce += 1;
2655
2656 if self.is_impersonated(from) {
2658 let bypass_signature = self.impersonated_signature(&typed);
2659 let transaction =
2660 sign::build_typed_transaction(typed, bypass_signature)?;
2661 self.ensure_typed_transaction_supported(&transaction)?;
2662 PendingTransaction::with_impersonated(transaction, from)
2663 } else {
2664 let transaction = self.sign_request(&from, typed)?;
2665 self.ensure_typed_transaction_supported(&transaction)?;
2666 PendingTransaction::new(transaction)?
2667 }
2668 }
2669 };
2670
2671 let pooled = PoolTransaction::new(pending);
2672 txs.entry(block_index).or_default().push(Arc::new(pooled));
2673 }
2674
2675 txs
2676 };
2677
2678 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2679 Ok(())
2680 }
2681
2682 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2693 node_info!("anvil_rollback");
2694 let depth = depth.unwrap_or(1);
2695
2696 let current_height = self.backend.best_number();
2698 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2699 RpcError::invalid_params(format!(
2700 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2701 )),
2702 ))?;
2703
2704 let common_block =
2706 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2707
2708 self.backend.rollback(common_block).await?;
2709 Ok(())
2710 }
2711
2712 pub async fn evm_snapshot(&self) -> Result<U256> {
2716 node_info!("evm_snapshot");
2717 Ok(self.backend.create_state_snapshot().await)
2718 }
2719
2720 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2725 node_info!("evm_revert");
2726 self.backend.revert_state_snapshot(id).await
2727 }
2728
2729 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2733 node_info!("evm_increaseTime");
2734 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2735 }
2736
2737 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2741 node_info!("evm_setNextBlockTimestamp");
2742 self.backend.time().set_next_block_timestamp(seconds)
2743 }
2744
2745 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2750 node_info!("evm_setTime");
2751 let now = self.backend.time().current_call_timestamp();
2752 self.backend.time().reset(timestamp);
2753
2754 let offset = timestamp.saturating_sub(now);
2756 Ok(Duration::from_millis(offset).as_secs())
2757 }
2758
2759 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2763 node_info!("evm_setBlockGasLimit");
2764 self.backend.set_gas_limit(gas_limit.to());
2765 Ok(true)
2766 }
2767
2768 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2772 node_info!("anvil_setBlockTimestampInterval");
2773 self.backend.time().set_block_timestamp_interval(seconds);
2774 Ok(())
2775 }
2776
2777 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2781 node_info!("anvil_removeBlockTimestampInterval");
2782 Ok(self.backend.time().remove_block_timestamp_interval())
2783 }
2784
2785 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2792 node_info!("evm_mine");
2793
2794 self.do_evm_mine(opts).await?;
2795
2796 Ok("0x0".to_string())
2797 }
2798
2799 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2809 node_info!("evm_mine_detailed");
2810
2811 let mined_blocks = self.do_evm_mine(opts).await?;
2812
2813 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2814
2815 let latest = self.backend.best_number();
2816 for offset in (0..mined_blocks).rev() {
2817 let block_num = latest - offset;
2818 if let Some(mut block) =
2819 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2820 {
2821 let block_txs = match block.transactions_mut() {
2822 BlockTransactions::Full(txs) => txs,
2823 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2824 };
2825 for tx in block_txs.iter_mut() {
2826 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2827 && let Some(output) = receipt.out
2828 {
2829 if !receipt
2831 .inner
2832 .inner
2833 .inner
2834 .as_receipt_with_bloom()
2835 .receipt
2836 .status
2837 .coerce_status()
2838 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2839 {
2840 tx.other.insert(
2841 "revertReason".to_string(),
2842 serde_json::to_value(reason).expect("Infallible"),
2843 );
2844 }
2845 tx.other.insert(
2846 "output".to_string(),
2847 serde_json::to_value(output).expect("Infallible"),
2848 );
2849 }
2850 }
2851 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2852 blocks.push(block);
2853 }
2854 }
2855
2856 Ok(blocks)
2857 }
2858
2859 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2863 node_info!("anvil_setBlock");
2864 self.backend.set_block_number(block_number);
2865 Ok(())
2866 }
2867
2868 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2872 node_info!("anvil_setRpcUrl");
2873 if let Some(fork) = self.backend.get_fork() {
2874 let mut config = fork.config.write();
2875 let new_provider = Arc::new(
2877 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2878 |_| {
2879 TransportErrorKind::custom_str(
2880 format!("Failed to parse invalid url {url}").as_str(),
2881 )
2882 },
2883 )?, );
2886 config.provider = new_provider;
2887 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2888 config.eth_rpc_url = url;
2889 }
2890 Ok(())
2891 }
2892
2893 pub async fn anvil_enable_traces(&self) -> Result<()> {
2898 node_info!("anvil_enableTraces");
2899 Err(BlockchainError::RpcUnimplemented)
2900 }
2901
2902 pub async fn eth_send_unsigned_transaction(
2906 &self,
2907 request: WithOtherFields<TransactionRequest>,
2908 ) -> Result<TxHash> {
2909 node_info!("eth_sendUnsignedTransaction");
2910 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2912
2913 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2914
2915 let request = self.build_typed_tx_request(request, nonce)?;
2916
2917 let bypass_signature = self.impersonated_signature(&request);
2918 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2919
2920 self.ensure_typed_transaction_supported(&transaction)?;
2921
2922 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2923
2924 self.backend.validate_pool_transaction(&pending_transaction).await?;
2926
2927 let requires = required_marker(nonce, on_chain_nonce, from);
2928 let provides = vec![to_marker(nonce, from)];
2929
2930 self.add_pending_transaction(pending_transaction, requires, provides)
2931 }
2932
2933 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2939 node_info!("txpool_status");
2940 Ok(self.pool.txpool_status())
2941 }
2942
2943 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2950 node_info!("txpool_inspect");
2951 let mut inspect = TxpoolInspect::default();
2952
2953 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2954 let tx = &tx.pending_transaction.transaction;
2955 let to = tx.to();
2956 let gas_price = tx.max_fee_per_gas();
2957 let value = tx.value();
2958 let gas = tx.gas_limit();
2959 TxpoolInspectSummary { to, value, gas, gas_price }
2960 }
2961
2962 for pending in self.pool.ready_transactions() {
2969 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2970 let key = pending.pending_transaction.nonce().to_string();
2971 entry.insert(key, convert(pending));
2972 }
2973 for queued in self.pool.pending_transactions() {
2974 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2975 let key = queued.pending_transaction.nonce().to_string();
2976 entry.insert(key, convert(queued));
2977 }
2978 Ok(inspect)
2979 }
2980
2981 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2988 node_info!("txpool_content");
2989 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2990 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2991 let from = *tx.pending_transaction.sender();
2992 let tx = transaction_build(
2993 Some(tx.hash()),
2994 tx.pending_transaction.transaction.clone(),
2995 None,
2996 None,
2997 None,
2998 );
2999
3000 let WithOtherFields { inner: mut tx, other } = tx.0;
3001
3002 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
3005
3006 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
3007
3008 Ok(tx)
3009 }
3010
3011 for pending in self.pool.ready_transactions() {
3012 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
3013 let key = pending.pending_transaction.nonce().to_string();
3014 entry.insert(key, convert(pending)?);
3015 }
3016 for queued in self.pool.pending_transactions() {
3017 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
3018 let key = queued.pending_transaction.nonce().to_string();
3019 entry.insert(key, convert(queued)?);
3020 }
3021
3022 Ok(content)
3023 }
3024}
3025
3026impl EthApi {
3028 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
3034 node_info!("wallet_getCapabilities");
3035 Ok(self.backend.get_capabilities())
3036 }
3037
3038 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
3042 node_info!("anvil_addCapability");
3043 self.backend.add_capability(address);
3044 Ok(())
3045 }
3046
3047 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
3048 node_info!("anvil_setExecutor");
3049 self.backend.set_executor(executor_pk)
3050 }
3051}
3052
3053impl EthApi {
3054 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
3056 where
3057 C: FnOnce(Self) -> F,
3058 F: Future<Output = Result<R>> + Send + 'static,
3059 R: Send + 'static,
3060 {
3061 let (tx, rx) = oneshot::channel();
3062 let this = self.clone();
3063 let f = c(this);
3064 tokio::task::spawn_blocking(move || {
3065 tokio::runtime::Handle::current().block_on(async move {
3066 let res = f.await;
3067 let _ = tx.send(res);
3068 })
3069 });
3070 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
3071 }
3072
3073 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
3075 let mut blocks_to_mine = 1u64;
3076
3077 if let Some(opts) = opts {
3078 let timestamp = match opts {
3079 MineOptions::Timestamp(timestamp) => timestamp,
3080 MineOptions::Options { timestamp, blocks } => {
3081 if let Some(blocks) = blocks {
3082 blocks_to_mine = blocks;
3083 }
3084 timestamp
3085 }
3086 };
3087 if let Some(timestamp) = timestamp {
3088 self.evm_set_next_block_timestamp(timestamp)?;
3090 }
3091 }
3092
3093 self.on_blocking_task(|this| async move {
3096 for _ in 0..blocks_to_mine {
3098 this.mine_one().await;
3099 }
3100 Ok(())
3101 })
3102 .await?;
3103
3104 Ok(blocks_to_mine)
3105 }
3106
3107 async fn do_estimate_gas(
3108 &self,
3109 request: WithOtherFields<TransactionRequest>,
3110 block_number: Option<BlockId>,
3111 overrides: EvmOverrides,
3112 ) -> Result<u128> {
3113 let block_request = self.block_request(block_number).await?;
3114 if let BlockRequest::Number(number) = block_request
3116 && let Some(fork) = self.get_fork()
3117 && fork.predates_fork(number)
3118 {
3119 if overrides.has_state() || overrides.has_block() {
3120 return Err(BlockchainError::EvmOverrideError(
3121 "not available on past forked blocks".to_string(),
3122 ));
3123 }
3124 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
3125 }
3126
3127 self.on_blocking_task(|this| async move {
3130 this.backend
3131 .with_database_at(Some(block_request), |state, mut block| {
3132 let mut cache_db = CacheDB::new(state);
3133 if let Some(state_overrides) = overrides.state {
3134 apply_state_overrides(
3135 state_overrides.into_iter().collect(),
3136 &mut cache_db,
3137 )?;
3138 }
3139 if let Some(block_overrides) = overrides.block {
3140 cache_db.apply_block_overrides(*block_overrides, &mut block);
3141 }
3142 this.do_estimate_gas_with_state(request, &cache_db, block)
3143 })
3144 .await?
3145 })
3146 .await
3147 }
3148
3149 fn do_estimate_gas_with_state(
3153 &self,
3154 mut request: WithOtherFields<TransactionRequest>,
3155 state: &dyn DatabaseRef,
3156 block_env: BlockEnv,
3157 ) -> Result<u128> {
3158 let to = request.to.as_ref().and_then(TxKind::to);
3161
3162 let maybe_transfer = (request.input.input().is_none()
3164 || request.input.input().is_some_and(|data| data.is_empty()))
3165 && request.authorization_list.is_none()
3166 && request.access_list.is_none()
3167 && request.blob_versioned_hashes.is_none();
3168
3169 if maybe_transfer
3170 && let Some(to) = to
3171 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
3172 && target_code.as_ref().is_empty()
3173 {
3174 return Ok(MIN_TRANSACTION_GAS);
3175 }
3176
3177 let fees = FeeDetails::new(
3178 request.gas_price,
3179 request.max_fee_per_gas,
3180 request.max_priority_fee_per_gas,
3181 request.max_fee_per_blob_gas,
3182 )?
3183 .or_zero_fees();
3184
3185 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
3188
3189 let gas_price = fees.gas_price.unwrap_or_default();
3190 if gas_price > 0
3192 && let Some(from) = request.from
3193 {
3194 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
3195 if let Some(value) = request.value {
3196 if value > available_funds {
3197 return Err(InvalidTransactionError::InsufficientFunds.into());
3198 }
3199 available_funds -= value;
3201 }
3202 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
3204 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
3205 }
3206
3207 let mut call_to_estimate = request.clone();
3208 call_to_estimate.gas = Some(highest_gas_limit as u64);
3209
3210 let ethres =
3212 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3213
3214 let gas_used = match ethres.try_into()? {
3215 GasEstimationCallResult::Success(gas) => Ok(gas),
3216 GasEstimationCallResult::OutOfGas => {
3217 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3218 }
3219 GasEstimationCallResult::Revert(output) => {
3220 Err(InvalidTransactionError::Revert(output).into())
3221 }
3222 GasEstimationCallResult::EvmError(err) => {
3223 warn!(target: "node", "estimation failed due to {:?}", err);
3224 Err(BlockchainError::EvmError(err))
3225 }
3226 }?;
3227
3228 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3235
3236 let mut mid_gas_limit =
3238 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3239
3240 while (highest_gas_limit - lowest_gas_limit) > 1 {
3242 request.gas = Some(mid_gas_limit as u64);
3243 let ethres = self.backend.call_with_state(
3244 &state,
3245 request.clone(),
3246 fees.clone(),
3247 block_env.clone(),
3248 );
3249
3250 match ethres.try_into()? {
3251 GasEstimationCallResult::Success(_) => {
3252 highest_gas_limit = mid_gas_limit;
3256 }
3257 GasEstimationCallResult::OutOfGas
3258 | GasEstimationCallResult::Revert(_)
3259 | GasEstimationCallResult::EvmError(_) => {
3260 lowest_gas_limit = mid_gas_limit;
3267 }
3268 };
3269 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3271 }
3272
3273 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3274
3275 Ok(highest_gas_limit)
3276 }
3277
3278 pub fn set_transaction_order(&self, order: TransactionOrder) {
3280 *self.transaction_order.write() = order;
3281 }
3282
3283 fn transaction_priority(&self, tx: &FoundryTxEnvelope) -> TransactionPriority {
3285 self.transaction_order.read().priority(tx)
3286 }
3287
3288 pub fn chain_id(&self) -> u64 {
3290 self.backend.chain_id().to::<u64>()
3291 }
3292
3293 pub fn get_fork(&self) -> Option<ClientFork> {
3295 self.backend.get_fork()
3296 }
3297
3298 pub fn instance_id(&self) -> B256 {
3300 *self.instance_id.read()
3301 }
3302
3303 pub fn reset_instance_id(&self) {
3305 *self.instance_id.write() = B256::random();
3306 }
3307
3308 #[expect(clippy::borrowed_box)]
3310 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3311 self.signers.iter().find(|signer| signer.is_signer_for(address))
3312 }
3313
3314 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3316 self.backend.new_block_notifications()
3317 }
3318
3319 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3321 self.pool.add_ready_listener()
3322 }
3323
3324 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3326 let (tx, rx) = unbounded_channel();
3327 let mut hashes = self.new_ready_transactions();
3328
3329 let this = self.clone();
3330
3331 tokio::spawn(async move {
3332 while let Some(hash) = hashes.next().await {
3333 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3334 && tx.send(txn).is_err()
3335 {
3336 break;
3337 }
3338 }
3339 });
3340
3341 rx
3342 }
3343
3344 pub fn storage_info(&self) -> StorageInfo {
3346 StorageInfo::new(Arc::clone(&self.backend))
3347 }
3348
3349 pub fn is_fork(&self) -> bool {
3351 self.backend.is_fork()
3352 }
3353
3354 pub async fn mine_one(&self) {
3356 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3357 let outcome = self.backend.mine_block(transactions).await;
3358
3359 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3360 self.pool.on_mined_block(outcome);
3361 }
3362
3363 async fn pending_block(&self) -> AnyRpcBlock {
3365 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3366 let info = self.backend.pending_block(transactions).await;
3367 self.backend.convert_block(info.block)
3368 }
3369
3370 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3372 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3373 let BlockInfo { block, transactions, receipts: _ } =
3374 self.backend.pending_block(transactions).await;
3375
3376 let mut partial_block = self.backend.convert_block(block.clone());
3377
3378 let mut block_transactions = Vec::with_capacity(block.body.transactions.len());
3379 let base_fee = self.backend.base_fee();
3380
3381 for info in transactions {
3382 let tx = block.body.transactions.get(info.transaction_index as usize)?.clone();
3383
3384 let tx = transaction_build(
3385 Some(info.transaction_hash),
3386 tx,
3387 Some(&block),
3388 Some(info),
3389 Some(base_fee),
3390 );
3391 block_transactions.push(tx);
3392 }
3393
3394 partial_block.transactions = BlockTransactions::from(block_transactions);
3395
3396 Some(partial_block)
3397 }
3398
3399 fn build_typed_tx_request(
3400 &self,
3401 request: WithOtherFields<TransactionRequest>,
3402 nonce: u64,
3403 ) -> Result<FoundryTypedTx> {
3404 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
3405 let max_fee_per_gas = request.max_fee_per_gas;
3406 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
3407 let gas_price = request.gas_price;
3408
3409 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
3410 let from = request.from;
3411
3412 let request = match transaction_request_to_typed(request) {
3413 Some(FoundryTypedTx::Legacy(mut m)) => {
3414 m.nonce = nonce;
3415 m.chain_id = Some(chain_id);
3416 m.gas_limit = gas_limit;
3417 if gas_price.is_none() {
3418 m.gas_price = self.gas_price();
3419 }
3420 FoundryTypedTx::Legacy(m)
3421 }
3422 Some(FoundryTypedTx::Eip2930(mut m)) => {
3423 m.nonce = nonce;
3424 m.chain_id = chain_id;
3425 m.gas_limit = gas_limit;
3426 if gas_price.is_none() {
3427 m.gas_price = self.gas_price();
3428 }
3429 FoundryTypedTx::Eip2930(m)
3430 }
3431 Some(FoundryTypedTx::Eip1559(mut m)) => {
3432 m.nonce = nonce;
3433 m.chain_id = chain_id;
3434 m.gas_limit = gas_limit;
3435 if max_fee_per_gas.is_none() {
3436 m.max_fee_per_gas = self.gas_price();
3437 }
3438 FoundryTypedTx::Eip1559(m)
3439 }
3440 Some(FoundryTypedTx::Eip7702(mut m)) => {
3441 m.nonce = nonce;
3442 m.chain_id = chain_id;
3443 m.gas_limit = gas_limit;
3444 if max_fee_per_gas.is_none() {
3445 m.max_fee_per_gas = self.gas_price();
3446 }
3447 FoundryTypedTx::Eip7702(m)
3448 }
3449 Some(FoundryTypedTx::Eip4844(m)) => {
3450 FoundryTypedTx::Eip4844(match m {
3451 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
3453 m.tx.nonce = nonce;
3454 m.tx.chain_id = chain_id;
3455 m.tx.gas_limit = gas_limit;
3456 if max_fee_per_gas.is_none() {
3457 m.tx.max_fee_per_gas = self.gas_price();
3458 }
3459 if max_fee_per_blob_gas.is_none() {
3460 m.tx.max_fee_per_blob_gas =
3461 self.backend.fees().get_next_block_blob_base_fee_per_gas();
3462 }
3463 TxEip4844Variant::TxEip4844WithSidecar(m)
3464 }
3465 TxEip4844Variant::TxEip4844(mut tx) => {
3466 if !self.backend.skip_blob_validation(from) {
3467 return Err(BlockchainError::FailedToDecodeTransaction);
3468 }
3469
3470 tx.nonce = nonce;
3472 tx.chain_id = chain_id;
3473 tx.gas_limit = gas_limit;
3474 if max_fee_per_gas.is_none() {
3475 tx.max_fee_per_gas = self.gas_price();
3476 }
3477 if max_fee_per_blob_gas.is_none() {
3478 tx.max_fee_per_blob_gas =
3479 self.backend.fees().get_next_block_blob_base_fee_per_gas();
3480 }
3481
3482 TxEip4844Variant::TxEip4844(tx)
3483 }
3484 })
3485 }
3486 Some(FoundryTypedTx::Deposit(mut m)) => {
3487 m.gas_limit = gas_limit;
3488 FoundryTypedTx::Deposit(m)
3489 }
3490 None => return Err(BlockchainError::FailedToDecodeTransaction),
3491 };
3492 Ok(request)
3493 }
3494
3495 pub fn is_impersonated(&self, addr: Address) -> bool {
3497 self.backend.cheats().is_impersonated(addr)
3498 }
3499
3500 fn impersonated_signature(&self, request: &FoundryTypedTx) -> Signature {
3502 match request {
3503 FoundryTypedTx::Legacy(_) => Signature::from_scalars_and_parity(
3506 B256::with_last_byte(1),
3507 B256::with_last_byte(1),
3508 false,
3509 ),
3510 FoundryTypedTx::Eip2930(_)
3511 | FoundryTypedTx::Eip1559(_)
3512 | FoundryTypedTx::Eip7702(_)
3513 | FoundryTypedTx::Eip4844(_)
3514 | FoundryTypedTx::Deposit(_) => Signature::from_scalars_and_parity(
3515 B256::with_last_byte(1),
3516 B256::with_last_byte(1),
3517 false,
3518 ),
3519 }
3520 }
3521
3522 async fn get_transaction_count(
3524 &self,
3525 address: Address,
3526 block_number: Option<BlockId>,
3527 ) -> Result<u64> {
3528 let block_request = self.block_request(block_number).await?;
3529
3530 if let BlockRequest::Number(number) = block_request
3531 && let Some(fork) = self.get_fork()
3532 && fork.predates_fork(number)
3533 {
3534 return Ok(fork.get_nonce(address, number).await?);
3535 }
3536
3537 self.backend.get_nonce(address, block_request).await
3538 }
3539
3540 async fn request_nonce(
3548 &self,
3549 request: &TransactionRequest,
3550 from: Address,
3551 ) -> Result<(u64, u64)> {
3552 let highest_nonce =
3553 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3554 let nonce = request.nonce.unwrap_or(highest_nonce);
3555
3556 Ok((nonce, highest_nonce))
3557 }
3558
3559 fn add_pending_transaction(
3561 &self,
3562 pending_transaction: PendingTransaction,
3563 requires: Vec<TxMarker>,
3564 provides: Vec<TxMarker>,
3565 ) -> Result<TxHash> {
3566 let from = *pending_transaction.sender();
3567 let priority = self.transaction_priority(&pending_transaction.transaction);
3568 let pool_transaction =
3569 PoolTransaction { requires, provides, pending_transaction, priority };
3570 let tx = self.pool.add_transaction(pool_transaction)?;
3571 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3572 Ok(*tx.hash())
3573 }
3574
3575 pub async fn state_root(&self) -> Option<B256> {
3577 self.backend.get_db().read().await.maybe_state_root()
3578 }
3579
3580 fn ensure_typed_transaction_supported(&self, tx: &FoundryTxEnvelope) -> Result<()> {
3582 match &tx {
3583 FoundryTxEnvelope::Eip2930(_) => self.backend.ensure_eip2930_active(),
3584 FoundryTxEnvelope::Eip1559(_) => self.backend.ensure_eip1559_active(),
3585 FoundryTxEnvelope::Eip4844(_) => self.backend.ensure_eip4844_active(),
3586 FoundryTxEnvelope::Eip7702(_) => self.backend.ensure_eip7702_active(),
3587 FoundryTxEnvelope::Deposit(_) => self.backend.ensure_op_deposits_active(),
3588 FoundryTxEnvelope::Legacy(_) => Ok(()),
3589 }
3590 }
3591}
3592
3593fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3594 if provided_nonce == on_chain_nonce {
3595 return Vec::new();
3596 }
3597 let prev_nonce = provided_nonce.saturating_sub(1);
3598 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3599}
3600
3601fn convert_transact_out(out: &Option<Output>) -> Bytes {
3602 match out {
3603 None => Default::default(),
3604 Some(Output::Call(out)) => out.to_vec().into(),
3605 Some(Output::Create(out, _)) => out.to_vec().into(),
3606 }
3607}
3608
3609fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3611 let out = convert_transact_out(out);
3612 match exit {
3613 return_ok!() => Ok(out),
3614 return_revert!() => Err(InvalidTransactionError::Revert(Some(out)).into()),
3615 reason => Err(BlockchainError::EvmError(reason)),
3616 }
3617}
3618
3619fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3621 match transaction_request_to_typed(request.clone()) {
3622 Some(request) => match request {
3623 FoundryTypedTx::Legacy(req) => match req.to {
3624 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3625 TxKind::Create => MIN_CREATE_GAS,
3626 },
3627 FoundryTypedTx::Eip1559(req) => match req.to {
3628 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3629 TxKind::Create => MIN_CREATE_GAS,
3630 },
3631 FoundryTypedTx::Eip7702(req) => {
3632 MIN_TRANSACTION_GAS
3633 + req.authorization_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3634 }
3635 FoundryTypedTx::Eip2930(req) => match req.to {
3636 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3637 TxKind::Create => MIN_CREATE_GAS,
3638 },
3639 FoundryTypedTx::Eip4844(_) => MIN_TRANSACTION_GAS,
3640 FoundryTypedTx::Deposit(req) => match req.to {
3641 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3642 TxKind::Create => MIN_CREATE_GAS,
3643 },
3644 },
3645 _ => MIN_CREATE_GAS,
3648 }
3649}
3650
3651enum GasEstimationCallResult {
3653 Success(u128),
3654 OutOfGas,
3655 Revert(Option<Bytes>),
3656 EvmError(InstructionResult),
3657}
3658
3659impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3663 type Error = BlockchainError;
3664
3665 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3666 match res {
3667 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3669 Ok(Self::OutOfGas)
3670 }
3671 Err(err) => Err(err),
3672 Ok((exit, output, gas, _)) => match exit {
3673 return_ok!() => Ok(Self::Success(gas)),
3674
3675 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3677 InstructionResult::CallTooDeep
3678 | InstructionResult::OutOfFunds
3679 | InstructionResult::CreateInitCodeStartingEF00
3680 | InstructionResult::InvalidEOFInitCode
3681 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3682
3683 InstructionResult::OutOfGas
3685 | InstructionResult::MemoryOOG
3686 | InstructionResult::MemoryLimitOOG
3687 | InstructionResult::PrecompileOOG
3688 | InstructionResult::InvalidOperandOOG
3689 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3690
3691 InstructionResult::OpcodeNotFound
3693 | InstructionResult::CallNotAllowedInsideStatic
3694 | InstructionResult::StateChangeDuringStaticCall
3695 | InstructionResult::InvalidFEOpcode
3696 | InstructionResult::InvalidJump
3697 | InstructionResult::NotActivated
3698 | InstructionResult::StackUnderflow
3699 | InstructionResult::StackOverflow
3700 | InstructionResult::OutOfOffset
3701 | InstructionResult::CreateCollision
3702 | InstructionResult::OverflowPayment
3703 | InstructionResult::PrecompileError
3704 | InstructionResult::NonceOverflow
3705 | InstructionResult::CreateContractSizeLimit
3706 | InstructionResult::CreateContractStartingWithEF
3707 | InstructionResult::CreateInitCodeSizeLimit
3708 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3709 },
3710 }
3711 }
3712}