1use super::{
2 backend::mem::{BlockRequest, DatabaseRef, State},
3 sign::build_typed_transaction,
4};
5use crate::{
6 ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
7 eth::{
8 backend::{
9 self,
10 db::SerializableState,
11 mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
12 notifications::NewBlockNotifications,
13 validate::TransactionValidator,
14 },
15 error::{
16 BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
17 },
18 fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
19 macros::node_info,
20 miner::FixedBlockTimeMiner,
21 pool::{
22 Pool,
23 transactions::{
24 PoolTransaction, TransactionOrder, TransactionPriority, TxMarker, to_marker,
25 },
26 },
27 sign::{self, Signer},
28 },
29 filter::{EthFilter, Filters, LogsFilter},
30 mem::transaction_build,
31};
32use alloy_consensus::{Blob, Transaction, TrieAccount, TxEip4844Variant, transaction::Recovered};
33use alloy_dyn_abi::TypedData;
34use alloy_eips::{
35 eip2718::Encodable2718,
36 eip7910::{EthConfig, EthForkConfig},
37};
38use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
39use alloy_network::{
40 AnyRpcBlock, AnyRpcTransaction, BlockResponse, ReceiptResponse, TransactionBuilder,
41 TransactionBuilder4844, TransactionResponse, eip2718::Decodable2718,
42};
43use alloy_primitives::{
44 Address, B64, B256, Bytes, Signature, TxHash, TxKind, U64, U256,
45 map::{HashMap, HashSet},
46};
47use alloy_rpc_types::{
48 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
49 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
50 anvil::{
51 ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
52 },
53 request::TransactionRequest,
54 simulate::{SimulatePayload, SimulatedBlock},
55 state::{AccountOverride, EvmOverrides, StateOverridesBuilder},
56 trace::{
57 filter::TraceFilter,
58 geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
59 parity::LocalizedTransactionTrace,
60 },
61 txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
62};
63use alloy_rpc_types_eth::FillTransaction;
64use alloy_serde::WithOtherFields;
65use alloy_sol_types::{SolCall, SolValue, sol};
66use alloy_transport::TransportErrorKind;
67use anvil_core::{
68 eth::{
69 EthRequest,
70 block::BlockInfo,
71 transaction::{MaybeImpersonatedTransaction, PendingTransaction},
72 wallet::WalletCapabilities,
73 },
74 types::{ReorgOptions, TransactionData},
75};
76use anvil_rpc::{error::RpcError, response::ResponseResult};
77use foundry_common::provider::ProviderBuilder;
78use foundry_evm::decode::RevertDecoder;
79use foundry_primitives::{
80 FoundryTransactionRequest, FoundryTxEnvelope, FoundryTxReceipt, FoundryTxType, FoundryTypedTx,
81};
82use futures::{
83 StreamExt, TryFutureExt,
84 channel::{mpsc::Receiver, oneshot},
85};
86use parking_lot::RwLock;
87use revm::{
88 context::BlockEnv,
89 context_interface::{block::BlobExcessGasAndPrice, result::Output},
90 database::CacheDB,
91 interpreter::{InstructionResult, return_ok, return_revert},
92 primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
93};
94use std::{sync::Arc, time::Duration};
95use tokio::{
96 sync::mpsc::{UnboundedReceiver, unbounded_channel},
97 try_join,
98};
99
100pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
102
103#[derive(Clone)]
107pub struct EthApi {
108 pool: Arc<Pool>,
110 pub backend: Arc<backend::mem::Backend>,
113 is_mining: bool,
115 signers: Arc<Vec<Box<dyn Signer>>>,
117 fee_history_cache: FeeHistoryCache,
119 fee_history_limit: u64,
121 miner: Miner,
126 logger: LoggingManager,
128 filters: Filters,
130 transaction_order: Arc<RwLock<TransactionOrder>>,
132 net_listening: bool,
134 instance_id: Arc<RwLock<B256>>,
136}
137
138impl EthApi {
139 #[expect(clippy::too_many_arguments)]
141 pub fn new(
142 pool: Arc<Pool>,
143 backend: Arc<backend::mem::Backend>,
144 signers: Arc<Vec<Box<dyn Signer>>>,
145 fee_history_cache: FeeHistoryCache,
146 fee_history_limit: u64,
147 miner: Miner,
148 logger: LoggingManager,
149 filters: Filters,
150 transactions_order: TransactionOrder,
151 ) -> Self {
152 Self {
153 pool,
154 backend,
155 is_mining: true,
156 signers,
157 fee_history_cache,
158 fee_history_limit,
159 miner,
160 logger,
161 filters,
162 net_listening: true,
163 transaction_order: Arc::new(RwLock::new(transactions_order)),
164 instance_id: Arc::new(RwLock::new(B256::random())),
165 }
166 }
167
168 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
170 trace!(target: "rpc::api", "executing eth request");
171 let response = match request.clone() {
172 EthRequest::EthProtocolVersion(()) => self.protocol_version().to_rpc_result(),
173 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
174 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
175 EthRequest::EthGetAccount(addr, block) => {
176 self.get_account(addr, block).await.to_rpc_result()
177 }
178 EthRequest::EthGetAccountInfo(addr, block) => {
179 self.get_account_info(addr, block).await.to_rpc_result()
180 }
181 EthRequest::EthGetBalance(addr, block) => {
182 self.balance(addr, block).await.to_rpc_result()
183 }
184 EthRequest::EthGetTransactionByHash(hash) => {
185 self.transaction_by_hash(hash).await.to_rpc_result()
186 }
187 EthRequest::EthSendTransaction(request) => {
188 self.send_transaction(*request).await.to_rpc_result()
189 }
190 EthRequest::EthSendTransactionSync(request) => {
191 self.send_transaction_sync(*request).await.to_rpc_result()
192 }
193 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
194 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
195 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
196 EthRequest::EthHashrate(()) => self.hashrate().to_rpc_result(),
197 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
198 EthRequest::EthMaxPriorityFeePerGas(_) => {
199 self.gas_max_priority_fee_per_gas().to_rpc_result()
200 }
201 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
202 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
203 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
204 EthRequest::EthCoinbase(()) => self.author().to_rpc_result(),
205 EthRequest::EthGetStorageAt(addr, slot, block) => {
206 self.storage_at(addr, slot, block).await.to_rpc_result()
207 }
208 EthRequest::EthGetBlockByHash(hash, full) => {
209 if full {
210 self.block_by_hash_full(hash).await.to_rpc_result()
211 } else {
212 self.block_by_hash(hash).await.to_rpc_result()
213 }
214 }
215 EthRequest::EthGetBlockByNumber(num, full) => {
216 if full {
217 self.block_by_number_full(num).await.to_rpc_result()
218 } else {
219 self.block_by_number(num).await.to_rpc_result()
220 }
221 }
222 EthRequest::EthGetTransactionCount(addr, block) => {
223 self.transaction_count(addr, block).await.to_rpc_result()
224 }
225 EthRequest::EthGetTransactionCountByHash(hash) => {
226 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
227 }
228 EthRequest::EthGetTransactionCountByNumber(num) => {
229 self.block_transaction_count_by_number(num).await.to_rpc_result()
230 }
231 EthRequest::EthGetUnclesCountByHash(hash) => {
232 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
233 }
234 EthRequest::EthGetUnclesCountByNumber(num) => {
235 self.block_uncles_count_by_number(num).await.to_rpc_result()
236 }
237 EthRequest::EthGetCodeAt(addr, block) => {
238 self.get_code(addr, block).await.to_rpc_result()
239 }
240 EthRequest::EthGetProof(addr, keys, block) => {
241 self.get_proof(addr, keys, block).await.to_rpc_result()
242 }
243 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
244 EthRequest::PersonalSign(content, addr) => {
245 self.sign(addr, content).await.to_rpc_result()
246 }
247 EthRequest::EthSignTransaction(request) => {
248 self.sign_transaction(*request).await.to_rpc_result()
249 }
250 EthRequest::EthSignTypedData(addr, data) => {
251 self.sign_typed_data(addr, data).await.to_rpc_result()
252 }
253 EthRequest::EthSignTypedDataV3(addr, data) => {
254 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
255 }
256 EthRequest::EthSignTypedDataV4(addr, data) => {
257 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
258 }
259 EthRequest::EthSendRawTransaction(tx) => {
260 self.send_raw_transaction(tx).await.to_rpc_result()
261 }
262 EthRequest::EthSendRawTransactionSync(tx) => {
263 self.send_raw_transaction_sync(tx).await.to_rpc_result()
264 }
265 EthRequest::EthCall(call, block, state_override, block_overrides) => self
266 .call(call, block, EvmOverrides::new(state_override, block_overrides))
267 .await
268 .to_rpc_result(),
269 EthRequest::EthSimulateV1(simulation, block) => {
270 self.simulate_v1(simulation, block).await.to_rpc_result()
271 }
272 EthRequest::EthCreateAccessList(call, block) => {
273 self.create_access_list(call, block).await.to_rpc_result()
274 }
275 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
276 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
277 .await
278 .to_rpc_result(),
279 EthRequest::EthFillTransaction(request) => {
280 self.fill_transaction(request).await.to_rpc_result()
281 }
282 EthRequest::EthGetRawTransactionByHash(hash) => {
283 self.raw_transaction(hash).await.to_rpc_result()
284 }
285 EthRequest::GetBlobByHash(hash) => {
286 self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
287 }
288 EthRequest::GetBlobByTransactionHash(hash) => {
289 self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
290 }
291 EthRequest::GetGenesisTime(()) => self.anvil_get_genesis_time().to_rpc_result(),
292 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
293 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
294 }
295 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
296 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
297 }
298 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
299 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
300 }
301 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
302 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
303 }
304 EthRequest::EthGetTransactionReceipt(tx) => {
305 self.transaction_receipt(tx).await.to_rpc_result()
306 }
307 EthRequest::EthGetBlockReceipts(number) => {
308 self.block_receipts(number).await.to_rpc_result()
309 }
310 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
311 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
312 }
313 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
314 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
315 }
316 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
317 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
318 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
319 EthRequest::EthConfig(_) => self.config().to_rpc_result(),
320 EthRequest::EthSubmitWork(nonce, pow, digest) => {
321 self.submit_work(nonce, pow, digest).to_rpc_result()
322 }
323 EthRequest::EthSubmitHashRate(rate, id) => {
324 self.submit_hashrate(rate, id).to_rpc_result()
325 }
326 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
327 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
328 }
329 EthRequest::DebugGetRawTransaction(hash) => {
331 self.raw_transaction(hash).await.to_rpc_result()
332 }
333 EthRequest::DebugTraceTransaction(tx, opts) => {
335 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
336 }
337 EthRequest::DebugTraceCall(tx, block, opts) => {
339 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
340 }
341 EthRequest::DebugCodeByHash(hash, block) => {
342 self.debug_code_by_hash(hash, block).await.to_rpc_result()
343 }
344 EthRequest::DebugDbGet(key) => self.debug_db_get(key).await.to_rpc_result(),
345 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
346 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
347 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
348 EthRequest::ImpersonateAccount(addr) => {
349 self.anvil_impersonate_account(addr).await.to_rpc_result()
350 }
351 EthRequest::StopImpersonatingAccount(addr) => {
352 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
353 }
354 EthRequest::AutoImpersonateAccount(enable) => {
355 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
356 }
357 EthRequest::ImpersonateSignature(signature, address) => {
358 self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
359 }
360 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
361 EthRequest::Mine(blocks, interval) => {
362 self.anvil_mine(blocks, interval).await.to_rpc_result()
363 }
364 EthRequest::SetAutomine(enabled) => {
365 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
366 }
367 EthRequest::SetIntervalMining(interval) => {
368 self.anvil_set_interval_mining(interval).to_rpc_result()
369 }
370 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
371 EthRequest::DropTransaction(tx) => {
372 self.anvil_drop_transaction(tx).await.to_rpc_result()
373 }
374 EthRequest::DropAllTransactions() => {
375 self.anvil_drop_all_transactions().await.to_rpc_result()
376 }
377 EthRequest::Reset(fork) => {
378 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
379 }
380 EthRequest::SetBalance(addr, val) => {
381 self.anvil_set_balance(addr, val).await.to_rpc_result()
382 }
383 EthRequest::AddBalance(addr, val) => {
384 self.anvil_add_balance(addr, val).await.to_rpc_result()
385 }
386 EthRequest::DealERC20(addr, token_addr, val) => {
387 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
388 }
389 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
390 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
391 .await
392 .to_rpc_result(),
393 EthRequest::SetCode(addr, code) => {
394 self.anvil_set_code(addr, code).await.to_rpc_result()
395 }
396 EthRequest::SetNonce(addr, nonce) => {
397 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
398 }
399 EthRequest::SetStorageAt(addr, slot, val) => {
400 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
401 }
402 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
403 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
404 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
405 EthRequest::SetMinGasPrice(gas) => {
406 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
407 }
408 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
409 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
410 }
411 EthRequest::DumpState(preserve_historical_states) => self
412 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
413 .await
414 .to_rpc_result(),
415 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
416 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
417 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
418 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
419 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
420 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
421 EthRequest::EvmSetNextBlockTimeStamp(time) => {
422 if time >= U256::from(u64::MAX) {
423 return ResponseResult::Error(RpcError::invalid_params(
424 "The timestamp is too big",
425 ));
426 }
427 let time = time.to::<u64>();
428 self.evm_set_next_block_timestamp(time).to_rpc_result()
429 }
430 EthRequest::EvmSetTime(timestamp) => {
431 if timestamp >= U256::from(u64::MAX) {
432 return ResponseResult::Error(RpcError::invalid_params(
433 "The timestamp is too big",
434 ));
435 }
436 let time = timestamp.to::<u64>();
437 self.evm_set_time(time).to_rpc_result()
438 }
439 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
440 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
441 }
442 EthRequest::EvmSetBlockTimeStampInterval(time) => {
443 self.evm_set_block_timestamp_interval(time).to_rpc_result()
444 }
445 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
446 self.evm_remove_block_timestamp_interval().to_rpc_result()
447 }
448 EthRequest::EvmMine(mine) => {
449 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
450 }
451 EthRequest::EvmMineDetailed(mine) => {
452 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
453 }
454 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
455 EthRequest::EthSendUnsignedTransaction(tx) => {
456 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
457 }
458 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
459 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
460 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
461 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
462 EthRequest::EthNewPendingTransactionFilter(_) => {
463 self.new_pending_transaction_filter().await.to_rpc_result()
464 }
465 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
466 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
467 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
468 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
469 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
470 EthRequest::ErigonGetHeaderByNumber(num) => {
471 self.erigon_get_header_by_number(num).await.to_rpc_result()
472 }
473 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
474 EthRequest::OtsGetInternalOperations(hash) => {
475 self.ots_get_internal_operations(hash).await.to_rpc_result()
476 }
477 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
478 EthRequest::OtsTraceTransaction(hash) => {
479 self.ots_trace_transaction(hash).await.to_rpc_result()
480 }
481 EthRequest::OtsGetTransactionError(hash) => {
482 self.ots_get_transaction_error(hash).await.to_rpc_result()
483 }
484 EthRequest::OtsGetBlockDetails(num) => {
485 self.ots_get_block_details(num).await.to_rpc_result()
486 }
487 EthRequest::OtsGetBlockDetailsByHash(hash) => {
488 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
489 }
490 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
491 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
492 }
493 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
494 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
495 }
496 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
497 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
498 }
499 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
500 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
501 }
502 EthRequest::EthGetTransactionBySenderAndNonce(sender, nonce) => {
503 self.transaction_by_sender_and_nonce(sender, nonce).await.to_rpc_result()
504 }
505 EthRequest::OtsGetContractCreator(address) => {
506 self.ots_get_contract_creator(address).await.to_rpc_result()
507 }
508 EthRequest::RemovePoolTransactions(address) => {
509 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
510 }
511 EthRequest::Reorg(reorg_options) => {
512 self.anvil_reorg(reorg_options).await.to_rpc_result()
513 }
514 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
515 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
516 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
517 EthRequest::AnvilSetExecutor(executor_pk) => {
518 self.anvil_set_executor(executor_pk).to_rpc_result()
519 }
520 };
521
522 if let ResponseResult::Error(err) = &response {
523 node_info!("\nRPC request failed:");
524 node_info!(" Request: {:?}", request);
525 node_info!(" Error: {}\n", err);
526 }
527
528 response
529 }
530
531 fn sign_request(&self, from: &Address, request: FoundryTypedTx) -> Result<FoundryTxEnvelope> {
532 match request {
533 FoundryTypedTx::Deposit(_) => {
534 let nil_signature = Signature::from_scalars_and_parity(
535 B256::with_last_byte(1),
536 B256::with_last_byte(1),
537 false,
538 );
539 return build_typed_transaction(request, nil_signature);
540 }
541 _ => {
542 for signer in self.signers.iter() {
543 if signer.accounts().contains(from) {
544 let signature = signer.sign_transaction(request.clone(), from)?;
545 return build_typed_transaction(request, signature);
546 }
547 }
548 }
549 }
550 Err(BlockchainError::NoSignerAvailable)
551 }
552
553 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
554 let block_request = match block_number {
555 Some(BlockId::Number(BlockNumber::Pending)) => {
556 let pending_txs = self.pool.ready_transactions().collect();
557 BlockRequest::Pending(pending_txs)
558 }
559 _ => {
560 let number = self.backend.ensure_block_number(block_number).await?;
561 BlockRequest::Number(number)
562 }
563 };
564 Ok(block_request)
565 }
566
567 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
568 match self.pool.get_transaction(hash) {
569 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
570 None => match self.backend.transaction_by_hash(hash).await? {
571 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
572 None => Ok(None),
573 },
574 }
575 }
576
577 pub fn client_version(&self) -> Result<String> {
581 node_info!("web3_clientVersion");
582 Ok(CLIENT_VERSION.to_string())
583 }
584
585 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
589 node_info!("web3_sha3");
590 let hash = alloy_primitives::keccak256(bytes.as_ref());
591 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
592 }
593
594 pub fn protocol_version(&self) -> Result<u64> {
598 node_info!("eth_protocolVersion");
599 Ok(1)
600 }
601
602 pub fn hashrate(&self) -> Result<U256> {
606 node_info!("eth_hashrate");
607 Ok(U256::ZERO)
608 }
609
610 pub fn author(&self) -> Result<Address> {
614 node_info!("eth_coinbase");
615 Ok(self.backend.coinbase())
616 }
617
618 pub fn is_mining(&self) -> Result<bool> {
622 node_info!("eth_mining");
623 Ok(self.is_mining)
624 }
625
626 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
632 node_info!("eth_chainId");
633 Ok(Some(self.backend.chain_id().to::<U64>()))
634 }
635
636 pub fn network_id(&self) -> Result<Option<String>> {
640 node_info!("eth_networkId");
641 let chain_id = self.backend.chain_id().to::<u64>();
642 Ok(Some(format!("{chain_id}")))
643 }
644
645 pub fn net_listening(&self) -> Result<bool> {
649 node_info!("net_listening");
650 Ok(self.net_listening)
651 }
652
653 fn eth_gas_price(&self) -> Result<U256> {
655 node_info!("eth_gasPrice");
656 Ok(U256::from(self.gas_price()))
657 }
658
659 pub fn gas_price(&self) -> u128 {
661 if self.backend.is_eip1559() {
662 if self.backend.is_min_priority_fee_enforced() {
663 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
664 } else {
665 self.backend.base_fee() as u128
666 }
667 } else {
668 self.backend.fees().raw_gas_price()
669 }
670 }
671
672 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
674 Ok(self.backend.excess_blob_gas_and_price())
675 }
676
677 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
682 self.max_priority_fee_per_gas()
683 }
684
685 pub fn blob_base_fee(&self) -> Result<U256> {
689 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
690 }
691
692 pub fn gas_limit(&self) -> U256 {
694 U256::from(self.backend.gas_limit())
695 }
696
697 pub fn accounts(&self) -> Result<Vec<Address>> {
701 node_info!("eth_accounts");
702 let mut unique = HashSet::new();
703 let mut accounts: Vec<Address> = Vec::new();
704 for signer in self.signers.iter() {
705 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
706 }
707 accounts.extend(
708 self.backend
709 .cheats()
710 .impersonated_accounts()
711 .into_iter()
712 .filter(|acc| unique.insert(*acc)),
713 );
714 Ok(accounts.into_iter().collect())
715 }
716
717 pub fn block_number(&self) -> Result<U256> {
721 node_info!("eth_blockNumber");
722 Ok(U256::from(self.backend.best_number()))
723 }
724
725 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
729 node_info!("eth_getBalance");
730 let block_request = self.block_request(block_number).await?;
731
732 if let BlockRequest::Number(number) = block_request
734 && let Some(fork) = self.get_fork()
735 && fork.predates_fork(number)
736 {
737 return Ok(fork.get_balance(address, number).await?);
738 }
739
740 self.backend.get_balance(address, Some(block_request)).await
741 }
742
743 pub async fn get_account(
747 &self,
748 address: Address,
749 block_number: Option<BlockId>,
750 ) -> Result<TrieAccount> {
751 node_info!("eth_getAccount");
752 let block_request = self.block_request(block_number).await?;
753
754 if let BlockRequest::Number(number) = block_request
756 && let Some(fork) = self.get_fork()
757 && fork.predates_fork(number)
758 {
759 return Ok(fork.get_account(address, number).await?);
760 }
761
762 self.backend.get_account_at_block(address, Some(block_request)).await
763 }
764
765 pub async fn get_account_info(
769 &self,
770 address: Address,
771 block_number: Option<BlockId>,
772 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
773 node_info!("eth_getAccountInfo");
774
775 if let Some(fork) = self.get_fork() {
776 let block_request = self.block_request(block_number).await?;
777 if let BlockRequest::Number(number) = block_request {
779 trace!(target: "node", "get_account_info: fork block {}, requested block {number}", fork.block_number());
780 return if fork.predates_fork(number) {
781 let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
784 let code = fork.get_code(address, number).map_err(BlockchainError::from);
785 let nonce = self.get_transaction_count(address, Some(number.into()));
786 let (balance, code, nonce) = try_join!(balance, code, nonce)?;
787
788 Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code })
789 } else {
790 let account_info = self.backend.get_account(address).await?;
793 let code = self.backend.get_code(address, Some(block_request)).await?;
794 Ok(alloy_rpc_types::eth::AccountInfo {
795 balance: account_info.balance,
796 nonce: account_info.nonce,
797 code,
798 })
799 };
800 }
801 }
802
803 let account = self.get_account(address, block_number);
804 let code = self.get_code(address, block_number);
805 let (account, code) = try_join!(account, code)?;
806 Ok(alloy_rpc_types::eth::AccountInfo {
807 balance: account.balance,
808 nonce: account.nonce,
809 code,
810 })
811 }
812 pub async fn storage_at(
816 &self,
817 address: Address,
818 index: U256,
819 block_number: Option<BlockId>,
820 ) -> Result<B256> {
821 node_info!("eth_getStorageAt");
822 let block_request = self.block_request(block_number).await?;
823
824 if let BlockRequest::Number(number) = block_request
826 && let Some(fork) = self.get_fork()
827 && fork.predates_fork(number)
828 {
829 return Ok(B256::from(
830 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
831 ));
832 }
833
834 self.backend.storage_at(address, index, Some(block_request)).await
835 }
836
837 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
841 node_info!("eth_getBlockByHash");
842 self.backend.block_by_hash(hash).await
843 }
844
845 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
849 node_info!("eth_getBlockByHash");
850 self.backend.block_by_hash_full(hash).await
851 }
852
853 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
857 node_info!("eth_getBlockByNumber");
858 if number == BlockNumber::Pending {
859 return Ok(Some(self.pending_block().await));
860 }
861
862 self.backend.block_by_number(number).await
863 }
864
865 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
869 node_info!("eth_getBlockByNumber");
870 if number == BlockNumber::Pending {
871 return Ok(self.pending_block_full().await);
872 }
873 self.backend.block_by_number_full(number).await
874 }
875
876 pub async fn transaction_count(
883 &self,
884 address: Address,
885 block_number: Option<BlockId>,
886 ) -> Result<U256> {
887 node_info!("eth_getTransactionCount");
888 self.get_transaction_count(address, block_number).await.map(U256::from)
889 }
890
891 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
895 node_info!("eth_getBlockTransactionCountByHash");
896 let block = self.backend.block_by_hash(hash).await?;
897 let txs = block.map(|b| match b.transactions() {
898 BlockTransactions::Full(txs) => U256::from(txs.len()),
899 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
900 BlockTransactions::Uncle => U256::from(0),
901 });
902 Ok(txs)
903 }
904
905 pub async fn block_transaction_count_by_number(
909 &self,
910 block_number: BlockNumber,
911 ) -> Result<Option<U256>> {
912 node_info!("eth_getBlockTransactionCountByNumber");
913 let block_request = self.block_request(Some(block_number.into())).await?;
914 if let BlockRequest::Pending(txs) = block_request {
915 let block = self.backend.pending_block(txs).await;
916 return Ok(Some(U256::from(block.block.body.transactions.len())));
917 }
918 let block = self.backend.block_by_number(block_number).await?;
919 let txs = block.map(|b| match b.transactions() {
920 BlockTransactions::Full(txs) => U256::from(txs.len()),
921 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
922 BlockTransactions::Uncle => U256::from(0),
923 });
924 Ok(txs)
925 }
926
927 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
931 node_info!("eth_getUncleCountByBlockHash");
932 let block =
933 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
934 Ok(U256::from(block.uncles.len()))
935 }
936
937 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
941 node_info!("eth_getUncleCountByBlockNumber");
942 let block = self
943 .backend
944 .block_by_number(block_number)
945 .await?
946 .ok_or(BlockchainError::BlockNotFound)?;
947 Ok(U256::from(block.uncles.len()))
948 }
949
950 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
954 node_info!("eth_getCode");
955 let block_request = self.block_request(block_number).await?;
956 if let BlockRequest::Number(number) = block_request
958 && let Some(fork) = self.get_fork()
959 && fork.predates_fork(number)
960 {
961 return Ok(fork.get_code(address, number).await?);
962 }
963 self.backend.get_code(address, Some(block_request)).await
964 }
965
966 pub async fn get_proof(
971 &self,
972 address: Address,
973 keys: Vec<B256>,
974 block_number: Option<BlockId>,
975 ) -> Result<EIP1186AccountProofResponse> {
976 node_info!("eth_getProof");
977 let block_request = self.block_request(block_number).await?;
978
979 if let BlockRequest::Number(number) = block_request
982 && let Some(fork) = self.get_fork()
983 && fork.predates_fork_inclusive(number)
984 {
985 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
986 }
987
988 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
989 Ok(proof)
990 }
991
992 pub async fn sign_typed_data(
996 &self,
997 _address: Address,
998 _data: serde_json::Value,
999 ) -> Result<String> {
1000 node_info!("eth_signTypedData");
1001 Err(BlockchainError::RpcUnimplemented)
1002 }
1003
1004 pub async fn sign_typed_data_v3(
1008 &self,
1009 _address: Address,
1010 _data: serde_json::Value,
1011 ) -> Result<String> {
1012 node_info!("eth_signTypedData_v3");
1013 Err(BlockchainError::RpcUnimplemented)
1014 }
1015
1016 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
1020 node_info!("eth_signTypedData_v4");
1021 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1022 let signature = signer.sign_typed_data(address, data).await?;
1023 let signature = alloy_primitives::hex::encode(signature.as_bytes());
1024 Ok(format!("0x{signature}"))
1025 }
1026
1027 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1031 node_info!("eth_sign");
1032 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1033 let signature =
1034 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1035 Ok(format!("0x{signature}"))
1036 }
1037
1038 pub async fn sign_transaction(
1042 &self,
1043 request: WithOtherFields<TransactionRequest>,
1044 ) -> Result<String> {
1045 node_info!("eth_signTransaction");
1046
1047 let from = request.from.map(Ok).unwrap_or_else(|| {
1048 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1049 })?;
1050
1051 let (nonce, _) = self.request_nonce(&request, from).await?;
1052
1053 let request = self.build_tx_request(request, nonce).await?;
1054
1055 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1056 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1057 }
1058
1059 pub async fn send_transaction(
1063 &self,
1064 request: WithOtherFields<TransactionRequest>,
1065 ) -> Result<TxHash> {
1066 node_info!("eth_sendTransaction");
1067
1068 let from = request.from.map(Ok).unwrap_or_else(|| {
1069 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1070 })?;
1071 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1072
1073 let request = self.build_tx_request(request, nonce).await?;
1074
1075 let pending_transaction = if self.is_impersonated(from) {
1077 let bypass_signature = self.impersonated_signature(&request);
1078 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1079 self.ensure_typed_transaction_supported(&transaction)?;
1080 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1081 PendingTransaction::with_impersonated(transaction, from)
1082 } else {
1083 let transaction = self.sign_request(&from, request)?;
1084 self.ensure_typed_transaction_supported(&transaction)?;
1085 PendingTransaction::new(transaction)?
1086 };
1087 self.backend.validate_pool_transaction(&pending_transaction).await?;
1089
1090 let requires = required_marker(nonce, on_chain_nonce, from);
1091 let provides = vec![to_marker(nonce, from)];
1092 debug_assert!(requires != provides);
1093
1094 self.add_pending_transaction(pending_transaction, requires, provides)
1095 }
1096
1097 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
1099 let mut stream = self.new_block_notifications();
1100 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1102 return Ok(receipt);
1103 }
1104 while let Some(notification) = stream.next().await {
1105 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1106 && block.body.transactions.iter().any(|tx| tx.hash() == hash)
1107 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1108 {
1109 return Ok(receipt);
1110 }
1111 }
1112
1113 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1114 }
1115
1116 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<FoundryTxReceipt> {
1118 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1119 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1120 .await
1121 .unwrap_or_else(|_elapsed| {
1122 Err(BlockchainError::TransactionConfirmationTimeout {
1123 hash,
1124 duration: TIMEOUT_DURATION,
1125 })
1126 })
1127 }
1128
1129 pub async fn send_transaction_sync(
1133 &self,
1134 request: WithOtherFields<TransactionRequest>,
1135 ) -> Result<FoundryTxReceipt> {
1136 node_info!("eth_sendTransactionSync");
1137 let hash = self.send_transaction(request).await?;
1138
1139 let receipt = self.check_transaction_inclusion(hash).await?;
1140
1141 Ok(receipt)
1142 }
1143
1144 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1148 node_info!("eth_sendRawTransaction");
1149 let mut data = tx.as_ref();
1150 if data.is_empty() {
1151 return Err(BlockchainError::EmptyRawTransactionData);
1152 }
1153
1154 let transaction = FoundryTxEnvelope::decode_2718(&mut data)
1155 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1156
1157 self.ensure_typed_transaction_supported(&transaction)?;
1158
1159 let pending_transaction = PendingTransaction::new(transaction)?;
1160
1161 self.backend.validate_pool_transaction(&pending_transaction).await?;
1163
1164 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1165 let from = *pending_transaction.sender();
1166 let nonce = pending_transaction.transaction.nonce();
1167 let requires = required_marker(nonce, on_chain_nonce, from);
1168
1169 let priority = self.transaction_priority(&pending_transaction.transaction);
1170 let pool_transaction = PoolTransaction {
1171 requires,
1172 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1173 pending_transaction,
1174 priority,
1175 };
1176
1177 let tx = self.pool.add_transaction(pool_transaction)?;
1178 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1179 Ok(*tx.hash())
1180 }
1181
1182 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<FoundryTxReceipt> {
1186 node_info!("eth_sendRawTransactionSync");
1187
1188 let hash = self.send_raw_transaction(tx).await?;
1189 let receipt = self.check_transaction_inclusion(hash).await?;
1190
1191 Ok(receipt)
1192 }
1193
1194 pub async fn call(
1198 &self,
1199 request: WithOtherFields<TransactionRequest>,
1200 block_number: Option<BlockId>,
1201 overrides: EvmOverrides,
1202 ) -> Result<Bytes> {
1203 node_info!("eth_call");
1204 let block_request = self.block_request(block_number).await?;
1205 if let BlockRequest::Number(number) = block_request
1207 && let Some(fork) = self.get_fork()
1208 && fork.predates_fork(number)
1209 {
1210 if overrides.has_state() || overrides.has_block() {
1211 return Err(BlockchainError::EvmOverrideError(
1212 "not available on past forked blocks".to_string(),
1213 ));
1214 }
1215 return Ok(fork.call(&request, Some(number.into())).await?);
1216 }
1217
1218 let fees = FeeDetails::new(
1219 request.gas_price,
1220 request.max_fee_per_gas,
1221 request.max_priority_fee_per_gas,
1222 request.max_fee_per_blob_gas,
1223 )?
1224 .or_zero_fees();
1225 self.on_blocking_task(|this| async move {
1228 let (exit, out, gas, _) =
1229 this.backend.call(request, fees, Some(block_request), overrides).await?;
1230 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1231
1232 ensure_return_ok(exit, &out)
1233 })
1234 .await
1235 }
1236
1237 pub async fn simulate_v1(
1238 &self,
1239 request: SimulatePayload,
1240 block_number: Option<BlockId>,
1241 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1242 node_info!("eth_simulateV1");
1243 let block_request = self.block_request(block_number).await?;
1244 if let BlockRequest::Number(number) = block_request
1246 && let Some(fork) = self.get_fork()
1247 && fork.predates_fork(number)
1248 {
1249 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1250 }
1251
1252 self.on_blocking_task(|this| async move {
1255 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1256 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1257
1258 Ok(simulated_blocks)
1259 })
1260 .await
1261 }
1262
1263 pub async fn create_access_list(
1277 &self,
1278 mut request: WithOtherFields<TransactionRequest>,
1279 block_number: Option<BlockId>,
1280 ) -> Result<AccessListResult> {
1281 node_info!("eth_createAccessList");
1282 let block_request = self.block_request(block_number).await?;
1283 if let BlockRequest::Number(number) = block_request
1285 && let Some(fork) = self.get_fork()
1286 && fork.predates_fork(number)
1287 {
1288 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1289 }
1290
1291 self.backend
1292 .with_database_at(Some(block_request), |state, block_env| {
1293 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1294 &state,
1295 request.clone(),
1296 FeeDetails::zero(),
1297 block_env.clone(),
1298 )?;
1299 ensure_return_ok(exit, &out)?;
1300
1301 request.access_list = Some(access_list.clone());
1303
1304 let (exit, out, gas_used, _) = self.backend.call_with_state(
1305 &state,
1306 request.clone(),
1307 FeeDetails::zero(),
1308 block_env,
1309 )?;
1310 ensure_return_ok(exit, &out)?;
1311
1312 Ok(AccessListResult {
1313 access_list: AccessList(access_list.0),
1314 gas_used: U256::from(gas_used),
1315 error: None,
1316 })
1317 })
1318 .await?
1319 }
1320
1321 pub async fn estimate_gas(
1326 &self,
1327 request: WithOtherFields<TransactionRequest>,
1328 block_number: Option<BlockId>,
1329 overrides: EvmOverrides,
1330 ) -> Result<U256> {
1331 node_info!("eth_estimateGas");
1332 self.do_estimate_gas(
1333 request,
1334 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1335 overrides,
1336 )
1337 .await
1338 .map(U256::from)
1339 }
1340
1341 pub async fn fill_transaction(
1348 &self,
1349 mut request: WithOtherFields<TransactionRequest>,
1350 ) -> Result<FillTransaction<AnyRpcTransaction>> {
1351 node_info!("eth_fillTransaction");
1352
1353 let from = match request.as_ref().from() {
1354 Some(from) => from,
1355 None => self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)?,
1356 };
1357
1358 let nonce = if let Some(nonce) = request.as_ref().nonce() {
1359 nonce
1360 } else {
1361 self.request_nonce(&request, from).await?.0
1362 };
1363
1364 if request.as_ref().gas_limit().is_none() {
1368 let estimated_gas =
1369 self.estimate_gas(request.clone(), None, EvmOverrides::default()).await?;
1370 request.as_mut().set_gas_limit(estimated_gas.to());
1371 }
1372
1373 let typed_tx = self.build_tx_request(request, nonce).await?;
1374 let tx = build_typed_transaction(
1375 typed_tx,
1376 Signature::new(Default::default(), Default::default(), false),
1377 )?;
1378
1379 let raw = tx.encoded_2718().to_vec().into();
1380
1381 let mut tx =
1382 transaction_build(None, MaybeImpersonatedTransaction::new(tx), None, None, None);
1383
1384 tx.0.inner.inner = Recovered::new_unchecked(tx.0.inner.inner.into_inner(), from);
1387
1388 Ok(FillTransaction { raw, tx })
1389 }
1390
1391 pub fn anvil_get_blob_by_versioned_hash(
1393 &self,
1394 hash: B256,
1395 ) -> Result<Option<alloy_consensus::Blob>> {
1396 node_info!("anvil_getBlobByHash");
1397 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1398 }
1399
1400 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1402 node_info!("anvil_getBlobsByTransactionHash");
1403 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1404 }
1405
1406 pub fn anvil_get_blobs_by_block_id(
1408 &self,
1409 block_id: impl Into<BlockId>,
1410 versioned_hashes: Vec<B256>,
1411 ) -> Result<Option<Vec<Blob>>> {
1412 node_info!("anvil_getBlobsByBlockId");
1413 Ok(self.backend.get_blobs_by_block_id(block_id, versioned_hashes)?)
1414 }
1415
1416 pub fn anvil_get_genesis_time(&self) -> Result<u64> {
1420 node_info!("anvil_getGenesisTime");
1421 Ok(self.backend.genesis_time())
1422 }
1423
1424 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1431 node_info!("eth_getTransactionByHash");
1432 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1433 let from = *pending.sender();
1434 let tx = transaction_build(
1435 Some(*pending.hash()),
1436 pending.transaction,
1437 None,
1438 None,
1439 Some(self.backend.base_fee()),
1440 );
1441
1442 let WithOtherFields { inner: mut tx, other } = tx.0;
1443 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1446
1447 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1448 });
1449 if tx.is_none() {
1450 tx = self.backend.transaction_by_hash(hash).await?
1451 }
1452
1453 Ok(tx)
1454 }
1455
1456 pub async fn transaction_by_block_hash_and_index(
1460 &self,
1461 hash: B256,
1462 index: Index,
1463 ) -> Result<Option<AnyRpcTransaction>> {
1464 node_info!("eth_getTransactionByBlockHashAndIndex");
1465 self.backend.transaction_by_block_hash_and_index(hash, index).await
1466 }
1467
1468 pub async fn transaction_by_block_number_and_index(
1472 &self,
1473 block: BlockNumber,
1474 idx: Index,
1475 ) -> Result<Option<AnyRpcTransaction>> {
1476 node_info!("eth_getTransactionByBlockNumberAndIndex");
1477 self.backend.transaction_by_block_number_and_index(block, idx).await
1478 }
1479
1480 pub async fn transaction_by_sender_and_nonce(
1487 &self,
1488 sender: Address,
1489 nonce: U256,
1490 ) -> Result<Option<AnyRpcTransaction>> {
1491 node_info!("eth_getTransactionBySenderAndNonce");
1492
1493 for pending_tx in self.pool.ready_transactions().chain(self.pool.pending_transactions()) {
1495 if U256::from(pending_tx.pending_transaction.nonce()) == nonce
1496 && *pending_tx.pending_transaction.sender() == sender
1497 {
1498 let tx = transaction_build(
1499 Some(*pending_tx.pending_transaction.hash()),
1500 pending_tx.pending_transaction.transaction.clone(),
1501 None,
1502 None,
1503 Some(self.backend.base_fee()),
1504 );
1505
1506 let WithOtherFields { inner: mut tx, other } = tx.0;
1507 let from = *pending_tx.pending_transaction.sender();
1510 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1511
1512 return Ok(Some(AnyRpcTransaction(WithOtherFields { inner: tx, other })));
1513 }
1514 }
1515
1516 let highest_nonce = self.transaction_count(sender, None).await?.saturating_to::<u64>();
1517 let target_nonce = nonce.saturating_to::<u64>();
1518
1519 if target_nonce >= highest_nonce {
1521 return Ok(None);
1522 }
1523
1524 let latest_block = self.backend.best_number();
1526 if latest_block == 0 {
1527 return Ok(None);
1528 }
1529
1530 let mut low = 1u64;
1532 let mut high = latest_block;
1533
1534 while low <= high {
1535 let mid = low + (high - low) / 2;
1536 let mid_nonce =
1537 self.transaction_count(sender, Some(mid.into())).await?.saturating_to::<u64>();
1538
1539 if mid_nonce > target_nonce {
1540 high = mid - 1;
1541 } else {
1542 low = mid + 1;
1543 }
1544 }
1545
1546 let target_block = low;
1548 if target_block <= latest_block
1549 && let Some(txs) =
1550 self.backend.mined_transactions_by_block_number(target_block.into()).await
1551 {
1552 for tx in txs {
1553 if tx.from() == sender
1554 && tx.nonce() == target_nonce
1555 && let Some(mined_tx) = self.backend.transaction_by_hash(tx.tx_hash()).await?
1556 {
1557 return Ok(Some(mined_tx));
1558 }
1559 }
1560 }
1561
1562 Ok(None)
1563 }
1564
1565 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<FoundryTxReceipt>> {
1569 node_info!("eth_getTransactionReceipt");
1570 self.backend.transaction_receipt(hash).await
1571 }
1572
1573 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<FoundryTxReceipt>>> {
1577 node_info!("eth_getBlockReceipts");
1578 self.backend.block_receipts(number).await
1579 }
1580
1581 pub async fn uncle_by_block_hash_and_index(
1585 &self,
1586 block_hash: B256,
1587 idx: Index,
1588 ) -> Result<Option<AnyRpcBlock>> {
1589 node_info!("eth_getUncleByBlockHashAndIndex");
1590 let number =
1591 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1592 if let Some(fork) = self.get_fork()
1593 && fork.predates_fork_inclusive(number)
1594 {
1595 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1596 }
1597 Ok(None)
1599 }
1600
1601 pub async fn uncle_by_block_number_and_index(
1605 &self,
1606 block_number: BlockNumber,
1607 idx: Index,
1608 ) -> Result<Option<AnyRpcBlock>> {
1609 node_info!("eth_getUncleByBlockNumberAndIndex");
1610 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1611 if let Some(fork) = self.get_fork()
1612 && fork.predates_fork_inclusive(number)
1613 {
1614 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1615 }
1616 Ok(None)
1618 }
1619
1620 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1624 node_info!("eth_getLogs");
1625 self.backend.logs(filter).await
1626 }
1627
1628 pub fn work(&self) -> Result<Work> {
1632 node_info!("eth_getWork");
1633 Err(BlockchainError::RpcUnimplemented)
1634 }
1635
1636 pub fn syncing(&self) -> Result<bool> {
1640 node_info!("eth_syncing");
1641 Ok(false)
1642 }
1643
1644 pub fn config(&self) -> Result<EthConfig> {
1655 node_info!("eth_config");
1656 Ok(EthConfig {
1657 current: EthForkConfig {
1658 activation_time: 0,
1659 blob_schedule: self.backend.blob_params(),
1660 chain_id: self.backend.env().read().evm_env.cfg_env.chain_id,
1661 fork_id: Bytes::from_static(&[0; 4]),
1662 precompiles: self.backend.precompiles(),
1663 system_contracts: self.backend.system_contracts(),
1664 },
1665 next: None,
1666 last: None,
1667 })
1668 }
1669
1670 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1674 node_info!("eth_submitWork");
1675 Err(BlockchainError::RpcUnimplemented)
1676 }
1677
1678 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1682 node_info!("eth_submitHashrate");
1683 Err(BlockchainError::RpcUnimplemented)
1684 }
1685
1686 pub async fn fee_history(
1690 &self,
1691 block_count: U256,
1692 newest_block: BlockNumber,
1693 reward_percentiles: Vec<f64>,
1694 ) -> Result<FeeHistory> {
1695 node_info!("eth_feeHistory");
1696 let current = self.backend.best_number();
1699 let slots_in_an_epoch = 32u64;
1700
1701 let number = match newest_block {
1702 BlockNumber::Latest | BlockNumber::Pending => current,
1703 BlockNumber::Earliest => 0,
1704 BlockNumber::Number(n) => n,
1705 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1706 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1707 };
1708
1709 if let Some(fork) = self.get_fork() {
1711 if fork.predates_fork_inclusive(number) {
1714 return fork
1715 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1716 .await
1717 .map_err(BlockchainError::AlloyForkProvider);
1718 }
1719 }
1720
1721 const MAX_BLOCK_COUNT: u64 = 1024u64;
1722 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1723
1724 let highest = number;
1726 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1727
1728 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1730 return Err(FeeHistoryError::InvalidBlockRange.into());
1731 }
1732
1733 let mut response = FeeHistory {
1734 oldest_block: lowest,
1735 base_fee_per_gas: Vec::new(),
1736 gas_used_ratio: Vec::new(),
1737 reward: Some(Default::default()),
1738 base_fee_per_blob_gas: Default::default(),
1739 blob_gas_used_ratio: Default::default(),
1740 };
1741 let mut rewards = Vec::new();
1742
1743 {
1744 let fee_history = self.fee_history_cache.lock();
1745
1746 for n in lowest..=highest {
1748 if let Some(block) = fee_history.get(&n) {
1750 response.base_fee_per_gas.push(block.base_fee);
1751 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1752 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1753 response.gas_used_ratio.push(block.gas_used_ratio);
1754
1755 if !reward_percentiles.is_empty() {
1757 let mut block_rewards = Vec::new();
1758 let resolution_per_percentile: f64 = 2.0;
1759 for p in &reward_percentiles {
1760 let p = p.clamp(0.0, 100.0);
1761 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1762 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1763 block_rewards.push(reward);
1764 }
1765 rewards.push(block_rewards);
1766 }
1767 }
1768 }
1769 }
1770
1771 response.reward = Some(rewards);
1772
1773 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1778
1779 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1783
1784 Ok(response)
1785 }
1786
1787 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1794 node_info!("eth_maxPriorityFeePerGas");
1795 Ok(U256::from(self.lowest_suggestion_tip()))
1796 }
1797
1798 fn lowest_suggestion_tip(&self) -> u128 {
1802 let block_number = self.backend.best_number();
1803 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1804
1805 match latest_cached_block {
1806 Some(block) => block.rewards.iter().copied().min(),
1807 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1808 }
1809 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1810 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1811 }
1812
1813 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1817 node_info!("eth_newFilter");
1818 let historic = if filter.block_option.get_from_block().is_some() {
1821 self.backend.logs(filter.clone()).await?
1822 } else {
1823 vec![]
1824 };
1825 let filter = EthFilter::Logs(Box::new(LogsFilter {
1826 blocks: self.new_block_notifications(),
1827 storage: self.storage_info(),
1828 filter: FilteredParams::new(Some(filter)),
1829 historic: Some(historic),
1830 }));
1831 Ok(self.filters.add_filter(filter).await)
1832 }
1833
1834 pub async fn new_block_filter(&self) -> Result<String> {
1838 node_info!("eth_newBlockFilter");
1839 let filter = EthFilter::Blocks(self.new_block_notifications());
1840 Ok(self.filters.add_filter(filter).await)
1841 }
1842
1843 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1847 node_info!("eth_newPendingTransactionFilter");
1848 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1849 Ok(self.filters.add_filter(filter).await)
1850 }
1851
1852 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1856 node_info!("eth_getFilterChanges");
1857 self.filters.get_filter_changes(id).await
1858 }
1859
1860 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1864 node_info!("eth_getFilterLogs");
1865 if let Some(filter) = self.filters.get_log_filter(id).await {
1866 self.backend.logs(filter).await
1867 } else {
1868 Ok(Vec::new())
1869 }
1870 }
1871
1872 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1874 node_info!("eth_uninstallFilter");
1875 Ok(self.filters.uninstall_filter(id).await.is_some())
1876 }
1877
1878 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1882 node_info!("debug_getRawTransaction");
1883 self.inner_raw_transaction(hash).await
1884 }
1885
1886 pub async fn raw_transaction_by_block_hash_and_index(
1890 &self,
1891 block_hash: B256,
1892 index: Index,
1893 ) -> Result<Option<Bytes>> {
1894 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1895 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1896 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1897 None => Ok(None),
1898 }
1899 }
1900
1901 pub async fn raw_transaction_by_block_number_and_index(
1905 &self,
1906 block_number: BlockNumber,
1907 index: Index,
1908 ) -> Result<Option<Bytes>> {
1909 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1910 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1911 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1912 None => Ok(None),
1913 }
1914 }
1915
1916 pub async fn debug_trace_transaction(
1920 &self,
1921 tx_hash: B256,
1922 opts: GethDebugTracingOptions,
1923 ) -> Result<GethTrace> {
1924 node_info!("debug_traceTransaction");
1925 self.backend.debug_trace_transaction(tx_hash, opts).await
1926 }
1927
1928 pub async fn debug_trace_call(
1932 &self,
1933 request: WithOtherFields<TransactionRequest>,
1934 block_number: Option<BlockId>,
1935 opts: GethDebugTracingCallOptions,
1936 ) -> Result<GethTrace> {
1937 node_info!("debug_traceCall");
1938 let block_request = self.block_request(block_number).await?;
1939 let fees = FeeDetails::new(
1940 request.gas_price,
1941 request.max_fee_per_gas,
1942 request.max_priority_fee_per_gas,
1943 request.max_fee_per_blob_gas,
1944 )?
1945 .or_zero_fees();
1946
1947 let result: std::result::Result<GethTrace, BlockchainError> =
1948 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1949 result
1950 }
1951
1952 pub async fn debug_code_by_hash(
1956 &self,
1957 hash: B256,
1958 block_id: Option<BlockId>,
1959 ) -> Result<Option<Bytes>> {
1960 node_info!("debug_codeByHash");
1961 self.backend.debug_code_by_hash(hash, block_id).await
1962 }
1963
1964 pub async fn debug_db_get(&self, key: String) -> Result<Option<Bytes>> {
1969 node_info!("debug_dbGet");
1970 self.backend.debug_db_get(key).await
1971 }
1972
1973 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1977 node_info!("trace_transaction");
1978 self.backend.trace_transaction(tx_hash).await
1979 }
1980
1981 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1985 node_info!("trace_block");
1986 self.backend.trace_block(block).await
1987 }
1988
1989 pub async fn trace_filter(
1993 &self,
1994 filter: TraceFilter,
1995 ) -> Result<Vec<LocalizedTransactionTrace>> {
1996 node_info!("trace_filter");
1997 self.backend.trace_filter(filter).await
1998 }
1999}
2000
2001impl EthApi {
2004 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
2008 node_info!("anvil_impersonateAccount");
2009 self.backend.impersonate(address);
2010 Ok(())
2011 }
2012
2013 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
2017 node_info!("anvil_stopImpersonatingAccount");
2018 self.backend.stop_impersonating(address);
2019 Ok(())
2020 }
2021
2022 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
2026 node_info!("anvil_autoImpersonateAccount");
2027 self.backend.auto_impersonate_account(enabled);
2028 Ok(())
2029 }
2030
2031 pub async fn anvil_impersonate_signature(
2033 &self,
2034 signature: Bytes,
2035 address: Address,
2036 ) -> Result<()> {
2037 node_info!("anvil_impersonateSignature");
2038 self.backend.impersonate_signature(signature, address).await
2039 }
2040
2041 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
2045 node_info!("anvil_getAutomine");
2046 Ok(self.miner.is_auto_mine())
2047 }
2048
2049 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
2053 node_info!("anvil_getIntervalMining");
2054 Ok(self.miner.get_interval())
2055 }
2056
2057 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
2062 node_info!("evm_setAutomine");
2063 if self.miner.is_auto_mine() {
2064 if enable_automine {
2065 return Ok(());
2066 }
2067 self.miner.set_mining_mode(MiningMode::None);
2068 } else if enable_automine {
2069 let listener = self.pool.add_ready_listener();
2070 let mode = MiningMode::instant(1_000, listener);
2071 self.miner.set_mining_mode(mode);
2072 }
2073 Ok(())
2074 }
2075
2076 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
2080 node_info!("anvil_mine");
2081 let interval = interval.map(|i| i.to::<u64>());
2082 let blocks = num_blocks.unwrap_or(U256::from(1));
2083 if blocks.is_zero() {
2084 return Ok(());
2085 }
2086
2087 self.on_blocking_task(|this| async move {
2088 for _ in 0..blocks.to::<u64>() {
2090 if let Some(interval) = interval {
2092 this.backend.time().increase_time(interval);
2093 }
2094 this.mine_one().await;
2095 }
2096 Ok(())
2097 })
2098 .await?;
2099
2100 Ok(())
2101 }
2102
2103 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
2107 node_info!("evm_setIntervalMining");
2108 let mining_mode = if secs == 0 {
2109 MiningMode::None
2110 } else {
2111 let block_time = Duration::from_secs(secs);
2112
2113 self.backend.update_interval_mine_block_time(block_time);
2115
2116 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
2117 };
2118 self.miner.set_mining_mode(mining_mode);
2119 Ok(())
2120 }
2121
2122 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
2126 node_info!("anvil_dropTransaction");
2127 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
2128 }
2129
2130 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
2134 node_info!("anvil_dropAllTransactions");
2135 self.pool.clear();
2136 Ok(())
2137 }
2138
2139 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
2145 self.reset_instance_id();
2146 node_info!("anvil_reset");
2147 if let Some(forking) = forking {
2148 self.backend.reset_fork(forking).await
2150 } else {
2151 self.backend.reset_to_in_mem().await
2154 }
2155 }
2156
2157 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
2158 node_info!("anvil_setChainId");
2159 self.backend.set_chain_id(chain_id);
2160 Ok(())
2161 }
2162
2163 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
2167 node_info!("anvil_setBalance");
2168 self.backend.set_balance(address, balance).await?;
2169 Ok(())
2170 }
2171
2172 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
2176 node_info!("anvil_addBalance");
2177 let current_balance = self.backend.get_balance(address, None).await?;
2178 self.backend.set_balance(address, current_balance + balance).await?;
2179 Ok(())
2180 }
2181
2182 async fn find_erc20_storage_slot(
2199 &self,
2200 token_address: Address,
2201 calldata: Bytes,
2202 expected_value: U256,
2203 ) -> Result<B256> {
2204 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2205
2206 let access_list_result =
2208 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2209 let access_list = access_list_result.access_list;
2210
2211 for item in access_list.0 {
2214 if item.address != token_address {
2215 continue;
2216 };
2217 for slot in &item.storage_keys {
2218 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2219 (*slot, B256::from(expected_value.to_be_bytes())),
2220 ));
2221
2222 let state_override = StateOverridesBuilder::default()
2223 .append(token_address, account_override)
2224 .build();
2225
2226 let evm_override = EvmOverrides::state(Some(state_override));
2227
2228 let Ok(result) =
2229 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2230 else {
2231 continue;
2233 };
2234
2235 let Ok(result_value) = U256::abi_decode(&result) else {
2236 continue;
2238 };
2239
2240 if result_value == expected_value {
2241 return Ok(*slot);
2242 }
2243 }
2244 }
2245
2246 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2247 }
2248
2249 pub async fn anvil_deal_erc20(
2253 &self,
2254 address: Address,
2255 token_address: Address,
2256 balance: U256,
2257 ) -> Result<()> {
2258 node_info!("anvil_dealERC20");
2259
2260 sol! {
2261 #[sol(rpc)]
2262 contract IERC20 {
2263 function balanceOf(address target) external view returns (uint256);
2264 }
2265 }
2266
2267 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2268
2269 let slot =
2271 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2272 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2273 })?;
2274
2275 self.anvil_set_storage_at(
2277 token_address,
2278 U256::from_be_bytes(slot.0),
2279 B256::from(balance.to_be_bytes()),
2280 )
2281 .await?;
2282
2283 Ok(())
2284 }
2285
2286 pub async fn anvil_set_erc20_allowance(
2290 &self,
2291 owner: Address,
2292 spender: Address,
2293 token_address: Address,
2294 amount: U256,
2295 ) -> Result<()> {
2296 node_info!("anvil_setERC20Allowance");
2297
2298 sol! {
2299 #[sol(rpc)]
2300 contract IERC20 {
2301 function allowance(address owner, address spender) external view returns (uint256);
2302 }
2303 }
2304
2305 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2306
2307 let slot =
2309 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2310 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2311 })?;
2312
2313 self.anvil_set_storage_at(
2315 token_address,
2316 U256::from_be_bytes(slot.0),
2317 B256::from(amount.to_be_bytes()),
2318 )
2319 .await?;
2320
2321 Ok(())
2322 }
2323
2324 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2328 node_info!("anvil_setCode");
2329 self.backend.set_code(address, code).await?;
2330 Ok(())
2331 }
2332
2333 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2337 node_info!("anvil_setNonce");
2338 self.backend.set_nonce(address, nonce).await?;
2339 Ok(())
2340 }
2341
2342 pub async fn anvil_set_storage_at(
2346 &self,
2347 address: Address,
2348 slot: U256,
2349 val: B256,
2350 ) -> Result<bool> {
2351 node_info!("anvil_setStorageAt");
2352 self.backend.set_storage_at(address, slot, val).await?;
2353 Ok(true)
2354 }
2355
2356 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2360 node_info!("anvil_setLoggingEnabled");
2361 self.logger.set_enabled(enable);
2362 Ok(())
2363 }
2364
2365 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2369 node_info!("anvil_setMinGasPrice");
2370 if self.backend.is_eip1559() {
2371 return Err(RpcError::invalid_params(
2372 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2373 )
2374 .into());
2375 }
2376 self.backend.set_gas_price(gas.to());
2377 Ok(())
2378 }
2379
2380 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2384 node_info!("anvil_setNextBlockBaseFeePerGas");
2385 if !self.backend.is_eip1559() {
2386 return Err(RpcError::invalid_params(
2387 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2388 )
2389 .into());
2390 }
2391 self.backend.set_base_fee(basefee.to());
2392 Ok(())
2393 }
2394
2395 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2399 node_info!("anvil_setCoinbase");
2400 self.backend.set_coinbase(address);
2401 Ok(())
2402 }
2403
2404 pub async fn anvil_dump_state(
2409 &self,
2410 preserve_historical_states: Option<bool>,
2411 ) -> Result<Bytes> {
2412 node_info!("anvil_dumpState");
2413 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2414 }
2415
2416 pub async fn serialized_state(
2418 &self,
2419 preserve_historical_states: bool,
2420 ) -> Result<SerializableState> {
2421 self.backend.serialized_state(preserve_historical_states).await
2422 }
2423
2424 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2429 node_info!("anvil_loadState");
2430 self.backend.load_state_bytes(buf).await
2431 }
2432
2433 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2437 node_info!("anvil_nodeInfo");
2438
2439 let env = self.backend.env().read();
2440 let fork_config = self.backend.get_fork();
2441 let tx_order = self.transaction_order.read();
2442 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2443
2444 Ok(NodeInfo {
2445 current_block_number: self.backend.best_number(),
2446 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2447 current_block_hash: self.backend.best_hash(),
2448 hard_fork: hard_fork.to_string(),
2449 transaction_order: match *tx_order {
2450 TransactionOrder::Fifo => "fifo".to_string(),
2451 TransactionOrder::Fees => "fees".to_string(),
2452 },
2453 environment: NodeEnvironment {
2454 base_fee: self.backend.base_fee() as u128,
2455 chain_id: self.backend.chain_id().to::<u64>(),
2456 gas_limit: self.backend.gas_limit(),
2457 gas_price: self.gas_price(),
2458 },
2459 fork_config: fork_config
2460 .map(|fork| {
2461 let config = fork.config.read();
2462
2463 NodeForkConfig {
2464 fork_url: Some(config.eth_rpc_url.clone()),
2465 fork_block_number: Some(config.block_number),
2466 fork_retry_backoff: Some(config.backoff.as_millis()),
2467 }
2468 })
2469 .unwrap_or_default(),
2470 })
2471 }
2472
2473 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2477 node_info!("anvil_metadata");
2478 let fork_config = self.backend.get_fork();
2479
2480 Ok(Metadata {
2481 client_version: CLIENT_VERSION.to_string(),
2482 chain_id: self.backend.chain_id().to::<u64>(),
2483 latest_block_hash: self.backend.best_hash(),
2484 latest_block_number: self.backend.best_number(),
2485 instance_id: *self.instance_id.read(),
2486 forked_network: fork_config.map(|cfg| ForkedNetwork {
2487 chain_id: cfg.chain_id(),
2488 fork_block_number: cfg.block_number(),
2489 fork_block_hash: cfg.block_hash(),
2490 }),
2491 snapshots: self.backend.list_state_snapshots(),
2492 })
2493 }
2494
2495 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2496 node_info!("anvil_removePoolTransactions");
2497 self.pool.remove_transactions_by_address(address);
2498 Ok(())
2499 }
2500
2501 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2515 node_info!("anvil_reorg");
2516 let depth = options.depth;
2517 let tx_block_pairs = options.tx_block_pairs;
2518
2519 let current_height = self.backend.best_number();
2521 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2522 RpcError::invalid_params(format!(
2523 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2524 )),
2525 ))?;
2526
2527 let common_block =
2529 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2530
2531 let block_pool_txs = if tx_block_pairs.is_empty() {
2534 HashMap::default()
2535 } else {
2536 let mut pairs = tx_block_pairs;
2537
2538 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2540 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2541 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2542 depth - 1
2543 ))));
2544 }
2545
2546 pairs.sort_by_key(|a| a.1);
2548
2549 let mut nonces: HashMap<Address, u64> = HashMap::default();
2552
2553 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2554 for pair in pairs {
2555 let (tx_data, block_index) = pair;
2556
2557 let pending = match tx_data {
2558 TransactionData::Raw(bytes) => {
2559 let mut data = bytes.as_ref();
2560 let decoded = FoundryTxEnvelope::decode_2718(&mut data)
2561 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2562 PendingTransaction::new(decoded)?
2563 }
2564
2565 TransactionData::JSON(request) => {
2566 let from = request.from.map(Ok).unwrap_or_else(|| {
2567 self.accounts()?
2568 .first()
2569 .copied()
2570 .ok_or(BlockchainError::NoSignerAvailable)
2571 })?;
2572
2573 let curr_nonce = nonces.entry(from).or_insert(
2575 self.get_transaction_count(
2576 from,
2577 Some(common_block.header.number.into()),
2578 )
2579 .await?,
2580 );
2581
2582 let typed = self.build_tx_request(request.into(), *curr_nonce).await?;
2584
2585 *curr_nonce += 1;
2587
2588 if self.is_impersonated(from) {
2590 let bypass_signature = self.impersonated_signature(&typed);
2591 let transaction =
2592 sign::build_typed_transaction(typed, bypass_signature)?;
2593 self.ensure_typed_transaction_supported(&transaction)?;
2594 PendingTransaction::with_impersonated(transaction, from)
2595 } else {
2596 let transaction = self.sign_request(&from, typed)?;
2597 self.ensure_typed_transaction_supported(&transaction)?;
2598 PendingTransaction::new(transaction)?
2599 }
2600 }
2601 };
2602
2603 let pooled = PoolTransaction::new(pending);
2604 txs.entry(block_index).or_default().push(Arc::new(pooled));
2605 }
2606
2607 txs
2608 };
2609
2610 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2611 Ok(())
2612 }
2613
2614 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2625 node_info!("anvil_rollback");
2626 let depth = depth.unwrap_or(1);
2627
2628 let current_height = self.backend.best_number();
2630 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2631 RpcError::invalid_params(format!(
2632 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2633 )),
2634 ))?;
2635
2636 let common_block =
2638 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2639
2640 self.backend.rollback(common_block).await?;
2641 Ok(())
2642 }
2643
2644 pub async fn evm_snapshot(&self) -> Result<U256> {
2648 node_info!("evm_snapshot");
2649 Ok(self.backend.create_state_snapshot().await)
2650 }
2651
2652 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2657 node_info!("evm_revert");
2658 self.backend.revert_state_snapshot(id).await
2659 }
2660
2661 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2665 node_info!("evm_increaseTime");
2666 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2667 }
2668
2669 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2673 node_info!("evm_setNextBlockTimestamp");
2674 self.backend.time().set_next_block_timestamp(seconds)
2675 }
2676
2677 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2682 node_info!("evm_setTime");
2683 let now = self.backend.time().current_call_timestamp();
2684 self.backend.time().reset(timestamp);
2685
2686 let offset = timestamp.saturating_sub(now);
2688 Ok(Duration::from_millis(offset).as_secs())
2689 }
2690
2691 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2695 node_info!("evm_setBlockGasLimit");
2696 self.backend.set_gas_limit(gas_limit.to());
2697 Ok(true)
2698 }
2699
2700 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2704 node_info!("anvil_setBlockTimestampInterval");
2705 self.backend.time().set_block_timestamp_interval(seconds);
2706 Ok(())
2707 }
2708
2709 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2713 node_info!("anvil_removeBlockTimestampInterval");
2714 Ok(self.backend.time().remove_block_timestamp_interval())
2715 }
2716
2717 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2724 node_info!("evm_mine");
2725
2726 self.do_evm_mine(opts).await?;
2727
2728 Ok("0x0".to_string())
2729 }
2730
2731 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2741 node_info!("evm_mine_detailed");
2742
2743 let mined_blocks = self.do_evm_mine(opts).await?;
2744
2745 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2746
2747 let latest = self.backend.best_number();
2748 for offset in (0..mined_blocks).rev() {
2749 let block_num = latest - offset;
2750 if let Some(mut block) =
2751 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2752 {
2753 let block_txs = match block.transactions_mut() {
2754 BlockTransactions::Full(txs) => txs,
2755 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2756 };
2757 for tx in block_txs.iter_mut() {
2758 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2759 && let Some(output) = receipt.out
2760 {
2761 if !receipt.inner.as_ref().status()
2763 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2764 {
2765 tx.other.insert(
2766 "revertReason".to_string(),
2767 serde_json::to_value(reason).expect("Infallible"),
2768 );
2769 }
2770 tx.other.insert(
2771 "output".to_string(),
2772 serde_json::to_value(output).expect("Infallible"),
2773 );
2774 }
2775 }
2776 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2777 blocks.push(block);
2778 }
2779 }
2780
2781 Ok(blocks)
2782 }
2783
2784 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2788 node_info!("anvil_setRpcUrl");
2789 if let Some(fork) = self.backend.get_fork() {
2790 let mut config = fork.config.write();
2791 let new_provider = Arc::new(
2793 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2794 |_| {
2795 TransportErrorKind::custom_str(
2796 format!("Failed to parse invalid url {url}").as_str(),
2797 )
2798 },
2799 )?, );
2802 config.provider = new_provider;
2803 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2804 config.eth_rpc_url = url;
2805 }
2806 Ok(())
2807 }
2808
2809 pub async fn anvil_enable_traces(&self) -> Result<()> {
2814 node_info!("anvil_enableTraces");
2815 Err(BlockchainError::RpcUnimplemented)
2816 }
2817
2818 pub async fn eth_send_unsigned_transaction(
2822 &self,
2823 request: WithOtherFields<TransactionRequest>,
2824 ) -> Result<TxHash> {
2825 node_info!("eth_sendUnsignedTransaction");
2826 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2828
2829 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2830
2831 let request = self.build_tx_request(request, nonce).await?;
2832
2833 let bypass_signature = self.impersonated_signature(&request);
2834 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2835
2836 self.ensure_typed_transaction_supported(&transaction)?;
2837
2838 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2839
2840 self.backend.validate_pool_transaction(&pending_transaction).await?;
2842
2843 let requires = required_marker(nonce, on_chain_nonce, from);
2844 let provides = vec![to_marker(nonce, from)];
2845
2846 self.add_pending_transaction(pending_transaction, requires, provides)
2847 }
2848
2849 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2855 node_info!("txpool_status");
2856 Ok(self.pool.txpool_status())
2857 }
2858
2859 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2866 node_info!("txpool_inspect");
2867 let mut inspect = TxpoolInspect::default();
2868
2869 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2870 let tx = &tx.pending_transaction.transaction;
2871 let to = tx.to();
2872 let gas_price = tx.max_fee_per_gas();
2873 let value = tx.value();
2874 let gas = tx.gas_limit();
2875 TxpoolInspectSummary { to, value, gas, gas_price }
2876 }
2877
2878 for pending in self.pool.ready_transactions() {
2885 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2886 let key = pending.pending_transaction.nonce().to_string();
2887 entry.insert(key, convert(pending));
2888 }
2889 for queued in self.pool.pending_transactions() {
2890 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2891 let key = queued.pending_transaction.nonce().to_string();
2892 entry.insert(key, convert(queued));
2893 }
2894 Ok(inspect)
2895 }
2896
2897 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2904 node_info!("txpool_content");
2905 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2906 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2907 let from = *tx.pending_transaction.sender();
2908 let tx = transaction_build(
2909 Some(tx.hash()),
2910 tx.pending_transaction.transaction.clone(),
2911 None,
2912 None,
2913 None,
2914 );
2915
2916 let WithOtherFields { inner: mut tx, other } = tx.0;
2917
2918 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2921
2922 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2923
2924 Ok(tx)
2925 }
2926
2927 for pending in self.pool.ready_transactions() {
2928 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2929 let key = pending.pending_transaction.nonce().to_string();
2930 entry.insert(key, convert(pending)?);
2931 }
2932 for queued in self.pool.pending_transactions() {
2933 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2934 let key = queued.pending_transaction.nonce().to_string();
2935 entry.insert(key, convert(queued)?);
2936 }
2937
2938 Ok(content)
2939 }
2940}
2941
2942impl EthApi {
2944 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2950 node_info!("wallet_getCapabilities");
2951 Ok(self.backend.get_capabilities())
2952 }
2953
2954 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2958 node_info!("anvil_addCapability");
2959 self.backend.add_capability(address);
2960 Ok(())
2961 }
2962
2963 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2964 node_info!("anvil_setExecutor");
2965 self.backend.set_executor(executor_pk)
2966 }
2967}
2968
2969impl EthApi {
2970 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2972 where
2973 C: FnOnce(Self) -> F,
2974 F: Future<Output = Result<R>> + Send + 'static,
2975 R: Send + 'static,
2976 {
2977 let (tx, rx) = oneshot::channel();
2978 let this = self.clone();
2979 let f = c(this);
2980 tokio::task::spawn_blocking(move || {
2981 tokio::runtime::Handle::current().block_on(async move {
2982 let res = f.await;
2983 let _ = tx.send(res);
2984 })
2985 });
2986 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2987 }
2988
2989 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2991 let mut blocks_to_mine = 1u64;
2992
2993 if let Some(opts) = opts {
2994 let timestamp = match opts {
2995 MineOptions::Timestamp(timestamp) => timestamp,
2996 MineOptions::Options { timestamp, blocks } => {
2997 if let Some(blocks) = blocks {
2998 blocks_to_mine = blocks;
2999 }
3000 timestamp
3001 }
3002 };
3003 if let Some(timestamp) = timestamp {
3004 self.evm_set_next_block_timestamp(timestamp)?;
3006 }
3007 }
3008
3009 self.on_blocking_task(|this| async move {
3012 for _ in 0..blocks_to_mine {
3014 this.mine_one().await;
3015 }
3016 Ok(())
3017 })
3018 .await?;
3019
3020 Ok(blocks_to_mine)
3021 }
3022
3023 async fn do_estimate_gas(
3024 &self,
3025 request: WithOtherFields<TransactionRequest>,
3026 block_number: Option<BlockId>,
3027 overrides: EvmOverrides,
3028 ) -> Result<u128> {
3029 let block_request = self.block_request(block_number).await?;
3030 if let BlockRequest::Number(number) = block_request
3032 && let Some(fork) = self.get_fork()
3033 && fork.predates_fork(number)
3034 {
3035 if overrides.has_state() || overrides.has_block() {
3036 return Err(BlockchainError::EvmOverrideError(
3037 "not available on past forked blocks".to_string(),
3038 ));
3039 }
3040 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
3041 }
3042
3043 self.on_blocking_task(|this| async move {
3046 this.backend
3047 .with_database_at(Some(block_request), |state, mut block| {
3048 let mut cache_db = CacheDB::new(state);
3049 if let Some(state_overrides) = overrides.state {
3050 apply_state_overrides(
3051 state_overrides.into_iter().collect(),
3052 &mut cache_db,
3053 )?;
3054 }
3055 if let Some(block_overrides) = overrides.block {
3056 cache_db.apply_block_overrides(*block_overrides, &mut block);
3057 }
3058 this.do_estimate_gas_with_state(request, &cache_db, block)
3059 })
3060 .await?
3061 })
3062 .await
3063 }
3064
3065 fn do_estimate_gas_with_state(
3069 &self,
3070 mut request: WithOtherFields<TransactionRequest>,
3071 state: &dyn DatabaseRef,
3072 block_env: BlockEnv,
3073 ) -> Result<u128> {
3074 let to = request.to.as_ref().and_then(TxKind::to);
3077
3078 let maybe_transfer = (request.input.input().is_none()
3080 || request.input.input().is_some_and(|data| data.is_empty()))
3081 && request.authorization_list.is_none()
3082 && request.access_list.is_none()
3083 && request.blob_versioned_hashes.is_none();
3084
3085 if maybe_transfer
3086 && let Some(to) = to
3087 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
3088 && target_code.as_ref().is_empty()
3089 {
3090 return Ok(MIN_TRANSACTION_GAS);
3091 }
3092
3093 let fees = FeeDetails::new(
3094 request.gas_price,
3095 request.max_fee_per_gas,
3096 request.max_priority_fee_per_gas,
3097 request.max_fee_per_blob_gas,
3098 )?
3099 .or_zero_fees();
3100
3101 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
3104
3105 let gas_price = fees.gas_price.unwrap_or_default();
3106 if gas_price > 0
3108 && let Some(from) = request.from
3109 {
3110 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
3111 if let Some(value) = request.value {
3112 if value > available_funds {
3113 return Err(InvalidTransactionError::InsufficientFunds.into());
3114 }
3115 available_funds -= value;
3117 }
3118 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
3120 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
3121 }
3122
3123 let mut call_to_estimate = request.clone();
3124 call_to_estimate.gas = Some(highest_gas_limit as u64);
3125
3126 let ethres =
3128 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3129
3130 let gas_used = match ethres.try_into()? {
3131 GasEstimationCallResult::Success(gas) => Ok(gas),
3132 GasEstimationCallResult::OutOfGas => {
3133 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3134 }
3135 GasEstimationCallResult::Revert(output) => {
3136 Err(InvalidTransactionError::Revert(output).into())
3137 }
3138 GasEstimationCallResult::EvmError(err) => {
3139 warn!(target: "node", "estimation failed due to {:?}", err);
3140 Err(BlockchainError::EvmError(err))
3141 }
3142 }?;
3143
3144 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3151
3152 let mut mid_gas_limit =
3154 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3155
3156 while (highest_gas_limit - lowest_gas_limit) > 1 {
3158 request.gas = Some(mid_gas_limit as u64);
3159 let ethres = self.backend.call_with_state(
3160 &state,
3161 request.clone(),
3162 fees.clone(),
3163 block_env.clone(),
3164 );
3165
3166 match ethres.try_into()? {
3167 GasEstimationCallResult::Success(_) => {
3168 highest_gas_limit = mid_gas_limit;
3172 }
3173 GasEstimationCallResult::OutOfGas
3174 | GasEstimationCallResult::Revert(_)
3175 | GasEstimationCallResult::EvmError(_) => {
3176 lowest_gas_limit = mid_gas_limit;
3183 }
3184 };
3185 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3187 }
3188
3189 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3190
3191 Ok(highest_gas_limit)
3192 }
3193
3194 pub fn set_transaction_order(&self, order: TransactionOrder) {
3196 *self.transaction_order.write() = order;
3197 }
3198
3199 fn transaction_priority(&self, tx: &FoundryTxEnvelope) -> TransactionPriority {
3201 self.transaction_order.read().priority(tx)
3202 }
3203
3204 pub fn chain_id(&self) -> u64 {
3206 self.backend.chain_id().to::<u64>()
3207 }
3208
3209 pub fn get_fork(&self) -> Option<ClientFork> {
3211 self.backend.get_fork()
3212 }
3213
3214 pub fn instance_id(&self) -> B256 {
3216 *self.instance_id.read()
3217 }
3218
3219 pub fn reset_instance_id(&self) {
3221 *self.instance_id.write() = B256::random();
3222 }
3223
3224 #[expect(clippy::borrowed_box)]
3226 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3227 self.signers.iter().find(|signer| signer.is_signer_for(address))
3228 }
3229
3230 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3232 self.backend.new_block_notifications()
3233 }
3234
3235 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3237 self.pool.add_ready_listener()
3238 }
3239
3240 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3242 let (tx, rx) = unbounded_channel();
3243 let mut hashes = self.new_ready_transactions();
3244
3245 let this = self.clone();
3246
3247 tokio::spawn(async move {
3248 while let Some(hash) = hashes.next().await {
3249 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3250 && tx.send(txn).is_err()
3251 {
3252 break;
3253 }
3254 }
3255 });
3256
3257 rx
3258 }
3259
3260 pub fn storage_info(&self) -> StorageInfo {
3262 StorageInfo::new(Arc::clone(&self.backend))
3263 }
3264
3265 pub fn is_fork(&self) -> bool {
3267 self.backend.is_fork()
3268 }
3269
3270 pub async fn mine_one(&self) {
3272 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3273 let outcome = self.backend.mine_block(transactions).await;
3274
3275 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3276 self.pool.on_mined_block(outcome);
3277 }
3278
3279 async fn pending_block(&self) -> AnyRpcBlock {
3281 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3282 let info = self.backend.pending_block(transactions).await;
3283 self.backend.convert_block(info.block)
3284 }
3285
3286 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3288 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3289 let BlockInfo { block, transactions, receipts: _ } =
3290 self.backend.pending_block(transactions).await;
3291
3292 let mut partial_block = self.backend.convert_block(block.clone());
3293
3294 let mut block_transactions = Vec::with_capacity(block.body.transactions.len());
3295 let base_fee = self.backend.base_fee();
3296
3297 for info in transactions {
3298 let tx = block.body.transactions.get(info.transaction_index as usize)?.clone();
3299
3300 let tx = transaction_build(
3301 Some(info.transaction_hash),
3302 tx,
3303 Some(&block),
3304 Some(info),
3305 Some(base_fee),
3306 );
3307 block_transactions.push(tx);
3308 }
3309
3310 partial_block.transactions = BlockTransactions::from(block_transactions);
3311
3312 Some(partial_block)
3313 }
3314
3315 async fn build_tx_request(
3318 &self,
3319 request: WithOtherFields<TransactionRequest>,
3320 nonce: u64,
3321 ) -> Result<FoundryTypedTx> {
3322 let mut request = Into::<FoundryTransactionRequest>::into(request);
3323 let from = request.from().or(self.accounts()?.first().copied());
3324
3325 request.chain_id().is_none().then(|| request.set_chain_id(self.chain_id()));
3327 request.nonce().is_none().then(|| request.set_nonce(nonce));
3328 request.kind().is_none().then(|| request.set_kind(TxKind::default()));
3329 if request.gas_limit().is_none() {
3330 request.set_gas_limit(
3331 self.do_estimate_gas(request.as_ref().clone(), None, EvmOverrides::default())
3332 .await
3333 .map(|v| v as u64)
3334 .unwrap_or(self.backend.gas_limit()),
3335 );
3336 }
3337
3338 if let Err((tx_type, _)) = request.missing_keys() {
3340 if matches!(tx_type, FoundryTxType::Legacy | FoundryTxType::Eip2930) {
3341 request.gas_price().is_none().then(|| request.set_gas_price(self.gas_price()));
3342 }
3343 if tx_type == FoundryTxType::Eip2930 {
3344 request
3345 .access_list()
3346 .is_none()
3347 .then(|| request.set_access_list(Default::default()));
3348 }
3349 if matches!(
3350 tx_type,
3351 FoundryTxType::Eip1559 | FoundryTxType::Eip4844 | FoundryTxType::Eip7702
3352 ) {
3353 request
3354 .max_fee_per_gas()
3355 .is_none()
3356 .then(|| request.set_max_fee_per_gas(self.gas_price()));
3357 request
3358 .max_priority_fee_per_gas()
3359 .is_none()
3360 .then(|| request.set_max_priority_fee_per_gas(MIN_SUGGESTED_PRIORITY_FEE));
3361 }
3362 if tx_type == FoundryTxType::Eip4844 {
3363 request.as_ref().max_fee_per_blob_gas().is_none().then(|| {
3364 request.as_mut().set_max_fee_per_blob_gas(
3365 self.backend.fees().get_next_block_blob_base_fee_per_gas(),
3366 )
3367 });
3368 }
3369 }
3370
3371 match request
3372 .build_unsigned()
3373 .map_err(|e| BlockchainError::InvalidTransactionRequest(e.to_string()))?
3374 {
3375 FoundryTypedTx::Eip4844(TxEip4844Variant::TxEip4844(_))
3376 if !self.backend.skip_blob_validation(from) =>
3377 {
3378 Err(BlockchainError::FailedToDecodeTransaction)
3380 }
3381 res => Ok(res),
3382 }
3383 }
3384
3385 pub fn is_impersonated(&self, addr: Address) -> bool {
3387 self.backend.cheats().is_impersonated(addr)
3388 }
3389
3390 fn impersonated_signature(&self, request: &FoundryTypedTx) -> Signature {
3392 match request {
3393 FoundryTypedTx::Legacy(_) => Signature::from_scalars_and_parity(
3396 B256::with_last_byte(1),
3397 B256::with_last_byte(1),
3398 false,
3399 ),
3400 FoundryTypedTx::Eip2930(_)
3401 | FoundryTypedTx::Eip1559(_)
3402 | FoundryTypedTx::Eip7702(_)
3403 | FoundryTypedTx::Eip4844(_)
3404 | FoundryTypedTx::Deposit(_) => Signature::from_scalars_and_parity(
3405 B256::with_last_byte(1),
3406 B256::with_last_byte(1),
3407 false,
3408 ),
3409 FoundryTypedTx::Tempo(_) => todo!(),
3411 }
3412 }
3413
3414 async fn get_transaction_count(
3416 &self,
3417 address: Address,
3418 block_number: Option<BlockId>,
3419 ) -> Result<u64> {
3420 let block_request = self.block_request(block_number).await?;
3421
3422 if let BlockRequest::Number(number) = block_request
3423 && let Some(fork) = self.get_fork()
3424 && fork.predates_fork(number)
3425 {
3426 return Ok(fork.get_nonce(address, number).await?);
3427 }
3428
3429 self.backend.get_nonce(address, block_request).await
3430 }
3431
3432 async fn request_nonce(
3440 &self,
3441 request: &TransactionRequest,
3442 from: Address,
3443 ) -> Result<(u64, u64)> {
3444 let highest_nonce =
3445 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3446 let nonce = request.nonce.unwrap_or(highest_nonce);
3447
3448 Ok((nonce, highest_nonce))
3449 }
3450
3451 fn add_pending_transaction(
3453 &self,
3454 pending_transaction: PendingTransaction,
3455 requires: Vec<TxMarker>,
3456 provides: Vec<TxMarker>,
3457 ) -> Result<TxHash> {
3458 let from = *pending_transaction.sender();
3459 let priority = self.transaction_priority(&pending_transaction.transaction);
3460 let pool_transaction =
3461 PoolTransaction { requires, provides, pending_transaction, priority };
3462 let tx = self.pool.add_transaction(pool_transaction)?;
3463 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3464 Ok(*tx.hash())
3465 }
3466
3467 pub async fn state_root(&self) -> Option<B256> {
3469 self.backend.get_db().read().await.maybe_state_root()
3470 }
3471
3472 fn ensure_typed_transaction_supported(&self, tx: &FoundryTxEnvelope) -> Result<()> {
3474 match &tx {
3475 FoundryTxEnvelope::Eip2930(_) => self.backend.ensure_eip2930_active(),
3476 FoundryTxEnvelope::Eip1559(_) => self.backend.ensure_eip1559_active(),
3477 FoundryTxEnvelope::Eip4844(_) => self.backend.ensure_eip4844_active(),
3478 FoundryTxEnvelope::Eip7702(_) => self.backend.ensure_eip7702_active(),
3479 FoundryTxEnvelope::Deposit(_) => self.backend.ensure_op_deposits_active(),
3480 FoundryTxEnvelope::Legacy(_) => Ok(()),
3481 FoundryTxEnvelope::Tempo(_) => todo!(),
3483 }
3484 }
3485}
3486
3487fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3488 if provided_nonce == on_chain_nonce {
3489 return Vec::new();
3490 }
3491 let prev_nonce = provided_nonce.saturating_sub(1);
3492 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3493}
3494
3495fn convert_transact_out(out: &Option<Output>) -> Bytes {
3496 match out {
3497 None => Default::default(),
3498 Some(Output::Call(out)) => out.to_vec().into(),
3499 Some(Output::Create(out, _)) => out.to_vec().into(),
3500 }
3501}
3502
3503fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3505 let out = convert_transact_out(out);
3506 match exit {
3507 return_ok!() => Ok(out),
3508 return_revert!() => Err(InvalidTransactionError::Revert(Some(out)).into()),
3509 reason => Err(BlockchainError::EvmError(reason)),
3510 }
3511}
3512
3513fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3515 match request.kind() {
3516 Some(TxKind::Call(_)) => {
3517 MIN_TRANSACTION_GAS
3518 + request.inner().authorization_list.as_ref().map_or(0, |auths_list| {
3519 auths_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3520 })
3521 }
3522 Some(TxKind::Create) => MIN_CREATE_GAS,
3523 None => MIN_CREATE_GAS,
3525 }
3526}
3527
3528enum GasEstimationCallResult {
3530 Success(u128),
3531 OutOfGas,
3532 Revert(Option<Bytes>),
3533 EvmError(InstructionResult),
3534}
3535
3536impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3540 type Error = BlockchainError;
3541
3542 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3543 match res {
3544 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3546 Ok(Self::OutOfGas)
3547 }
3548 Err(err) => Err(err),
3549 Ok((exit, output, gas, _)) => match exit {
3550 return_ok!() => Ok(Self::Success(gas)),
3551
3552 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3554 InstructionResult::CallTooDeep
3555 | InstructionResult::OutOfFunds
3556 | InstructionResult::CreateInitCodeStartingEF00
3557 | InstructionResult::InvalidEOFInitCode
3558 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3559
3560 InstructionResult::OutOfGas
3562 | InstructionResult::MemoryOOG
3563 | InstructionResult::MemoryLimitOOG
3564 | InstructionResult::PrecompileOOG
3565 | InstructionResult::InvalidOperandOOG
3566 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3567
3568 InstructionResult::OpcodeNotFound
3570 | InstructionResult::CallNotAllowedInsideStatic
3571 | InstructionResult::StateChangeDuringStaticCall
3572 | InstructionResult::InvalidFEOpcode
3573 | InstructionResult::InvalidJump
3574 | InstructionResult::NotActivated
3575 | InstructionResult::StackUnderflow
3576 | InstructionResult::StackOverflow
3577 | InstructionResult::OutOfOffset
3578 | InstructionResult::CreateCollision
3579 | InstructionResult::OverflowPayment
3580 | InstructionResult::PrecompileError
3581 | InstructionResult::NonceOverflow
3582 | InstructionResult::CreateContractSizeLimit
3583 | InstructionResult::CreateContractStartingWithEF
3584 | InstructionResult::CreateInitCodeSizeLimit
3585 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3586 },
3587 }
3588 }
3589}