1use super::{
2 backend::mem::{BlockRequest, DatabaseRef, State},
3 sign::build_typed_transaction,
4};
5use crate::{
6 ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
7 eth::{
8 backend::{
9 self,
10 db::SerializableState,
11 mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
12 notifications::NewBlockNotifications,
13 validate::TransactionValidator,
14 },
15 error::{
16 BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
17 },
18 fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
19 macros::node_info,
20 miner::FixedBlockTimeMiner,
21 pool::{
22 Pool,
23 transactions::{
24 PoolTransaction, TransactionOrder, TransactionPriority, TxMarker, to_marker,
25 },
26 },
27 sign::{self, Signer},
28 },
29 filter::{EthFilter, Filters, LogsFilter},
30 mem::transaction_build,
31};
32use alloy_consensus::{Blob, Transaction, TrieAccount, TxEip4844Variant, transaction::Recovered};
33use alloy_dyn_abi::TypedData;
34use alloy_eips::{
35 eip2718::Encodable2718,
36 eip7910::{EthConfig, EthForkConfig},
37};
38use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
39use alloy_network::{
40 AnyRpcBlock, AnyRpcTransaction, BlockResponse, ReceiptResponse, TransactionBuilder,
41 TransactionBuilder4844, TransactionResponse, eip2718::Decodable2718,
42};
43use alloy_primitives::{
44 Address, B64, B256, Bytes, Signature, TxHash, TxKind, U64, U256,
45 map::{HashMap, HashSet},
46};
47use alloy_rpc_types::{
48 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
49 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
50 anvil::{
51 ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
52 },
53 request::TransactionRequest,
54 simulate::{SimulatePayload, SimulatedBlock},
55 state::{AccountOverride, EvmOverrides, StateOverridesBuilder},
56 trace::{
57 filter::TraceFilter,
58 geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
59 parity::{LocalizedTransactionTrace, TraceResultsWithTransactionHash, TraceType},
60 },
61 txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
62};
63use alloy_rpc_types_eth::FillTransaction;
64use alloy_serde::WithOtherFields;
65use alloy_sol_types::{SolCall, SolValue, sol};
66use alloy_transport::TransportErrorKind;
67use anvil_core::{
68 eth::{
69 EthRequest,
70 block::BlockInfo,
71 transaction::{MaybeImpersonatedTransaction, PendingTransaction},
72 },
73 types::{ReorgOptions, TransactionData},
74};
75use anvil_rpc::{error::RpcError, response::ResponseResult};
76use foundry_common::provider::ProviderBuilder;
77use foundry_evm::decode::RevertDecoder;
78use foundry_primitives::{
79 FoundryTransactionRequest, FoundryTxEnvelope, FoundryTxReceipt, FoundryTxType, FoundryTypedTx,
80};
81use futures::{
82 StreamExt, TryFutureExt,
83 channel::{mpsc::Receiver, oneshot},
84};
85use parking_lot::RwLock;
86use revm::{
87 context::BlockEnv,
88 context_interface::{block::BlobExcessGasAndPrice, result::Output},
89 database::CacheDB,
90 interpreter::{InstructionResult, return_ok, return_revert},
91 primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
92};
93use std::{sync::Arc, time::Duration};
94use tokio::{
95 sync::mpsc::{UnboundedReceiver, unbounded_channel},
96 try_join,
97};
98
99pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
101
102#[derive(Clone)]
106pub struct EthApi {
107 pool: Arc<Pool>,
109 pub backend: Arc<backend::mem::Backend>,
112 is_mining: bool,
114 signers: Arc<Vec<Box<dyn Signer>>>,
116 fee_history_cache: FeeHistoryCache,
118 fee_history_limit: u64,
120 miner: Miner,
125 logger: LoggingManager,
127 filters: Filters,
129 transaction_order: Arc<RwLock<TransactionOrder>>,
131 net_listening: bool,
133 instance_id: Arc<RwLock<B256>>,
135}
136
137impl EthApi {
138 #[expect(clippy::too_many_arguments)]
140 pub fn new(
141 pool: Arc<Pool>,
142 backend: Arc<backend::mem::Backend>,
143 signers: Arc<Vec<Box<dyn Signer>>>,
144 fee_history_cache: FeeHistoryCache,
145 fee_history_limit: u64,
146 miner: Miner,
147 logger: LoggingManager,
148 filters: Filters,
149 transactions_order: TransactionOrder,
150 ) -> Self {
151 Self {
152 pool,
153 backend,
154 is_mining: true,
155 signers,
156 fee_history_cache,
157 fee_history_limit,
158 miner,
159 logger,
160 filters,
161 net_listening: true,
162 transaction_order: Arc::new(RwLock::new(transactions_order)),
163 instance_id: Arc::new(RwLock::new(B256::random())),
164 }
165 }
166
167 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
169 trace!(target: "rpc::api", "executing eth request");
170 let response = match request.clone() {
171 EthRequest::EthProtocolVersion(()) => self.protocol_version().to_rpc_result(),
172 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
173 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
174 EthRequest::EthGetAccount(addr, block) => {
175 self.get_account(addr, block).await.to_rpc_result()
176 }
177 EthRequest::EthGetAccountInfo(addr, block) => {
178 self.get_account_info(addr, block).await.to_rpc_result()
179 }
180 EthRequest::EthGetBalance(addr, block) => {
181 self.balance(addr, block).await.to_rpc_result()
182 }
183 EthRequest::EthGetTransactionByHash(hash) => {
184 self.transaction_by_hash(hash).await.to_rpc_result()
185 }
186 EthRequest::EthSendTransaction(request) => {
187 self.send_transaction(*request).await.to_rpc_result()
188 }
189 EthRequest::EthSendTransactionSync(request) => {
190 self.send_transaction_sync(*request).await.to_rpc_result()
191 }
192 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
193 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
194 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
195 EthRequest::EthHashrate(()) => self.hashrate().to_rpc_result(),
196 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
197 EthRequest::EthMaxPriorityFeePerGas(_) => {
198 self.gas_max_priority_fee_per_gas().to_rpc_result()
199 }
200 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
201 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
202 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
203 EthRequest::EthCoinbase(()) => self.author().to_rpc_result(),
204 EthRequest::EthGetStorageAt(addr, slot, block) => {
205 self.storage_at(addr, slot, block).await.to_rpc_result()
206 }
207 EthRequest::EthGetBlockByHash(hash, full) => {
208 if full {
209 self.block_by_hash_full(hash).await.to_rpc_result()
210 } else {
211 self.block_by_hash(hash).await.to_rpc_result()
212 }
213 }
214 EthRequest::EthGetBlockByNumber(num, full) => {
215 if full {
216 self.block_by_number_full(num).await.to_rpc_result()
217 } else {
218 self.block_by_number(num).await.to_rpc_result()
219 }
220 }
221 EthRequest::EthGetTransactionCount(addr, block) => {
222 self.transaction_count(addr, block).await.to_rpc_result()
223 }
224 EthRequest::EthGetTransactionCountByHash(hash) => {
225 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
226 }
227 EthRequest::EthGetTransactionCountByNumber(num) => {
228 self.block_transaction_count_by_number(num).await.to_rpc_result()
229 }
230 EthRequest::EthGetUnclesCountByHash(hash) => {
231 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
232 }
233 EthRequest::EthGetUnclesCountByNumber(num) => {
234 self.block_uncles_count_by_number(num).await.to_rpc_result()
235 }
236 EthRequest::EthGetCodeAt(addr, block) => {
237 self.get_code(addr, block).await.to_rpc_result()
238 }
239 EthRequest::EthGetProof(addr, keys, block) => {
240 self.get_proof(addr, keys, block).await.to_rpc_result()
241 }
242 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
243 EthRequest::PersonalSign(content, addr) => {
244 self.sign(addr, content).await.to_rpc_result()
245 }
246 EthRequest::EthSignTransaction(request) => {
247 self.sign_transaction(*request).await.to_rpc_result()
248 }
249 EthRequest::EthSignTypedData(addr, data) => {
250 self.sign_typed_data(addr, data).await.to_rpc_result()
251 }
252 EthRequest::EthSignTypedDataV3(addr, data) => {
253 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
254 }
255 EthRequest::EthSignTypedDataV4(addr, data) => {
256 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
257 }
258 EthRequest::EthSendRawTransaction(tx) => {
259 self.send_raw_transaction(tx).await.to_rpc_result()
260 }
261 EthRequest::EthSendRawTransactionSync(tx) => {
262 self.send_raw_transaction_sync(tx).await.to_rpc_result()
263 }
264 EthRequest::EthCall(call, block, state_override, block_overrides) => self
265 .call(call, block, EvmOverrides::new(state_override, block_overrides))
266 .await
267 .to_rpc_result(),
268 EthRequest::EthSimulateV1(simulation, block) => {
269 self.simulate_v1(simulation, block).await.to_rpc_result()
270 }
271 EthRequest::EthCreateAccessList(call, block) => {
272 self.create_access_list(call, block).await.to_rpc_result()
273 }
274 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
275 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
276 .await
277 .to_rpc_result(),
278 EthRequest::EthFillTransaction(request) => {
279 self.fill_transaction(request).await.to_rpc_result()
280 }
281 EthRequest::EthGetRawTransactionByHash(hash) => {
282 self.raw_transaction(hash).await.to_rpc_result()
283 }
284 EthRequest::GetBlobByHash(hash) => {
285 self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
286 }
287 EthRequest::GetBlobByTransactionHash(hash) => {
288 self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
289 }
290 EthRequest::GetGenesisTime(()) => self.anvil_get_genesis_time().to_rpc_result(),
291 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
292 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
293 }
294 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
295 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
296 }
297 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
298 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
299 }
300 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
301 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
302 }
303 EthRequest::EthGetTransactionReceipt(tx) => {
304 self.transaction_receipt(tx).await.to_rpc_result()
305 }
306 EthRequest::EthGetBlockReceipts(number) => {
307 self.block_receipts(number).await.to_rpc_result()
308 }
309 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
310 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
311 }
312 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
313 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
314 }
315 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
316 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
317 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
318 EthRequest::EthConfig(_) => self.config().to_rpc_result(),
319 EthRequest::EthSubmitWork(nonce, pow, digest) => {
320 self.submit_work(nonce, pow, digest).to_rpc_result()
321 }
322 EthRequest::EthSubmitHashRate(rate, id) => {
323 self.submit_hashrate(rate, id).to_rpc_result()
324 }
325 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
326 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
327 }
328 EthRequest::DebugGetRawTransaction(hash) => {
330 self.raw_transaction(hash).await.to_rpc_result()
331 }
332 EthRequest::DebugTraceTransaction(tx, opts) => {
334 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
335 }
336 EthRequest::DebugTraceCall(tx, block, opts) => {
338 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
339 }
340 EthRequest::DebugCodeByHash(hash, block) => {
341 self.debug_code_by_hash(hash, block).await.to_rpc_result()
342 }
343 EthRequest::DebugDbGet(key) => self.debug_db_get(key).await.to_rpc_result(),
344 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
345 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
346 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
347 EthRequest::TraceReplayBlockTransactions(block, trace_types) => {
348 self.trace_replay_block_transactions(block, trace_types).await.to_rpc_result()
349 }
350 EthRequest::ImpersonateAccount(addr) => {
351 self.anvil_impersonate_account(addr).await.to_rpc_result()
352 }
353 EthRequest::StopImpersonatingAccount(addr) => {
354 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
355 }
356 EthRequest::AutoImpersonateAccount(enable) => {
357 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
358 }
359 EthRequest::ImpersonateSignature(signature, address) => {
360 self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
361 }
362 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
363 EthRequest::Mine(blocks, interval) => {
364 self.anvil_mine(blocks, interval).await.to_rpc_result()
365 }
366 EthRequest::SetAutomine(enabled) => {
367 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
368 }
369 EthRequest::SetIntervalMining(interval) => {
370 self.anvil_set_interval_mining(interval).to_rpc_result()
371 }
372 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
373 EthRequest::DropTransaction(tx) => {
374 self.anvil_drop_transaction(tx).await.to_rpc_result()
375 }
376 EthRequest::DropAllTransactions() => {
377 self.anvil_drop_all_transactions().await.to_rpc_result()
378 }
379 EthRequest::Reset(fork) => {
380 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
381 }
382 EthRequest::SetBalance(addr, val) => {
383 self.anvil_set_balance(addr, val).await.to_rpc_result()
384 }
385 EthRequest::AddBalance(addr, val) => {
386 self.anvil_add_balance(addr, val).await.to_rpc_result()
387 }
388 EthRequest::DealERC20(addr, token_addr, val) => {
389 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
390 }
391 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
392 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
393 .await
394 .to_rpc_result(),
395 EthRequest::SetCode(addr, code) => {
396 self.anvil_set_code(addr, code).await.to_rpc_result()
397 }
398 EthRequest::SetNonce(addr, nonce) => {
399 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
400 }
401 EthRequest::SetStorageAt(addr, slot, val) => {
402 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
403 }
404 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
405 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
406 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
407 EthRequest::SetMinGasPrice(gas) => {
408 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
409 }
410 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
411 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
412 }
413 EthRequest::DumpState(preserve_historical_states) => self
414 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
415 .await
416 .to_rpc_result(),
417 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
418 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
419 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
420 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
421 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
422 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
423 EthRequest::EvmSetNextBlockTimeStamp(time) => {
424 if time >= U256::from(u64::MAX) {
425 return ResponseResult::Error(RpcError::invalid_params(
426 "The timestamp is too big",
427 ));
428 }
429 let time = time.to::<u64>();
430 self.evm_set_next_block_timestamp(time).to_rpc_result()
431 }
432 EthRequest::EvmSetTime(timestamp) => {
433 if timestamp >= U256::from(u64::MAX) {
434 return ResponseResult::Error(RpcError::invalid_params(
435 "The timestamp is too big",
436 ));
437 }
438 let time = timestamp.to::<u64>();
439 self.evm_set_time(time).to_rpc_result()
440 }
441 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
442 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
443 }
444 EthRequest::EvmSetBlockTimeStampInterval(time) => {
445 self.evm_set_block_timestamp_interval(time).to_rpc_result()
446 }
447 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
448 self.evm_remove_block_timestamp_interval().to_rpc_result()
449 }
450 EthRequest::EvmMine(mine) => {
451 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
452 }
453 EthRequest::EvmMineDetailed(mine) => {
454 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
455 }
456 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
457 EthRequest::EthSendUnsignedTransaction(tx) => {
458 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
459 }
460 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
461 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
462 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
463 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
464 EthRequest::EthNewPendingTransactionFilter(_) => {
465 self.new_pending_transaction_filter().await.to_rpc_result()
466 }
467 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
468 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
469 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
470 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
471 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
472 EthRequest::ErigonGetHeaderByNumber(num) => {
473 self.erigon_get_header_by_number(num).await.to_rpc_result()
474 }
475 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
476 EthRequest::OtsGetInternalOperations(hash) => {
477 self.ots_get_internal_operations(hash).await.to_rpc_result()
478 }
479 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
480 EthRequest::OtsTraceTransaction(hash) => {
481 self.ots_trace_transaction(hash).await.to_rpc_result()
482 }
483 EthRequest::OtsGetTransactionError(hash) => {
484 self.ots_get_transaction_error(hash).await.to_rpc_result()
485 }
486 EthRequest::OtsGetBlockDetails(num) => {
487 self.ots_get_block_details(num).await.to_rpc_result()
488 }
489 EthRequest::OtsGetBlockDetailsByHash(hash) => {
490 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
491 }
492 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
493 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
494 }
495 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
496 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
497 }
498 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
499 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
500 }
501 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
502 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
503 }
504 EthRequest::EthGetTransactionBySenderAndNonce(sender, nonce) => {
505 self.transaction_by_sender_and_nonce(sender, nonce).await.to_rpc_result()
506 }
507 EthRequest::OtsGetContractCreator(address) => {
508 self.ots_get_contract_creator(address).await.to_rpc_result()
509 }
510 EthRequest::RemovePoolTransactions(address) => {
511 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
512 }
513 EthRequest::Reorg(reorg_options) => {
514 self.anvil_reorg(reorg_options).await.to_rpc_result()
515 }
516 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
517 };
518
519 if let ResponseResult::Error(err) = &response {
520 node_info!("\nRPC request failed:");
521 node_info!(" Request: {:?}", request);
522 node_info!(" Error: {}\n", err);
523 }
524
525 response
526 }
527
528 fn sign_request(&self, from: &Address, request: FoundryTypedTx) -> Result<FoundryTxEnvelope> {
529 match request {
530 FoundryTypedTx::Deposit(_) => {
531 let nil_signature = Signature::from_scalars_and_parity(
532 B256::with_last_byte(1),
533 B256::with_last_byte(1),
534 false,
535 );
536 return build_typed_transaction(request, nil_signature);
537 }
538 _ => {
539 for signer in self.signers.iter() {
540 if signer.accounts().contains(from) {
541 let signature = signer.sign_transaction(request.clone(), from)?;
542 return build_typed_transaction(request, signature);
543 }
544 }
545 }
546 }
547 Err(BlockchainError::NoSignerAvailable)
548 }
549
550 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
551 let block_request = match block_number {
552 Some(BlockId::Number(BlockNumber::Pending)) => {
553 let pending_txs = self.pool.ready_transactions().collect();
554 BlockRequest::Pending(pending_txs)
555 }
556 _ => {
557 let number = self.backend.ensure_block_number(block_number).await?;
558 BlockRequest::Number(number)
559 }
560 };
561 Ok(block_request)
562 }
563
564 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
565 match self.pool.get_transaction(hash) {
566 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
567 None => match self.backend.transaction_by_hash(hash).await? {
568 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
569 None => Ok(None),
570 },
571 }
572 }
573
574 pub fn client_version(&self) -> Result<String> {
578 node_info!("web3_clientVersion");
579 Ok(CLIENT_VERSION.to_string())
580 }
581
582 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
586 node_info!("web3_sha3");
587 let hash = alloy_primitives::keccak256(bytes.as_ref());
588 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
589 }
590
591 pub fn protocol_version(&self) -> Result<u64> {
595 node_info!("eth_protocolVersion");
596 Ok(1)
597 }
598
599 pub fn hashrate(&self) -> Result<U256> {
603 node_info!("eth_hashrate");
604 Ok(U256::ZERO)
605 }
606
607 pub fn author(&self) -> Result<Address> {
611 node_info!("eth_coinbase");
612 Ok(self.backend.coinbase())
613 }
614
615 pub fn is_mining(&self) -> Result<bool> {
619 node_info!("eth_mining");
620 Ok(self.is_mining)
621 }
622
623 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
629 node_info!("eth_chainId");
630 Ok(Some(self.backend.chain_id().to::<U64>()))
631 }
632
633 pub fn network_id(&self) -> Result<Option<String>> {
637 node_info!("eth_networkId");
638 let chain_id = self.backend.chain_id().to::<u64>();
639 Ok(Some(format!("{chain_id}")))
640 }
641
642 pub fn net_listening(&self) -> Result<bool> {
646 node_info!("net_listening");
647 Ok(self.net_listening)
648 }
649
650 fn eth_gas_price(&self) -> Result<U256> {
652 node_info!("eth_gasPrice");
653 Ok(U256::from(self.gas_price()))
654 }
655
656 pub fn gas_price(&self) -> u128 {
658 if self.backend.is_eip1559() {
659 if self.backend.is_min_priority_fee_enforced() {
660 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
661 } else {
662 self.backend.base_fee() as u128
663 }
664 } else {
665 self.backend.fees().raw_gas_price()
666 }
667 }
668
669 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
671 Ok(self.backend.excess_blob_gas_and_price())
672 }
673
674 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
679 self.max_priority_fee_per_gas()
680 }
681
682 pub fn blob_base_fee(&self) -> Result<U256> {
686 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
687 }
688
689 pub fn gas_limit(&self) -> U256 {
691 U256::from(self.backend.gas_limit())
692 }
693
694 pub fn accounts(&self) -> Result<Vec<Address>> {
698 node_info!("eth_accounts");
699 let mut unique = HashSet::new();
700 let mut accounts: Vec<Address> = Vec::new();
701 for signer in self.signers.iter() {
702 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
703 }
704 accounts.extend(
705 self.backend
706 .cheats()
707 .impersonated_accounts()
708 .into_iter()
709 .filter(|acc| unique.insert(*acc)),
710 );
711 Ok(accounts.into_iter().collect())
712 }
713
714 pub fn block_number(&self) -> Result<U256> {
718 node_info!("eth_blockNumber");
719 Ok(U256::from(self.backend.best_number()))
720 }
721
722 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
726 node_info!("eth_getBalance");
727 let block_request = self.block_request(block_number).await?;
728
729 if let BlockRequest::Number(number) = block_request
731 && let Some(fork) = self.get_fork()
732 && fork.predates_fork(number)
733 {
734 return Ok(fork.get_balance(address, number).await?);
735 }
736
737 self.backend.get_balance(address, Some(block_request)).await
738 }
739
740 pub async fn get_account(
744 &self,
745 address: Address,
746 block_number: Option<BlockId>,
747 ) -> Result<TrieAccount> {
748 node_info!("eth_getAccount");
749 let block_request = self.block_request(block_number).await?;
750
751 if let BlockRequest::Number(number) = block_request
753 && let Some(fork) = self.get_fork()
754 && fork.predates_fork(number)
755 {
756 return Ok(fork.get_account(address, number).await?);
757 }
758
759 self.backend.get_account_at_block(address, Some(block_request)).await
760 }
761
762 pub async fn get_account_info(
766 &self,
767 address: Address,
768 block_number: Option<BlockId>,
769 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
770 node_info!("eth_getAccountInfo");
771
772 if let Some(fork) = self.get_fork() {
773 let block_request = self.block_request(block_number).await?;
774 if let BlockRequest::Number(number) = block_request {
776 trace!(target: "node", "get_account_info: fork block {}, requested block {number}", fork.block_number());
777 return if fork.predates_fork(number) {
778 let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
781 let code = fork.get_code(address, number).map_err(BlockchainError::from);
782 let nonce = self.get_transaction_count(address, Some(number.into()));
783 let (balance, code, nonce) = try_join!(balance, code, nonce)?;
784
785 Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code })
786 } else {
787 let account_info = self.backend.get_account(address).await?;
790 let code = self.backend.get_code(address, Some(block_request)).await?;
791 Ok(alloy_rpc_types::eth::AccountInfo {
792 balance: account_info.balance,
793 nonce: account_info.nonce,
794 code,
795 })
796 };
797 }
798 }
799
800 let account = self.get_account(address, block_number);
801 let code = self.get_code(address, block_number);
802 let (account, code) = try_join!(account, code)?;
803 Ok(alloy_rpc_types::eth::AccountInfo {
804 balance: account.balance,
805 nonce: account.nonce,
806 code,
807 })
808 }
809 pub async fn storage_at(
813 &self,
814 address: Address,
815 index: U256,
816 block_number: Option<BlockId>,
817 ) -> Result<B256> {
818 node_info!("eth_getStorageAt");
819 let block_request = self.block_request(block_number).await?;
820
821 if let BlockRequest::Number(number) = block_request
823 && let Some(fork) = self.get_fork()
824 && fork.predates_fork(number)
825 {
826 return Ok(B256::from(
827 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
828 ));
829 }
830
831 self.backend.storage_at(address, index, Some(block_request)).await
832 }
833
834 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
838 node_info!("eth_getBlockByHash");
839 self.backend.block_by_hash(hash).await
840 }
841
842 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
846 node_info!("eth_getBlockByHash");
847 self.backend.block_by_hash_full(hash).await
848 }
849
850 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
854 node_info!("eth_getBlockByNumber");
855 if number == BlockNumber::Pending {
856 return Ok(Some(self.pending_block().await));
857 }
858
859 self.backend.block_by_number(number).await
860 }
861
862 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
866 node_info!("eth_getBlockByNumber");
867 if number == BlockNumber::Pending {
868 return Ok(self.pending_block_full().await);
869 }
870 self.backend.block_by_number_full(number).await
871 }
872
873 pub async fn transaction_count(
880 &self,
881 address: Address,
882 block_number: Option<BlockId>,
883 ) -> Result<U256> {
884 node_info!("eth_getTransactionCount");
885 self.get_transaction_count(address, block_number).await.map(U256::from)
886 }
887
888 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
892 node_info!("eth_getBlockTransactionCountByHash");
893 let block = self.backend.block_by_hash(hash).await?;
894 let txs = block.map(|b| match b.transactions() {
895 BlockTransactions::Full(txs) => U256::from(txs.len()),
896 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
897 BlockTransactions::Uncle => U256::from(0),
898 });
899 Ok(txs)
900 }
901
902 pub async fn block_transaction_count_by_number(
906 &self,
907 block_number: BlockNumber,
908 ) -> Result<Option<U256>> {
909 node_info!("eth_getBlockTransactionCountByNumber");
910 let block_request = self.block_request(Some(block_number.into())).await?;
911 if let BlockRequest::Pending(txs) = block_request {
912 let block = self.backend.pending_block(txs).await;
913 return Ok(Some(U256::from(block.block.body.transactions.len())));
914 }
915 let block = self.backend.block_by_number(block_number).await?;
916 let txs = block.map(|b| match b.transactions() {
917 BlockTransactions::Full(txs) => U256::from(txs.len()),
918 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
919 BlockTransactions::Uncle => U256::from(0),
920 });
921 Ok(txs)
922 }
923
924 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
928 node_info!("eth_getUncleCountByBlockHash");
929 let block =
930 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
931 Ok(U256::from(block.uncles.len()))
932 }
933
934 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
938 node_info!("eth_getUncleCountByBlockNumber");
939 let block = self
940 .backend
941 .block_by_number(block_number)
942 .await?
943 .ok_or(BlockchainError::BlockNotFound)?;
944 Ok(U256::from(block.uncles.len()))
945 }
946
947 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
951 node_info!("eth_getCode");
952 let block_request = self.block_request(block_number).await?;
953 if let BlockRequest::Number(number) = block_request
955 && let Some(fork) = self.get_fork()
956 && fork.predates_fork(number)
957 {
958 return Ok(fork.get_code(address, number).await?);
959 }
960 self.backend.get_code(address, Some(block_request)).await
961 }
962
963 pub async fn get_proof(
968 &self,
969 address: Address,
970 keys: Vec<B256>,
971 block_number: Option<BlockId>,
972 ) -> Result<EIP1186AccountProofResponse> {
973 node_info!("eth_getProof");
974 let block_request = self.block_request(block_number).await?;
975
976 if let BlockRequest::Number(number) = block_request
979 && let Some(fork) = self.get_fork()
980 && fork.predates_fork_inclusive(number)
981 {
982 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
983 }
984
985 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
986 Ok(proof)
987 }
988
989 pub async fn sign_typed_data(
993 &self,
994 _address: Address,
995 _data: serde_json::Value,
996 ) -> Result<String> {
997 node_info!("eth_signTypedData");
998 Err(BlockchainError::RpcUnimplemented)
999 }
1000
1001 pub async fn sign_typed_data_v3(
1005 &self,
1006 _address: Address,
1007 _data: serde_json::Value,
1008 ) -> Result<String> {
1009 node_info!("eth_signTypedData_v3");
1010 Err(BlockchainError::RpcUnimplemented)
1011 }
1012
1013 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
1017 node_info!("eth_signTypedData_v4");
1018 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1019 let signature = signer.sign_typed_data(address, data).await?;
1020 let signature = alloy_primitives::hex::encode(signature.as_bytes());
1021 Ok(format!("0x{signature}"))
1022 }
1023
1024 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1028 node_info!("eth_sign");
1029 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1030 let signature =
1031 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1032 Ok(format!("0x{signature}"))
1033 }
1034
1035 pub async fn sign_transaction(
1039 &self,
1040 request: WithOtherFields<TransactionRequest>,
1041 ) -> Result<String> {
1042 node_info!("eth_signTransaction");
1043
1044 let from = request.from.map(Ok).unwrap_or_else(|| {
1045 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1046 })?;
1047
1048 let (nonce, _) = self.request_nonce(&request, from).await?;
1049
1050 let request = self.build_tx_request(request, nonce).await?;
1051
1052 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1053 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1054 }
1055
1056 pub async fn send_transaction(
1060 &self,
1061 request: WithOtherFields<TransactionRequest>,
1062 ) -> Result<TxHash> {
1063 node_info!("eth_sendTransaction");
1064
1065 let from = request.from.map(Ok).unwrap_or_else(|| {
1066 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1067 })?;
1068 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1069
1070 let request = self.build_tx_request(request, nonce).await?;
1071
1072 let pending_transaction = if self.is_impersonated(from) {
1074 let bypass_signature = self.impersonated_signature(&request);
1075 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1076 self.ensure_typed_transaction_supported(&transaction)?;
1077 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1078 PendingTransaction::with_impersonated(transaction, from)
1079 } else {
1080 let transaction = self.sign_request(&from, request)?;
1081 self.ensure_typed_transaction_supported(&transaction)?;
1082 PendingTransaction::new(transaction)?
1083 };
1084 self.backend.validate_pool_transaction(&pending_transaction).await?;
1086
1087 let requires = required_marker(nonce, on_chain_nonce, from);
1088 let provides = vec![to_marker(nonce, from)];
1089 debug_assert!(requires != provides);
1090
1091 self.add_pending_transaction(pending_transaction, requires, provides)
1092 }
1093
1094 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
1096 let mut stream = self.new_block_notifications();
1097 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1099 return Ok(receipt);
1100 }
1101 while let Some(notification) = stream.next().await {
1102 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1103 && block.body.transactions.iter().any(|tx| tx.hash() == hash)
1104 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1105 {
1106 return Ok(receipt);
1107 }
1108 }
1109
1110 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1111 }
1112
1113 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
1115 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1116 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1117 .await
1118 .unwrap_or_else(|_elapsed| {
1119 Err(BlockchainError::TransactionConfirmationTimeout {
1120 hash,
1121 duration: TIMEOUT_DURATION,
1122 })
1123 })
1124 }
1125
1126 pub async fn send_transaction_sync(
1130 &self,
1131 request: WithOtherFields<TransactionRequest>,
1132 ) -> Result<FoundryTxReceipt> {
1133 node_info!("eth_sendTransactionSync");
1134 let hash = self.send_transaction(request).await?;
1135
1136 let receipt = self.check_transaction_inclusion(hash).await?;
1137
1138 Ok(receipt)
1139 }
1140
1141 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1145 node_info!("eth_sendRawTransaction");
1146 let mut data = tx.as_ref();
1147 if data.is_empty() {
1148 return Err(BlockchainError::EmptyRawTransactionData);
1149 }
1150
1151 let transaction = FoundryTxEnvelope::decode_2718(&mut data)
1152 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1153
1154 self.ensure_typed_transaction_supported(&transaction)?;
1155
1156 let pending_transaction = PendingTransaction::new(transaction)?;
1157
1158 self.backend.validate_pool_transaction(&pending_transaction).await?;
1160
1161 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1162 let from = *pending_transaction.sender();
1163 let nonce = pending_transaction.transaction.nonce();
1164 let requires = required_marker(nonce, on_chain_nonce, from);
1165
1166 let priority = self.transaction_priority(&pending_transaction.transaction);
1167 let pool_transaction = PoolTransaction {
1168 requires,
1169 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1170 pending_transaction,
1171 priority,
1172 };
1173
1174 let tx = self.pool.add_transaction(pool_transaction)?;
1175 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1176 Ok(*tx.hash())
1177 }
1178
1179 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<FoundryTxReceipt> {
1183 node_info!("eth_sendRawTransactionSync");
1184
1185 let hash = self.send_raw_transaction(tx).await?;
1186 let receipt = self.check_transaction_inclusion(hash).await?;
1187
1188 Ok(receipt)
1189 }
1190
1191 pub async fn call(
1195 &self,
1196 request: WithOtherFields<TransactionRequest>,
1197 block_number: Option<BlockId>,
1198 overrides: EvmOverrides,
1199 ) -> Result<Bytes> {
1200 node_info!("eth_call");
1201 let block_request = self.block_request(block_number).await?;
1202 if let BlockRequest::Number(number) = block_request
1204 && let Some(fork) = self.get_fork()
1205 && fork.predates_fork(number)
1206 {
1207 if overrides.has_state() || overrides.has_block() {
1208 return Err(BlockchainError::EvmOverrideError(
1209 "not available on past forked blocks".to_string(),
1210 ));
1211 }
1212 return Ok(fork.call(&request, Some(number.into())).await?);
1213 }
1214
1215 let fees = FeeDetails::new(
1216 request.gas_price,
1217 request.max_fee_per_gas,
1218 request.max_priority_fee_per_gas,
1219 request.max_fee_per_blob_gas,
1220 )?
1221 .or_zero_fees();
1222 self.on_blocking_task(|this| async move {
1225 let (exit, out, gas, _) =
1226 this.backend.call(request, fees, Some(block_request), overrides).await?;
1227 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1228
1229 ensure_return_ok(exit, &out)
1230 })
1231 .await
1232 }
1233
1234 pub async fn simulate_v1(
1235 &self,
1236 request: SimulatePayload,
1237 block_number: Option<BlockId>,
1238 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1239 node_info!("eth_simulateV1");
1240 let block_request = self.block_request(block_number).await?;
1241 if let BlockRequest::Number(number) = block_request
1243 && let Some(fork) = self.get_fork()
1244 && fork.predates_fork(number)
1245 {
1246 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1247 }
1248
1249 self.on_blocking_task(|this| async move {
1252 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1253 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1254
1255 Ok(simulated_blocks)
1256 })
1257 .await
1258 }
1259
1260 pub async fn create_access_list(
1274 &self,
1275 mut request: WithOtherFields<TransactionRequest>,
1276 block_number: Option<BlockId>,
1277 ) -> Result<AccessListResult> {
1278 node_info!("eth_createAccessList");
1279 let block_request = self.block_request(block_number).await?;
1280 if let BlockRequest::Number(number) = block_request
1282 && let Some(fork) = self.get_fork()
1283 && fork.predates_fork(number)
1284 {
1285 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1286 }
1287
1288 self.backend
1289 .with_database_at(Some(block_request), |state, block_env| {
1290 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1291 &state,
1292 request.clone(),
1293 FeeDetails::zero(),
1294 block_env.clone(),
1295 )?;
1296 ensure_return_ok(exit, &out)?;
1297
1298 request.access_list = Some(access_list.clone());
1300
1301 let (exit, out, gas_used, _) = self.backend.call_with_state(
1302 &state,
1303 request.clone(),
1304 FeeDetails::zero(),
1305 block_env,
1306 )?;
1307 ensure_return_ok(exit, &out)?;
1308
1309 Ok(AccessListResult {
1310 access_list: AccessList(access_list.0),
1311 gas_used: U256::from(gas_used),
1312 error: None,
1313 })
1314 })
1315 .await?
1316 }
1317
1318 pub async fn estimate_gas(
1323 &self,
1324 request: WithOtherFields<TransactionRequest>,
1325 block_number: Option<BlockId>,
1326 overrides: EvmOverrides,
1327 ) -> Result<U256> {
1328 node_info!("eth_estimateGas");
1329 self.do_estimate_gas(
1330 request,
1331 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1332 overrides,
1333 )
1334 .await
1335 .map(U256::from)
1336 }
1337
1338 pub async fn fill_transaction(
1345 &self,
1346 mut request: WithOtherFields<TransactionRequest>,
1347 ) -> Result<FillTransaction<AnyRpcTransaction>> {
1348 node_info!("eth_fillTransaction");
1349
1350 let from = match request.as_ref().from() {
1351 Some(from) => from,
1352 None => self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)?,
1353 };
1354
1355 let nonce = if let Some(nonce) = request.as_ref().nonce() {
1356 nonce
1357 } else {
1358 self.request_nonce(&request, from).await?.0
1359 };
1360
1361 if request.as_ref().gas_limit().is_none() {
1365 let estimated_gas =
1366 self.estimate_gas(request.clone(), None, EvmOverrides::default()).await?;
1367 request.as_mut().set_gas_limit(estimated_gas.to());
1368 }
1369
1370 let typed_tx = self.build_tx_request(request, nonce).await?;
1371 let tx = build_typed_transaction(
1372 typed_tx,
1373 Signature::new(Default::default(), Default::default(), false),
1374 )?;
1375
1376 let raw = tx.encoded_2718().to_vec().into();
1377
1378 let mut tx =
1379 transaction_build(None, MaybeImpersonatedTransaction::new(tx), None, None, None);
1380
1381 tx.0.inner.inner = Recovered::new_unchecked(tx.0.inner.inner.into_inner(), from);
1384
1385 Ok(FillTransaction { raw, tx })
1386 }
1387
1388 pub fn anvil_get_blob_by_versioned_hash(
1390 &self,
1391 hash: B256,
1392 ) -> Result<Option<alloy_consensus::Blob>> {
1393 node_info!("anvil_getBlobByHash");
1394 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1395 }
1396
1397 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1399 node_info!("anvil_getBlobsByTransactionHash");
1400 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1401 }
1402
1403 pub fn anvil_get_blobs_by_block_id(
1405 &self,
1406 block_id: impl Into<BlockId>,
1407 versioned_hashes: Vec<B256>,
1408 ) -> Result<Option<Vec<Blob>>> {
1409 node_info!("anvil_getBlobsByBlockId");
1410 Ok(self.backend.get_blobs_by_block_id(block_id, versioned_hashes)?)
1411 }
1412
1413 pub fn anvil_get_genesis_time(&self) -> Result<u64> {
1417 node_info!("anvil_getGenesisTime");
1418 Ok(self.backend.genesis_time())
1419 }
1420
1421 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1428 node_info!("eth_getTransactionByHash");
1429 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1430 let from = *pending.sender();
1431 let tx = transaction_build(
1432 Some(*pending.hash()),
1433 pending.transaction,
1434 None,
1435 None,
1436 Some(self.backend.base_fee()),
1437 );
1438
1439 let WithOtherFields { inner: mut tx, other } = tx.0;
1440 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1443
1444 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1445 });
1446 if tx.is_none() {
1447 tx = self.backend.transaction_by_hash(hash).await?
1448 }
1449
1450 Ok(tx)
1451 }
1452
1453 pub async fn transaction_by_block_hash_and_index(
1457 &self,
1458 hash: B256,
1459 index: Index,
1460 ) -> Result<Option<AnyRpcTransaction>> {
1461 node_info!("eth_getTransactionByBlockHashAndIndex");
1462 self.backend.transaction_by_block_hash_and_index(hash, index).await
1463 }
1464
1465 pub async fn transaction_by_block_number_and_index(
1469 &self,
1470 block: BlockNumber,
1471 idx: Index,
1472 ) -> Result<Option<AnyRpcTransaction>> {
1473 node_info!("eth_getTransactionByBlockNumberAndIndex");
1474 self.backend.transaction_by_block_number_and_index(block, idx).await
1475 }
1476
1477 pub async fn transaction_by_sender_and_nonce(
1484 &self,
1485 sender: Address,
1486 nonce: U256,
1487 ) -> Result<Option<AnyRpcTransaction>> {
1488 node_info!("eth_getTransactionBySenderAndNonce");
1489
1490 for pending_tx in self.pool.ready_transactions().chain(self.pool.pending_transactions()) {
1492 if U256::from(pending_tx.pending_transaction.nonce()) == nonce
1493 && *pending_tx.pending_transaction.sender() == sender
1494 {
1495 let tx = transaction_build(
1496 Some(*pending_tx.pending_transaction.hash()),
1497 pending_tx.pending_transaction.transaction.clone(),
1498 None,
1499 None,
1500 Some(self.backend.base_fee()),
1501 );
1502
1503 let WithOtherFields { inner: mut tx, other } = tx.0;
1504 let from = *pending_tx.pending_transaction.sender();
1507 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1508
1509 return Ok(Some(AnyRpcTransaction(WithOtherFields { inner: tx, other })));
1510 }
1511 }
1512
1513 let highest_nonce = self.transaction_count(sender, None).await?.saturating_to::<u64>();
1514 let target_nonce = nonce.saturating_to::<u64>();
1515
1516 if target_nonce >= highest_nonce {
1518 return Ok(None);
1519 }
1520
1521 let latest_block = self.backend.best_number();
1523 if latest_block == 0 {
1524 return Ok(None);
1525 }
1526
1527 let mut low = 1u64;
1529 let mut high = latest_block;
1530
1531 while low <= high {
1532 let mid = low + (high - low) / 2;
1533 let mid_nonce =
1534 self.transaction_count(sender, Some(mid.into())).await?.saturating_to::<u64>();
1535
1536 if mid_nonce > target_nonce {
1537 high = mid - 1;
1538 } else {
1539 low = mid + 1;
1540 }
1541 }
1542
1543 let target_block = low;
1545 if target_block <= latest_block
1546 && let Some(txs) =
1547 self.backend.mined_transactions_by_block_number(target_block.into()).await
1548 {
1549 for tx in txs {
1550 if tx.from() == sender
1551 && tx.nonce() == target_nonce
1552 && let Some(mined_tx) = self.backend.transaction_by_hash(tx.tx_hash()).await?
1553 {
1554 return Ok(Some(mined_tx));
1555 }
1556 }
1557 }
1558
1559 Ok(None)
1560 }
1561
1562 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<FoundryTxReceipt>> {
1566 node_info!("eth_getTransactionReceipt");
1567 self.backend.transaction_receipt(hash).await
1568 }
1569
1570 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<FoundryTxReceipt>>> {
1574 node_info!("eth_getBlockReceipts");
1575 self.backend.block_receipts(number).await
1576 }
1577
1578 pub async fn uncle_by_block_hash_and_index(
1582 &self,
1583 block_hash: B256,
1584 idx: Index,
1585 ) -> Result<Option<AnyRpcBlock>> {
1586 node_info!("eth_getUncleByBlockHashAndIndex");
1587 let number =
1588 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1589 if let Some(fork) = self.get_fork()
1590 && fork.predates_fork_inclusive(number)
1591 {
1592 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1593 }
1594 Ok(None)
1596 }
1597
1598 pub async fn uncle_by_block_number_and_index(
1602 &self,
1603 block_number: BlockNumber,
1604 idx: Index,
1605 ) -> Result<Option<AnyRpcBlock>> {
1606 node_info!("eth_getUncleByBlockNumberAndIndex");
1607 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1608 if let Some(fork) = self.get_fork()
1609 && fork.predates_fork_inclusive(number)
1610 {
1611 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1612 }
1613 Ok(None)
1615 }
1616
1617 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1621 node_info!("eth_getLogs");
1622 self.backend.logs(filter).await
1623 }
1624
1625 pub fn work(&self) -> Result<Work> {
1629 node_info!("eth_getWork");
1630 Err(BlockchainError::RpcUnimplemented)
1631 }
1632
1633 pub fn syncing(&self) -> Result<bool> {
1637 node_info!("eth_syncing");
1638 Ok(false)
1639 }
1640
1641 pub fn config(&self) -> Result<EthConfig> {
1652 node_info!("eth_config");
1653 Ok(EthConfig {
1654 current: EthForkConfig {
1655 activation_time: 0,
1656 blob_schedule: self.backend.blob_params(),
1657 chain_id: self.backend.env().read().evm_env.cfg_env.chain_id,
1658 fork_id: Bytes::from_static(&[0; 4]),
1659 precompiles: self.backend.precompiles(),
1660 system_contracts: self.backend.system_contracts(),
1661 },
1662 next: None,
1663 last: None,
1664 })
1665 }
1666
1667 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1671 node_info!("eth_submitWork");
1672 Err(BlockchainError::RpcUnimplemented)
1673 }
1674
1675 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1679 node_info!("eth_submitHashrate");
1680 Err(BlockchainError::RpcUnimplemented)
1681 }
1682
1683 pub async fn fee_history(
1687 &self,
1688 block_count: U256,
1689 newest_block: BlockNumber,
1690 reward_percentiles: Vec<f64>,
1691 ) -> Result<FeeHistory> {
1692 node_info!("eth_feeHistory");
1693 let current = self.backend.best_number();
1696 let slots_in_an_epoch = 32u64;
1697
1698 let number = match newest_block {
1699 BlockNumber::Latest | BlockNumber::Pending => current,
1700 BlockNumber::Earliest => 0,
1701 BlockNumber::Number(n) => n,
1702 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1703 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1704 };
1705
1706 if let Some(fork) = self.get_fork() {
1708 if fork.predates_fork_inclusive(number) {
1711 return fork
1712 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1713 .await
1714 .map_err(BlockchainError::AlloyForkProvider);
1715 }
1716 }
1717
1718 const MAX_BLOCK_COUNT: u64 = 1024u64;
1719 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1720
1721 let highest = number;
1723 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1724
1725 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1727 return Err(FeeHistoryError::InvalidBlockRange.into());
1728 }
1729
1730 let mut response = FeeHistory {
1731 oldest_block: lowest,
1732 base_fee_per_gas: Vec::new(),
1733 gas_used_ratio: Vec::new(),
1734 reward: Some(Default::default()),
1735 base_fee_per_blob_gas: Default::default(),
1736 blob_gas_used_ratio: Default::default(),
1737 };
1738 let mut rewards = Vec::new();
1739
1740 {
1741 let fee_history = self.fee_history_cache.lock();
1742
1743 for n in lowest..=highest {
1745 if let Some(block) = fee_history.get(&n) {
1747 response.base_fee_per_gas.push(block.base_fee);
1748 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1749 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1750 response.gas_used_ratio.push(block.gas_used_ratio);
1751
1752 if !reward_percentiles.is_empty() {
1754 let mut block_rewards = Vec::new();
1755 let resolution_per_percentile: f64 = 2.0;
1756 for p in &reward_percentiles {
1757 let p = p.clamp(0.0, 100.0);
1758 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1759 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1760 block_rewards.push(reward);
1761 }
1762 rewards.push(block_rewards);
1763 }
1764 }
1765 }
1766 }
1767
1768 response.reward = Some(rewards);
1769
1770 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1775
1776 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1780
1781 Ok(response)
1782 }
1783
1784 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1791 node_info!("eth_maxPriorityFeePerGas");
1792 Ok(U256::from(self.lowest_suggestion_tip()))
1793 }
1794
1795 fn lowest_suggestion_tip(&self) -> u128 {
1799 let block_number = self.backend.best_number();
1800 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1801
1802 match latest_cached_block {
1803 Some(block) => block.rewards.iter().copied().min(),
1804 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1805 }
1806 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1807 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1808 }
1809
1810 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1814 node_info!("eth_newFilter");
1815 let historic = if filter.block_option.get_from_block().is_some() {
1818 self.backend.logs(filter.clone()).await?
1819 } else {
1820 vec![]
1821 };
1822 let filter = EthFilter::Logs(Box::new(LogsFilter {
1823 blocks: self.new_block_notifications(),
1824 storage: self.storage_info(),
1825 filter: FilteredParams::new(Some(filter)),
1826 historic: Some(historic),
1827 }));
1828 Ok(self.filters.add_filter(filter).await)
1829 }
1830
1831 pub async fn new_block_filter(&self) -> Result<String> {
1835 node_info!("eth_newBlockFilter");
1836 let filter = EthFilter::Blocks(self.new_block_notifications());
1837 Ok(self.filters.add_filter(filter).await)
1838 }
1839
1840 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1844 node_info!("eth_newPendingTransactionFilter");
1845 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1846 Ok(self.filters.add_filter(filter).await)
1847 }
1848
1849 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1853 node_info!("eth_getFilterChanges");
1854 self.filters.get_filter_changes(id).await
1855 }
1856
1857 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1861 node_info!("eth_getFilterLogs");
1862 if let Some(filter) = self.filters.get_log_filter(id).await {
1863 self.backend.logs(filter).await
1864 } else {
1865 Err(BlockchainError::FilterNotFound)
1866 }
1867 }
1868
1869 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1871 node_info!("eth_uninstallFilter");
1872 Ok(self.filters.uninstall_filter(id).await.is_some())
1873 }
1874
1875 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1879 node_info!("debug_getRawTransaction");
1880 self.inner_raw_transaction(hash).await
1881 }
1882
1883 pub async fn raw_transaction_by_block_hash_and_index(
1887 &self,
1888 block_hash: B256,
1889 index: Index,
1890 ) -> Result<Option<Bytes>> {
1891 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1892 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1893 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1894 None => Ok(None),
1895 }
1896 }
1897
1898 pub async fn raw_transaction_by_block_number_and_index(
1902 &self,
1903 block_number: BlockNumber,
1904 index: Index,
1905 ) -> Result<Option<Bytes>> {
1906 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1907 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1908 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1909 None => Ok(None),
1910 }
1911 }
1912
1913 pub async fn debug_trace_transaction(
1917 &self,
1918 tx_hash: B256,
1919 opts: GethDebugTracingOptions,
1920 ) -> Result<GethTrace> {
1921 node_info!("debug_traceTransaction");
1922 self.backend.debug_trace_transaction(tx_hash, opts).await
1923 }
1924
1925 pub async fn debug_trace_call(
1929 &self,
1930 request: WithOtherFields<TransactionRequest>,
1931 block_number: Option<BlockId>,
1932 opts: GethDebugTracingCallOptions,
1933 ) -> Result<GethTrace> {
1934 node_info!("debug_traceCall");
1935 let block_request = self.block_request(block_number).await?;
1936 let fees = FeeDetails::new(
1937 request.gas_price,
1938 request.max_fee_per_gas,
1939 request.max_priority_fee_per_gas,
1940 request.max_fee_per_blob_gas,
1941 )?
1942 .or_zero_fees();
1943
1944 let result: std::result::Result<GethTrace, BlockchainError> =
1945 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1946 result
1947 }
1948
1949 pub async fn debug_code_by_hash(
1953 &self,
1954 hash: B256,
1955 block_id: Option<BlockId>,
1956 ) -> Result<Option<Bytes>> {
1957 node_info!("debug_codeByHash");
1958 self.backend.debug_code_by_hash(hash, block_id).await
1959 }
1960
1961 pub async fn debug_db_get(&self, key: String) -> Result<Option<Bytes>> {
1966 node_info!("debug_dbGet");
1967 self.backend.debug_db_get(key).await
1968 }
1969
1970 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1974 node_info!("trace_transaction");
1975 self.backend.trace_transaction(tx_hash).await
1976 }
1977
1978 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1982 node_info!("trace_block");
1983 self.backend.trace_block(block).await
1984 }
1985
1986 pub async fn trace_filter(
1990 &self,
1991 filter: TraceFilter,
1992 ) -> Result<Vec<LocalizedTransactionTrace>> {
1993 node_info!("trace_filter");
1994 self.backend.trace_filter(filter).await
1995 }
1996
1997 pub async fn trace_replay_block_transactions(
2001 &self,
2002 block: BlockNumber,
2003 trace_types: HashSet<TraceType>,
2004 ) -> Result<Vec<TraceResultsWithTransactionHash>> {
2005 node_info!("trace_replayBlockTransactions");
2006 self.backend.trace_replay_block_transactions(block, trace_types).await
2007 }
2008}
2009
2010impl EthApi {
2013 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
2017 node_info!("anvil_impersonateAccount");
2018 self.backend.impersonate(address);
2019 Ok(())
2020 }
2021
2022 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
2026 node_info!("anvil_stopImpersonatingAccount");
2027 self.backend.stop_impersonating(address);
2028 Ok(())
2029 }
2030
2031 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
2035 node_info!("anvil_autoImpersonateAccount");
2036 self.backend.auto_impersonate_account(enabled);
2037 Ok(())
2038 }
2039
2040 pub async fn anvil_impersonate_signature(
2042 &self,
2043 signature: Bytes,
2044 address: Address,
2045 ) -> Result<()> {
2046 node_info!("anvil_impersonateSignature");
2047 self.backend.impersonate_signature(signature, address).await
2048 }
2049
2050 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
2054 node_info!("anvil_getAutomine");
2055 Ok(self.miner.is_auto_mine())
2056 }
2057
2058 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
2062 node_info!("anvil_getIntervalMining");
2063 Ok(self.miner.get_interval())
2064 }
2065
2066 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
2071 node_info!("evm_setAutomine");
2072 if self.miner.is_auto_mine() {
2073 if enable_automine {
2074 return Ok(());
2075 }
2076 self.miner.set_mining_mode(MiningMode::None);
2077 } else if enable_automine {
2078 let listener = self.pool.add_ready_listener();
2079 let mode = MiningMode::instant(1_000, listener);
2080 self.miner.set_mining_mode(mode);
2081 }
2082 Ok(())
2083 }
2084
2085 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
2089 node_info!("anvil_mine");
2090 let interval = interval.map(|i| i.to::<u64>());
2091 let blocks = num_blocks.unwrap_or(U256::from(1));
2092 if blocks.is_zero() {
2093 return Ok(());
2094 }
2095
2096 self.on_blocking_task(|this| async move {
2097 for _ in 0..blocks.to::<u64>() {
2099 if let Some(interval) = interval {
2101 this.backend.time().increase_time(interval);
2102 }
2103 this.mine_one().await;
2104 }
2105 Ok(())
2106 })
2107 .await?;
2108
2109 Ok(())
2110 }
2111
2112 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
2116 node_info!("evm_setIntervalMining");
2117 let mining_mode = if secs == 0 {
2118 MiningMode::None
2119 } else {
2120 let block_time = Duration::from_secs(secs);
2121
2122 self.backend.update_interval_mine_block_time(block_time);
2124
2125 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
2126 };
2127 self.miner.set_mining_mode(mining_mode);
2128 Ok(())
2129 }
2130
2131 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
2135 node_info!("anvil_dropTransaction");
2136 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
2137 }
2138
2139 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
2143 node_info!("anvil_dropAllTransactions");
2144 self.pool.clear();
2145 Ok(())
2146 }
2147
2148 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
2154 self.reset_instance_id();
2155 node_info!("anvil_reset");
2156 if let Some(forking) = forking {
2157 self.backend.reset_fork(forking).await
2159 } else {
2160 self.backend.reset_to_in_mem().await
2163 }
2164 }
2165
2166 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
2167 node_info!("anvil_setChainId");
2168 self.backend.set_chain_id(chain_id);
2169 Ok(())
2170 }
2171
2172 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
2176 node_info!("anvil_setBalance");
2177 self.backend.set_balance(address, balance).await?;
2178 Ok(())
2179 }
2180
2181 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
2185 node_info!("anvil_addBalance");
2186 let current_balance = self.backend.get_balance(address, None).await?;
2187 self.backend.set_balance(address, current_balance + balance).await?;
2188 Ok(())
2189 }
2190
2191 async fn find_erc20_storage_slot(
2208 &self,
2209 token_address: Address,
2210 calldata: Bytes,
2211 expected_value: U256,
2212 ) -> Result<B256> {
2213 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2214
2215 let access_list_result =
2217 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2218 let access_list = access_list_result.access_list;
2219
2220 for item in access_list.0 {
2223 if item.address != token_address {
2224 continue;
2225 };
2226 for slot in &item.storage_keys {
2227 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2228 (*slot, B256::from(expected_value.to_be_bytes())),
2229 ));
2230
2231 let state_override = StateOverridesBuilder::default()
2232 .append(token_address, account_override)
2233 .build();
2234
2235 let evm_override = EvmOverrides::state(Some(state_override));
2236
2237 let Ok(result) =
2238 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2239 else {
2240 continue;
2242 };
2243
2244 let Ok(result_value) = U256::abi_decode(&result) else {
2245 continue;
2247 };
2248
2249 if result_value == expected_value {
2250 return Ok(*slot);
2251 }
2252 }
2253 }
2254
2255 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2256 }
2257
2258 pub async fn anvil_deal_erc20(
2262 &self,
2263 address: Address,
2264 token_address: Address,
2265 balance: U256,
2266 ) -> Result<()> {
2267 node_info!("anvil_dealERC20");
2268
2269 sol! {
2270 #[sol(rpc)]
2271 contract IERC20 {
2272 function balanceOf(address target) external view returns (uint256);
2273 }
2274 }
2275
2276 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2277
2278 let slot =
2280 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2281 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2282 })?;
2283
2284 self.anvil_set_storage_at(
2286 token_address,
2287 U256::from_be_bytes(slot.0),
2288 B256::from(balance.to_be_bytes()),
2289 )
2290 .await?;
2291
2292 Ok(())
2293 }
2294
2295 pub async fn anvil_set_erc20_allowance(
2299 &self,
2300 owner: Address,
2301 spender: Address,
2302 token_address: Address,
2303 amount: U256,
2304 ) -> Result<()> {
2305 node_info!("anvil_setERC20Allowance");
2306
2307 sol! {
2308 #[sol(rpc)]
2309 contract IERC20 {
2310 function allowance(address owner, address spender) external view returns (uint256);
2311 }
2312 }
2313
2314 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2315
2316 let slot =
2318 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2319 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2320 })?;
2321
2322 self.anvil_set_storage_at(
2324 token_address,
2325 U256::from_be_bytes(slot.0),
2326 B256::from(amount.to_be_bytes()),
2327 )
2328 .await?;
2329
2330 Ok(())
2331 }
2332
2333 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2337 node_info!("anvil_setCode");
2338 self.backend.set_code(address, code).await?;
2339 Ok(())
2340 }
2341
2342 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2346 node_info!("anvil_setNonce");
2347 self.backend.set_nonce(address, nonce).await?;
2348 Ok(())
2349 }
2350
2351 pub async fn anvil_set_storage_at(
2355 &self,
2356 address: Address,
2357 slot: U256,
2358 val: B256,
2359 ) -> Result<bool> {
2360 node_info!("anvil_setStorageAt");
2361 self.backend.set_storage_at(address, slot, val).await?;
2362 Ok(true)
2363 }
2364
2365 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2369 node_info!("anvil_setLoggingEnabled");
2370 self.logger.set_enabled(enable);
2371 Ok(())
2372 }
2373
2374 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2378 node_info!("anvil_setMinGasPrice");
2379 if self.backend.is_eip1559() {
2380 return Err(RpcError::invalid_params(
2381 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2382 )
2383 .into());
2384 }
2385 self.backend.set_gas_price(gas.to());
2386 Ok(())
2387 }
2388
2389 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2393 node_info!("anvil_setNextBlockBaseFeePerGas");
2394 if !self.backend.is_eip1559() {
2395 return Err(RpcError::invalid_params(
2396 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2397 )
2398 .into());
2399 }
2400 self.backend.set_base_fee(basefee.to());
2401 Ok(())
2402 }
2403
2404 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2408 node_info!("anvil_setCoinbase");
2409 self.backend.set_coinbase(address);
2410 Ok(())
2411 }
2412
2413 pub async fn anvil_dump_state(
2418 &self,
2419 preserve_historical_states: Option<bool>,
2420 ) -> Result<Bytes> {
2421 node_info!("anvil_dumpState");
2422 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2423 }
2424
2425 pub async fn serialized_state(
2427 &self,
2428 preserve_historical_states: bool,
2429 ) -> Result<SerializableState> {
2430 self.backend.serialized_state(preserve_historical_states).await
2431 }
2432
2433 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2438 node_info!("anvil_loadState");
2439 self.backend.load_state_bytes(buf).await
2440 }
2441
2442 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2446 node_info!("anvil_nodeInfo");
2447
2448 let env = self.backend.env().read();
2449 let fork_config = self.backend.get_fork();
2450 let tx_order = self.transaction_order.read();
2451 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2452
2453 Ok(NodeInfo {
2454 current_block_number: self.backend.best_number(),
2455 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2456 current_block_hash: self.backend.best_hash(),
2457 hard_fork: hard_fork.to_string(),
2458 transaction_order: match *tx_order {
2459 TransactionOrder::Fifo => "fifo".to_string(),
2460 TransactionOrder::Fees => "fees".to_string(),
2461 },
2462 environment: NodeEnvironment {
2463 base_fee: self.backend.base_fee() as u128,
2464 chain_id: self.backend.chain_id().to::<u64>(),
2465 gas_limit: self.backend.gas_limit(),
2466 gas_price: self.gas_price(),
2467 },
2468 fork_config: fork_config
2469 .map(|fork| {
2470 let config = fork.config.read();
2471
2472 NodeForkConfig {
2473 fork_url: Some(config.eth_rpc_url.clone()),
2474 fork_block_number: Some(config.block_number),
2475 fork_retry_backoff: Some(config.backoff.as_millis()),
2476 }
2477 })
2478 .unwrap_or_default(),
2479 })
2480 }
2481
2482 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2486 node_info!("anvil_metadata");
2487 let fork_config = self.backend.get_fork();
2488
2489 Ok(Metadata {
2490 client_version: CLIENT_VERSION.to_string(),
2491 chain_id: self.backend.chain_id().to::<u64>(),
2492 latest_block_hash: self.backend.best_hash(),
2493 latest_block_number: self.backend.best_number(),
2494 instance_id: *self.instance_id.read(),
2495 forked_network: fork_config.map(|cfg| ForkedNetwork {
2496 chain_id: cfg.chain_id(),
2497 fork_block_number: cfg.block_number(),
2498 fork_block_hash: cfg.block_hash(),
2499 }),
2500 snapshots: self.backend.list_state_snapshots(),
2501 })
2502 }
2503
2504 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2505 node_info!("anvil_removePoolTransactions");
2506 self.pool.remove_transactions_by_address(address);
2507 Ok(())
2508 }
2509
2510 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2524 node_info!("anvil_reorg");
2525 let depth = options.depth;
2526 let tx_block_pairs = options.tx_block_pairs;
2527
2528 let current_height = self.backend.best_number();
2530 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2531 RpcError::invalid_params(format!(
2532 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2533 )),
2534 ))?;
2535
2536 let common_block =
2538 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2539
2540 let block_pool_txs = if tx_block_pairs.is_empty() {
2543 HashMap::default()
2544 } else {
2545 let mut pairs = tx_block_pairs;
2546
2547 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2549 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2550 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2551 depth - 1
2552 ))));
2553 }
2554
2555 pairs.sort_by_key(|a| a.1);
2557
2558 let mut nonces: HashMap<Address, u64> = HashMap::default();
2561
2562 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2563 for pair in pairs {
2564 let (tx_data, block_index) = pair;
2565
2566 let pending = match tx_data {
2567 TransactionData::Raw(bytes) => {
2568 let mut data = bytes.as_ref();
2569 let decoded = FoundryTxEnvelope::decode_2718(&mut data)
2570 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2571 PendingTransaction::new(decoded)?
2572 }
2573
2574 TransactionData::JSON(request) => {
2575 let from = request.from.map(Ok).unwrap_or_else(|| {
2576 self.accounts()?
2577 .first()
2578 .copied()
2579 .ok_or(BlockchainError::NoSignerAvailable)
2580 })?;
2581
2582 let curr_nonce = nonces.entry(from).or_insert(
2584 self.get_transaction_count(
2585 from,
2586 Some(common_block.header.number.into()),
2587 )
2588 .await?,
2589 );
2590
2591 let typed = self.build_tx_request(request.into(), *curr_nonce).await?;
2593
2594 *curr_nonce += 1;
2596
2597 if self.is_impersonated(from) {
2599 let bypass_signature = self.impersonated_signature(&typed);
2600 let transaction =
2601 sign::build_typed_transaction(typed, bypass_signature)?;
2602 self.ensure_typed_transaction_supported(&transaction)?;
2603 PendingTransaction::with_impersonated(transaction, from)
2604 } else {
2605 let transaction = self.sign_request(&from, typed)?;
2606 self.ensure_typed_transaction_supported(&transaction)?;
2607 PendingTransaction::new(transaction)?
2608 }
2609 }
2610 };
2611
2612 let pooled = PoolTransaction::new(pending);
2613 txs.entry(block_index).or_default().push(Arc::new(pooled));
2614 }
2615
2616 txs
2617 };
2618
2619 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2620 Ok(())
2621 }
2622
2623 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2634 node_info!("anvil_rollback");
2635 let depth = depth.unwrap_or(1);
2636
2637 let current_height = self.backend.best_number();
2639 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2640 RpcError::invalid_params(format!(
2641 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2642 )),
2643 ))?;
2644
2645 let common_block =
2647 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2648
2649 self.backend.rollback(common_block).await?;
2650 Ok(())
2651 }
2652
2653 pub async fn evm_snapshot(&self) -> Result<U256> {
2657 node_info!("evm_snapshot");
2658 Ok(self.backend.create_state_snapshot().await)
2659 }
2660
2661 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2666 node_info!("evm_revert");
2667 self.backend.revert_state_snapshot(id).await
2668 }
2669
2670 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2674 node_info!("evm_increaseTime");
2675 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2676 }
2677
2678 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2682 node_info!("evm_setNextBlockTimestamp");
2683 self.backend.time().set_next_block_timestamp(seconds)
2684 }
2685
2686 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2691 node_info!("evm_setTime");
2692 let now = self.backend.time().current_call_timestamp();
2693 self.backend.time().reset(timestamp);
2694
2695 let offset = timestamp.saturating_sub(now);
2697 Ok(Duration::from_millis(offset).as_secs())
2698 }
2699
2700 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2704 node_info!("evm_setBlockGasLimit");
2705 self.backend.set_gas_limit(gas_limit.to());
2706 Ok(true)
2707 }
2708
2709 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2713 node_info!("anvil_setBlockTimestampInterval");
2714 self.backend.time().set_block_timestamp_interval(seconds);
2715 Ok(())
2716 }
2717
2718 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2722 node_info!("anvil_removeBlockTimestampInterval");
2723 Ok(self.backend.time().remove_block_timestamp_interval())
2724 }
2725
2726 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2733 node_info!("evm_mine");
2734
2735 self.do_evm_mine(opts).await?;
2736
2737 Ok("0x0".to_string())
2738 }
2739
2740 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2750 node_info!("evm_mine_detailed");
2751
2752 let mined_blocks = self.do_evm_mine(opts).await?;
2753
2754 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2755
2756 let latest = self.backend.best_number();
2757 for offset in (0..mined_blocks).rev() {
2758 let block_num = latest - offset;
2759 if let Some(mut block) =
2760 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2761 {
2762 let block_txs = match block.transactions_mut() {
2763 BlockTransactions::Full(txs) => txs,
2764 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2765 };
2766 for tx in block_txs.iter_mut() {
2767 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2768 && let Some(output) = receipt.out
2769 {
2770 if !receipt.inner.as_ref().status()
2772 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2773 {
2774 tx.other.insert(
2775 "revertReason".to_string(),
2776 serde_json::to_value(reason).expect("Infallible"),
2777 );
2778 }
2779 tx.other.insert(
2780 "output".to_string(),
2781 serde_json::to_value(output).expect("Infallible"),
2782 );
2783 }
2784 }
2785 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2786 blocks.push(block);
2787 }
2788 }
2789
2790 Ok(blocks)
2791 }
2792
2793 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2797 node_info!("anvil_setRpcUrl");
2798 if let Some(fork) = self.backend.get_fork() {
2799 let mut config = fork.config.write();
2800 let new_provider = Arc::new(
2802 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2803 |_| {
2804 TransportErrorKind::custom_str(
2805 format!("Failed to parse invalid url {url}").as_str(),
2806 )
2807 },
2808 )?, );
2811 config.provider = new_provider;
2812 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2813 config.eth_rpc_url = url;
2814 }
2815 Ok(())
2816 }
2817
2818 pub async fn anvil_enable_traces(&self) -> Result<()> {
2823 node_info!("anvil_enableTraces");
2824 Err(BlockchainError::RpcUnimplemented)
2825 }
2826
2827 pub async fn eth_send_unsigned_transaction(
2831 &self,
2832 request: WithOtherFields<TransactionRequest>,
2833 ) -> Result<TxHash> {
2834 node_info!("eth_sendUnsignedTransaction");
2835 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2837
2838 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2839
2840 let request = self.build_tx_request(request, nonce).await?;
2841
2842 let bypass_signature = self.impersonated_signature(&request);
2843 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2844
2845 self.ensure_typed_transaction_supported(&transaction)?;
2846
2847 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2848
2849 self.backend.validate_pool_transaction(&pending_transaction).await?;
2851
2852 let requires = required_marker(nonce, on_chain_nonce, from);
2853 let provides = vec![to_marker(nonce, from)];
2854
2855 self.add_pending_transaction(pending_transaction, requires, provides)
2856 }
2857
2858 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2864 node_info!("txpool_status");
2865 Ok(self.pool.txpool_status())
2866 }
2867
2868 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2875 node_info!("txpool_inspect");
2876 let mut inspect = TxpoolInspect::default();
2877
2878 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2879 let tx = &tx.pending_transaction.transaction;
2880 let to = tx.to();
2881 let gas_price = tx.max_fee_per_gas();
2882 let value = tx.value();
2883 let gas = tx.gas_limit();
2884 TxpoolInspectSummary { to, value, gas, gas_price }
2885 }
2886
2887 for pending in self.pool.ready_transactions() {
2894 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2895 let key = pending.pending_transaction.nonce().to_string();
2896 entry.insert(key, convert(pending));
2897 }
2898 for queued in self.pool.pending_transactions() {
2899 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2900 let key = queued.pending_transaction.nonce().to_string();
2901 entry.insert(key, convert(queued));
2902 }
2903 Ok(inspect)
2904 }
2905
2906 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2913 node_info!("txpool_content");
2914 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2915 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2916 let from = *tx.pending_transaction.sender();
2917 let tx = transaction_build(
2918 Some(tx.hash()),
2919 tx.pending_transaction.transaction.clone(),
2920 None,
2921 None,
2922 None,
2923 );
2924
2925 let WithOtherFields { inner: mut tx, other } = tx.0;
2926
2927 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2930
2931 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2932
2933 Ok(tx)
2934 }
2935
2936 for pending in self.pool.ready_transactions() {
2937 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2938 let key = pending.pending_transaction.nonce().to_string();
2939 entry.insert(key, convert(pending)?);
2940 }
2941 for queued in self.pool.pending_transactions() {
2942 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2943 let key = queued.pending_transaction.nonce().to_string();
2944 entry.insert(key, convert(queued)?);
2945 }
2946
2947 Ok(content)
2948 }
2949}
2950
2951impl EthApi {
2952 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2954 where
2955 C: FnOnce(Self) -> F,
2956 F: Future<Output = Result<R>> + Send + 'static,
2957 R: Send + 'static,
2958 {
2959 let (tx, rx) = oneshot::channel();
2960 let this = self.clone();
2961 let f = c(this);
2962 tokio::task::spawn_blocking(move || {
2963 tokio::runtime::Handle::current().block_on(async move {
2964 let res = f.await;
2965 let _ = tx.send(res);
2966 })
2967 });
2968 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2969 }
2970
2971 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2973 let mut blocks_to_mine = 1u64;
2974
2975 if let Some(opts) = opts {
2976 let timestamp = match opts {
2977 MineOptions::Timestamp(timestamp) => timestamp,
2978 MineOptions::Options { timestamp, blocks } => {
2979 if let Some(blocks) = blocks {
2980 blocks_to_mine = blocks;
2981 }
2982 timestamp
2983 }
2984 };
2985 if let Some(timestamp) = timestamp {
2986 self.evm_set_next_block_timestamp(timestamp)?;
2988 }
2989 }
2990
2991 self.on_blocking_task(|this| async move {
2994 for _ in 0..blocks_to_mine {
2996 this.mine_one().await;
2997 }
2998 Ok(())
2999 })
3000 .await?;
3001
3002 Ok(blocks_to_mine)
3003 }
3004
3005 async fn do_estimate_gas(
3006 &self,
3007 request: WithOtherFields<TransactionRequest>,
3008 block_number: Option<BlockId>,
3009 overrides: EvmOverrides,
3010 ) -> Result<u128> {
3011 let block_request = self.block_request(block_number).await?;
3012 if let BlockRequest::Number(number) = block_request
3014 && let Some(fork) = self.get_fork()
3015 && fork.predates_fork(number)
3016 {
3017 if overrides.has_state() || overrides.has_block() {
3018 return Err(BlockchainError::EvmOverrideError(
3019 "not available on past forked blocks".to_string(),
3020 ));
3021 }
3022 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
3023 }
3024
3025 self.on_blocking_task(|this| async move {
3028 this.backend
3029 .with_database_at(Some(block_request), |state, mut block| {
3030 let mut cache_db = CacheDB::new(state);
3031 if let Some(state_overrides) = overrides.state {
3032 apply_state_overrides(
3033 state_overrides.into_iter().collect(),
3034 &mut cache_db,
3035 )?;
3036 }
3037 if let Some(block_overrides) = overrides.block {
3038 cache_db.apply_block_overrides(*block_overrides, &mut block);
3039 }
3040 this.do_estimate_gas_with_state(request, &cache_db, block)
3041 })
3042 .await?
3043 })
3044 .await
3045 }
3046
3047 fn do_estimate_gas_with_state(
3051 &self,
3052 mut request: WithOtherFields<TransactionRequest>,
3053 state: &dyn DatabaseRef,
3054 block_env: BlockEnv,
3055 ) -> Result<u128> {
3056 let to = request.to.as_ref().and_then(TxKind::to);
3059
3060 let maybe_transfer = (request.input.input().is_none()
3062 || request.input.input().is_some_and(|data| data.is_empty()))
3063 && request.authorization_list.is_none()
3064 && request.access_list.is_none()
3065 && request.blob_versioned_hashes.is_none();
3066
3067 if maybe_transfer
3068 && let Some(to) = to
3069 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
3070 && target_code.as_ref().is_empty()
3071 {
3072 return Ok(MIN_TRANSACTION_GAS);
3073 }
3074
3075 let fees = FeeDetails::new(
3076 request.gas_price,
3077 request.max_fee_per_gas,
3078 request.max_priority_fee_per_gas,
3079 request.max_fee_per_blob_gas,
3080 )?
3081 .or_zero_fees();
3082
3083 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
3086
3087 let gas_price = fees.gas_price.unwrap_or_default();
3088 if gas_price > 0
3090 && let Some(from) = request.from
3091 {
3092 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
3093 if let Some(value) = request.value {
3094 if value > available_funds {
3095 return Err(InvalidTransactionError::InsufficientFunds.into());
3096 }
3097 available_funds -= value;
3099 }
3100 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
3102 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
3103 }
3104
3105 let mut call_to_estimate = request.clone();
3106 call_to_estimate.gas = Some(highest_gas_limit as u64);
3107
3108 let ethres =
3110 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3111
3112 let gas_used = match ethres.try_into()? {
3113 GasEstimationCallResult::Success(gas) => Ok(gas),
3114 GasEstimationCallResult::OutOfGas => {
3115 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3116 }
3117 GasEstimationCallResult::Revert(output) => {
3118 Err(InvalidTransactionError::Revert(output).into())
3119 }
3120 GasEstimationCallResult::EvmError(err) => {
3121 warn!(target: "node", "estimation failed due to {:?}", err);
3122 Err(BlockchainError::EvmError(err))
3123 }
3124 }?;
3125
3126 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3133
3134 let mut mid_gas_limit =
3136 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3137
3138 while (highest_gas_limit - lowest_gas_limit) > 1 {
3140 request.gas = Some(mid_gas_limit as u64);
3141 let ethres = self.backend.call_with_state(
3142 &state,
3143 request.clone(),
3144 fees.clone(),
3145 block_env.clone(),
3146 );
3147
3148 match ethres.try_into()? {
3149 GasEstimationCallResult::Success(_) => {
3150 highest_gas_limit = mid_gas_limit;
3154 }
3155 GasEstimationCallResult::OutOfGas
3156 | GasEstimationCallResult::Revert(_)
3157 | GasEstimationCallResult::EvmError(_) => {
3158 lowest_gas_limit = mid_gas_limit;
3165 }
3166 };
3167 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3169 }
3170
3171 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3172
3173 Ok(highest_gas_limit)
3174 }
3175
3176 pub fn set_transaction_order(&self, order: TransactionOrder) {
3178 *self.transaction_order.write() = order;
3179 }
3180
3181 fn transaction_priority(&self, tx: &FoundryTxEnvelope) -> TransactionPriority {
3183 self.transaction_order.read().priority(tx)
3184 }
3185
3186 pub fn chain_id(&self) -> u64 {
3188 self.backend.chain_id().to::<u64>()
3189 }
3190
3191 pub fn get_fork(&self) -> Option<ClientFork> {
3193 self.backend.get_fork()
3194 }
3195
3196 pub fn instance_id(&self) -> B256 {
3198 *self.instance_id.read()
3199 }
3200
3201 pub fn reset_instance_id(&self) {
3203 *self.instance_id.write() = B256::random();
3204 }
3205
3206 #[expect(clippy::borrowed_box)]
3208 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3209 self.signers.iter().find(|signer| signer.is_signer_for(address))
3210 }
3211
3212 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3214 self.backend.new_block_notifications()
3215 }
3216
3217 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3219 self.pool.add_ready_listener()
3220 }
3221
3222 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3224 let (tx, rx) = unbounded_channel();
3225 let mut hashes = self.new_ready_transactions();
3226
3227 let this = self.clone();
3228
3229 tokio::spawn(async move {
3230 while let Some(hash) = hashes.next().await {
3231 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3232 && tx.send(txn).is_err()
3233 {
3234 break;
3235 }
3236 }
3237 });
3238
3239 rx
3240 }
3241
3242 pub fn storage_info(&self) -> StorageInfo {
3244 StorageInfo::new(Arc::clone(&self.backend))
3245 }
3246
3247 pub fn is_fork(&self) -> bool {
3249 self.backend.is_fork()
3250 }
3251
3252 pub async fn mine_one(&self) {
3254 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3255 let outcome = self.backend.mine_block(transactions).await;
3256
3257 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3258 self.pool.on_mined_block(outcome);
3259 }
3260
3261 async fn pending_block(&self) -> AnyRpcBlock {
3263 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3264 let info = self.backend.pending_block(transactions).await;
3265 self.backend.convert_block(info.block)
3266 }
3267
3268 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3270 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3271 let BlockInfo { block, transactions, receipts: _ } =
3272 self.backend.pending_block(transactions).await;
3273
3274 let mut partial_block = self.backend.convert_block(block.clone());
3275
3276 let mut block_transactions = Vec::with_capacity(block.body.transactions.len());
3277 let base_fee = self.backend.base_fee();
3278
3279 for info in transactions {
3280 let tx = block.body.transactions.get(info.transaction_index as usize)?.clone();
3281
3282 let tx = transaction_build(
3283 Some(info.transaction_hash),
3284 tx,
3285 Some(&block),
3286 Some(info),
3287 Some(base_fee),
3288 );
3289 block_transactions.push(tx);
3290 }
3291
3292 partial_block.transactions = BlockTransactions::from(block_transactions);
3293
3294 Some(partial_block)
3295 }
3296
3297 async fn build_tx_request(
3300 &self,
3301 request: WithOtherFields<TransactionRequest>,
3302 nonce: u64,
3303 ) -> Result<FoundryTypedTx> {
3304 let mut request = Into::<FoundryTransactionRequest>::into(request);
3305 let from = request.from().or(self.accounts()?.first().copied());
3306
3307 request.chain_id().is_none().then(|| request.set_chain_id(self.chain_id()));
3309 request.nonce().is_none().then(|| request.set_nonce(nonce));
3310 request.kind().is_none().then(|| request.set_kind(TxKind::default()));
3311 if request.gas_limit().is_none() {
3312 request.set_gas_limit(
3313 self.do_estimate_gas(
3314 request.as_ref().clone().into(),
3315 None,
3316 EvmOverrides::default(),
3317 )
3318 .await
3319 .map(|v| v as u64)
3320 .unwrap_or(self.backend.gas_limit()),
3321 );
3322 }
3323
3324 if let Err((tx_type, _)) = request.missing_keys() {
3326 if matches!(tx_type, FoundryTxType::Legacy | FoundryTxType::Eip2930) {
3327 request.gas_price().is_none().then(|| request.set_gas_price(self.gas_price()));
3328 }
3329 if tx_type == FoundryTxType::Eip2930 {
3330 request
3331 .access_list()
3332 .is_none()
3333 .then(|| request.set_access_list(Default::default()));
3334 }
3335 if matches!(
3336 tx_type,
3337 FoundryTxType::Eip1559 | FoundryTxType::Eip4844 | FoundryTxType::Eip7702
3338 ) {
3339 request
3340 .max_fee_per_gas()
3341 .is_none()
3342 .then(|| request.set_max_fee_per_gas(self.gas_price()));
3343 request
3344 .max_priority_fee_per_gas()
3345 .is_none()
3346 .then(|| request.set_max_priority_fee_per_gas(MIN_SUGGESTED_PRIORITY_FEE));
3347 }
3348 if tx_type == FoundryTxType::Eip4844 {
3349 request.as_ref().max_fee_per_blob_gas().is_none().then(|| {
3350 request.as_mut().set_max_fee_per_blob_gas(
3351 self.backend.fees().get_next_block_blob_base_fee_per_gas(),
3352 )
3353 });
3354 }
3355 }
3356
3357 match request
3358 .build_unsigned()
3359 .map_err(|e| BlockchainError::InvalidTransactionRequest(e.to_string()))?
3360 {
3361 FoundryTypedTx::Eip4844(TxEip4844Variant::TxEip4844(_))
3362 if !self.backend.skip_blob_validation(from) =>
3363 {
3364 Err(BlockchainError::FailedToDecodeTransaction)
3366 }
3367 res => Ok(res),
3368 }
3369 }
3370
3371 pub fn is_impersonated(&self, addr: Address) -> bool {
3373 self.backend.cheats().is_impersonated(addr)
3374 }
3375
3376 fn impersonated_signature(&self, request: &FoundryTypedTx) -> Signature {
3378 match request {
3379 FoundryTypedTx::Legacy(_)
3380 | FoundryTypedTx::Eip2930(_)
3381 | FoundryTypedTx::Eip1559(_)
3382 | FoundryTypedTx::Eip7702(_)
3383 | FoundryTypedTx::Eip4844(_)
3384 | FoundryTypedTx::Deposit(_) => Signature::from_scalars_and_parity(
3385 B256::with_last_byte(1),
3386 B256::with_last_byte(1),
3387 false,
3388 ),
3389 FoundryTypedTx::Tempo(_) => todo!(),
3391 }
3392 }
3393
3394 async fn get_transaction_count(
3396 &self,
3397 address: Address,
3398 block_number: Option<BlockId>,
3399 ) -> Result<u64> {
3400 let block_request = self.block_request(block_number).await?;
3401
3402 if let BlockRequest::Number(number) = block_request
3403 && let Some(fork) = self.get_fork()
3404 && fork.predates_fork(number)
3405 {
3406 return Ok(fork.get_nonce(address, number).await?);
3407 }
3408
3409 self.backend.get_nonce(address, block_request).await
3410 }
3411
3412 async fn request_nonce(
3420 &self,
3421 request: &TransactionRequest,
3422 from: Address,
3423 ) -> Result<(u64, u64)> {
3424 let highest_nonce =
3425 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3426 let nonce = request.nonce.unwrap_or(highest_nonce);
3427
3428 Ok((nonce, highest_nonce))
3429 }
3430
3431 fn add_pending_transaction(
3433 &self,
3434 pending_transaction: PendingTransaction,
3435 requires: Vec<TxMarker>,
3436 provides: Vec<TxMarker>,
3437 ) -> Result<TxHash> {
3438 let from = *pending_transaction.sender();
3439 let priority = self.transaction_priority(&pending_transaction.transaction);
3440 let pool_transaction =
3441 PoolTransaction { requires, provides, pending_transaction, priority };
3442 let tx = self.pool.add_transaction(pool_transaction)?;
3443 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3444 Ok(*tx.hash())
3445 }
3446
3447 pub async fn state_root(&self) -> Option<B256> {
3449 self.backend.get_db().read().await.maybe_state_root()
3450 }
3451
3452 fn ensure_typed_transaction_supported(&self, tx: &FoundryTxEnvelope) -> Result<()> {
3454 match &tx {
3455 FoundryTxEnvelope::Eip2930(_) => self.backend.ensure_eip2930_active(),
3456 FoundryTxEnvelope::Eip1559(_) => self.backend.ensure_eip1559_active(),
3457 FoundryTxEnvelope::Eip4844(_) => self.backend.ensure_eip4844_active(),
3458 FoundryTxEnvelope::Eip7702(_) => self.backend.ensure_eip7702_active(),
3459 FoundryTxEnvelope::Deposit(_) => self.backend.ensure_op_deposits_active(),
3460 FoundryTxEnvelope::Legacy(_) => Ok(()),
3461 FoundryTxEnvelope::Tempo(_) => todo!(),
3463 }
3464 }
3465}
3466
3467fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3468 if provided_nonce == on_chain_nonce {
3469 return Vec::new();
3470 }
3471 let prev_nonce = provided_nonce.saturating_sub(1);
3472 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3473}
3474
3475fn convert_transact_out(out: &Option<Output>) -> Bytes {
3476 match out {
3477 None => Default::default(),
3478 Some(Output::Call(out)) => out.to_vec().into(),
3479 Some(Output::Create(out, _)) => out.to_vec().into(),
3480 }
3481}
3482
3483fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3485 let out = convert_transact_out(out);
3486 match exit {
3487 return_ok!() => Ok(out),
3488 return_revert!() => Err(InvalidTransactionError::Revert(Some(out)).into()),
3489 reason => Err(BlockchainError::EvmError(reason)),
3490 }
3491}
3492
3493fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3495 match request.kind() {
3496 Some(TxKind::Call(_)) => {
3497 MIN_TRANSACTION_GAS
3498 + request.inner().authorization_list.as_ref().map_or(0, |auths_list| {
3499 auths_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3500 })
3501 }
3502 Some(TxKind::Create) => MIN_CREATE_GAS,
3503 None => MIN_CREATE_GAS,
3505 }
3506}
3507
3508enum GasEstimationCallResult {
3510 Success(u128),
3511 OutOfGas,
3512 Revert(Option<Bytes>),
3513 EvmError(InstructionResult),
3514}
3515
3516impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3520 type Error = BlockchainError;
3521
3522 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3523 match res {
3524 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3526 Ok(Self::OutOfGas)
3527 }
3528 Err(err) => Err(err),
3529 Ok((exit, output, gas, _)) => match exit {
3530 return_ok!() => Ok(Self::Success(gas)),
3531
3532 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3534 InstructionResult::CallTooDeep
3535 | InstructionResult::OutOfFunds
3536 | InstructionResult::CreateInitCodeStartingEF00
3537 | InstructionResult::InvalidEOFInitCode
3538 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3539
3540 InstructionResult::OutOfGas
3542 | InstructionResult::MemoryOOG
3543 | InstructionResult::MemoryLimitOOG
3544 | InstructionResult::PrecompileOOG
3545 | InstructionResult::InvalidOperandOOG
3546 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3547
3548 InstructionResult::OpcodeNotFound
3550 | InstructionResult::CallNotAllowedInsideStatic
3551 | InstructionResult::StateChangeDuringStaticCall
3552 | InstructionResult::InvalidFEOpcode
3553 | InstructionResult::InvalidJump
3554 | InstructionResult::NotActivated
3555 | InstructionResult::StackUnderflow
3556 | InstructionResult::StackOverflow
3557 | InstructionResult::OutOfOffset
3558 | InstructionResult::CreateCollision
3559 | InstructionResult::OverflowPayment
3560 | InstructionResult::PrecompileError
3561 | InstructionResult::NonceOverflow
3562 | InstructionResult::CreateContractSizeLimit
3563 | InstructionResult::CreateContractStartingWithEF
3564 | InstructionResult::CreateInitCodeSizeLimit
3565 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3566 },
3567 }
3568 }
3569}