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