1use super::{
2 backend::mem::{BlockRequest, DatabaseRef, State},
3 sign::build_typed_transaction,
4};
5use crate::{
6 ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
7 eth::{
8 backend::{
9 self,
10 db::SerializableState,
11 mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
12 notifications::NewBlockNotifications,
13 validate::TransactionValidator,
14 },
15 error::{
16 BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
17 },
18 fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
19 macros::node_info,
20 miner::FixedBlockTimeMiner,
21 pool::{
22 Pool,
23 transactions::{
24 PoolTransaction, TransactionOrder, TransactionPriority, TxMarker, to_marker,
25 },
26 },
27 sign::{self, Signer},
28 },
29 filter::{EthFilter, Filters, LogsFilter},
30 mem::transaction_build,
31};
32use alloy_consensus::{Blob, Transaction, TrieAccount, TxEip4844Variant, transaction::Recovered};
33use alloy_dyn_abi::TypedData;
34use alloy_eips::{
35 eip2718::Encodable2718,
36 eip4844::BlobTransactionSidecar,
37 eip7910::{EthConfig, EthForkConfig},
38};
39use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
40use alloy_network::{
41 AnyRpcBlock, AnyRpcTransaction, BlockResponse, ReceiptResponse, TransactionBuilder,
42 TransactionBuilder4844, TransactionResponse, eip2718::Decodable2718,
43};
44use alloy_primitives::{
45 Address, B64, B256, Bytes, Signature, TxHash, TxKind, U64, U256,
46 map::{HashMap, HashSet},
47};
48use alloy_rpc_types::{
49 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
50 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
51 anvil::{
52 ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
53 },
54 request::TransactionRequest,
55 simulate::{SimulatePayload, SimulatedBlock},
56 state::{AccountOverride, EvmOverrides, StateOverridesBuilder},
57 trace::{
58 filter::TraceFilter,
59 geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
60 parity::LocalizedTransactionTrace,
61 },
62 txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
63};
64use alloy_rpc_types_eth::FillTransaction;
65use alloy_serde::WithOtherFields;
66use alloy_sol_types::{SolCall, SolValue, sol};
67use alloy_transport::TransportErrorKind;
68use anvil_core::{
69 eth::{
70 EthRequest,
71 block::BlockInfo,
72 transaction::{MaybeImpersonatedTransaction, PendingTransaction},
73 wallet::WalletCapabilities,
74 },
75 types::{ReorgOptions, TransactionData},
76};
77use anvil_rpc::{error::RpcError, response::ResponseResult};
78use foundry_common::provider::ProviderBuilder;
79use foundry_evm::decode::RevertDecoder;
80use foundry_primitives::{
81 FoundryTransactionRequest, FoundryTxEnvelope, FoundryTxReceipt, FoundryTxType, FoundryTypedTx,
82};
83use futures::{
84 StreamExt, TryFutureExt,
85 channel::{mpsc::Receiver, oneshot},
86};
87use parking_lot::RwLock;
88use revm::{
89 context::BlockEnv,
90 context_interface::{block::BlobExcessGasAndPrice, result::Output},
91 database::CacheDB,
92 interpreter::{InstructionResult, return_ok, return_revert},
93 primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
94};
95use std::{sync::Arc, time::Duration};
96use tokio::{
97 sync::mpsc::{UnboundedReceiver, unbounded_channel},
98 try_join,
99};
100
101pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
103
104#[derive(Clone)]
108pub struct EthApi {
109 pool: Arc<Pool>,
111 pub backend: Arc<backend::mem::Backend>,
114 is_mining: bool,
116 signers: Arc<Vec<Box<dyn Signer>>>,
118 fee_history_cache: FeeHistoryCache,
120 fee_history_limit: u64,
122 miner: Miner,
127 logger: LoggingManager,
129 filters: Filters,
131 transaction_order: Arc<RwLock<TransactionOrder>>,
133 net_listening: bool,
135 instance_id: Arc<RwLock<B256>>,
137}
138
139impl EthApi {
140 #[expect(clippy::too_many_arguments)]
142 pub fn new(
143 pool: Arc<Pool>,
144 backend: Arc<backend::mem::Backend>,
145 signers: Arc<Vec<Box<dyn Signer>>>,
146 fee_history_cache: FeeHistoryCache,
147 fee_history_limit: u64,
148 miner: Miner,
149 logger: LoggingManager,
150 filters: Filters,
151 transactions_order: TransactionOrder,
152 ) -> Self {
153 Self {
154 pool,
155 backend,
156 is_mining: true,
157 signers,
158 fee_history_cache,
159 fee_history_limit,
160 miner,
161 logger,
162 filters,
163 net_listening: true,
164 transaction_order: Arc::new(RwLock::new(transactions_order)),
165 instance_id: Arc::new(RwLock::new(B256::random())),
166 }
167 }
168
169 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
171 trace!(target: "rpc::api", "executing eth request");
172 let response = match request.clone() {
173 EthRequest::EthProtocolVersion(()) => self.protocol_version().to_rpc_result(),
174 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
175 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
176 EthRequest::EthGetAccount(addr, block) => {
177 self.get_account(addr, block).await.to_rpc_result()
178 }
179 EthRequest::EthGetAccountInfo(addr, block) => {
180 self.get_account_info(addr, block).await.to_rpc_result()
181 }
182 EthRequest::EthGetBalance(addr, block) => {
183 self.balance(addr, block).await.to_rpc_result()
184 }
185 EthRequest::EthGetTransactionByHash(hash) => {
186 self.transaction_by_hash(hash).await.to_rpc_result()
187 }
188 EthRequest::EthSendTransaction(request) => {
189 self.send_transaction(*request).await.to_rpc_result()
190 }
191 EthRequest::EthSendTransactionSync(request) => {
192 self.send_transaction_sync(*request).await.to_rpc_result()
193 }
194 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
195 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
196 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
197 EthRequest::EthHashrate(()) => self.hashrate().to_rpc_result(),
198 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
199 EthRequest::EthMaxPriorityFeePerGas(_) => {
200 self.gas_max_priority_fee_per_gas().to_rpc_result()
201 }
202 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
203 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
204 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
205 EthRequest::EthCoinbase(()) => self.author().to_rpc_result(),
206 EthRequest::EthGetStorageAt(addr, slot, block) => {
207 self.storage_at(addr, slot, block).await.to_rpc_result()
208 }
209 EthRequest::EthGetBlockByHash(hash, full) => {
210 if full {
211 self.block_by_hash_full(hash).await.to_rpc_result()
212 } else {
213 self.block_by_hash(hash).await.to_rpc_result()
214 }
215 }
216 EthRequest::EthGetBlockByNumber(num, full) => {
217 if full {
218 self.block_by_number_full(num).await.to_rpc_result()
219 } else {
220 self.block_by_number(num).await.to_rpc_result()
221 }
222 }
223 EthRequest::EthGetTransactionCount(addr, block) => {
224 self.transaction_count(addr, block).await.to_rpc_result()
225 }
226 EthRequest::EthGetTransactionCountByHash(hash) => {
227 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
228 }
229 EthRequest::EthGetTransactionCountByNumber(num) => {
230 self.block_transaction_count_by_number(num).await.to_rpc_result()
231 }
232 EthRequest::EthGetUnclesCountByHash(hash) => {
233 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
234 }
235 EthRequest::EthGetUnclesCountByNumber(num) => {
236 self.block_uncles_count_by_number(num).await.to_rpc_result()
237 }
238 EthRequest::EthGetCodeAt(addr, block) => {
239 self.get_code(addr, block).await.to_rpc_result()
240 }
241 EthRequest::EthGetProof(addr, keys, block) => {
242 self.get_proof(addr, keys, block).await.to_rpc_result()
243 }
244 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
245 EthRequest::PersonalSign(content, addr) => {
246 self.sign(addr, content).await.to_rpc_result()
247 }
248 EthRequest::EthSignTransaction(request) => {
249 self.sign_transaction(*request).await.to_rpc_result()
250 }
251 EthRequest::EthSignTypedData(addr, data) => {
252 self.sign_typed_data(addr, data).await.to_rpc_result()
253 }
254 EthRequest::EthSignTypedDataV3(addr, data) => {
255 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
256 }
257 EthRequest::EthSignTypedDataV4(addr, data) => {
258 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
259 }
260 EthRequest::EthSendRawTransaction(tx) => {
261 self.send_raw_transaction(tx).await.to_rpc_result()
262 }
263 EthRequest::EthSendRawTransactionSync(tx) => {
264 self.send_raw_transaction_sync(tx).await.to_rpc_result()
265 }
266 EthRequest::EthCall(call, block, state_override, block_overrides) => self
267 .call(call, block, EvmOverrides::new(state_override, block_overrides))
268 .await
269 .to_rpc_result(),
270 EthRequest::EthSimulateV1(simulation, block) => {
271 self.simulate_v1(simulation, block).await.to_rpc_result()
272 }
273 EthRequest::EthCreateAccessList(call, block) => {
274 self.create_access_list(call, block).await.to_rpc_result()
275 }
276 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
277 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
278 .await
279 .to_rpc_result(),
280 EthRequest::EthFillTransaction(request) => {
281 self.fill_transaction(request).await.to_rpc_result()
282 }
283 EthRequest::EthGetRawTransactionByHash(hash) => {
284 self.raw_transaction(hash).await.to_rpc_result()
285 }
286 EthRequest::GetBlobByHash(hash) => {
287 self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
288 }
289 EthRequest::GetBlobByTransactionHash(hash) => {
290 self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
291 }
292 EthRequest::GetBlobSidecarsByBlockId(block_id) => {
293 self.anvil_get_blob_sidecars_by_block_id(block_id).to_rpc_result()
294 }
295 EthRequest::GetGenesisTime(()) => self.anvil_get_genesis_time().to_rpc_result(),
296 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
297 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
298 }
299 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
300 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
301 }
302 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
303 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
304 }
305 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
306 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
307 }
308 EthRequest::EthGetTransactionReceipt(tx) => {
309 self.transaction_receipt(tx).await.to_rpc_result()
310 }
311 EthRequest::EthGetBlockReceipts(number) => {
312 self.block_receipts(number).await.to_rpc_result()
313 }
314 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
315 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
316 }
317 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
318 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
319 }
320 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
321 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
322 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
323 EthRequest::EthConfig(_) => self.config().to_rpc_result(),
324 EthRequest::EthSubmitWork(nonce, pow, digest) => {
325 self.submit_work(nonce, pow, digest).to_rpc_result()
326 }
327 EthRequest::EthSubmitHashRate(rate, id) => {
328 self.submit_hashrate(rate, id).to_rpc_result()
329 }
330 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
331 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
332 }
333 EthRequest::DebugGetRawTransaction(hash) => {
335 self.raw_transaction(hash).await.to_rpc_result()
336 }
337 EthRequest::DebugTraceTransaction(tx, opts) => {
339 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
340 }
341 EthRequest::DebugTraceCall(tx, block, opts) => {
343 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
344 }
345 EthRequest::DebugCodeByHash(hash, block) => {
346 self.debug_code_by_hash(hash, block).await.to_rpc_result()
347 }
348 EthRequest::DebugDbGet(key) => self.debug_db_get(key).await.to_rpc_result(),
349 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
350 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
351 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
352 EthRequest::ImpersonateAccount(addr) => {
353 self.anvil_impersonate_account(addr).await.to_rpc_result()
354 }
355 EthRequest::StopImpersonatingAccount(addr) => {
356 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
357 }
358 EthRequest::AutoImpersonateAccount(enable) => {
359 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
360 }
361 EthRequest::ImpersonateSignature(signature, address) => {
362 self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
363 }
364 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
365 EthRequest::Mine(blocks, interval) => {
366 self.anvil_mine(blocks, interval).await.to_rpc_result()
367 }
368 EthRequest::SetAutomine(enabled) => {
369 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
370 }
371 EthRequest::SetIntervalMining(interval) => {
372 self.anvil_set_interval_mining(interval).to_rpc_result()
373 }
374 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
375 EthRequest::DropTransaction(tx) => {
376 self.anvil_drop_transaction(tx).await.to_rpc_result()
377 }
378 EthRequest::DropAllTransactions() => {
379 self.anvil_drop_all_transactions().await.to_rpc_result()
380 }
381 EthRequest::Reset(fork) => {
382 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
383 }
384 EthRequest::SetBalance(addr, val) => {
385 self.anvil_set_balance(addr, val).await.to_rpc_result()
386 }
387 EthRequest::AddBalance(addr, val) => {
388 self.anvil_add_balance(addr, val).await.to_rpc_result()
389 }
390 EthRequest::DealERC20(addr, token_addr, val) => {
391 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
392 }
393 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
394 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
395 .await
396 .to_rpc_result(),
397 EthRequest::SetCode(addr, code) => {
398 self.anvil_set_code(addr, code).await.to_rpc_result()
399 }
400 EthRequest::SetNonce(addr, nonce) => {
401 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
402 }
403 EthRequest::SetStorageAt(addr, slot, val) => {
404 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
405 }
406 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
407 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
408 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
409 EthRequest::SetMinGasPrice(gas) => {
410 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
411 }
412 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
413 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
414 }
415 EthRequest::DumpState(preserve_historical_states) => self
416 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
417 .await
418 .to_rpc_result(),
419 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
420 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
421 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
422 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
423 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
424 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
425 EthRequest::EvmSetNextBlockTimeStamp(time) => {
426 if time >= U256::from(u64::MAX) {
427 return ResponseResult::Error(RpcError::invalid_params(
428 "The timestamp is too big",
429 ));
430 }
431 let time = time.to::<u64>();
432 self.evm_set_next_block_timestamp(time).to_rpc_result()
433 }
434 EthRequest::EvmSetTime(timestamp) => {
435 if timestamp >= U256::from(u64::MAX) {
436 return ResponseResult::Error(RpcError::invalid_params(
437 "The timestamp is too big",
438 ));
439 }
440 let time = timestamp.to::<u64>();
441 self.evm_set_time(time).to_rpc_result()
442 }
443 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
444 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
445 }
446 EthRequest::EvmSetBlockTimeStampInterval(time) => {
447 self.evm_set_block_timestamp_interval(time).to_rpc_result()
448 }
449 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
450 self.evm_remove_block_timestamp_interval().to_rpc_result()
451 }
452 EthRequest::EvmMine(mine) => {
453 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
454 }
455 EthRequest::EvmMineDetailed(mine) => {
456 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
457 }
458 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
459 EthRequest::EthSendUnsignedTransaction(tx) => {
460 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
461 }
462 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
463 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
464 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
465 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
466 EthRequest::EthNewPendingTransactionFilter(_) => {
467 self.new_pending_transaction_filter().await.to_rpc_result()
468 }
469 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
470 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
471 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
472 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
473 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
474 EthRequest::ErigonGetHeaderByNumber(num) => {
475 self.erigon_get_header_by_number(num).await.to_rpc_result()
476 }
477 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
478 EthRequest::OtsGetInternalOperations(hash) => {
479 self.ots_get_internal_operations(hash).await.to_rpc_result()
480 }
481 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
482 EthRequest::OtsTraceTransaction(hash) => {
483 self.ots_trace_transaction(hash).await.to_rpc_result()
484 }
485 EthRequest::OtsGetTransactionError(hash) => {
486 self.ots_get_transaction_error(hash).await.to_rpc_result()
487 }
488 EthRequest::OtsGetBlockDetails(num) => {
489 self.ots_get_block_details(num).await.to_rpc_result()
490 }
491 EthRequest::OtsGetBlockDetailsByHash(hash) => {
492 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
493 }
494 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
495 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
496 }
497 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
498 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
499 }
500 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
501 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
502 }
503 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
504 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
505 }
506 EthRequest::EthGetTransactionBySenderAndNonce(sender, nonce) => {
507 self.transaction_by_sender_and_nonce(sender, nonce).await.to_rpc_result()
508 }
509 EthRequest::OtsGetContractCreator(address) => {
510 self.ots_get_contract_creator(address).await.to_rpc_result()
511 }
512 EthRequest::RemovePoolTransactions(address) => {
513 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
514 }
515 EthRequest::Reorg(reorg_options) => {
516 self.anvil_reorg(reorg_options).await.to_rpc_result()
517 }
518 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
519 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
520 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
521 EthRequest::AnvilSetExecutor(executor_pk) => {
522 self.anvil_set_executor(executor_pk).to_rpc_result()
523 }
524 };
525
526 if let ResponseResult::Error(err) = &response {
527 node_info!("\nRPC request failed:");
528 node_info!(" Request: {:?}", request);
529 node_info!(" Error: {}\n", err);
530 }
531
532 response
533 }
534
535 fn sign_request(&self, from: &Address, request: FoundryTypedTx) -> Result<FoundryTxEnvelope> {
536 match request {
537 FoundryTypedTx::Deposit(_) => {
538 let nil_signature = Signature::from_scalars_and_parity(
539 B256::with_last_byte(1),
540 B256::with_last_byte(1),
541 false,
542 );
543 return build_typed_transaction(request, nil_signature);
544 }
545 _ => {
546 for signer in self.signers.iter() {
547 if signer.accounts().contains(from) {
548 let signature = signer.sign_transaction(request.clone(), from)?;
549 return build_typed_transaction(request, signature);
550 }
551 }
552 }
553 }
554 Err(BlockchainError::NoSignerAvailable)
555 }
556
557 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
558 let block_request = match block_number {
559 Some(BlockId::Number(BlockNumber::Pending)) => {
560 let pending_txs = self.pool.ready_transactions().collect();
561 BlockRequest::Pending(pending_txs)
562 }
563 _ => {
564 let number = self.backend.ensure_block_number(block_number).await?;
565 BlockRequest::Number(number)
566 }
567 };
568 Ok(block_request)
569 }
570
571 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
572 match self.pool.get_transaction(hash) {
573 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
574 None => match self.backend.transaction_by_hash(hash).await? {
575 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
576 None => Ok(None),
577 },
578 }
579 }
580
581 pub fn client_version(&self) -> Result<String> {
585 node_info!("web3_clientVersion");
586 Ok(CLIENT_VERSION.to_string())
587 }
588
589 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
593 node_info!("web3_sha3");
594 let hash = alloy_primitives::keccak256(bytes.as_ref());
595 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
596 }
597
598 pub fn protocol_version(&self) -> Result<u64> {
602 node_info!("eth_protocolVersion");
603 Ok(1)
604 }
605
606 pub fn hashrate(&self) -> Result<U256> {
610 node_info!("eth_hashrate");
611 Ok(U256::ZERO)
612 }
613
614 pub fn author(&self) -> Result<Address> {
618 node_info!("eth_coinbase");
619 Ok(self.backend.coinbase())
620 }
621
622 pub fn is_mining(&self) -> Result<bool> {
626 node_info!("eth_mining");
627 Ok(self.is_mining)
628 }
629
630 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
636 node_info!("eth_chainId");
637 Ok(Some(self.backend.chain_id().to::<U64>()))
638 }
639
640 pub fn network_id(&self) -> Result<Option<String>> {
644 node_info!("eth_networkId");
645 let chain_id = self.backend.chain_id().to::<u64>();
646 Ok(Some(format!("{chain_id}")))
647 }
648
649 pub fn net_listening(&self) -> Result<bool> {
653 node_info!("net_listening");
654 Ok(self.net_listening)
655 }
656
657 fn eth_gas_price(&self) -> Result<U256> {
659 node_info!("eth_gasPrice");
660 Ok(U256::from(self.gas_price()))
661 }
662
663 pub fn gas_price(&self) -> u128 {
665 if self.backend.is_eip1559() {
666 if self.backend.is_min_priority_fee_enforced() {
667 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
668 } else {
669 self.backend.base_fee() as u128
670 }
671 } else {
672 self.backend.fees().raw_gas_price()
673 }
674 }
675
676 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
678 Ok(self.backend.excess_blob_gas_and_price())
679 }
680
681 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
686 self.max_priority_fee_per_gas()
687 }
688
689 pub fn blob_base_fee(&self) -> Result<U256> {
693 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
694 }
695
696 pub fn gas_limit(&self) -> U256 {
698 U256::from(self.backend.gas_limit())
699 }
700
701 pub fn accounts(&self) -> Result<Vec<Address>> {
705 node_info!("eth_accounts");
706 let mut unique = HashSet::new();
707 let mut accounts: Vec<Address> = Vec::new();
708 for signer in self.signers.iter() {
709 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
710 }
711 accounts.extend(
712 self.backend
713 .cheats()
714 .impersonated_accounts()
715 .into_iter()
716 .filter(|acc| unique.insert(*acc)),
717 );
718 Ok(accounts.into_iter().collect())
719 }
720
721 pub fn block_number(&self) -> Result<U256> {
725 node_info!("eth_blockNumber");
726 Ok(U256::from(self.backend.best_number()))
727 }
728
729 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
733 node_info!("eth_getBalance");
734 let block_request = self.block_request(block_number).await?;
735
736 if let BlockRequest::Number(number) = block_request
738 && let Some(fork) = self.get_fork()
739 && fork.predates_fork(number)
740 {
741 return Ok(fork.get_balance(address, number).await?);
742 }
743
744 self.backend.get_balance(address, Some(block_request)).await
745 }
746
747 pub async fn get_account(
751 &self,
752 address: Address,
753 block_number: Option<BlockId>,
754 ) -> Result<TrieAccount> {
755 node_info!("eth_getAccount");
756 let block_request = self.block_request(block_number).await?;
757
758 if let BlockRequest::Number(number) = block_request
760 && let Some(fork) = self.get_fork()
761 && fork.predates_fork(number)
762 {
763 return Ok(fork.get_account(address, number).await?);
764 }
765
766 self.backend.get_account_at_block(address, Some(block_request)).await
767 }
768
769 pub async fn get_account_info(
773 &self,
774 address: Address,
775 block_number: Option<BlockId>,
776 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
777 node_info!("eth_getAccountInfo");
778
779 if let Some(fork) = self.get_fork() {
780 let block_request = self.block_request(block_number).await?;
781 if let BlockRequest::Number(number) = block_request {
783 trace!(target: "node", "get_account_info: fork block {}, requested block {number}", fork.block_number());
784 return if fork.predates_fork(number) {
785 let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
788 let code = fork.get_code(address, number).map_err(BlockchainError::from);
789 let nonce = self.get_transaction_count(address, Some(number.into()));
790 let (balance, code, nonce) = try_join!(balance, code, nonce)?;
791
792 Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code })
793 } else {
794 let account_info = self.backend.get_account(address).await?;
797 let code = self.backend.get_code(address, Some(block_request)).await?;
798 Ok(alloy_rpc_types::eth::AccountInfo {
799 balance: account_info.balance,
800 nonce: account_info.nonce,
801 code,
802 })
803 };
804 }
805 }
806
807 let account = self.get_account(address, block_number);
808 let code = self.get_code(address, block_number);
809 let (account, code) = try_join!(account, code)?;
810 Ok(alloy_rpc_types::eth::AccountInfo {
811 balance: account.balance,
812 nonce: account.nonce,
813 code,
814 })
815 }
816 pub async fn storage_at(
820 &self,
821 address: Address,
822 index: U256,
823 block_number: Option<BlockId>,
824 ) -> Result<B256> {
825 node_info!("eth_getStorageAt");
826 let block_request = self.block_request(block_number).await?;
827
828 if let BlockRequest::Number(number) = block_request
830 && let Some(fork) = self.get_fork()
831 && fork.predates_fork(number)
832 {
833 return Ok(B256::from(
834 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
835 ));
836 }
837
838 self.backend.storage_at(address, index, Some(block_request)).await
839 }
840
841 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
845 node_info!("eth_getBlockByHash");
846 self.backend.block_by_hash(hash).await
847 }
848
849 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
853 node_info!("eth_getBlockByHash");
854 self.backend.block_by_hash_full(hash).await
855 }
856
857 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
861 node_info!("eth_getBlockByNumber");
862 if number == BlockNumber::Pending {
863 return Ok(Some(self.pending_block().await));
864 }
865
866 self.backend.block_by_number(number).await
867 }
868
869 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
873 node_info!("eth_getBlockByNumber");
874 if number == BlockNumber::Pending {
875 return Ok(self.pending_block_full().await);
876 }
877 self.backend.block_by_number_full(number).await
878 }
879
880 pub async fn transaction_count(
887 &self,
888 address: Address,
889 block_number: Option<BlockId>,
890 ) -> Result<U256> {
891 node_info!("eth_getTransactionCount");
892 self.get_transaction_count(address, block_number).await.map(U256::from)
893 }
894
895 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
899 node_info!("eth_getBlockTransactionCountByHash");
900 let block = self.backend.block_by_hash(hash).await?;
901 let txs = block.map(|b| match b.transactions() {
902 BlockTransactions::Full(txs) => U256::from(txs.len()),
903 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
904 BlockTransactions::Uncle => U256::from(0),
905 });
906 Ok(txs)
907 }
908
909 pub async fn block_transaction_count_by_number(
913 &self,
914 block_number: BlockNumber,
915 ) -> Result<Option<U256>> {
916 node_info!("eth_getBlockTransactionCountByNumber");
917 let block_request = self.block_request(Some(block_number.into())).await?;
918 if let BlockRequest::Pending(txs) = block_request {
919 let block = self.backend.pending_block(txs).await;
920 return Ok(Some(U256::from(block.block.body.transactions.len())));
921 }
922 let block = self.backend.block_by_number(block_number).await?;
923 let txs = block.map(|b| match b.transactions() {
924 BlockTransactions::Full(txs) => U256::from(txs.len()),
925 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
926 BlockTransactions::Uncle => U256::from(0),
927 });
928 Ok(txs)
929 }
930
931 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
935 node_info!("eth_getUncleCountByBlockHash");
936 let block =
937 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
938 Ok(U256::from(block.uncles.len()))
939 }
940
941 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
945 node_info!("eth_getUncleCountByBlockNumber");
946 let block = self
947 .backend
948 .block_by_number(block_number)
949 .await?
950 .ok_or(BlockchainError::BlockNotFound)?;
951 Ok(U256::from(block.uncles.len()))
952 }
953
954 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
958 node_info!("eth_getCode");
959 let block_request = self.block_request(block_number).await?;
960 if let BlockRequest::Number(number) = block_request
962 && let Some(fork) = self.get_fork()
963 && fork.predates_fork(number)
964 {
965 return Ok(fork.get_code(address, number).await?);
966 }
967 self.backend.get_code(address, Some(block_request)).await
968 }
969
970 pub async fn get_proof(
975 &self,
976 address: Address,
977 keys: Vec<B256>,
978 block_number: Option<BlockId>,
979 ) -> Result<EIP1186AccountProofResponse> {
980 node_info!("eth_getProof");
981 let block_request = self.block_request(block_number).await?;
982
983 if let BlockRequest::Number(number) = block_request
986 && let Some(fork) = self.get_fork()
987 && fork.predates_fork_inclusive(number)
988 {
989 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
990 }
991
992 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
993 Ok(proof)
994 }
995
996 pub async fn sign_typed_data(
1000 &self,
1001 _address: Address,
1002 _data: serde_json::Value,
1003 ) -> Result<String> {
1004 node_info!("eth_signTypedData");
1005 Err(BlockchainError::RpcUnimplemented)
1006 }
1007
1008 pub async fn sign_typed_data_v3(
1012 &self,
1013 _address: Address,
1014 _data: serde_json::Value,
1015 ) -> Result<String> {
1016 node_info!("eth_signTypedData_v3");
1017 Err(BlockchainError::RpcUnimplemented)
1018 }
1019
1020 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
1024 node_info!("eth_signTypedData_v4");
1025 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1026 let signature = signer.sign_typed_data(address, data).await?;
1027 let signature = alloy_primitives::hex::encode(signature.as_bytes());
1028 Ok(format!("0x{signature}"))
1029 }
1030
1031 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1035 node_info!("eth_sign");
1036 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1037 let signature =
1038 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1039 Ok(format!("0x{signature}"))
1040 }
1041
1042 pub async fn sign_transaction(
1046 &self,
1047 request: WithOtherFields<TransactionRequest>,
1048 ) -> Result<String> {
1049 node_info!("eth_signTransaction");
1050
1051 let from = request.from.map(Ok).unwrap_or_else(|| {
1052 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1053 })?;
1054
1055 let (nonce, _) = self.request_nonce(&request, from).await?;
1056
1057 let request = self.build_tx_request(request, nonce).await?;
1058
1059 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1060 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1061 }
1062
1063 pub async fn send_transaction(
1067 &self,
1068 request: WithOtherFields<TransactionRequest>,
1069 ) -> Result<TxHash> {
1070 node_info!("eth_sendTransaction");
1071
1072 let from = request.from.map(Ok).unwrap_or_else(|| {
1073 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1074 })?;
1075 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1076
1077 let request = self.build_tx_request(request, nonce).await?;
1078
1079 let pending_transaction = if self.is_impersonated(from) {
1081 let bypass_signature = self.impersonated_signature(&request);
1082 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1083 self.ensure_typed_transaction_supported(&transaction)?;
1084 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1085 PendingTransaction::with_impersonated(transaction, from)
1086 } else {
1087 let transaction = self.sign_request(&from, request)?;
1088 self.ensure_typed_transaction_supported(&transaction)?;
1089 PendingTransaction::new(transaction)?
1090 };
1091 self.backend.validate_pool_transaction(&pending_transaction).await?;
1093
1094 let requires = required_marker(nonce, on_chain_nonce, from);
1095 let provides = vec![to_marker(nonce, from)];
1096 debug_assert!(requires != provides);
1097
1098 self.add_pending_transaction(pending_transaction, requires, provides)
1099 }
1100
1101 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
1103 let mut stream = self.new_block_notifications();
1104 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1106 return Ok(receipt);
1107 }
1108 while let Some(notification) = stream.next().await {
1109 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1110 && block.body.transactions.iter().any(|tx| tx.hash() == hash)
1111 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1112 {
1113 return Ok(receipt);
1114 }
1115 }
1116
1117 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1118 }
1119
1120 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
1122 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1123 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1124 .await
1125 .unwrap_or_else(|_elapsed| {
1126 Err(BlockchainError::TransactionConfirmationTimeout {
1127 hash,
1128 duration: TIMEOUT_DURATION,
1129 })
1130 })
1131 }
1132
1133 pub async fn send_transaction_sync(
1137 &self,
1138 request: WithOtherFields<TransactionRequest>,
1139 ) -> Result<FoundryTxReceipt> {
1140 node_info!("eth_sendTransactionSync");
1141 let hash = self.send_transaction(request).await?;
1142
1143 let receipt = self.check_transaction_inclusion(hash).await?;
1144
1145 Ok(receipt)
1146 }
1147
1148 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1152 node_info!("eth_sendRawTransaction");
1153 let mut data = tx.as_ref();
1154 if data.is_empty() {
1155 return Err(BlockchainError::EmptyRawTransactionData);
1156 }
1157
1158 let transaction = FoundryTxEnvelope::decode_2718(&mut data)
1159 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1160
1161 self.ensure_typed_transaction_supported(&transaction)?;
1162
1163 let pending_transaction = PendingTransaction::new(transaction)?;
1164
1165 self.backend.validate_pool_transaction(&pending_transaction).await?;
1167
1168 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1169 let from = *pending_transaction.sender();
1170 let nonce = pending_transaction.transaction.nonce();
1171 let requires = required_marker(nonce, on_chain_nonce, from);
1172
1173 let priority = self.transaction_priority(&pending_transaction.transaction);
1174 let pool_transaction = PoolTransaction {
1175 requires,
1176 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1177 pending_transaction,
1178 priority,
1179 };
1180
1181 let tx = self.pool.add_transaction(pool_transaction)?;
1182 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1183 Ok(*tx.hash())
1184 }
1185
1186 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<FoundryTxReceipt> {
1190 node_info!("eth_sendRawTransactionSync");
1191
1192 let hash = self.send_raw_transaction(tx).await?;
1193 let receipt = self.check_transaction_inclusion(hash).await?;
1194
1195 Ok(receipt)
1196 }
1197
1198 pub async fn call(
1202 &self,
1203 request: WithOtherFields<TransactionRequest>,
1204 block_number: Option<BlockId>,
1205 overrides: EvmOverrides,
1206 ) -> Result<Bytes> {
1207 node_info!("eth_call");
1208 let block_request = self.block_request(block_number).await?;
1209 if let BlockRequest::Number(number) = block_request
1211 && let Some(fork) = self.get_fork()
1212 && fork.predates_fork(number)
1213 {
1214 if overrides.has_state() || overrides.has_block() {
1215 return Err(BlockchainError::EvmOverrideError(
1216 "not available on past forked blocks".to_string(),
1217 ));
1218 }
1219 return Ok(fork.call(&request, Some(number.into())).await?);
1220 }
1221
1222 let fees = FeeDetails::new(
1223 request.gas_price,
1224 request.max_fee_per_gas,
1225 request.max_priority_fee_per_gas,
1226 request.max_fee_per_blob_gas,
1227 )?
1228 .or_zero_fees();
1229 self.on_blocking_task(|this| async move {
1232 let (exit, out, gas, _) =
1233 this.backend.call(request, fees, Some(block_request), overrides).await?;
1234 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1235
1236 ensure_return_ok(exit, &out)
1237 })
1238 .await
1239 }
1240
1241 pub async fn simulate_v1(
1242 &self,
1243 request: SimulatePayload,
1244 block_number: Option<BlockId>,
1245 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1246 node_info!("eth_simulateV1");
1247 let block_request = self.block_request(block_number).await?;
1248 if let BlockRequest::Number(number) = block_request
1250 && let Some(fork) = self.get_fork()
1251 && fork.predates_fork(number)
1252 {
1253 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1254 }
1255
1256 self.on_blocking_task(|this| async move {
1259 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1260 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1261
1262 Ok(simulated_blocks)
1263 })
1264 .await
1265 }
1266
1267 pub async fn create_access_list(
1281 &self,
1282 mut request: WithOtherFields<TransactionRequest>,
1283 block_number: Option<BlockId>,
1284 ) -> Result<AccessListResult> {
1285 node_info!("eth_createAccessList");
1286 let block_request = self.block_request(block_number).await?;
1287 if let BlockRequest::Number(number) = block_request
1289 && let Some(fork) = self.get_fork()
1290 && fork.predates_fork(number)
1291 {
1292 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1293 }
1294
1295 self.backend
1296 .with_database_at(Some(block_request), |state, block_env| {
1297 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1298 &state,
1299 request.clone(),
1300 FeeDetails::zero(),
1301 block_env.clone(),
1302 )?;
1303 ensure_return_ok(exit, &out)?;
1304
1305 request.access_list = Some(access_list.clone());
1307
1308 let (exit, out, gas_used, _) = self.backend.call_with_state(
1309 &state,
1310 request.clone(),
1311 FeeDetails::zero(),
1312 block_env,
1313 )?;
1314 ensure_return_ok(exit, &out)?;
1315
1316 Ok(AccessListResult {
1317 access_list: AccessList(access_list.0),
1318 gas_used: U256::from(gas_used),
1319 error: None,
1320 })
1321 })
1322 .await?
1323 }
1324
1325 pub async fn estimate_gas(
1330 &self,
1331 request: WithOtherFields<TransactionRequest>,
1332 block_number: Option<BlockId>,
1333 overrides: EvmOverrides,
1334 ) -> Result<U256> {
1335 node_info!("eth_estimateGas");
1336 self.do_estimate_gas(
1337 request,
1338 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1339 overrides,
1340 )
1341 .await
1342 .map(U256::from)
1343 }
1344
1345 pub async fn fill_transaction(
1352 &self,
1353 mut request: WithOtherFields<TransactionRequest>,
1354 ) -> Result<FillTransaction<AnyRpcTransaction>> {
1355 node_info!("eth_fillTransaction");
1356
1357 let from = match request.as_ref().from() {
1358 Some(from) => from,
1359 None => self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)?,
1360 };
1361
1362 let nonce = if let Some(nonce) = request.as_ref().nonce() {
1363 nonce
1364 } else {
1365 self.request_nonce(&request, from).await?.0
1366 };
1367
1368 if request.as_ref().gas_limit().is_none() {
1372 let estimated_gas =
1373 self.estimate_gas(request.clone(), None, EvmOverrides::default()).await?;
1374 request.as_mut().set_gas_limit(estimated_gas.to());
1375 }
1376
1377 let typed_tx = self.build_tx_request(request, nonce).await?;
1378 let tx = build_typed_transaction(
1379 typed_tx,
1380 Signature::new(Default::default(), Default::default(), false),
1381 )?;
1382
1383 let raw = tx.encoded_2718().to_vec().into();
1384
1385 let mut tx =
1386 transaction_build(None, MaybeImpersonatedTransaction::new(tx), None, None, None);
1387
1388 tx.0.inner.inner = Recovered::new_unchecked(tx.0.inner.inner.into_inner(), from);
1391
1392 Ok(FillTransaction { raw, tx })
1393 }
1394
1395 pub fn anvil_get_blob_by_versioned_hash(
1397 &self,
1398 hash: B256,
1399 ) -> Result<Option<alloy_consensus::Blob>> {
1400 node_info!("anvil_getBlobByHash");
1401 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1402 }
1403
1404 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1406 node_info!("anvil_getBlobsByTransactionHash");
1407 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1408 }
1409
1410 pub fn anvil_get_blobs_by_block_id(
1412 &self,
1413 block_id: impl Into<BlockId>,
1414 versioned_hashes: Vec<B256>,
1415 ) -> Result<Option<Vec<Blob>>> {
1416 node_info!("anvil_getBlobsByBlockId");
1417 Ok(self.backend.get_blobs_by_block_id(block_id, versioned_hashes)?)
1418 }
1419
1420 pub fn anvil_get_blob_sidecars_by_block_id(
1422 &self,
1423 block_id: BlockId,
1424 ) -> Result<Option<BlobTransactionSidecar>> {
1425 node_info!("anvil_getBlobSidecarsByBlockId");
1426 Ok(self.backend.get_blob_sidecars_by_block_id(block_id)?)
1427 }
1428
1429 pub fn anvil_get_genesis_time(&self) -> Result<u64> {
1433 node_info!("anvil_getGenesisTime");
1434 Ok(self.backend.genesis_time())
1435 }
1436
1437 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1444 node_info!("eth_getTransactionByHash");
1445 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1446 let from = *pending.sender();
1447 let tx = transaction_build(
1448 Some(*pending.hash()),
1449 pending.transaction,
1450 None,
1451 None,
1452 Some(self.backend.base_fee()),
1453 );
1454
1455 let WithOtherFields { inner: mut tx, other } = tx.0;
1456 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1459
1460 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1461 });
1462 if tx.is_none() {
1463 tx = self.backend.transaction_by_hash(hash).await?
1464 }
1465
1466 Ok(tx)
1467 }
1468
1469 pub async fn transaction_by_block_hash_and_index(
1473 &self,
1474 hash: B256,
1475 index: Index,
1476 ) -> Result<Option<AnyRpcTransaction>> {
1477 node_info!("eth_getTransactionByBlockHashAndIndex");
1478 self.backend.transaction_by_block_hash_and_index(hash, index).await
1479 }
1480
1481 pub async fn transaction_by_block_number_and_index(
1485 &self,
1486 block: BlockNumber,
1487 idx: Index,
1488 ) -> Result<Option<AnyRpcTransaction>> {
1489 node_info!("eth_getTransactionByBlockNumberAndIndex");
1490 self.backend.transaction_by_block_number_and_index(block, idx).await
1491 }
1492
1493 pub async fn transaction_by_sender_and_nonce(
1500 &self,
1501 sender: Address,
1502 nonce: U256,
1503 ) -> Result<Option<AnyRpcTransaction>> {
1504 node_info!("eth_getTransactionBySenderAndNonce");
1505
1506 for pending_tx in self.pool.ready_transactions().chain(self.pool.pending_transactions()) {
1508 if U256::from(pending_tx.pending_transaction.nonce()) == nonce
1509 && *pending_tx.pending_transaction.sender() == sender
1510 {
1511 let tx = transaction_build(
1512 Some(*pending_tx.pending_transaction.hash()),
1513 pending_tx.pending_transaction.transaction.clone(),
1514 None,
1515 None,
1516 Some(self.backend.base_fee()),
1517 );
1518
1519 let WithOtherFields { inner: mut tx, other } = tx.0;
1520 let from = *pending_tx.pending_transaction.sender();
1523 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1524
1525 return Ok(Some(AnyRpcTransaction(WithOtherFields { inner: tx, other })));
1526 }
1527 }
1528
1529 let highest_nonce = self.transaction_count(sender, None).await?.saturating_to::<u64>();
1530 let target_nonce = nonce.saturating_to::<u64>();
1531
1532 if target_nonce >= highest_nonce {
1534 return Ok(None);
1535 }
1536
1537 let latest_block = self.backend.best_number();
1539 if latest_block == 0 {
1540 return Ok(None);
1541 }
1542
1543 let mut low = 1u64;
1545 let mut high = latest_block;
1546
1547 while low <= high {
1548 let mid = low + (high - low) / 2;
1549 let mid_nonce =
1550 self.transaction_count(sender, Some(mid.into())).await?.saturating_to::<u64>();
1551
1552 if mid_nonce > target_nonce {
1553 high = mid - 1;
1554 } else {
1555 low = mid + 1;
1556 }
1557 }
1558
1559 let target_block = low;
1561 if target_block <= latest_block
1562 && let Some(txs) =
1563 self.backend.mined_transactions_by_block_number(target_block.into()).await
1564 {
1565 for tx in txs {
1566 if tx.from() == sender
1567 && tx.nonce() == target_nonce
1568 && let Some(mined_tx) = self.backend.transaction_by_hash(tx.tx_hash()).await?
1569 {
1570 return Ok(Some(mined_tx));
1571 }
1572 }
1573 }
1574
1575 Ok(None)
1576 }
1577
1578 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<FoundryTxReceipt>> {
1582 node_info!("eth_getTransactionReceipt");
1583 self.backend.transaction_receipt(hash).await
1584 }
1585
1586 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<FoundryTxReceipt>>> {
1590 node_info!("eth_getBlockReceipts");
1591 self.backend.block_receipts(number).await
1592 }
1593
1594 pub async fn uncle_by_block_hash_and_index(
1598 &self,
1599 block_hash: B256,
1600 idx: Index,
1601 ) -> Result<Option<AnyRpcBlock>> {
1602 node_info!("eth_getUncleByBlockHashAndIndex");
1603 let number =
1604 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1605 if let Some(fork) = self.get_fork()
1606 && fork.predates_fork_inclusive(number)
1607 {
1608 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1609 }
1610 Ok(None)
1612 }
1613
1614 pub async fn uncle_by_block_number_and_index(
1618 &self,
1619 block_number: BlockNumber,
1620 idx: Index,
1621 ) -> Result<Option<AnyRpcBlock>> {
1622 node_info!("eth_getUncleByBlockNumberAndIndex");
1623 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1624 if let Some(fork) = self.get_fork()
1625 && fork.predates_fork_inclusive(number)
1626 {
1627 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1628 }
1629 Ok(None)
1631 }
1632
1633 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1637 node_info!("eth_getLogs");
1638 self.backend.logs(filter).await
1639 }
1640
1641 pub fn work(&self) -> Result<Work> {
1645 node_info!("eth_getWork");
1646 Err(BlockchainError::RpcUnimplemented)
1647 }
1648
1649 pub fn syncing(&self) -> Result<bool> {
1653 node_info!("eth_syncing");
1654 Ok(false)
1655 }
1656
1657 pub fn config(&self) -> Result<EthConfig> {
1668 node_info!("eth_config");
1669 Ok(EthConfig {
1670 current: EthForkConfig {
1671 activation_time: 0,
1672 blob_schedule: self.backend.blob_params(),
1673 chain_id: self.backend.env().read().evm_env.cfg_env.chain_id,
1674 fork_id: Bytes::from_static(&[0; 4]),
1675 precompiles: self.backend.precompiles(),
1676 system_contracts: self.backend.system_contracts(),
1677 },
1678 next: None,
1679 last: None,
1680 })
1681 }
1682
1683 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1687 node_info!("eth_submitWork");
1688 Err(BlockchainError::RpcUnimplemented)
1689 }
1690
1691 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1695 node_info!("eth_submitHashrate");
1696 Err(BlockchainError::RpcUnimplemented)
1697 }
1698
1699 pub async fn fee_history(
1703 &self,
1704 block_count: U256,
1705 newest_block: BlockNumber,
1706 reward_percentiles: Vec<f64>,
1707 ) -> Result<FeeHistory> {
1708 node_info!("eth_feeHistory");
1709 let current = self.backend.best_number();
1712 let slots_in_an_epoch = 32u64;
1713
1714 let number = match newest_block {
1715 BlockNumber::Latest | BlockNumber::Pending => current,
1716 BlockNumber::Earliest => 0,
1717 BlockNumber::Number(n) => n,
1718 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1719 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1720 };
1721
1722 if let Some(fork) = self.get_fork() {
1724 if fork.predates_fork_inclusive(number) {
1727 return fork
1728 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1729 .await
1730 .map_err(BlockchainError::AlloyForkProvider);
1731 }
1732 }
1733
1734 const MAX_BLOCK_COUNT: u64 = 1024u64;
1735 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1736
1737 let highest = number;
1739 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1740
1741 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1743 return Err(FeeHistoryError::InvalidBlockRange.into());
1744 }
1745
1746 let mut response = FeeHistory {
1747 oldest_block: lowest,
1748 base_fee_per_gas: Vec::new(),
1749 gas_used_ratio: Vec::new(),
1750 reward: Some(Default::default()),
1751 base_fee_per_blob_gas: Default::default(),
1752 blob_gas_used_ratio: Default::default(),
1753 };
1754 let mut rewards = Vec::new();
1755
1756 {
1757 let fee_history = self.fee_history_cache.lock();
1758
1759 for n in lowest..=highest {
1761 if let Some(block) = fee_history.get(&n) {
1763 response.base_fee_per_gas.push(block.base_fee);
1764 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1765 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1766 response.gas_used_ratio.push(block.gas_used_ratio);
1767
1768 if !reward_percentiles.is_empty() {
1770 let mut block_rewards = Vec::new();
1771 let resolution_per_percentile: f64 = 2.0;
1772 for p in &reward_percentiles {
1773 let p = p.clamp(0.0, 100.0);
1774 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1775 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1776 block_rewards.push(reward);
1777 }
1778 rewards.push(block_rewards);
1779 }
1780 }
1781 }
1782 }
1783
1784 response.reward = Some(rewards);
1785
1786 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1791
1792 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1796
1797 Ok(response)
1798 }
1799
1800 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1807 node_info!("eth_maxPriorityFeePerGas");
1808 Ok(U256::from(self.lowest_suggestion_tip()))
1809 }
1810
1811 fn lowest_suggestion_tip(&self) -> u128 {
1815 let block_number = self.backend.best_number();
1816 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1817
1818 match latest_cached_block {
1819 Some(block) => block.rewards.iter().copied().min(),
1820 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1821 }
1822 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1823 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1824 }
1825
1826 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1830 node_info!("eth_newFilter");
1831 let historic = if filter.block_option.get_from_block().is_some() {
1834 self.backend.logs(filter.clone()).await?
1835 } else {
1836 vec![]
1837 };
1838 let filter = EthFilter::Logs(Box::new(LogsFilter {
1839 blocks: self.new_block_notifications(),
1840 storage: self.storage_info(),
1841 filter: FilteredParams::new(Some(filter)),
1842 historic: Some(historic),
1843 }));
1844 Ok(self.filters.add_filter(filter).await)
1845 }
1846
1847 pub async fn new_block_filter(&self) -> Result<String> {
1851 node_info!("eth_newBlockFilter");
1852 let filter = EthFilter::Blocks(self.new_block_notifications());
1853 Ok(self.filters.add_filter(filter).await)
1854 }
1855
1856 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1860 node_info!("eth_newPendingTransactionFilter");
1861 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1862 Ok(self.filters.add_filter(filter).await)
1863 }
1864
1865 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1869 node_info!("eth_getFilterChanges");
1870 self.filters.get_filter_changes(id).await
1871 }
1872
1873 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1877 node_info!("eth_getFilterLogs");
1878 if let Some(filter) = self.filters.get_log_filter(id).await {
1879 self.backend.logs(filter).await
1880 } else {
1881 Ok(Vec::new())
1882 }
1883 }
1884
1885 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1887 node_info!("eth_uninstallFilter");
1888 Ok(self.filters.uninstall_filter(id).await.is_some())
1889 }
1890
1891 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1895 node_info!("debug_getRawTransaction");
1896 self.inner_raw_transaction(hash).await
1897 }
1898
1899 pub async fn raw_transaction_by_block_hash_and_index(
1903 &self,
1904 block_hash: B256,
1905 index: Index,
1906 ) -> Result<Option<Bytes>> {
1907 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1908 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1909 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1910 None => Ok(None),
1911 }
1912 }
1913
1914 pub async fn raw_transaction_by_block_number_and_index(
1918 &self,
1919 block_number: BlockNumber,
1920 index: Index,
1921 ) -> Result<Option<Bytes>> {
1922 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1923 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1924 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1925 None => Ok(None),
1926 }
1927 }
1928
1929 pub async fn debug_trace_transaction(
1933 &self,
1934 tx_hash: B256,
1935 opts: GethDebugTracingOptions,
1936 ) -> Result<GethTrace> {
1937 node_info!("debug_traceTransaction");
1938 self.backend.debug_trace_transaction(tx_hash, opts).await
1939 }
1940
1941 pub async fn debug_trace_call(
1945 &self,
1946 request: WithOtherFields<TransactionRequest>,
1947 block_number: Option<BlockId>,
1948 opts: GethDebugTracingCallOptions,
1949 ) -> Result<GethTrace> {
1950 node_info!("debug_traceCall");
1951 let block_request = self.block_request(block_number).await?;
1952 let fees = FeeDetails::new(
1953 request.gas_price,
1954 request.max_fee_per_gas,
1955 request.max_priority_fee_per_gas,
1956 request.max_fee_per_blob_gas,
1957 )?
1958 .or_zero_fees();
1959
1960 let result: std::result::Result<GethTrace, BlockchainError> =
1961 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1962 result
1963 }
1964
1965 pub async fn debug_code_by_hash(
1969 &self,
1970 hash: B256,
1971 block_id: Option<BlockId>,
1972 ) -> Result<Option<Bytes>> {
1973 node_info!("debug_codeByHash");
1974 self.backend.debug_code_by_hash(hash, block_id).await
1975 }
1976
1977 pub async fn debug_db_get(&self, key: String) -> Result<Option<Bytes>> {
1982 node_info!("debug_dbGet");
1983 self.backend.debug_db_get(key).await
1984 }
1985
1986 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1990 node_info!("trace_transaction");
1991 self.backend.trace_transaction(tx_hash).await
1992 }
1993
1994 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1998 node_info!("trace_block");
1999 self.backend.trace_block(block).await
2000 }
2001
2002 pub async fn trace_filter(
2006 &self,
2007 filter: TraceFilter,
2008 ) -> Result<Vec<LocalizedTransactionTrace>> {
2009 node_info!("trace_filter");
2010 self.backend.trace_filter(filter).await
2011 }
2012}
2013
2014impl EthApi {
2017 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
2021 node_info!("anvil_impersonateAccount");
2022 self.backend.impersonate(address);
2023 Ok(())
2024 }
2025
2026 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
2030 node_info!("anvil_stopImpersonatingAccount");
2031 self.backend.stop_impersonating(address);
2032 Ok(())
2033 }
2034
2035 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
2039 node_info!("anvil_autoImpersonateAccount");
2040 self.backend.auto_impersonate_account(enabled);
2041 Ok(())
2042 }
2043
2044 pub async fn anvil_impersonate_signature(
2046 &self,
2047 signature: Bytes,
2048 address: Address,
2049 ) -> Result<()> {
2050 node_info!("anvil_impersonateSignature");
2051 self.backend.impersonate_signature(signature, address).await
2052 }
2053
2054 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
2058 node_info!("anvil_getAutomine");
2059 Ok(self.miner.is_auto_mine())
2060 }
2061
2062 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
2066 node_info!("anvil_getIntervalMining");
2067 Ok(self.miner.get_interval())
2068 }
2069
2070 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
2075 node_info!("evm_setAutomine");
2076 if self.miner.is_auto_mine() {
2077 if enable_automine {
2078 return Ok(());
2079 }
2080 self.miner.set_mining_mode(MiningMode::None);
2081 } else if enable_automine {
2082 let listener = self.pool.add_ready_listener();
2083 let mode = MiningMode::instant(1_000, listener);
2084 self.miner.set_mining_mode(mode);
2085 }
2086 Ok(())
2087 }
2088
2089 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
2093 node_info!("anvil_mine");
2094 let interval = interval.map(|i| i.to::<u64>());
2095 let blocks = num_blocks.unwrap_or(U256::from(1));
2096 if blocks.is_zero() {
2097 return Ok(());
2098 }
2099
2100 self.on_blocking_task(|this| async move {
2101 for _ in 0..blocks.to::<u64>() {
2103 if let Some(interval) = interval {
2105 this.backend.time().increase_time(interval);
2106 }
2107 this.mine_one().await;
2108 }
2109 Ok(())
2110 })
2111 .await?;
2112
2113 Ok(())
2114 }
2115
2116 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
2120 node_info!("evm_setIntervalMining");
2121 let mining_mode = if secs == 0 {
2122 MiningMode::None
2123 } else {
2124 let block_time = Duration::from_secs(secs);
2125
2126 self.backend.update_interval_mine_block_time(block_time);
2128
2129 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
2130 };
2131 self.miner.set_mining_mode(mining_mode);
2132 Ok(())
2133 }
2134
2135 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
2139 node_info!("anvil_dropTransaction");
2140 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
2141 }
2142
2143 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
2147 node_info!("anvil_dropAllTransactions");
2148 self.pool.clear();
2149 Ok(())
2150 }
2151
2152 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
2158 self.reset_instance_id();
2159 node_info!("anvil_reset");
2160 if let Some(forking) = forking {
2161 self.backend.reset_fork(forking).await
2163 } else {
2164 self.backend.reset_to_in_mem().await
2167 }
2168 }
2169
2170 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
2171 node_info!("anvil_setChainId");
2172 self.backend.set_chain_id(chain_id);
2173 Ok(())
2174 }
2175
2176 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
2180 node_info!("anvil_setBalance");
2181 self.backend.set_balance(address, balance).await?;
2182 Ok(())
2183 }
2184
2185 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
2189 node_info!("anvil_addBalance");
2190 let current_balance = self.backend.get_balance(address, None).await?;
2191 self.backend.set_balance(address, current_balance + balance).await?;
2192 Ok(())
2193 }
2194
2195 async fn find_erc20_storage_slot(
2212 &self,
2213 token_address: Address,
2214 calldata: Bytes,
2215 expected_value: U256,
2216 ) -> Result<B256> {
2217 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2218
2219 let access_list_result =
2221 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2222 let access_list = access_list_result.access_list;
2223
2224 for item in access_list.0 {
2227 if item.address != token_address {
2228 continue;
2229 };
2230 for slot in &item.storage_keys {
2231 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2232 (*slot, B256::from(expected_value.to_be_bytes())),
2233 ));
2234
2235 let state_override = StateOverridesBuilder::default()
2236 .append(token_address, account_override)
2237 .build();
2238
2239 let evm_override = EvmOverrides::state(Some(state_override));
2240
2241 let Ok(result) =
2242 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2243 else {
2244 continue;
2246 };
2247
2248 let Ok(result_value) = U256::abi_decode(&result) else {
2249 continue;
2251 };
2252
2253 if result_value == expected_value {
2254 return Ok(*slot);
2255 }
2256 }
2257 }
2258
2259 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2260 }
2261
2262 pub async fn anvil_deal_erc20(
2266 &self,
2267 address: Address,
2268 token_address: Address,
2269 balance: U256,
2270 ) -> Result<()> {
2271 node_info!("anvil_dealERC20");
2272
2273 sol! {
2274 #[sol(rpc)]
2275 contract IERC20 {
2276 function balanceOf(address target) external view returns (uint256);
2277 }
2278 }
2279
2280 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2281
2282 let slot =
2284 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2285 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2286 })?;
2287
2288 self.anvil_set_storage_at(
2290 token_address,
2291 U256::from_be_bytes(slot.0),
2292 B256::from(balance.to_be_bytes()),
2293 )
2294 .await?;
2295
2296 Ok(())
2297 }
2298
2299 pub async fn anvil_set_erc20_allowance(
2303 &self,
2304 owner: Address,
2305 spender: Address,
2306 token_address: Address,
2307 amount: U256,
2308 ) -> Result<()> {
2309 node_info!("anvil_setERC20Allowance");
2310
2311 sol! {
2312 #[sol(rpc)]
2313 contract IERC20 {
2314 function allowance(address owner, address spender) external view returns (uint256);
2315 }
2316 }
2317
2318 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2319
2320 let slot =
2322 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2323 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2324 })?;
2325
2326 self.anvil_set_storage_at(
2328 token_address,
2329 U256::from_be_bytes(slot.0),
2330 B256::from(amount.to_be_bytes()),
2331 )
2332 .await?;
2333
2334 Ok(())
2335 }
2336
2337 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2341 node_info!("anvil_setCode");
2342 self.backend.set_code(address, code).await?;
2343 Ok(())
2344 }
2345
2346 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2350 node_info!("anvil_setNonce");
2351 self.backend.set_nonce(address, nonce).await?;
2352 Ok(())
2353 }
2354
2355 pub async fn anvil_set_storage_at(
2359 &self,
2360 address: Address,
2361 slot: U256,
2362 val: B256,
2363 ) -> Result<bool> {
2364 node_info!("anvil_setStorageAt");
2365 self.backend.set_storage_at(address, slot, val).await?;
2366 Ok(true)
2367 }
2368
2369 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2373 node_info!("anvil_setLoggingEnabled");
2374 self.logger.set_enabled(enable);
2375 Ok(())
2376 }
2377
2378 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2382 node_info!("anvil_setMinGasPrice");
2383 if self.backend.is_eip1559() {
2384 return Err(RpcError::invalid_params(
2385 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2386 )
2387 .into());
2388 }
2389 self.backend.set_gas_price(gas.to());
2390 Ok(())
2391 }
2392
2393 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2397 node_info!("anvil_setNextBlockBaseFeePerGas");
2398 if !self.backend.is_eip1559() {
2399 return Err(RpcError::invalid_params(
2400 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2401 )
2402 .into());
2403 }
2404 self.backend.set_base_fee(basefee.to());
2405 Ok(())
2406 }
2407
2408 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2412 node_info!("anvil_setCoinbase");
2413 self.backend.set_coinbase(address);
2414 Ok(())
2415 }
2416
2417 pub async fn anvil_dump_state(
2422 &self,
2423 preserve_historical_states: Option<bool>,
2424 ) -> Result<Bytes> {
2425 node_info!("anvil_dumpState");
2426 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2427 }
2428
2429 pub async fn serialized_state(
2431 &self,
2432 preserve_historical_states: bool,
2433 ) -> Result<SerializableState> {
2434 self.backend.serialized_state(preserve_historical_states).await
2435 }
2436
2437 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2442 node_info!("anvil_loadState");
2443 self.backend.load_state_bytes(buf).await
2444 }
2445
2446 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2450 node_info!("anvil_nodeInfo");
2451
2452 let env = self.backend.env().read();
2453 let fork_config = self.backend.get_fork();
2454 let tx_order = self.transaction_order.read();
2455 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2456
2457 Ok(NodeInfo {
2458 current_block_number: self.backend.best_number(),
2459 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2460 current_block_hash: self.backend.best_hash(),
2461 hard_fork: hard_fork.to_string(),
2462 transaction_order: match *tx_order {
2463 TransactionOrder::Fifo => "fifo".to_string(),
2464 TransactionOrder::Fees => "fees".to_string(),
2465 },
2466 environment: NodeEnvironment {
2467 base_fee: self.backend.base_fee() as u128,
2468 chain_id: self.backend.chain_id().to::<u64>(),
2469 gas_limit: self.backend.gas_limit(),
2470 gas_price: self.gas_price(),
2471 },
2472 fork_config: fork_config
2473 .map(|fork| {
2474 let config = fork.config.read();
2475
2476 NodeForkConfig {
2477 fork_url: Some(config.eth_rpc_url.clone()),
2478 fork_block_number: Some(config.block_number),
2479 fork_retry_backoff: Some(config.backoff.as_millis()),
2480 }
2481 })
2482 .unwrap_or_default(),
2483 })
2484 }
2485
2486 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2490 node_info!("anvil_metadata");
2491 let fork_config = self.backend.get_fork();
2492
2493 Ok(Metadata {
2494 client_version: CLIENT_VERSION.to_string(),
2495 chain_id: self.backend.chain_id().to::<u64>(),
2496 latest_block_hash: self.backend.best_hash(),
2497 latest_block_number: self.backend.best_number(),
2498 instance_id: *self.instance_id.read(),
2499 forked_network: fork_config.map(|cfg| ForkedNetwork {
2500 chain_id: cfg.chain_id(),
2501 fork_block_number: cfg.block_number(),
2502 fork_block_hash: cfg.block_hash(),
2503 }),
2504 snapshots: self.backend.list_state_snapshots(),
2505 })
2506 }
2507
2508 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2509 node_info!("anvil_removePoolTransactions");
2510 self.pool.remove_transactions_by_address(address);
2511 Ok(())
2512 }
2513
2514 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2528 node_info!("anvil_reorg");
2529 let depth = options.depth;
2530 let tx_block_pairs = options.tx_block_pairs;
2531
2532 let current_height = self.backend.best_number();
2534 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2535 RpcError::invalid_params(format!(
2536 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2537 )),
2538 ))?;
2539
2540 let common_block =
2542 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2543
2544 let block_pool_txs = if tx_block_pairs.is_empty() {
2547 HashMap::default()
2548 } else {
2549 let mut pairs = tx_block_pairs;
2550
2551 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2553 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2554 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2555 depth - 1
2556 ))));
2557 }
2558
2559 pairs.sort_by_key(|a| a.1);
2561
2562 let mut nonces: HashMap<Address, u64> = HashMap::default();
2565
2566 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2567 for pair in pairs {
2568 let (tx_data, block_index) = pair;
2569
2570 let pending = match tx_data {
2571 TransactionData::Raw(bytes) => {
2572 let mut data = bytes.as_ref();
2573 let decoded = FoundryTxEnvelope::decode_2718(&mut data)
2574 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2575 PendingTransaction::new(decoded)?
2576 }
2577
2578 TransactionData::JSON(request) => {
2579 let from = request.from.map(Ok).unwrap_or_else(|| {
2580 self.accounts()?
2581 .first()
2582 .copied()
2583 .ok_or(BlockchainError::NoSignerAvailable)
2584 })?;
2585
2586 let curr_nonce = nonces.entry(from).or_insert(
2588 self.get_transaction_count(
2589 from,
2590 Some(common_block.header.number.into()),
2591 )
2592 .await?,
2593 );
2594
2595 let typed = self.build_tx_request(request.into(), *curr_nonce).await?;
2597
2598 *curr_nonce += 1;
2600
2601 if self.is_impersonated(from) {
2603 let bypass_signature = self.impersonated_signature(&typed);
2604 let transaction =
2605 sign::build_typed_transaction(typed, bypass_signature)?;
2606 self.ensure_typed_transaction_supported(&transaction)?;
2607 PendingTransaction::with_impersonated(transaction, from)
2608 } else {
2609 let transaction = self.sign_request(&from, typed)?;
2610 self.ensure_typed_transaction_supported(&transaction)?;
2611 PendingTransaction::new(transaction)?
2612 }
2613 }
2614 };
2615
2616 let pooled = PoolTransaction::new(pending);
2617 txs.entry(block_index).or_default().push(Arc::new(pooled));
2618 }
2619
2620 txs
2621 };
2622
2623 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2624 Ok(())
2625 }
2626
2627 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2638 node_info!("anvil_rollback");
2639 let depth = depth.unwrap_or(1);
2640
2641 let current_height = self.backend.best_number();
2643 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2644 RpcError::invalid_params(format!(
2645 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2646 )),
2647 ))?;
2648
2649 let common_block =
2651 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2652
2653 self.backend.rollback(common_block).await?;
2654 Ok(())
2655 }
2656
2657 pub async fn evm_snapshot(&self) -> Result<U256> {
2661 node_info!("evm_snapshot");
2662 Ok(self.backend.create_state_snapshot().await)
2663 }
2664
2665 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2670 node_info!("evm_revert");
2671 self.backend.revert_state_snapshot(id).await
2672 }
2673
2674 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2678 node_info!("evm_increaseTime");
2679 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2680 }
2681
2682 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2686 node_info!("evm_setNextBlockTimestamp");
2687 self.backend.time().set_next_block_timestamp(seconds)
2688 }
2689
2690 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2695 node_info!("evm_setTime");
2696 let now = self.backend.time().current_call_timestamp();
2697 self.backend.time().reset(timestamp);
2698
2699 let offset = timestamp.saturating_sub(now);
2701 Ok(Duration::from_millis(offset).as_secs())
2702 }
2703
2704 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2708 node_info!("evm_setBlockGasLimit");
2709 self.backend.set_gas_limit(gas_limit.to());
2710 Ok(true)
2711 }
2712
2713 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2717 node_info!("anvil_setBlockTimestampInterval");
2718 self.backend.time().set_block_timestamp_interval(seconds);
2719 Ok(())
2720 }
2721
2722 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2726 node_info!("anvil_removeBlockTimestampInterval");
2727 Ok(self.backend.time().remove_block_timestamp_interval())
2728 }
2729
2730 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2737 node_info!("evm_mine");
2738
2739 self.do_evm_mine(opts).await?;
2740
2741 Ok("0x0".to_string())
2742 }
2743
2744 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2754 node_info!("evm_mine_detailed");
2755
2756 let mined_blocks = self.do_evm_mine(opts).await?;
2757
2758 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2759
2760 let latest = self.backend.best_number();
2761 for offset in (0..mined_blocks).rev() {
2762 let block_num = latest - offset;
2763 if let Some(mut block) =
2764 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2765 {
2766 let block_txs = match block.transactions_mut() {
2767 BlockTransactions::Full(txs) => txs,
2768 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2769 };
2770 for tx in block_txs.iter_mut() {
2771 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2772 && let Some(output) = receipt.out
2773 {
2774 if !receipt.inner.as_ref().status()
2776 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2777 {
2778 tx.other.insert(
2779 "revertReason".to_string(),
2780 serde_json::to_value(reason).expect("Infallible"),
2781 );
2782 }
2783 tx.other.insert(
2784 "output".to_string(),
2785 serde_json::to_value(output).expect("Infallible"),
2786 );
2787 }
2788 }
2789 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2790 blocks.push(block);
2791 }
2792 }
2793
2794 Ok(blocks)
2795 }
2796
2797 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2801 node_info!("anvil_setBlock");
2802 self.backend.set_block_number(block_number);
2803 Ok(())
2804 }
2805
2806 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2810 node_info!("anvil_setRpcUrl");
2811 if let Some(fork) = self.backend.get_fork() {
2812 let mut config = fork.config.write();
2813 let new_provider = Arc::new(
2815 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2816 |_| {
2817 TransportErrorKind::custom_str(
2818 format!("Failed to parse invalid url {url}").as_str(),
2819 )
2820 },
2821 )?, );
2824 config.provider = new_provider;
2825 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2826 config.eth_rpc_url = url;
2827 }
2828 Ok(())
2829 }
2830
2831 pub async fn anvil_enable_traces(&self) -> Result<()> {
2836 node_info!("anvil_enableTraces");
2837 Err(BlockchainError::RpcUnimplemented)
2838 }
2839
2840 pub async fn eth_send_unsigned_transaction(
2844 &self,
2845 request: WithOtherFields<TransactionRequest>,
2846 ) -> Result<TxHash> {
2847 node_info!("eth_sendUnsignedTransaction");
2848 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2850
2851 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2852
2853 let request = self.build_tx_request(request, nonce).await?;
2854
2855 let bypass_signature = self.impersonated_signature(&request);
2856 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2857
2858 self.ensure_typed_transaction_supported(&transaction)?;
2859
2860 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2861
2862 self.backend.validate_pool_transaction(&pending_transaction).await?;
2864
2865 let requires = required_marker(nonce, on_chain_nonce, from);
2866 let provides = vec![to_marker(nonce, from)];
2867
2868 self.add_pending_transaction(pending_transaction, requires, provides)
2869 }
2870
2871 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2877 node_info!("txpool_status");
2878 Ok(self.pool.txpool_status())
2879 }
2880
2881 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2888 node_info!("txpool_inspect");
2889 let mut inspect = TxpoolInspect::default();
2890
2891 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2892 let tx = &tx.pending_transaction.transaction;
2893 let to = tx.to();
2894 let gas_price = tx.max_fee_per_gas();
2895 let value = tx.value();
2896 let gas = tx.gas_limit();
2897 TxpoolInspectSummary { to, value, gas, gas_price }
2898 }
2899
2900 for pending in self.pool.ready_transactions() {
2907 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2908 let key = pending.pending_transaction.nonce().to_string();
2909 entry.insert(key, convert(pending));
2910 }
2911 for queued in self.pool.pending_transactions() {
2912 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2913 let key = queued.pending_transaction.nonce().to_string();
2914 entry.insert(key, convert(queued));
2915 }
2916 Ok(inspect)
2917 }
2918
2919 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2926 node_info!("txpool_content");
2927 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2928 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2929 let from = *tx.pending_transaction.sender();
2930 let tx = transaction_build(
2931 Some(tx.hash()),
2932 tx.pending_transaction.transaction.clone(),
2933 None,
2934 None,
2935 None,
2936 );
2937
2938 let WithOtherFields { inner: mut tx, other } = tx.0;
2939
2940 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2943
2944 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2945
2946 Ok(tx)
2947 }
2948
2949 for pending in self.pool.ready_transactions() {
2950 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2951 let key = pending.pending_transaction.nonce().to_string();
2952 entry.insert(key, convert(pending)?);
2953 }
2954 for queued in self.pool.pending_transactions() {
2955 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2956 let key = queued.pending_transaction.nonce().to_string();
2957 entry.insert(key, convert(queued)?);
2958 }
2959
2960 Ok(content)
2961 }
2962}
2963
2964impl EthApi {
2966 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2972 node_info!("wallet_getCapabilities");
2973 Ok(self.backend.get_capabilities())
2974 }
2975
2976 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2980 node_info!("anvil_addCapability");
2981 self.backend.add_capability(address);
2982 Ok(())
2983 }
2984
2985 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2986 node_info!("anvil_setExecutor");
2987 self.backend.set_executor(executor_pk)
2988 }
2989}
2990
2991impl EthApi {
2992 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2994 where
2995 C: FnOnce(Self) -> F,
2996 F: Future<Output = Result<R>> + Send + 'static,
2997 R: Send + 'static,
2998 {
2999 let (tx, rx) = oneshot::channel();
3000 let this = self.clone();
3001 let f = c(this);
3002 tokio::task::spawn_blocking(move || {
3003 tokio::runtime::Handle::current().block_on(async move {
3004 let res = f.await;
3005 let _ = tx.send(res);
3006 })
3007 });
3008 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
3009 }
3010
3011 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
3013 let mut blocks_to_mine = 1u64;
3014
3015 if let Some(opts) = opts {
3016 let timestamp = match opts {
3017 MineOptions::Timestamp(timestamp) => timestamp,
3018 MineOptions::Options { timestamp, blocks } => {
3019 if let Some(blocks) = blocks {
3020 blocks_to_mine = blocks;
3021 }
3022 timestamp
3023 }
3024 };
3025 if let Some(timestamp) = timestamp {
3026 self.evm_set_next_block_timestamp(timestamp)?;
3028 }
3029 }
3030
3031 self.on_blocking_task(|this| async move {
3034 for _ in 0..blocks_to_mine {
3036 this.mine_one().await;
3037 }
3038 Ok(())
3039 })
3040 .await?;
3041
3042 Ok(blocks_to_mine)
3043 }
3044
3045 async fn do_estimate_gas(
3046 &self,
3047 request: WithOtherFields<TransactionRequest>,
3048 block_number: Option<BlockId>,
3049 overrides: EvmOverrides,
3050 ) -> Result<u128> {
3051 let block_request = self.block_request(block_number).await?;
3052 if let BlockRequest::Number(number) = block_request
3054 && let Some(fork) = self.get_fork()
3055 && fork.predates_fork(number)
3056 {
3057 if overrides.has_state() || overrides.has_block() {
3058 return Err(BlockchainError::EvmOverrideError(
3059 "not available on past forked blocks".to_string(),
3060 ));
3061 }
3062 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
3063 }
3064
3065 self.on_blocking_task(|this| async move {
3068 this.backend
3069 .with_database_at(Some(block_request), |state, mut block| {
3070 let mut cache_db = CacheDB::new(state);
3071 if let Some(state_overrides) = overrides.state {
3072 apply_state_overrides(
3073 state_overrides.into_iter().collect(),
3074 &mut cache_db,
3075 )?;
3076 }
3077 if let Some(block_overrides) = overrides.block {
3078 cache_db.apply_block_overrides(*block_overrides, &mut block);
3079 }
3080 this.do_estimate_gas_with_state(request, &cache_db, block)
3081 })
3082 .await?
3083 })
3084 .await
3085 }
3086
3087 fn do_estimate_gas_with_state(
3091 &self,
3092 mut request: WithOtherFields<TransactionRequest>,
3093 state: &dyn DatabaseRef,
3094 block_env: BlockEnv,
3095 ) -> Result<u128> {
3096 let to = request.to.as_ref().and_then(TxKind::to);
3099
3100 let maybe_transfer = (request.input.input().is_none()
3102 || request.input.input().is_some_and(|data| data.is_empty()))
3103 && request.authorization_list.is_none()
3104 && request.access_list.is_none()
3105 && request.blob_versioned_hashes.is_none();
3106
3107 if maybe_transfer
3108 && let Some(to) = to
3109 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
3110 && target_code.as_ref().is_empty()
3111 {
3112 return Ok(MIN_TRANSACTION_GAS);
3113 }
3114
3115 let fees = FeeDetails::new(
3116 request.gas_price,
3117 request.max_fee_per_gas,
3118 request.max_priority_fee_per_gas,
3119 request.max_fee_per_blob_gas,
3120 )?
3121 .or_zero_fees();
3122
3123 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
3126
3127 let gas_price = fees.gas_price.unwrap_or_default();
3128 if gas_price > 0
3130 && let Some(from) = request.from
3131 {
3132 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
3133 if let Some(value) = request.value {
3134 if value > available_funds {
3135 return Err(InvalidTransactionError::InsufficientFunds.into());
3136 }
3137 available_funds -= value;
3139 }
3140 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
3142 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
3143 }
3144
3145 let mut call_to_estimate = request.clone();
3146 call_to_estimate.gas = Some(highest_gas_limit as u64);
3147
3148 let ethres =
3150 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3151
3152 let gas_used = match ethres.try_into()? {
3153 GasEstimationCallResult::Success(gas) => Ok(gas),
3154 GasEstimationCallResult::OutOfGas => {
3155 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3156 }
3157 GasEstimationCallResult::Revert(output) => {
3158 Err(InvalidTransactionError::Revert(output).into())
3159 }
3160 GasEstimationCallResult::EvmError(err) => {
3161 warn!(target: "node", "estimation failed due to {:?}", err);
3162 Err(BlockchainError::EvmError(err))
3163 }
3164 }?;
3165
3166 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3173
3174 let mut mid_gas_limit =
3176 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3177
3178 while (highest_gas_limit - lowest_gas_limit) > 1 {
3180 request.gas = Some(mid_gas_limit as u64);
3181 let ethres = self.backend.call_with_state(
3182 &state,
3183 request.clone(),
3184 fees.clone(),
3185 block_env.clone(),
3186 );
3187
3188 match ethres.try_into()? {
3189 GasEstimationCallResult::Success(_) => {
3190 highest_gas_limit = mid_gas_limit;
3194 }
3195 GasEstimationCallResult::OutOfGas
3196 | GasEstimationCallResult::Revert(_)
3197 | GasEstimationCallResult::EvmError(_) => {
3198 lowest_gas_limit = mid_gas_limit;
3205 }
3206 };
3207 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3209 }
3210
3211 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3212
3213 Ok(highest_gas_limit)
3214 }
3215
3216 pub fn set_transaction_order(&self, order: TransactionOrder) {
3218 *self.transaction_order.write() = order;
3219 }
3220
3221 fn transaction_priority(&self, tx: &FoundryTxEnvelope) -> TransactionPriority {
3223 self.transaction_order.read().priority(tx)
3224 }
3225
3226 pub fn chain_id(&self) -> u64 {
3228 self.backend.chain_id().to::<u64>()
3229 }
3230
3231 pub fn get_fork(&self) -> Option<ClientFork> {
3233 self.backend.get_fork()
3234 }
3235
3236 pub fn instance_id(&self) -> B256 {
3238 *self.instance_id.read()
3239 }
3240
3241 pub fn reset_instance_id(&self) {
3243 *self.instance_id.write() = B256::random();
3244 }
3245
3246 #[expect(clippy::borrowed_box)]
3248 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3249 self.signers.iter().find(|signer| signer.is_signer_for(address))
3250 }
3251
3252 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3254 self.backend.new_block_notifications()
3255 }
3256
3257 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3259 self.pool.add_ready_listener()
3260 }
3261
3262 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3264 let (tx, rx) = unbounded_channel();
3265 let mut hashes = self.new_ready_transactions();
3266
3267 let this = self.clone();
3268
3269 tokio::spawn(async move {
3270 while let Some(hash) = hashes.next().await {
3271 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3272 && tx.send(txn).is_err()
3273 {
3274 break;
3275 }
3276 }
3277 });
3278
3279 rx
3280 }
3281
3282 pub fn storage_info(&self) -> StorageInfo {
3284 StorageInfo::new(Arc::clone(&self.backend))
3285 }
3286
3287 pub fn is_fork(&self) -> bool {
3289 self.backend.is_fork()
3290 }
3291
3292 pub async fn mine_one(&self) {
3294 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3295 let outcome = self.backend.mine_block(transactions).await;
3296
3297 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3298 self.pool.on_mined_block(outcome);
3299 }
3300
3301 async fn pending_block(&self) -> AnyRpcBlock {
3303 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3304 let info = self.backend.pending_block(transactions).await;
3305 self.backend.convert_block(info.block)
3306 }
3307
3308 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3310 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3311 let BlockInfo { block, transactions, receipts: _ } =
3312 self.backend.pending_block(transactions).await;
3313
3314 let mut partial_block = self.backend.convert_block(block.clone());
3315
3316 let mut block_transactions = Vec::with_capacity(block.body.transactions.len());
3317 let base_fee = self.backend.base_fee();
3318
3319 for info in transactions {
3320 let tx = block.body.transactions.get(info.transaction_index as usize)?.clone();
3321
3322 let tx = transaction_build(
3323 Some(info.transaction_hash),
3324 tx,
3325 Some(&block),
3326 Some(info),
3327 Some(base_fee),
3328 );
3329 block_transactions.push(tx);
3330 }
3331
3332 partial_block.transactions = BlockTransactions::from(block_transactions);
3333
3334 Some(partial_block)
3335 }
3336
3337 async fn build_tx_request(
3340 &self,
3341 request: WithOtherFields<TransactionRequest>,
3342 nonce: u64,
3343 ) -> Result<FoundryTypedTx> {
3344 let mut request = Into::<FoundryTransactionRequest>::into(request);
3345 let from = request.from().or(self.accounts()?.first().copied());
3346
3347 request.chain_id().is_none().then(|| request.set_chain_id(self.chain_id()));
3349 request.nonce().is_none().then(|| request.set_nonce(nonce));
3350 request.kind().is_none().then(|| request.set_kind(TxKind::default()));
3351 if request.gas_limit().is_none() {
3352 request.set_gas_limit(
3353 self.do_estimate_gas(request.as_ref().clone(), None, EvmOverrides::default())
3354 .await
3355 .map(|v| v as u64)
3356 .unwrap_or(self.backend.gas_limit()),
3357 );
3358 }
3359
3360 if let Err((tx_type, _)) = request.missing_keys() {
3362 if matches!(tx_type, FoundryTxType::Legacy | FoundryTxType::Eip2930) {
3363 request.gas_price().is_none().then(|| request.set_gas_price(self.gas_price()));
3364 }
3365 if tx_type == FoundryTxType::Eip2930 {
3366 request
3367 .access_list()
3368 .is_none()
3369 .then(|| request.set_access_list(Default::default()));
3370 }
3371 if matches!(
3372 tx_type,
3373 FoundryTxType::Eip1559 | FoundryTxType::Eip4844 | FoundryTxType::Eip7702
3374 ) {
3375 request
3376 .max_fee_per_gas()
3377 .is_none()
3378 .then(|| request.set_max_fee_per_gas(self.gas_price()));
3379 request
3381 .max_priority_fee_per_gas()
3382 .is_none()
3383 .then(|| request.set_max_priority_fee_per_gas(Default::default()));
3384 }
3385 if tx_type == FoundryTxType::Eip4844 {
3386 request.as_ref().max_fee_per_blob_gas().is_none().then(|| {
3387 request.as_mut().set_max_fee_per_blob_gas(
3388 self.backend.fees().get_next_block_blob_base_fee_per_gas(),
3389 )
3390 });
3391 }
3392 }
3393
3394 match request
3395 .build_unsigned()
3396 .map_err(|e| BlockchainError::InvalidTransactionRequest(e.to_string()))?
3397 {
3398 FoundryTypedTx::Eip4844(TxEip4844Variant::TxEip4844(_))
3399 if !self.backend.skip_blob_validation(from) =>
3400 {
3401 Err(BlockchainError::FailedToDecodeTransaction)
3403 }
3404 res => Ok(res),
3405 }
3406 }
3407
3408 pub fn is_impersonated(&self, addr: Address) -> bool {
3410 self.backend.cheats().is_impersonated(addr)
3411 }
3412
3413 fn impersonated_signature(&self, request: &FoundryTypedTx) -> Signature {
3415 match request {
3416 FoundryTypedTx::Legacy(_) => Signature::from_scalars_and_parity(
3419 B256::with_last_byte(1),
3420 B256::with_last_byte(1),
3421 false,
3422 ),
3423 FoundryTypedTx::Eip2930(_)
3424 | FoundryTypedTx::Eip1559(_)
3425 | FoundryTypedTx::Eip7702(_)
3426 | FoundryTypedTx::Eip4844(_)
3427 | FoundryTypedTx::Deposit(_) => Signature::from_scalars_and_parity(
3428 B256::with_last_byte(1),
3429 B256::with_last_byte(1),
3430 false,
3431 ),
3432 FoundryTypedTx::Tempo(_) => todo!(),
3434 }
3435 }
3436
3437 async fn get_transaction_count(
3439 &self,
3440 address: Address,
3441 block_number: Option<BlockId>,
3442 ) -> Result<u64> {
3443 let block_request = self.block_request(block_number).await?;
3444
3445 if let BlockRequest::Number(number) = block_request
3446 && let Some(fork) = self.get_fork()
3447 && fork.predates_fork(number)
3448 {
3449 return Ok(fork.get_nonce(address, number).await?);
3450 }
3451
3452 self.backend.get_nonce(address, block_request).await
3453 }
3454
3455 async fn request_nonce(
3463 &self,
3464 request: &TransactionRequest,
3465 from: Address,
3466 ) -> Result<(u64, u64)> {
3467 let highest_nonce =
3468 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3469 let nonce = request.nonce.unwrap_or(highest_nonce);
3470
3471 Ok((nonce, highest_nonce))
3472 }
3473
3474 fn add_pending_transaction(
3476 &self,
3477 pending_transaction: PendingTransaction,
3478 requires: Vec<TxMarker>,
3479 provides: Vec<TxMarker>,
3480 ) -> Result<TxHash> {
3481 let from = *pending_transaction.sender();
3482 let priority = self.transaction_priority(&pending_transaction.transaction);
3483 let pool_transaction =
3484 PoolTransaction { requires, provides, pending_transaction, priority };
3485 let tx = self.pool.add_transaction(pool_transaction)?;
3486 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3487 Ok(*tx.hash())
3488 }
3489
3490 pub async fn state_root(&self) -> Option<B256> {
3492 self.backend.get_db().read().await.maybe_state_root()
3493 }
3494
3495 fn ensure_typed_transaction_supported(&self, tx: &FoundryTxEnvelope) -> Result<()> {
3497 match &tx {
3498 FoundryTxEnvelope::Eip2930(_) => self.backend.ensure_eip2930_active(),
3499 FoundryTxEnvelope::Eip1559(_) => self.backend.ensure_eip1559_active(),
3500 FoundryTxEnvelope::Eip4844(_) => self.backend.ensure_eip4844_active(),
3501 FoundryTxEnvelope::Eip7702(_) => self.backend.ensure_eip7702_active(),
3502 FoundryTxEnvelope::Deposit(_) => self.backend.ensure_op_deposits_active(),
3503 FoundryTxEnvelope::Legacy(_) => Ok(()),
3504 FoundryTxEnvelope::Tempo(_) => todo!(),
3506 }
3507 }
3508}
3509
3510fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3511 if provided_nonce == on_chain_nonce {
3512 return Vec::new();
3513 }
3514 let prev_nonce = provided_nonce.saturating_sub(1);
3515 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3516}
3517
3518fn convert_transact_out(out: &Option<Output>) -> Bytes {
3519 match out {
3520 None => Default::default(),
3521 Some(Output::Call(out)) => out.to_vec().into(),
3522 Some(Output::Create(out, _)) => out.to_vec().into(),
3523 }
3524}
3525
3526fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3528 let out = convert_transact_out(out);
3529 match exit {
3530 return_ok!() => Ok(out),
3531 return_revert!() => Err(InvalidTransactionError::Revert(Some(out)).into()),
3532 reason => Err(BlockchainError::EvmError(reason)),
3533 }
3534}
3535
3536fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3538 match request.kind() {
3539 Some(TxKind::Call(_)) => {
3540 MIN_TRANSACTION_GAS
3541 + request.inner().authorization_list.as_ref().map_or(0, |auths_list| {
3542 auths_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3543 })
3544 }
3545 Some(TxKind::Create) => MIN_CREATE_GAS,
3546 None => MIN_CREATE_GAS,
3548 }
3549}
3550
3551enum GasEstimationCallResult {
3553 Success(u128),
3554 OutOfGas,
3555 Revert(Option<Bytes>),
3556 EvmError(InstructionResult),
3557}
3558
3559impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3563 type Error = BlockchainError;
3564
3565 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3566 match res {
3567 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3569 Ok(Self::OutOfGas)
3570 }
3571 Err(err) => Err(err),
3572 Ok((exit, output, gas, _)) => match exit {
3573 return_ok!() => Ok(Self::Success(gas)),
3574
3575 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3577 InstructionResult::CallTooDeep
3578 | InstructionResult::OutOfFunds
3579 | InstructionResult::CreateInitCodeStartingEF00
3580 | InstructionResult::InvalidEOFInitCode
3581 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3582
3583 InstructionResult::OutOfGas
3585 | InstructionResult::MemoryOOG
3586 | InstructionResult::MemoryLimitOOG
3587 | InstructionResult::PrecompileOOG
3588 | InstructionResult::InvalidOperandOOG
3589 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3590
3591 InstructionResult::OpcodeNotFound
3593 | InstructionResult::CallNotAllowedInsideStatic
3594 | InstructionResult::StateChangeDuringStaticCall
3595 | InstructionResult::InvalidFEOpcode
3596 | InstructionResult::InvalidJump
3597 | InstructionResult::NotActivated
3598 | InstructionResult::StackUnderflow
3599 | InstructionResult::StackOverflow
3600 | InstructionResult::OutOfOffset
3601 | InstructionResult::CreateCollision
3602 | InstructionResult::OverflowPayment
3603 | InstructionResult::PrecompileError
3604 | InstructionResult::NonceOverflow
3605 | InstructionResult::CreateContractSizeLimit
3606 | InstructionResult::CreateContractStartingWithEF
3607 | InstructionResult::CreateInitCodeSizeLimit
3608 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3609 },
3610 }
3611 }
3612}