1use super::{
2 backend::mem::{BlockRequest, DatabaseRef, State},
3 sign::build_typed_transaction,
4};
5use crate::{
6 ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
7 eth::{
8 backend::{
9 self,
10 db::SerializableState,
11 mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
12 notifications::NewBlockNotifications,
13 validate::TransactionValidator,
14 },
15 error::{
16 BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
17 },
18 fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
19 macros::node_info,
20 miner::FixedBlockTimeMiner,
21 pool::{
22 Pool,
23 transactions::{
24 PoolTransaction, TransactionOrder, TransactionPriority, TxMarker, to_marker,
25 },
26 },
27 sign::{self, Signer},
28 },
29 filter::{EthFilter, Filters, LogsFilter},
30 mem::transaction_build,
31};
32use alloy_consensus::{
33 Account, Blob,
34 transaction::{Recovered, eip4844::TxEip4844Variant},
35};
36use alloy_dyn_abi::TypedData;
37use alloy_eips::eip2718::Encodable2718;
38use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
39use alloy_network::{
40 AnyRpcBlock, AnyRpcTransaction, BlockResponse, Ethereum, NetworkWallet, TransactionBuilder,
41 TransactionResponse, eip2718::Decodable2718,
42};
43use alloy_primitives::{
44 Address, B64, B256, Bytes, Signature, TxHash, TxKind, U64, U256,
45 map::{HashMap, HashSet},
46};
47use alloy_provider::utils::{
48 EIP1559_FEE_ESTIMATION_PAST_BLOCKS, EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE,
49 eip1559_default_estimator,
50};
51use alloy_rpc_types::{
52 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
53 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
54 anvil::{
55 ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
56 },
57 request::TransactionRequest,
58 simulate::{SimulatePayload, SimulatedBlock},
59 state::{AccountOverride, EvmOverrides, StateOverridesBuilder},
60 trace::{
61 filter::TraceFilter,
62 geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
63 parity::LocalizedTransactionTrace,
64 },
65 txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
66};
67use alloy_serde::WithOtherFields;
68use alloy_sol_types::{SolCall, SolValue, sol};
69use alloy_transport::TransportErrorKind;
70use anvil_core::{
71 eth::{
72 EthRequest,
73 block::BlockInfo,
74 transaction::{
75 PendingTransaction, ReceiptResponse, TypedTransaction, TypedTransactionRequest,
76 transaction_request_to_typed,
77 },
78 wallet::{WalletCapabilities, WalletError},
79 },
80 types::{ReorgOptions, TransactionData},
81};
82use anvil_rpc::{error::RpcError, response::ResponseResult};
83use foundry_common::provider::ProviderBuilder;
84use foundry_evm::decode::RevertDecoder;
85use futures::{
86 StreamExt,
87 channel::{mpsc::Receiver, oneshot},
88};
89use parking_lot::RwLock;
90use revm::{
91 bytecode::Bytecode,
92 context::BlockEnv,
93 context_interface::{block::BlobExcessGasAndPrice, result::Output},
94 database::CacheDB,
95 interpreter::{InstructionResult, return_ok, return_revert},
96 primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
97};
98use std::{sync::Arc, time::Duration};
99use tokio::{
100 sync::mpsc::{UnboundedReceiver, unbounded_channel},
101 try_join,
102};
103
104pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
106
107#[derive(Clone)]
111pub struct EthApi {
112 pool: Arc<Pool>,
114 pub backend: Arc<backend::mem::Backend>,
117 is_mining: bool,
119 signers: Arc<Vec<Box<dyn Signer>>>,
121 fee_history_cache: FeeHistoryCache,
123 fee_history_limit: u64,
125 miner: Miner,
130 logger: LoggingManager,
132 filters: Filters,
134 transaction_order: Arc<RwLock<TransactionOrder>>,
136 net_listening: bool,
138 instance_id: Arc<RwLock<B256>>,
140}
141
142impl EthApi {
143 #[expect(clippy::too_many_arguments)]
145 pub fn new(
146 pool: Arc<Pool>,
147 backend: Arc<backend::mem::Backend>,
148 signers: Arc<Vec<Box<dyn Signer>>>,
149 fee_history_cache: FeeHistoryCache,
150 fee_history_limit: u64,
151 miner: Miner,
152 logger: LoggingManager,
153 filters: Filters,
154 transactions_order: TransactionOrder,
155 ) -> Self {
156 Self {
157 pool,
158 backend,
159 is_mining: true,
160 signers,
161 fee_history_cache,
162 fee_history_limit,
163 miner,
164 logger,
165 filters,
166 net_listening: true,
167 transaction_order: Arc::new(RwLock::new(transactions_order)),
168 instance_id: Arc::new(RwLock::new(B256::random())),
169 }
170 }
171
172 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
174 trace!(target: "rpc::api", "executing eth request");
175 let response = match request.clone() {
176 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
177 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
178 EthRequest::EthGetAccount(addr, block) => {
179 self.get_account(addr, block).await.to_rpc_result()
180 }
181 EthRequest::EthGetAccountInfo(addr, block) => {
182 self.get_account_info(addr, block).await.to_rpc_result()
183 }
184 EthRequest::EthGetBalance(addr, block) => {
185 self.balance(addr, block).await.to_rpc_result()
186 }
187 EthRequest::EthGetTransactionByHash(hash) => {
188 self.transaction_by_hash(hash).await.to_rpc_result()
189 }
190 EthRequest::EthSendTransaction(request) => {
191 self.send_transaction(*request).await.to_rpc_result()
192 }
193 EthRequest::EthSendTransactionSync(request) => {
194 self.send_transaction_sync(*request).await.to_rpc_result()
195 }
196 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
197 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
198 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
199 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
200 EthRequest::EthMaxPriorityFeePerGas(_) => {
201 self.gas_max_priority_fee_per_gas().to_rpc_result()
202 }
203 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
204 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
205 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
206 EthRequest::EthGetStorageAt(addr, slot, block) => {
207 self.storage_at(addr, slot, block).await.to_rpc_result()
208 }
209 EthRequest::EthGetBlockByHash(hash, full) => {
210 if full {
211 self.block_by_hash_full(hash).await.to_rpc_result()
212 } else {
213 self.block_by_hash(hash).await.to_rpc_result()
214 }
215 }
216 EthRequest::EthGetBlockByNumber(num, full) => {
217 if full {
218 self.block_by_number_full(num).await.to_rpc_result()
219 } else {
220 self.block_by_number(num).await.to_rpc_result()
221 }
222 }
223 EthRequest::EthGetTransactionCount(addr, block) => {
224 self.transaction_count(addr, block).await.to_rpc_result()
225 }
226 EthRequest::EthGetTransactionCountByHash(hash) => {
227 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
228 }
229 EthRequest::EthGetTransactionCountByNumber(num) => {
230 self.block_transaction_count_by_number(num).await.to_rpc_result()
231 }
232 EthRequest::EthGetUnclesCountByHash(hash) => {
233 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
234 }
235 EthRequest::EthGetUnclesCountByNumber(num) => {
236 self.block_uncles_count_by_number(num).await.to_rpc_result()
237 }
238 EthRequest::EthGetCodeAt(addr, block) => {
239 self.get_code(addr, block).await.to_rpc_result()
240 }
241 EthRequest::EthGetProof(addr, keys, block) => {
242 self.get_proof(addr, keys, block).await.to_rpc_result()
243 }
244 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
245 EthRequest::PersonalSign(content, addr) => {
246 self.sign(addr, content).await.to_rpc_result()
247 }
248 EthRequest::EthSignTransaction(request) => {
249 self.sign_transaction(*request).await.to_rpc_result()
250 }
251 EthRequest::EthSignTypedData(addr, data) => {
252 self.sign_typed_data(addr, data).await.to_rpc_result()
253 }
254 EthRequest::EthSignTypedDataV3(addr, data) => {
255 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
256 }
257 EthRequest::EthSignTypedDataV4(addr, data) => {
258 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
259 }
260 EthRequest::EthSendRawTransaction(tx) => {
261 self.send_raw_transaction(tx).await.to_rpc_result()
262 }
263 EthRequest::EthSendRawTransactionSync(tx) => {
264 self.send_raw_transaction_sync(tx).await.to_rpc_result()
265 }
266 EthRequest::EthCall(call, block, state_override, block_overrides) => self
267 .call(call, block, EvmOverrides::new(state_override, block_overrides))
268 .await
269 .to_rpc_result(),
270 EthRequest::EthSimulateV1(simulation, block) => {
271 self.simulate_v1(simulation, block).await.to_rpc_result()
272 }
273 EthRequest::EthCreateAccessList(call, block) => {
274 self.create_access_list(call, block).await.to_rpc_result()
275 }
276 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
277 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
278 .await
279 .to_rpc_result(),
280 EthRequest::EthGetRawTransactionByHash(hash) => {
281 self.raw_transaction(hash).await.to_rpc_result()
282 }
283 EthRequest::GetBlobByHash(hash) => {
284 self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
285 }
286 EthRequest::GetBlobByTransactionHash(hash) => {
287 self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
288 }
289 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
290 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
291 }
292 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
293 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
294 }
295 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
296 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
297 }
298 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
299 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
300 }
301 EthRequest::EthGetTransactionReceipt(tx) => {
302 self.transaction_receipt(tx).await.to_rpc_result()
303 }
304 EthRequest::EthGetBlockReceipts(number) => {
305 self.block_receipts(number).await.to_rpc_result()
306 }
307 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
308 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
309 }
310 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
311 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
312 }
313 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
314 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
315 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
316 EthRequest::EthSubmitWork(nonce, pow, digest) => {
317 self.submit_work(nonce, pow, digest).to_rpc_result()
318 }
319 EthRequest::EthSubmitHashRate(rate, id) => {
320 self.submit_hashrate(rate, id).to_rpc_result()
321 }
322 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
323 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
324 }
325 EthRequest::DebugGetRawTransaction(hash) => {
327 self.raw_transaction(hash).await.to_rpc_result()
328 }
329 EthRequest::DebugTraceTransaction(tx, opts) => {
331 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
332 }
333 EthRequest::DebugTraceCall(tx, block, opts) => {
335 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
336 }
337 anvil_core::eth::EthRequest::DebugTraceBlockByNumber(_, _) => unimplemented!(),
338 EthRequest::DebugCodeByHash(hash, block) => {
339 self.debug_code_by_hash(hash, block).await.to_rpc_result()
340 }
341 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
342 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
343 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
344 EthRequest::ImpersonateAccount(addr) => {
345 self.anvil_impersonate_account(addr).await.to_rpc_result()
346 }
347 EthRequest::StopImpersonatingAccount(addr) => {
348 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
349 }
350 EthRequest::AutoImpersonateAccount(enable) => {
351 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
352 }
353 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
354 EthRequest::Mine(blocks, interval) => {
355 self.anvil_mine(blocks, interval).await.to_rpc_result()
356 }
357 EthRequest::SetAutomine(enabled) => {
358 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
359 }
360 EthRequest::SetIntervalMining(interval) => {
361 self.anvil_set_interval_mining(interval).to_rpc_result()
362 }
363 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
364 EthRequest::DropTransaction(tx) => {
365 self.anvil_drop_transaction(tx).await.to_rpc_result()
366 }
367 EthRequest::DropAllTransactions() => {
368 self.anvil_drop_all_transactions().await.to_rpc_result()
369 }
370 EthRequest::Reset(fork) => {
371 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
372 }
373 EthRequest::SetBalance(addr, val) => {
374 self.anvil_set_balance(addr, val).await.to_rpc_result()
375 }
376 EthRequest::AddBalance(addr, val) => {
377 self.anvil_add_balance(addr, val).await.to_rpc_result()
378 }
379 EthRequest::DealERC20(addr, token_addr, val) => {
380 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
381 }
382 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
383 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
384 .await
385 .to_rpc_result(),
386 EthRequest::SetCode(addr, code) => {
387 self.anvil_set_code(addr, code).await.to_rpc_result()
388 }
389 EthRequest::SetNonce(addr, nonce) => {
390 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
391 }
392 EthRequest::SetStorageAt(addr, slot, val) => {
393 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
394 }
395 EthRequest::SetImmutableStorageAt(_, _) => {
396 return ResponseResult::Error(RpcError::invalid_params(
397 "anvil_setImmutableStorageAt is not supported on EVM anvil",
398 ));
399 }
400 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
401 EthRequest::EthCoinbase(()) => self.author().to_rpc_result(),
402 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
403 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
404 EthRequest::SetMinGasPrice(gas) => {
405 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
406 }
407 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
408 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
409 }
410 EthRequest::DumpState(preserve_historical_states) => self
411 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
412 .await
413 .to_rpc_result(),
414 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
415 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
416 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
417 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
418 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
419 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
420 EthRequest::EvmSetNextBlockTimeStamp(time) => {
421 if time >= U256::from(u64::MAX) {
422 return ResponseResult::Error(RpcError::invalid_params(
423 "The timestamp is too big",
424 ));
425 }
426 let time = time.to::<u64>();
427 self.evm_set_next_block_timestamp(time).to_rpc_result()
428 }
429 EthRequest::EvmSetTime(timestamp) => {
430 if timestamp >= U256::from(u64::MAX) {
431 return ResponseResult::Error(RpcError::invalid_params(
432 "The timestamp is too big",
433 ));
434 }
435 let time = timestamp.to::<u64>();
436 self.evm_set_time(time).to_rpc_result()
437 }
438 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
439 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
440 }
441 EthRequest::EvmSetBlockTimeStampInterval(time) => {
442 self.evm_set_block_timestamp_interval(time).to_rpc_result()
443 }
444 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
445 self.evm_remove_block_timestamp_interval().to_rpc_result()
446 }
447 EthRequest::EvmMine(mine) => {
448 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
449 }
450 EthRequest::EvmMineDetailed(mine) => {
451 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
452 }
453 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
454 EthRequest::EthSendUnsignedTransaction(tx) => {
455 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
456 }
457 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
458 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
459 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
460 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
461 EthRequest::EthNewPendingTransactionFilter(_) => {
462 self.new_pending_transaction_filter().await.to_rpc_result()
463 }
464 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
465 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
466 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
467 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
468 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
469 EthRequest::ErigonGetHeaderByNumber(num) => {
470 self.erigon_get_header_by_number(num).await.to_rpc_result()
471 }
472 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
473 EthRequest::OtsGetInternalOperations(hash) => {
474 self.ots_get_internal_operations(hash).await.to_rpc_result()
475 }
476 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
477 EthRequest::OtsTraceTransaction(hash) => {
478 self.ots_trace_transaction(hash).await.to_rpc_result()
479 }
480 EthRequest::OtsGetTransactionError(hash) => {
481 self.ots_get_transaction_error(hash).await.to_rpc_result()
482 }
483 EthRequest::OtsGetBlockDetails(num) => {
484 self.ots_get_block_details(num).await.to_rpc_result()
485 }
486 EthRequest::OtsGetBlockDetailsByHash(hash) => {
487 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
488 }
489 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
490 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
491 }
492 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
493 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
494 }
495 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
496 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
497 }
498 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
499 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
500 }
501 EthRequest::OtsGetContractCreator(address) => {
502 self.ots_get_contract_creator(address).await.to_rpc_result()
503 }
504 EthRequest::RemovePoolTransactions(address) => {
505 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
506 }
507 EthRequest::Reorg(reorg_options) => {
508 self.anvil_reorg(reorg_options).await.to_rpc_result()
509 }
510 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
511 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
512 EthRequest::WalletSendTransaction(tx) => {
513 self.wallet_send_transaction(*tx).await.to_rpc_result()
514 }
515 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
516 EthRequest::AnvilSetExecutor(executor_pk) => {
517 self.anvil_set_executor(executor_pk).to_rpc_result()
518 }
519 };
520
521 if let ResponseResult::Error(err) = &response {
522 node_info!("\nRPC request failed:");
523 node_info!(" Request: {:?}", request);
524 node_info!(" Error: {}\n", err);
525 }
526
527 response
528 }
529
530 fn sign_request(
531 &self,
532 from: &Address,
533 request: TypedTransactionRequest,
534 ) -> Result<TypedTransaction> {
535 match request {
536 TypedTransactionRequest::Deposit(_) => {
537 let nil_signature = Signature::from_scalars_and_parity(
538 B256::with_last_byte(1),
539 B256::with_last_byte(1),
540 false,
541 );
542 return build_typed_transaction(request, nil_signature);
543 }
544 _ => {
545 for signer in self.signers.iter() {
546 if signer.accounts().contains(from) {
547 let signature = signer.sign_transaction(request.clone(), from)?;
548 return build_typed_transaction(request, signature);
549 }
550 }
551 }
552 }
553 Err(BlockchainError::NoSignerAvailable)
554 }
555
556 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
557 let block_request = match block_number {
558 Some(BlockId::Number(BlockNumber::Pending)) => {
559 let pending_txs = self.pool.ready_transactions().collect();
560 BlockRequest::Pending(pending_txs)
561 }
562 _ => {
563 let number = self.backend.ensure_block_number(block_number).await?;
564 BlockRequest::Number(number)
565 }
566 };
567 Ok(block_request)
568 }
569
570 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
571 match self.pool.get_transaction(hash) {
572 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
573 None => match self.backend.transaction_by_hash(hash).await? {
574 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
575 None => Ok(None),
576 },
577 }
578 }
579
580 pub fn client_version(&self) -> Result<String> {
584 node_info!("web3_clientVersion");
585 Ok(CLIENT_VERSION.to_string())
586 }
587
588 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
592 node_info!("web3_sha3");
593 let hash = alloy_primitives::keccak256(bytes.as_ref());
594 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
595 }
596
597 pub fn protocol_version(&self) -> Result<u64> {
601 node_info!("eth_protocolVersion");
602 Ok(1)
603 }
604
605 pub fn hashrate(&self) -> Result<U256> {
609 node_info!("eth_hashrate");
610 Ok(U256::ZERO)
611 }
612
613 pub fn author(&self) -> Result<Address> {
617 node_info!("eth_coinbase");
618 Ok(self.backend.coinbase())
619 }
620
621 pub fn is_mining(&self) -> Result<bool> {
625 node_info!("eth_mining");
626 Ok(self.is_mining)
627 }
628
629 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
635 node_info!("eth_chainId");
636 Ok(Some(self.backend.chain_id().to::<U64>()))
637 }
638
639 pub fn network_id(&self) -> Result<Option<String>> {
643 node_info!("eth_networkId");
644 let chain_id = self.backend.chain_id().to::<u64>();
645 Ok(Some(format!("{chain_id}")))
646 }
647
648 pub fn net_listening(&self) -> Result<bool> {
652 node_info!("net_listening");
653 Ok(self.net_listening)
654 }
655
656 fn eth_gas_price(&self) -> Result<U256> {
658 node_info!("eth_gasPrice");
659 Ok(U256::from(self.gas_price()))
660 }
661
662 pub fn gas_price(&self) -> u128 {
664 if self.backend.is_eip1559() {
665 if self.backend.is_min_priority_fee_enforced() {
666 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
667 } else {
668 self.backend.base_fee() as u128
669 }
670 } else {
671 self.backend.fees().raw_gas_price()
672 }
673 }
674
675 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
677 Ok(self.backend.excess_blob_gas_and_price())
678 }
679
680 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
685 self.max_priority_fee_per_gas()
686 }
687
688 pub fn blob_base_fee(&self) -> Result<U256> {
692 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
693 }
694
695 pub fn gas_limit(&self) -> U256 {
697 U256::from(self.backend.gas_limit())
698 }
699
700 pub fn accounts(&self) -> Result<Vec<Address>> {
704 node_info!("eth_accounts");
705 let mut unique = HashSet::new();
706 let mut accounts: Vec<Address> = Vec::new();
707 for signer in self.signers.iter() {
708 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
709 }
710 accounts.extend(
711 self.backend
712 .cheats()
713 .impersonated_accounts()
714 .into_iter()
715 .filter(|acc| unique.insert(*acc)),
716 );
717 Ok(accounts.into_iter().collect())
718 }
719
720 pub fn block_number(&self) -> Result<U256> {
724 node_info!("eth_blockNumber");
725 Ok(U256::from(self.backend.best_number()))
726 }
727
728 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
732 node_info!("eth_getBalance");
733 let block_request = self.block_request(block_number).await?;
734
735 if let BlockRequest::Number(number) = block_request
737 && let Some(fork) = self.get_fork()
738 && fork.predates_fork(number)
739 {
740 return Ok(fork.get_balance(address, number).await?);
741 }
742
743 self.backend.get_balance(address, Some(block_request)).await
744 }
745
746 pub async fn get_account(
750 &self,
751 address: Address,
752 block_number: Option<BlockId>,
753 ) -> Result<Account> {
754 node_info!("eth_getAccount");
755 let block_request = self.block_request(block_number).await?;
756
757 if let BlockRequest::Number(number) = block_request
759 && let Some(fork) = self.get_fork()
760 && fork.predates_fork(number)
761 {
762 return Ok(fork.get_account(address, number).await?);
763 }
764
765 self.backend.get_account_at_block(address, Some(block_request)).await
766 }
767
768 pub async fn get_account_info(
770 &self,
771 address: Address,
772 block_number: Option<BlockId>,
773 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
774 node_info!("eth_getAccountInfo");
775 let account = self.get_account(address, block_number);
776 let code = self.get_code(address, block_number);
777 let (account, code) = try_join!(account, code)?;
778 Ok(alloy_rpc_types::eth::AccountInfo {
779 balance: account.balance,
780 nonce: account.nonce,
781 code,
782 })
783 }
784 pub async fn storage_at(
788 &self,
789 address: Address,
790 index: U256,
791 block_number: Option<BlockId>,
792 ) -> Result<B256> {
793 node_info!("eth_getStorageAt");
794 let block_request = self.block_request(block_number).await?;
795
796 if let BlockRequest::Number(number) = block_request
798 && let Some(fork) = self.get_fork()
799 && fork.predates_fork(number)
800 {
801 return Ok(B256::from(
802 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
803 ));
804 }
805
806 self.backend.storage_at(address, index, Some(block_request)).await
807 }
808
809 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
813 node_info!("eth_getBlockByHash");
814 self.backend.block_by_hash(hash).await
815 }
816
817 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
821 node_info!("eth_getBlockByHash");
822 self.backend.block_by_hash_full(hash).await
823 }
824
825 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
829 node_info!("eth_getBlockByNumber");
830 if number == BlockNumber::Pending {
831 return Ok(Some(self.pending_block().await));
832 }
833
834 self.backend.block_by_number(number).await
835 }
836
837 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
841 node_info!("eth_getBlockByNumber");
842 if number == BlockNumber::Pending {
843 return Ok(self.pending_block_full().await);
844 }
845 self.backend.block_by_number_full(number).await
846 }
847
848 pub async fn transaction_count(
855 &self,
856 address: Address,
857 block_number: Option<BlockId>,
858 ) -> Result<U256> {
859 node_info!("eth_getTransactionCount");
860 self.get_transaction_count(address, block_number).await.map(U256::from)
861 }
862
863 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
867 node_info!("eth_getBlockTransactionCountByHash");
868 let block = self.backend.block_by_hash(hash).await?;
869 let txs = block.map(|b| match b.transactions() {
870 BlockTransactions::Full(txs) => U256::from(txs.len()),
871 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
872 BlockTransactions::Uncle => U256::from(0),
873 });
874 Ok(txs)
875 }
876
877 pub async fn block_transaction_count_by_number(
881 &self,
882 block_number: BlockNumber,
883 ) -> Result<Option<U256>> {
884 node_info!("eth_getBlockTransactionCountByNumber");
885 let block_request = self.block_request(Some(block_number.into())).await?;
886 if let BlockRequest::Pending(txs) = block_request {
887 let block = self.backend.pending_block(txs).await;
888 return Ok(Some(U256::from(block.transactions.len())));
889 }
890 let block = self.backend.block_by_number(block_number).await?;
891 let txs = block.map(|b| match b.transactions() {
892 BlockTransactions::Full(txs) => U256::from(txs.len()),
893 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
894 BlockTransactions::Uncle => U256::from(0),
895 });
896 Ok(txs)
897 }
898
899 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
903 node_info!("eth_getUncleCountByBlockHash");
904 let block =
905 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
906 Ok(U256::from(block.uncles.len()))
907 }
908
909 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
913 node_info!("eth_getUncleCountByBlockNumber");
914 let block = self
915 .backend
916 .block_by_number(block_number)
917 .await?
918 .ok_or(BlockchainError::BlockNotFound)?;
919 Ok(U256::from(block.uncles.len()))
920 }
921
922 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
926 node_info!("eth_getCode");
927 let block_request = self.block_request(block_number).await?;
928 if let BlockRequest::Number(number) = block_request
930 && let Some(fork) = self.get_fork()
931 && fork.predates_fork(number)
932 {
933 return Ok(fork.get_code(address, number).await?);
934 }
935 self.backend.get_code(address, Some(block_request)).await
936 }
937
938 pub async fn get_proof(
943 &self,
944 address: Address,
945 keys: Vec<B256>,
946 block_number: Option<BlockId>,
947 ) -> Result<EIP1186AccountProofResponse> {
948 node_info!("eth_getProof");
949 let block_request = self.block_request(block_number).await?;
950
951 if let BlockRequest::Number(number) = block_request
954 && let Some(fork) = self.get_fork()
955 && fork.predates_fork_inclusive(number)
956 {
957 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
958 }
959
960 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
961 Ok(proof)
962 }
963
964 pub async fn sign_typed_data(
968 &self,
969 _address: Address,
970 _data: serde_json::Value,
971 ) -> Result<String> {
972 node_info!("eth_signTypedData");
973 Err(BlockchainError::RpcUnimplemented)
974 }
975
976 pub async fn sign_typed_data_v3(
980 &self,
981 _address: Address,
982 _data: serde_json::Value,
983 ) -> Result<String> {
984 node_info!("eth_signTypedData_v3");
985 Err(BlockchainError::RpcUnimplemented)
986 }
987
988 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
992 node_info!("eth_signTypedData_v4");
993 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
994 let signature = signer.sign_typed_data(address, data).await?;
995 let signature = alloy_primitives::hex::encode(signature.as_bytes());
996 Ok(format!("0x{signature}"))
997 }
998
999 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1003 node_info!("eth_sign");
1004 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1005 let signature =
1006 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1007 Ok(format!("0x{signature}"))
1008 }
1009
1010 pub async fn sign_transaction(
1014 &self,
1015 mut request: WithOtherFields<TransactionRequest>,
1016 ) -> Result<String> {
1017 node_info!("eth_signTransaction");
1018
1019 let from = request.from.map(Ok).unwrap_or_else(|| {
1020 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1021 })?;
1022
1023 let (nonce, _) = self.request_nonce(&request, from).await?;
1024
1025 if request.gas.is_none() {
1026 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1028 {
1029 request.gas = Some(gas.to());
1030 }
1031 }
1032
1033 let request = self.build_typed_tx_request(request, nonce)?;
1034
1035 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1036 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1037 }
1038
1039 pub async fn send_transaction(
1043 &self,
1044 mut request: WithOtherFields<TransactionRequest>,
1045 ) -> Result<TxHash> {
1046 node_info!("eth_sendTransaction");
1047
1048 let from = request.from.map(Ok).unwrap_or_else(|| {
1049 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1050 })?;
1051 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1052
1053 if request.gas.is_none() {
1054 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1056 {
1057 request.gas = Some(gas.to());
1058 }
1059 }
1060
1061 let request = self.build_typed_tx_request(request, nonce)?;
1062
1063 let pending_transaction = if self.is_impersonated(from) {
1065 let bypass_signature = self.impersonated_signature(&request);
1066 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1067 self.ensure_typed_transaction_supported(&transaction)?;
1068 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1069 PendingTransaction::with_impersonated(transaction, from)
1070 } else {
1071 let transaction = self.sign_request(&from, request)?;
1072 self.ensure_typed_transaction_supported(&transaction)?;
1073 PendingTransaction::new(transaction)?
1074 };
1075 self.backend.validate_pool_transaction(&pending_transaction).await?;
1077
1078 let requires = required_marker(nonce, on_chain_nonce, from);
1079 let provides = vec![to_marker(nonce, from)];
1080 debug_assert!(requires != provides);
1081
1082 self.add_pending_transaction(pending_transaction, requires, provides)
1083 }
1084
1085 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1087 let mut stream = self.new_block_notifications();
1088 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1090 return Ok(receipt);
1091 }
1092 while let Some(notification) = stream.next().await {
1093 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1094 && block.transactions.iter().any(|tx| tx.hash() == hash)
1095 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1096 {
1097 return Ok(receipt);
1098 }
1099 }
1100
1101 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1102 }
1103
1104 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1106 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1107 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1108 .await
1109 .unwrap_or_else(|_elapsed| {
1110 Err(BlockchainError::TransactionConfirmationTimeout {
1111 hash,
1112 duration: TIMEOUT_DURATION,
1113 })
1114 })
1115 }
1116
1117 pub async fn send_transaction_sync(
1121 &self,
1122 request: WithOtherFields<TransactionRequest>,
1123 ) -> Result<ReceiptResponse> {
1124 node_info!("eth_sendTransactionSync");
1125 let hash = self.send_transaction(request).await?;
1126
1127 let receipt = self.check_transaction_inclusion(hash).await?;
1128
1129 Ok(ReceiptResponse::from(receipt))
1130 }
1131
1132 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1136 node_info!("eth_sendRawTransaction");
1137 let mut data = tx.as_ref();
1138 if data.is_empty() {
1139 return Err(BlockchainError::EmptyRawTransactionData);
1140 }
1141
1142 let transaction = TypedTransaction::decode_2718(&mut data)
1143 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1144
1145 self.ensure_typed_transaction_supported(&transaction)?;
1146
1147 let pending_transaction = PendingTransaction::new(transaction)?;
1148
1149 self.backend.validate_pool_transaction(&pending_transaction).await?;
1151
1152 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1153 let from = *pending_transaction.sender();
1154 let nonce = pending_transaction.transaction.nonce();
1155 let requires = required_marker(nonce, on_chain_nonce, from);
1156
1157 let priority = self.transaction_priority(&pending_transaction.transaction);
1158 let pool_transaction = PoolTransaction {
1159 requires,
1160 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1161 pending_transaction,
1162 priority,
1163 };
1164
1165 let tx = self.pool.add_transaction(pool_transaction)?;
1166 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1167 Ok(*tx.hash())
1168 }
1169
1170 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<ReceiptResponse> {
1174 node_info!("eth_sendRawTransactionSync");
1175
1176 let hash = self.send_raw_transaction(tx).await?;
1177 let receipt = self.check_transaction_inclusion(hash).await?;
1178
1179 Ok(ReceiptResponse::from(receipt))
1180 }
1181
1182 pub async fn call(
1186 &self,
1187 request: WithOtherFields<TransactionRequest>,
1188 block_number: Option<BlockId>,
1189 overrides: EvmOverrides,
1190 ) -> Result<Bytes> {
1191 node_info!("eth_call");
1192 let block_request = self.block_request(block_number).await?;
1193 if let BlockRequest::Number(number) = block_request
1195 && let Some(fork) = self.get_fork()
1196 && fork.predates_fork(number)
1197 {
1198 if overrides.has_state() || overrides.has_block() {
1199 return Err(BlockchainError::EvmOverrideError(
1200 "not available on past forked blocks".to_string(),
1201 ));
1202 }
1203 return Ok(fork.call(&request, Some(number.into())).await?);
1204 }
1205
1206 let fees = FeeDetails::new(
1207 request.gas_price,
1208 request.max_fee_per_gas,
1209 request.max_priority_fee_per_gas,
1210 request.max_fee_per_blob_gas,
1211 )?
1212 .or_zero_fees();
1213 self.on_blocking_task(|this| async move {
1216 let (exit, out, gas, _) =
1217 this.backend.call(request, fees, Some(block_request), overrides).await?;
1218 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1219
1220 ensure_return_ok(exit, &out)
1221 })
1222 .await
1223 }
1224
1225 pub async fn simulate_v1(
1226 &self,
1227 request: SimulatePayload,
1228 block_number: Option<BlockId>,
1229 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1230 node_info!("eth_simulateV1");
1231 let block_request = self.block_request(block_number).await?;
1232 if let BlockRequest::Number(number) = block_request
1234 && let Some(fork) = self.get_fork()
1235 && fork.predates_fork(number)
1236 {
1237 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1238 }
1239
1240 self.on_blocking_task(|this| async move {
1243 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1244 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1245
1246 Ok(simulated_blocks)
1247 })
1248 .await
1249 }
1250
1251 pub async fn create_access_list(
1265 &self,
1266 mut request: WithOtherFields<TransactionRequest>,
1267 block_number: Option<BlockId>,
1268 ) -> Result<AccessListResult> {
1269 node_info!("eth_createAccessList");
1270 let block_request = self.block_request(block_number).await?;
1271 if let BlockRequest::Number(number) = block_request
1273 && let Some(fork) = self.get_fork()
1274 && fork.predates_fork(number)
1275 {
1276 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1277 }
1278
1279 self.backend
1280 .with_database_at(Some(block_request), |state, block_env| {
1281 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1282 &state,
1283 request.clone(),
1284 FeeDetails::zero(),
1285 block_env.clone(),
1286 )?;
1287 ensure_return_ok(exit, &out)?;
1288
1289 request.access_list = Some(access_list.clone());
1291
1292 let (exit, out, gas_used, _) = self.backend.call_with_state(
1293 &state,
1294 request.clone(),
1295 FeeDetails::zero(),
1296 block_env,
1297 )?;
1298 ensure_return_ok(exit, &out)?;
1299
1300 Ok(AccessListResult {
1301 access_list: AccessList(access_list.0),
1302 gas_used: U256::from(gas_used),
1303 error: None,
1304 })
1305 })
1306 .await?
1307 }
1308
1309 pub async fn estimate_gas(
1314 &self,
1315 request: WithOtherFields<TransactionRequest>,
1316 block_number: Option<BlockId>,
1317 overrides: EvmOverrides,
1318 ) -> Result<U256> {
1319 node_info!("eth_estimateGas");
1320 self.do_estimate_gas(
1321 request,
1322 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1323 overrides,
1324 )
1325 .await
1326 .map(U256::from)
1327 }
1328
1329 pub fn anvil_get_blob_by_versioned_hash(
1331 &self,
1332 hash: B256,
1333 ) -> Result<Option<alloy_consensus::Blob>> {
1334 node_info!("anvil_getBlobByHash");
1335 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1336 }
1337
1338 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1340 node_info!("anvil_getBlobsByTransactionHash");
1341 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1342 }
1343
1344 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1351 node_info!("eth_getTransactionByHash");
1352 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1353 let from = *pending.sender();
1354 let tx = transaction_build(
1355 Some(*pending.hash()),
1356 pending.transaction,
1357 None,
1358 None,
1359 Some(self.backend.base_fee()),
1360 );
1361
1362 let WithOtherFields { inner: mut tx, other } = tx.0;
1363 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1366
1367 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1368 });
1369 if tx.is_none() {
1370 tx = self.backend.transaction_by_hash(hash).await?
1371 }
1372
1373 Ok(tx)
1374 }
1375
1376 pub async fn transaction_by_block_hash_and_index(
1380 &self,
1381 hash: B256,
1382 index: Index,
1383 ) -> Result<Option<AnyRpcTransaction>> {
1384 node_info!("eth_getTransactionByBlockHashAndIndex");
1385 self.backend.transaction_by_block_hash_and_index(hash, index).await
1386 }
1387
1388 pub async fn transaction_by_block_number_and_index(
1392 &self,
1393 block: BlockNumber,
1394 idx: Index,
1395 ) -> Result<Option<AnyRpcTransaction>> {
1396 node_info!("eth_getTransactionByBlockNumberAndIndex");
1397 self.backend.transaction_by_block_number_and_index(block, idx).await
1398 }
1399
1400 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1404 node_info!("eth_getTransactionReceipt");
1405 self.backend.transaction_receipt(hash).await
1406 }
1407
1408 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1412 node_info!("eth_getBlockReceipts");
1413 self.backend.block_receipts(number).await
1414 }
1415
1416 pub async fn uncle_by_block_hash_and_index(
1420 &self,
1421 block_hash: B256,
1422 idx: Index,
1423 ) -> Result<Option<AnyRpcBlock>> {
1424 node_info!("eth_getUncleByBlockHashAndIndex");
1425 let number =
1426 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1427 if let Some(fork) = self.get_fork()
1428 && fork.predates_fork_inclusive(number)
1429 {
1430 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1431 }
1432 Ok(None)
1434 }
1435
1436 pub async fn uncle_by_block_number_and_index(
1440 &self,
1441 block_number: BlockNumber,
1442 idx: Index,
1443 ) -> Result<Option<AnyRpcBlock>> {
1444 node_info!("eth_getUncleByBlockNumberAndIndex");
1445 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1446 if let Some(fork) = self.get_fork()
1447 && fork.predates_fork_inclusive(number)
1448 {
1449 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1450 }
1451 Ok(None)
1453 }
1454
1455 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1459 node_info!("eth_getLogs");
1460 self.backend.logs(filter).await
1461 }
1462
1463 pub fn work(&self) -> Result<Work> {
1467 node_info!("eth_getWork");
1468 Err(BlockchainError::RpcUnimplemented)
1469 }
1470
1471 pub fn syncing(&self) -> Result<bool> {
1475 node_info!("eth_syncing");
1476 Ok(false)
1477 }
1478
1479 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1483 node_info!("eth_submitWork");
1484 Err(BlockchainError::RpcUnimplemented)
1485 }
1486
1487 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1491 node_info!("eth_submitHashrate");
1492 Err(BlockchainError::RpcUnimplemented)
1493 }
1494
1495 pub async fn fee_history(
1499 &self,
1500 block_count: U256,
1501 newest_block: BlockNumber,
1502 reward_percentiles: Vec<f64>,
1503 ) -> Result<FeeHistory> {
1504 node_info!("eth_feeHistory");
1505 let current = self.backend.best_number();
1508 let slots_in_an_epoch = 32u64;
1509
1510 let number = match newest_block {
1511 BlockNumber::Latest | BlockNumber::Pending => current,
1512 BlockNumber::Earliest => 0,
1513 BlockNumber::Number(n) => n,
1514 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1515 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1516 };
1517
1518 if let Some(fork) = self.get_fork() {
1520 if fork.predates_fork_inclusive(number) {
1523 return fork
1524 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1525 .await
1526 .map_err(BlockchainError::AlloyForkProvider);
1527 }
1528 }
1529
1530 const MAX_BLOCK_COUNT: u64 = 1024u64;
1531 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1532
1533 let highest = number;
1535 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1536
1537 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1539 return Err(FeeHistoryError::InvalidBlockRange.into());
1540 }
1541
1542 let mut response = FeeHistory {
1543 oldest_block: lowest,
1544 base_fee_per_gas: Vec::new(),
1545 gas_used_ratio: Vec::new(),
1546 reward: Some(Default::default()),
1547 base_fee_per_blob_gas: Default::default(),
1548 blob_gas_used_ratio: Default::default(),
1549 };
1550 let mut rewards = Vec::new();
1551
1552 {
1553 let fee_history = self.fee_history_cache.lock();
1554
1555 for n in lowest..=highest {
1557 if let Some(block) = fee_history.get(&n) {
1559 response.base_fee_per_gas.push(block.base_fee);
1560 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1561 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1562 response.gas_used_ratio.push(block.gas_used_ratio);
1563
1564 if !reward_percentiles.is_empty() {
1566 let mut block_rewards = Vec::new();
1567 let resolution_per_percentile: f64 = 2.0;
1568 for p in &reward_percentiles {
1569 let p = p.clamp(0.0, 100.0);
1570 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1571 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1572 block_rewards.push(reward);
1573 }
1574 rewards.push(block_rewards);
1575 }
1576 }
1577 }
1578 }
1579
1580 response.reward = Some(rewards);
1581
1582 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1587
1588 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1592
1593 Ok(response)
1594 }
1595
1596 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1603 node_info!("eth_maxPriorityFeePerGas");
1604 Ok(U256::from(self.lowest_suggestion_tip()))
1605 }
1606
1607 fn lowest_suggestion_tip(&self) -> u128 {
1611 let block_number = self.backend.best_number();
1612 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1613
1614 match latest_cached_block {
1615 Some(block) => block.rewards.iter().copied().min(),
1616 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1617 }
1618 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1619 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1620 }
1621
1622 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1626 node_info!("eth_newFilter");
1627 let historic = if filter.block_option.get_from_block().is_some() {
1630 self.backend.logs(filter.clone()).await?
1631 } else {
1632 vec![]
1633 };
1634 let filter = EthFilter::Logs(Box::new(LogsFilter {
1635 blocks: self.new_block_notifications(),
1636 storage: self.storage_info(),
1637 filter: FilteredParams::new(Some(filter)),
1638 historic: Some(historic),
1639 }));
1640 Ok(self.filters.add_filter(filter).await)
1641 }
1642
1643 pub async fn new_block_filter(&self) -> Result<String> {
1647 node_info!("eth_newBlockFilter");
1648 let filter = EthFilter::Blocks(self.new_block_notifications());
1649 Ok(self.filters.add_filter(filter).await)
1650 }
1651
1652 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1656 node_info!("eth_newPendingTransactionFilter");
1657 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1658 Ok(self.filters.add_filter(filter).await)
1659 }
1660
1661 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1665 node_info!("eth_getFilterChanges");
1666 self.filters.get_filter_changes(id).await
1667 }
1668
1669 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1673 node_info!("eth_getFilterLogs");
1674 if let Some(filter) = self.filters.get_log_filter(id).await {
1675 self.backend.logs(filter).await
1676 } else {
1677 Ok(Vec::new())
1678 }
1679 }
1680
1681 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1683 node_info!("eth_uninstallFilter");
1684 Ok(self.filters.uninstall_filter(id).await.is_some())
1685 }
1686
1687 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1691 node_info!("debug_getRawTransaction");
1692 self.inner_raw_transaction(hash).await
1693 }
1694
1695 pub async fn raw_transaction_by_block_hash_and_index(
1699 &self,
1700 block_hash: B256,
1701 index: Index,
1702 ) -> Result<Option<Bytes>> {
1703 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1704 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1705 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1706 None => Ok(None),
1707 }
1708 }
1709
1710 pub async fn raw_transaction_by_block_number_and_index(
1714 &self,
1715 block_number: BlockNumber,
1716 index: Index,
1717 ) -> Result<Option<Bytes>> {
1718 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1719 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1720 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1721 None => Ok(None),
1722 }
1723 }
1724
1725 pub async fn debug_trace_transaction(
1729 &self,
1730 tx_hash: B256,
1731 opts: GethDebugTracingOptions,
1732 ) -> Result<GethTrace> {
1733 node_info!("debug_traceTransaction");
1734 self.backend.debug_trace_transaction(tx_hash, opts).await
1735 }
1736
1737 pub async fn debug_trace_call(
1741 &self,
1742 request: WithOtherFields<TransactionRequest>,
1743 block_number: Option<BlockId>,
1744 opts: GethDebugTracingCallOptions,
1745 ) -> Result<GethTrace> {
1746 node_info!("debug_traceCall");
1747 let block_request = self.block_request(block_number).await?;
1748 let fees = FeeDetails::new(
1749 request.gas_price,
1750 request.max_fee_per_gas,
1751 request.max_priority_fee_per_gas,
1752 request.max_fee_per_blob_gas,
1753 )?
1754 .or_zero_fees();
1755
1756 let result: std::result::Result<GethTrace, BlockchainError> =
1757 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1758 result
1759 }
1760
1761 pub async fn debug_code_by_hash(
1765 &self,
1766 hash: B256,
1767 block_id: Option<BlockId>,
1768 ) -> Result<Option<Bytes>> {
1769 node_info!("debug_codeByHash");
1770 self.backend.debug_code_by_hash(hash, block_id).await
1771 }
1772
1773 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1777 node_info!("trace_transaction");
1778 self.backend.trace_transaction(tx_hash).await
1779 }
1780
1781 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1785 node_info!("trace_block");
1786 self.backend.trace_block(block).await
1787 }
1788
1789 pub async fn trace_filter(
1793 &self,
1794 filter: TraceFilter,
1795 ) -> Result<Vec<LocalizedTransactionTrace>> {
1796 node_info!("trace_filter");
1797 self.backend.trace_filter(filter).await
1798 }
1799}
1800
1801impl EthApi {
1804 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
1808 node_info!("anvil_impersonateAccount");
1809 self.backend.impersonate(address);
1810 Ok(())
1811 }
1812
1813 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
1817 node_info!("anvil_stopImpersonatingAccount");
1818 self.backend.stop_impersonating(address);
1819 Ok(())
1820 }
1821
1822 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
1826 node_info!("anvil_autoImpersonateAccount");
1827 self.backend.auto_impersonate_account(enabled);
1828 Ok(())
1829 }
1830
1831 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
1835 node_info!("anvil_getAutomine");
1836 Ok(self.miner.is_auto_mine())
1837 }
1838
1839 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
1843 node_info!("anvil_getIntervalMining");
1844 Ok(self.miner.get_interval())
1845 }
1846
1847 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
1852 node_info!("evm_setAutomine");
1853 if self.miner.is_auto_mine() {
1854 if enable_automine {
1855 return Ok(());
1856 }
1857 self.miner.set_mining_mode(MiningMode::None);
1858 } else if enable_automine {
1859 let listener = self.pool.add_ready_listener();
1860 let mode = MiningMode::instant(1_000, listener);
1861 self.miner.set_mining_mode(mode);
1862 }
1863 Ok(())
1864 }
1865
1866 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
1870 node_info!("anvil_mine");
1871 let interval = interval.map(|i| i.to::<u64>());
1872 let blocks = num_blocks.unwrap_or(U256::from(1));
1873 if blocks.is_zero() {
1874 return Ok(());
1875 }
1876
1877 self.on_blocking_task(|this| async move {
1878 for _ in 0..blocks.to::<u64>() {
1880 if let Some(interval) = interval {
1882 this.backend.time().increase_time(interval);
1883 }
1884 this.mine_one().await;
1885 }
1886 Ok(())
1887 })
1888 .await?;
1889
1890 Ok(())
1891 }
1892
1893 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
1897 node_info!("evm_setIntervalMining");
1898 let mining_mode = if secs == 0 {
1899 MiningMode::None
1900 } else {
1901 let block_time = Duration::from_secs(secs);
1902
1903 self.backend.update_interval_mine_block_time(block_time);
1905
1906 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
1907 };
1908 self.miner.set_mining_mode(mining_mode);
1909 Ok(())
1910 }
1911
1912 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
1916 node_info!("anvil_dropTransaction");
1917 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
1918 }
1919
1920 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
1924 node_info!("anvil_dropAllTransactions");
1925 self.pool.clear();
1926 Ok(())
1927 }
1928
1929 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
1935 self.reset_instance_id();
1936 node_info!("anvil_reset");
1937 if let Some(forking) = forking {
1938 self.backend.reset_fork(forking).await
1940 } else {
1941 self.backend.reset_to_in_mem().await
1944 }
1945 }
1946
1947 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
1948 node_info!("anvil_setChainId");
1949 self.backend.set_chain_id(chain_id);
1950 Ok(())
1951 }
1952
1953 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
1957 node_info!("anvil_setBalance");
1958 self.backend.set_balance(address, balance).await?;
1959 Ok(())
1960 }
1961
1962 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
1966 node_info!("anvil_addBalance");
1967 let current_balance = self.backend.get_balance(address, None).await?;
1968 self.backend.set_balance(address, current_balance + balance).await?;
1969 Ok(())
1970 }
1971
1972 async fn find_erc20_storage_slot(
1989 &self,
1990 token_address: Address,
1991 calldata: Bytes,
1992 expected_value: U256,
1993 ) -> Result<B256> {
1994 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
1995
1996 let access_list_result =
1998 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
1999 let access_list = access_list_result.access_list;
2000
2001 for item in access_list.0 {
2004 if item.address != token_address {
2005 continue;
2006 };
2007 for slot in &item.storage_keys {
2008 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2009 (*slot, B256::from(expected_value.to_be_bytes())),
2010 ));
2011
2012 let state_override = StateOverridesBuilder::default()
2013 .append(token_address, account_override)
2014 .build();
2015
2016 let evm_override = EvmOverrides::state(Some(state_override));
2017
2018 let Ok(result) =
2019 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2020 else {
2021 continue;
2023 };
2024
2025 let Ok(result_value) = U256::abi_decode(&result) else {
2026 continue;
2028 };
2029
2030 if result_value == expected_value {
2031 return Ok(*slot);
2032 }
2033 }
2034 }
2035
2036 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2037 }
2038
2039 pub async fn anvil_deal_erc20(
2043 &self,
2044 address: Address,
2045 token_address: Address,
2046 balance: U256,
2047 ) -> Result<()> {
2048 node_info!("anvil_dealERC20");
2049
2050 sol! {
2051 #[sol(rpc)]
2052 contract IERC20 {
2053 function balanceOf(address target) external view returns (uint256);
2054 }
2055 }
2056
2057 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2058
2059 let slot =
2061 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2062 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2063 })?;
2064
2065 self.anvil_set_storage_at(
2067 token_address,
2068 U256::from_be_bytes(slot.0),
2069 B256::from(balance.to_be_bytes()),
2070 )
2071 .await?;
2072
2073 Ok(())
2074 }
2075
2076 pub async fn anvil_set_erc20_allowance(
2080 &self,
2081 owner: Address,
2082 spender: Address,
2083 token_address: Address,
2084 amount: U256,
2085 ) -> Result<()> {
2086 node_info!("anvil_setERC20Allowance");
2087
2088 sol! {
2089 #[sol(rpc)]
2090 contract IERC20 {
2091 function allowance(address owner, address spender) external view returns (uint256);
2092 }
2093 }
2094
2095 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2096
2097 let slot =
2099 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2100 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2101 })?;
2102
2103 self.anvil_set_storage_at(
2105 token_address,
2106 U256::from_be_bytes(slot.0),
2107 B256::from(amount.to_be_bytes()),
2108 )
2109 .await?;
2110
2111 Ok(())
2112 }
2113
2114 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2118 node_info!("anvil_setCode");
2119 self.backend.set_code(address, code).await?;
2120 Ok(())
2121 }
2122
2123 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2127 node_info!("anvil_setNonce");
2128 self.backend.set_nonce(address, nonce).await?;
2129 Ok(())
2130 }
2131
2132 pub async fn anvil_set_storage_at(
2136 &self,
2137 address: Address,
2138 slot: U256,
2139 val: B256,
2140 ) -> Result<bool> {
2141 node_info!("anvil_setStorageAt");
2142 self.backend.set_storage_at(address, slot, val).await?;
2143 Ok(true)
2144 }
2145
2146 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2150 node_info!("anvil_setLoggingEnabled");
2151 self.logger.set_enabled(enable);
2152 Ok(())
2153 }
2154
2155 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2159 node_info!("anvil_setMinGasPrice");
2160 if self.backend.is_eip1559() {
2161 return Err(RpcError::invalid_params(
2162 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2163 )
2164 .into());
2165 }
2166 self.backend.set_gas_price(gas.to());
2167 Ok(())
2168 }
2169
2170 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2174 node_info!("anvil_setNextBlockBaseFeePerGas");
2175 if !self.backend.is_eip1559() {
2176 return Err(RpcError::invalid_params(
2177 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2178 )
2179 .into());
2180 }
2181 self.backend.set_base_fee(basefee.to());
2182 Ok(())
2183 }
2184
2185 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2189 node_info!("anvil_setCoinbase");
2190 self.backend.set_coinbase(address);
2191 Ok(())
2192 }
2193
2194 pub async fn anvil_dump_state(
2199 &self,
2200 preserve_historical_states: Option<bool>,
2201 ) -> Result<Bytes> {
2202 node_info!("anvil_dumpState");
2203 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2204 }
2205
2206 pub async fn serialized_state(
2208 &self,
2209 preserve_historical_states: bool,
2210 ) -> Result<SerializableState> {
2211 self.backend.serialized_state(preserve_historical_states).await
2212 }
2213
2214 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2219 node_info!("anvil_loadState");
2220 self.backend.load_state_bytes(buf).await
2221 }
2222
2223 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2227 node_info!("anvil_nodeInfo");
2228
2229 let env = self.backend.env().read();
2230 let fork_config = self.backend.get_fork();
2231 let tx_order = self.transaction_order.read();
2232 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2233
2234 Ok(NodeInfo {
2235 current_block_number: self.backend.best_number(),
2236 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2237 current_block_hash: self.backend.best_hash(),
2238 hard_fork: hard_fork.to_string(),
2239 transaction_order: match *tx_order {
2240 TransactionOrder::Fifo => "fifo".to_string(),
2241 TransactionOrder::Fees => "fees".to_string(),
2242 },
2243 environment: NodeEnvironment {
2244 base_fee: self.backend.base_fee() as u128,
2245 chain_id: self.backend.chain_id().to::<u64>(),
2246 gas_limit: self.backend.gas_limit(),
2247 gas_price: self.gas_price(),
2248 },
2249 fork_config: fork_config
2250 .map(|fork| {
2251 let config = fork.config.read();
2252
2253 NodeForkConfig {
2254 fork_url: Some(config.eth_rpc_url.clone()),
2255 fork_block_number: Some(config.block_number),
2256 fork_retry_backoff: Some(config.backoff.as_millis()),
2257 }
2258 })
2259 .unwrap_or_default(),
2260 })
2261 }
2262
2263 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2267 node_info!("anvil_metadata");
2268 let fork_config = self.backend.get_fork();
2269
2270 Ok(Metadata {
2271 client_version: CLIENT_VERSION.to_string(),
2272 chain_id: self.backend.chain_id().to::<u64>(),
2273 latest_block_hash: self.backend.best_hash(),
2274 latest_block_number: self.backend.best_number(),
2275 instance_id: *self.instance_id.read(),
2276 forked_network: fork_config.map(|cfg| ForkedNetwork {
2277 chain_id: cfg.chain_id(),
2278 fork_block_number: cfg.block_number(),
2279 fork_block_hash: cfg.block_hash(),
2280 }),
2281 snapshots: self.backend.list_state_snapshots(),
2282 })
2283 }
2284
2285 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2286 node_info!("anvil_removePoolTransactions");
2287 self.pool.remove_transactions_by_address(address);
2288 Ok(())
2289 }
2290
2291 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2305 node_info!("anvil_reorg");
2306 let depth = options.depth;
2307 let tx_block_pairs = options.tx_block_pairs;
2308
2309 let current_height = self.backend.best_number();
2311 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2312 RpcError::invalid_params(format!(
2313 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2314 )),
2315 ))?;
2316
2317 let common_block =
2319 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2320
2321 let block_pool_txs = if tx_block_pairs.is_empty() {
2324 HashMap::default()
2325 } else {
2326 let mut pairs = tx_block_pairs;
2327
2328 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2330 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2331 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2332 depth - 1
2333 ))));
2334 }
2335
2336 pairs.sort_by_key(|a| a.1);
2338
2339 let mut nonces: HashMap<Address, u64> = HashMap::default();
2342
2343 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2344 for pair in pairs {
2345 let (tx_data, block_index) = pair;
2346
2347 let pending = match tx_data {
2348 TransactionData::Raw(bytes) => {
2349 let mut data = bytes.as_ref();
2350 let decoded = TypedTransaction::decode_2718(&mut data)
2351 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2352 PendingTransaction::new(decoded)?
2353 }
2354
2355 TransactionData::JSON(req) => {
2356 let mut tx_req = WithOtherFields::new(req);
2357 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2358 self.accounts()?
2359 .first()
2360 .copied()
2361 .ok_or(BlockchainError::NoSignerAvailable)
2362 })?;
2363
2364 let curr_nonce = nonces.entry(from).or_insert(
2366 self.get_transaction_count(
2367 from,
2368 Some(common_block.header.number.into()),
2369 )
2370 .await?,
2371 );
2372
2373 if tx_req.gas.is_none()
2375 && let Ok(gas) = self
2376 .estimate_gas(tx_req.clone(), None, EvmOverrides::default())
2377 .await
2378 {
2379 tx_req.gas = Some(gas.to());
2380 }
2381
2382 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2384
2385 *curr_nonce += 1;
2387
2388 if self.is_impersonated(from) {
2390 let bypass_signature = self.impersonated_signature(&typed);
2391 let transaction =
2392 sign::build_typed_transaction(typed, bypass_signature)?;
2393 self.ensure_typed_transaction_supported(&transaction)?;
2394 PendingTransaction::with_impersonated(transaction, from)
2395 } else {
2396 let transaction = self.sign_request(&from, typed)?;
2397 self.ensure_typed_transaction_supported(&transaction)?;
2398 PendingTransaction::new(transaction)?
2399 }
2400 }
2401 };
2402
2403 let pooled = PoolTransaction::new(pending);
2404 txs.entry(block_index).or_default().push(Arc::new(pooled));
2405 }
2406
2407 txs
2408 };
2409
2410 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2411 Ok(())
2412 }
2413
2414 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2425 node_info!("anvil_rollback");
2426 let depth = depth.unwrap_or(1);
2427
2428 let current_height = self.backend.best_number();
2430 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2431 RpcError::invalid_params(format!(
2432 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2433 )),
2434 ))?;
2435
2436 let common_block =
2438 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2439
2440 self.backend.rollback(common_block).await?;
2441 Ok(())
2442 }
2443
2444 pub async fn evm_snapshot(&self) -> Result<U256> {
2448 node_info!("evm_snapshot");
2449 Ok(self.backend.create_state_snapshot().await)
2450 }
2451
2452 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2457 node_info!("evm_revert");
2458 self.backend.revert_state_snapshot(id).await
2459 }
2460
2461 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2465 node_info!("evm_increaseTime");
2466 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2467 }
2468
2469 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2473 node_info!("evm_setNextBlockTimestamp");
2474 self.backend.time().set_next_block_timestamp(seconds)
2475 }
2476
2477 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2482 node_info!("evm_setTime");
2483 let now = self.backend.time().current_call_timestamp();
2484 self.backend.time().reset(timestamp);
2485
2486 let offset = timestamp.saturating_sub(now);
2488 Ok(Duration::from_millis(offset).as_secs())
2489 }
2490
2491 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2495 node_info!("evm_setBlockGasLimit");
2496 self.backend.set_gas_limit(gas_limit.to());
2497 Ok(true)
2498 }
2499
2500 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2504 node_info!("anvil_setBlockTimestampInterval");
2505 self.backend.time().set_block_timestamp_interval(seconds);
2506 Ok(())
2507 }
2508
2509 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2513 node_info!("anvil_removeBlockTimestampInterval");
2514 Ok(self.backend.time().remove_block_timestamp_interval())
2515 }
2516
2517 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2524 node_info!("evm_mine");
2525
2526 self.do_evm_mine(opts).await?;
2527
2528 Ok("0x0".to_string())
2529 }
2530
2531 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2541 node_info!("evm_mine_detailed");
2542
2543 let mined_blocks = self.do_evm_mine(opts).await?;
2544
2545 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2546
2547 let latest = self.backend.best_number();
2548 for offset in (0..mined_blocks).rev() {
2549 let block_num = latest - offset;
2550 if let Some(mut block) =
2551 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2552 {
2553 let block_txs = match block.transactions_mut() {
2554 BlockTransactions::Full(txs) => txs,
2555 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2556 };
2557 for tx in block_txs.iter_mut() {
2558 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2559 && let Some(output) = receipt.out
2560 {
2561 if !receipt
2563 .inner
2564 .inner
2565 .as_receipt_with_bloom()
2566 .receipt
2567 .status
2568 .coerce_status()
2569 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2570 {
2571 tx.other.insert(
2572 "revertReason".to_string(),
2573 serde_json::to_value(reason).expect("Infallible"),
2574 );
2575 }
2576 tx.other.insert(
2577 "output".to_string(),
2578 serde_json::to_value(output).expect("Infallible"),
2579 );
2580 }
2581 }
2582 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2583 blocks.push(block);
2584 }
2585 }
2586
2587 Ok(blocks)
2588 }
2589
2590 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2594 node_info!("anvil_setBlock");
2595 self.backend.set_block_number(block_number);
2596 Ok(())
2597 }
2598
2599 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2603 node_info!("anvil_setRpcUrl");
2604 if let Some(fork) = self.backend.get_fork() {
2605 let mut config = fork.config.write();
2606 let new_provider = Arc::new(
2608 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2609 |_| {
2610 TransportErrorKind::custom_str(
2611 format!("Failed to parse invalid url {url}").as_str(),
2612 )
2613 },
2614 )?, );
2617 config.provider = new_provider;
2618 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2619 config.eth_rpc_url = url;
2620 }
2621 Ok(())
2622 }
2623
2624 pub async fn anvil_enable_traces(&self) -> Result<()> {
2629 node_info!("anvil_enableTraces");
2630 Err(BlockchainError::RpcUnimplemented)
2631 }
2632
2633 pub async fn eth_send_unsigned_transaction(
2637 &self,
2638 request: WithOtherFields<TransactionRequest>,
2639 ) -> Result<TxHash> {
2640 node_info!("eth_sendUnsignedTransaction");
2641 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2643
2644 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2645
2646 let request = self.build_typed_tx_request(request, nonce)?;
2647
2648 let bypass_signature = self.impersonated_signature(&request);
2649 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2650
2651 self.ensure_typed_transaction_supported(&transaction)?;
2652
2653 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2654
2655 self.backend.validate_pool_transaction(&pending_transaction).await?;
2657
2658 let requires = required_marker(nonce, on_chain_nonce, from);
2659 let provides = vec![to_marker(nonce, from)];
2660
2661 self.add_pending_transaction(pending_transaction, requires, provides)
2662 }
2663
2664 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2670 node_info!("txpool_status");
2671 Ok(self.pool.txpool_status())
2672 }
2673
2674 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2681 node_info!("txpool_inspect");
2682 let mut inspect = TxpoolInspect::default();
2683
2684 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2685 let tx = &tx.pending_transaction.transaction;
2686 let to = tx.to();
2687 let gas_price = tx.gas_price();
2688 let value = tx.value();
2689 let gas = tx.gas_limit();
2690 TxpoolInspectSummary { to, value, gas, gas_price }
2691 }
2692
2693 for pending in self.pool.ready_transactions() {
2700 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2701 let key = pending.pending_transaction.nonce().to_string();
2702 entry.insert(key, convert(pending));
2703 }
2704 for queued in self.pool.pending_transactions() {
2705 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2706 let key = queued.pending_transaction.nonce().to_string();
2707 entry.insert(key, convert(queued));
2708 }
2709 Ok(inspect)
2710 }
2711
2712 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2719 node_info!("txpool_content");
2720 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2721 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2722 let from = *tx.pending_transaction.sender();
2723 let tx = transaction_build(
2724 Some(tx.hash()),
2725 tx.pending_transaction.transaction.clone(),
2726 None,
2727 None,
2728 None,
2729 );
2730
2731 let WithOtherFields { inner: mut tx, other } = tx.0;
2732
2733 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2736
2737 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2738
2739 Ok(tx)
2740 }
2741
2742 for pending in self.pool.ready_transactions() {
2743 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2744 let key = pending.pending_transaction.nonce().to_string();
2745 entry.insert(key, convert(pending)?);
2746 }
2747 for queued in self.pool.pending_transactions() {
2748 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2749 let key = queued.pending_transaction.nonce().to_string();
2750 entry.insert(key, convert(queued)?);
2751 }
2752
2753 Ok(content)
2754 }
2755}
2756
2757impl EthApi {
2759 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2765 node_info!("wallet_getCapabilities");
2766 Ok(self.backend.get_capabilities())
2767 }
2768
2769 pub async fn wallet_send_transaction(
2770 &self,
2771 mut request: WithOtherFields<TransactionRequest>,
2772 ) -> Result<TxHash> {
2773 node_info!("wallet_sendTransaction");
2774
2775 if request.value.is_some_and(|val| val > U256::ZERO) {
2778 return Err(WalletError::ValueNotZero.into());
2779 }
2780
2781 if request.from.is_some() {
2783 return Err(WalletError::FromSet.into());
2784 }
2785
2786 if request.nonce.is_some() {
2788 return Err(WalletError::NonceSet.into());
2789 }
2790
2791 let capabilities = self.backend.get_capabilities();
2792 let valid_delegations: &[Address] = capabilities
2793 .get(self.chain_id())
2794 .map(|caps| caps.delegation.addresses.as_ref())
2795 .unwrap_or_default();
2796
2797 if let Some(authorizations) = &request.authorization_list
2798 && authorizations.iter().any(|auth| !valid_delegations.contains(&auth.address))
2799 {
2800 return Err(WalletError::InvalidAuthorization.into());
2801 }
2802
2803 match (request.authorization_list.is_some(), request.to) {
2805 (false, Some(TxKind::Call(addr))) => {
2808 let acc = self.backend.get_account(addr).await?;
2809
2810 let delegated_address = acc
2811 .code
2812 .map(|code| match code {
2813 Bytecode::Eip7702(c) => c.address(),
2814 _ => Address::ZERO,
2815 })
2816 .unwrap_or_default();
2817
2818 if delegated_address == Address::ZERO
2820 || !valid_delegations.contains(&delegated_address)
2821 {
2822 return Err(WalletError::IllegalDestination.into());
2823 }
2824 }
2825 (true, _) => (),
2827 _ => return Err(WalletError::IllegalDestination.into()),
2829 }
2830
2831 let wallet = self.backend.executor_wallet().ok_or(WalletError::InternalError)?;
2832
2833 let from = NetworkWallet::<Ethereum>::default_signer_address(&wallet);
2834
2835 let nonce = self.get_transaction_count(from, Some(BlockId::latest())).await?;
2836
2837 request.nonce = Some(nonce);
2838
2839 let chain_id = self.chain_id();
2840
2841 request.chain_id = Some(chain_id);
2842
2843 request.from = Some(from);
2844
2845 let gas_limit_fut =
2846 self.estimate_gas(request.clone(), Some(BlockId::latest()), EvmOverrides::default());
2847
2848 let fees_fut = self.fee_history(
2849 U256::from(EIP1559_FEE_ESTIMATION_PAST_BLOCKS),
2850 BlockNumber::Latest,
2851 vec![EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE],
2852 );
2853
2854 let (gas_limit, fees) = tokio::join!(gas_limit_fut, fees_fut);
2855
2856 let gas_limit = gas_limit?;
2857 let fees = fees?;
2858
2859 request.gas = Some(gas_limit.to());
2860
2861 let base_fee = fees.latest_block_base_fee().unwrap_or_default();
2862
2863 let estimation = eip1559_default_estimator(base_fee, &fees.reward.unwrap_or_default());
2864
2865 request.max_fee_per_gas = Some(estimation.max_fee_per_gas);
2866 request.max_priority_fee_per_gas = Some(estimation.max_priority_fee_per_gas);
2867 request.gas_price = None;
2868
2869 let envelope = request.build(&wallet).await.map_err(|_| WalletError::InternalError)?;
2870
2871 self.send_raw_transaction(envelope.encoded_2718().into()).await
2872 }
2873
2874 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2878 node_info!("anvil_addCapability");
2879 self.backend.add_capability(address);
2880 Ok(())
2881 }
2882
2883 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2884 node_info!("anvil_setExecutor");
2885 self.backend.set_executor(executor_pk)
2886 }
2887}
2888
2889impl EthApi {
2890 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2892 where
2893 C: FnOnce(Self) -> F,
2894 F: Future<Output = Result<R>> + Send + 'static,
2895 R: Send + 'static,
2896 {
2897 let (tx, rx) = oneshot::channel();
2898 let this = self.clone();
2899 let f = c(this);
2900 tokio::task::spawn_blocking(move || {
2901 tokio::runtime::Handle::current().block_on(async move {
2902 let res = f.await;
2903 let _ = tx.send(res);
2904 })
2905 });
2906 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2907 }
2908
2909 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2911 let mut blocks_to_mine = 1u64;
2912
2913 if let Some(opts) = opts {
2914 let timestamp = match opts {
2915 MineOptions::Timestamp(timestamp) => timestamp,
2916 MineOptions::Options { timestamp, blocks } => {
2917 if let Some(blocks) = blocks {
2918 blocks_to_mine = blocks;
2919 }
2920 timestamp
2921 }
2922 };
2923 if let Some(timestamp) = timestamp {
2924 self.evm_set_next_block_timestamp(timestamp)?;
2926 }
2927 }
2928
2929 self.on_blocking_task(|this| async move {
2932 for _ in 0..blocks_to_mine {
2934 this.mine_one().await;
2935 }
2936 Ok(())
2937 })
2938 .await?;
2939
2940 Ok(blocks_to_mine)
2941 }
2942
2943 async fn do_estimate_gas(
2944 &self,
2945 request: WithOtherFields<TransactionRequest>,
2946 block_number: Option<BlockId>,
2947 overrides: EvmOverrides,
2948 ) -> Result<u128> {
2949 let block_request = self.block_request(block_number).await?;
2950 if let BlockRequest::Number(number) = block_request
2952 && let Some(fork) = self.get_fork()
2953 && fork.predates_fork(number)
2954 {
2955 if overrides.has_state() || overrides.has_block() {
2956 return Err(BlockchainError::EvmOverrideError(
2957 "not available on past forked blocks".to_string(),
2958 ));
2959 }
2960 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
2961 }
2962
2963 self.on_blocking_task(|this| async move {
2966 this.backend
2967 .with_database_at(Some(block_request), |state, mut block| {
2968 let mut cache_db = CacheDB::new(state);
2969 if let Some(state_overrides) = overrides.state {
2970 apply_state_overrides(
2971 state_overrides.into_iter().collect(),
2972 &mut cache_db,
2973 )?;
2974 }
2975 if let Some(block_overrides) = overrides.block {
2976 cache_db.apply_block_overrides(*block_overrides, &mut block);
2977 }
2978 this.do_estimate_gas_with_state(request, &cache_db as &dyn DatabaseRef, block)
2979 })
2980 .await?
2981 })
2982 .await
2983 }
2984
2985 fn do_estimate_gas_with_state(
2989 &self,
2990 mut request: WithOtherFields<TransactionRequest>,
2991 state: &dyn DatabaseRef,
2992 block_env: BlockEnv,
2993 ) -> Result<u128> {
2994 let to = request.to.as_ref().and_then(TxKind::to);
2997
2998 let maybe_transfer = (request.input.input().is_none()
3000 || request.input.input().is_some_and(|data| data.is_empty()))
3001 && request.authorization_list.is_none()
3002 && request.access_list.is_none()
3003 && request.blob_versioned_hashes.is_none();
3004
3005 if maybe_transfer
3006 && let Some(to) = to
3007 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
3008 && target_code.as_ref().is_empty()
3009 {
3010 return Ok(MIN_TRANSACTION_GAS);
3011 }
3012
3013 let fees = FeeDetails::new(
3014 request.gas_price,
3015 request.max_fee_per_gas,
3016 request.max_priority_fee_per_gas,
3017 request.max_fee_per_blob_gas,
3018 )?
3019 .or_zero_fees();
3020
3021 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
3024
3025 let gas_price = fees.gas_price.unwrap_or_default();
3026 if gas_price > 0
3028 && let Some(from) = request.from
3029 {
3030 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
3031 if let Some(value) = request.value {
3032 if value > available_funds {
3033 return Err(InvalidTransactionError::InsufficientFunds.into());
3034 }
3035 available_funds -= value;
3037 }
3038 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
3040 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
3041 }
3042
3043 let mut call_to_estimate = request.clone();
3044 call_to_estimate.gas = Some(highest_gas_limit as u64);
3045
3046 let ethres =
3048 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3049
3050 let gas_used = match ethres.try_into()? {
3051 GasEstimationCallResult::Success(gas) => Ok(gas),
3052 GasEstimationCallResult::OutOfGas => {
3053 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3054 }
3055 GasEstimationCallResult::Revert(output) => {
3056 Err(InvalidTransactionError::Revert(output).into())
3057 }
3058 GasEstimationCallResult::EvmError(err) => {
3059 warn!(target: "node", "estimation failed due to {:?}", err);
3060 Err(BlockchainError::EvmError(err))
3061 }
3062 }?;
3063
3064 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3071
3072 let mut mid_gas_limit =
3074 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3075
3076 while (highest_gas_limit - lowest_gas_limit) > 1 {
3078 request.gas = Some(mid_gas_limit as u64);
3079 let ethres = self.backend.call_with_state(
3080 &state,
3081 request.clone(),
3082 fees.clone(),
3083 block_env.clone(),
3084 );
3085
3086 match ethres.try_into()? {
3087 GasEstimationCallResult::Success(_) => {
3088 highest_gas_limit = mid_gas_limit;
3092 }
3093 GasEstimationCallResult::OutOfGas
3094 | GasEstimationCallResult::Revert(_)
3095 | GasEstimationCallResult::EvmError(_) => {
3096 lowest_gas_limit = mid_gas_limit;
3103 }
3104 };
3105 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3107 }
3108
3109 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3110
3111 Ok(highest_gas_limit)
3112 }
3113
3114 pub fn set_transaction_order(&self, order: TransactionOrder) {
3116 *self.transaction_order.write() = order;
3117 }
3118
3119 fn transaction_priority(&self, tx: &TypedTransaction) -> TransactionPriority {
3121 self.transaction_order.read().priority(tx)
3122 }
3123
3124 pub fn chain_id(&self) -> u64 {
3126 self.backend.chain_id().to::<u64>()
3127 }
3128
3129 pub fn get_fork(&self) -> Option<ClientFork> {
3131 self.backend.get_fork()
3132 }
3133
3134 pub fn instance_id(&self) -> B256 {
3136 *self.instance_id.read()
3137 }
3138
3139 pub fn reset_instance_id(&self) {
3141 *self.instance_id.write() = B256::random();
3142 }
3143
3144 #[expect(clippy::borrowed_box)]
3146 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3147 self.signers.iter().find(|signer| signer.is_signer_for(address))
3148 }
3149
3150 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3152 self.backend.new_block_notifications()
3153 }
3154
3155 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3157 self.pool.add_ready_listener()
3158 }
3159
3160 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3162 let (tx, rx) = unbounded_channel();
3163 let mut hashes = self.new_ready_transactions();
3164
3165 let this = self.clone();
3166
3167 tokio::spawn(async move {
3168 while let Some(hash) = hashes.next().await {
3169 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3170 && tx.send(txn).is_err()
3171 {
3172 break;
3173 }
3174 }
3175 });
3176
3177 rx
3178 }
3179
3180 pub fn storage_info(&self) -> StorageInfo {
3182 StorageInfo::new(Arc::clone(&self.backend))
3183 }
3184
3185 pub fn is_fork(&self) -> bool {
3187 self.backend.is_fork()
3188 }
3189
3190 pub async fn mine_one(&self) {
3192 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3193 let outcome = self.backend.mine_block(transactions).await;
3194
3195 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3196 self.pool.on_mined_block(outcome);
3197 }
3198
3199 async fn pending_block(&self) -> AnyRpcBlock {
3201 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3202 let info = self.backend.pending_block(transactions).await;
3203 self.backend.convert_block(info.block)
3204 }
3205
3206 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3208 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3209 let BlockInfo { block, transactions, receipts: _ } =
3210 self.backend.pending_block(transactions).await;
3211
3212 let mut partial_block = self.backend.convert_block(block.clone());
3213
3214 let mut block_transactions = Vec::with_capacity(block.transactions.len());
3215 let base_fee = self.backend.base_fee();
3216
3217 for info in transactions {
3218 let tx = block.transactions.get(info.transaction_index as usize)?.clone();
3219
3220 let tx = transaction_build(
3221 Some(info.transaction_hash),
3222 tx,
3223 Some(&block),
3224 Some(info),
3225 Some(base_fee),
3226 );
3227 block_transactions.push(tx);
3228 }
3229
3230 partial_block.transactions = BlockTransactions::from(block_transactions);
3231
3232 Some(partial_block)
3233 }
3234
3235 fn build_typed_tx_request(
3236 &self,
3237 request: WithOtherFields<TransactionRequest>,
3238 nonce: u64,
3239 ) -> Result<TypedTransactionRequest> {
3240 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
3241 let max_fee_per_gas = request.max_fee_per_gas;
3242 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
3243 let gas_price = request.gas_price;
3244
3245 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
3246 let from = request.from;
3247
3248 let request = match transaction_request_to_typed(request) {
3249 Some(TypedTransactionRequest::Legacy(mut m)) => {
3250 m.nonce = nonce;
3251 m.chain_id = Some(chain_id);
3252 m.gas_limit = gas_limit;
3253 if gas_price.is_none() {
3254 m.gas_price = self.gas_price();
3255 }
3256 TypedTransactionRequest::Legacy(m)
3257 }
3258 Some(TypedTransactionRequest::EIP2930(mut m)) => {
3259 m.nonce = nonce;
3260 m.chain_id = chain_id;
3261 m.gas_limit = gas_limit;
3262 if gas_price.is_none() {
3263 m.gas_price = self.gas_price();
3264 }
3265 TypedTransactionRequest::EIP2930(m)
3266 }
3267 Some(TypedTransactionRequest::EIP1559(mut m)) => {
3268 m.nonce = nonce;
3269 m.chain_id = chain_id;
3270 m.gas_limit = gas_limit;
3271 if max_fee_per_gas.is_none() {
3272 m.max_fee_per_gas = self.gas_price();
3273 }
3274 TypedTransactionRequest::EIP1559(m)
3275 }
3276 Some(TypedTransactionRequest::EIP7702(mut m)) => {
3277 m.nonce = nonce;
3278 m.chain_id = chain_id;
3279 m.gas_limit = gas_limit;
3280 if max_fee_per_gas.is_none() {
3281 m.max_fee_per_gas = self.gas_price();
3282 }
3283 TypedTransactionRequest::EIP7702(m)
3284 }
3285 Some(TypedTransactionRequest::EIP4844(m)) => {
3286 TypedTransactionRequest::EIP4844(match m {
3287 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
3289 m.tx.nonce = nonce;
3290 m.tx.chain_id = chain_id;
3291 m.tx.gas_limit = gas_limit;
3292 if max_fee_per_gas.is_none() {
3293 m.tx.max_fee_per_gas = self.gas_price();
3294 }
3295 if max_fee_per_blob_gas.is_none() {
3296 m.tx.max_fee_per_blob_gas = self
3297 .excess_blob_gas_and_price()
3298 .unwrap_or_default()
3299 .map_or(0, |g| g.blob_gasprice)
3300 }
3301 TxEip4844Variant::TxEip4844WithSidecar(m)
3302 }
3303 TxEip4844Variant::TxEip4844(mut tx) => {
3304 if !self.backend.skip_blob_validation(from) {
3305 return Err(BlockchainError::FailedToDecodeTransaction);
3306 }
3307
3308 tx.nonce = nonce;
3310 tx.chain_id = chain_id;
3311 tx.gas_limit = gas_limit;
3312 if max_fee_per_gas.is_none() {
3313 tx.max_fee_per_gas = self.gas_price();
3314 }
3315 if max_fee_per_blob_gas.is_none() {
3316 tx.max_fee_per_blob_gas = self
3317 .excess_blob_gas_and_price()
3318 .unwrap_or_default()
3319 .map_or(0, |g| g.blob_gasprice)
3320 }
3321
3322 TxEip4844Variant::TxEip4844(tx)
3323 }
3324 })
3325 }
3326 Some(TypedTransactionRequest::Deposit(mut m)) => {
3327 m.gas_limit = gas_limit;
3328 TypedTransactionRequest::Deposit(m)
3329 }
3330 None => return Err(BlockchainError::FailedToDecodeTransaction),
3331 };
3332 Ok(request)
3333 }
3334
3335 pub fn is_impersonated(&self, addr: Address) -> bool {
3337 self.backend.cheats().is_impersonated(addr)
3338 }
3339
3340 fn impersonated_signature(&self, request: &TypedTransactionRequest) -> Signature {
3342 match request {
3343 TypedTransactionRequest::Legacy(_) => Signature::from_scalars_and_parity(
3346 B256::with_last_byte(1),
3347 B256::with_last_byte(1),
3348 false,
3349 ),
3350 TypedTransactionRequest::EIP2930(_)
3351 | TypedTransactionRequest::EIP1559(_)
3352 | TypedTransactionRequest::EIP7702(_)
3353 | TypedTransactionRequest::EIP4844(_)
3354 | TypedTransactionRequest::Deposit(_) => Signature::from_scalars_and_parity(
3355 B256::with_last_byte(1),
3356 B256::with_last_byte(1),
3357 false,
3358 ),
3359 }
3360 }
3361
3362 async fn get_transaction_count(
3364 &self,
3365 address: Address,
3366 block_number: Option<BlockId>,
3367 ) -> Result<u64> {
3368 let block_request = self.block_request(block_number).await?;
3369
3370 if let BlockRequest::Number(number) = block_request
3371 && let Some(fork) = self.get_fork()
3372 && fork.predates_fork(number)
3373 {
3374 return Ok(fork.get_nonce(address, number).await?);
3375 }
3376
3377 self.backend.get_nonce(address, block_request).await
3378 }
3379
3380 async fn request_nonce(
3388 &self,
3389 request: &TransactionRequest,
3390 from: Address,
3391 ) -> Result<(u64, u64)> {
3392 let highest_nonce =
3393 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3394 let nonce = request.nonce.unwrap_or(highest_nonce);
3395
3396 Ok((nonce, highest_nonce))
3397 }
3398
3399 fn add_pending_transaction(
3401 &self,
3402 pending_transaction: PendingTransaction,
3403 requires: Vec<TxMarker>,
3404 provides: Vec<TxMarker>,
3405 ) -> Result<TxHash> {
3406 let from = *pending_transaction.sender();
3407 let priority = self.transaction_priority(&pending_transaction.transaction);
3408 let pool_transaction =
3409 PoolTransaction { requires, provides, pending_transaction, priority };
3410 let tx = self.pool.add_transaction(pool_transaction)?;
3411 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3412 Ok(*tx.hash())
3413 }
3414
3415 pub async fn state_root(&self) -> Option<B256> {
3417 self.backend.get_db().read().await.maybe_state_root()
3418 }
3419
3420 fn ensure_typed_transaction_supported(&self, tx: &TypedTransaction) -> Result<()> {
3422 match &tx {
3423 TypedTransaction::EIP2930(_) => self.backend.ensure_eip2930_active(),
3424 TypedTransaction::EIP1559(_) => self.backend.ensure_eip1559_active(),
3425 TypedTransaction::EIP4844(_) => self.backend.ensure_eip4844_active(),
3426 TypedTransaction::EIP7702(_) => self.backend.ensure_eip7702_active(),
3427 TypedTransaction::Deposit(_) => self.backend.ensure_op_deposits_active(),
3428 TypedTransaction::Legacy(_) => Ok(()),
3429 }
3430 }
3431}
3432
3433fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3434 if provided_nonce == on_chain_nonce {
3435 return Vec::new();
3436 }
3437 let prev_nonce = provided_nonce.saturating_sub(1);
3438 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3439}
3440
3441fn convert_transact_out(out: &Option<Output>) -> Bytes {
3442 match out {
3443 None => Default::default(),
3444 Some(Output::Call(out)) => out.to_vec().into(),
3445 Some(Output::Create(out, _)) => out.to_vec().into(),
3446 }
3447}
3448
3449fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3451 let out = convert_transact_out(out);
3452 match exit {
3453 return_ok!() => Ok(out),
3454 return_revert!() => Err(InvalidTransactionError::Revert(Some(out.0.into())).into()),
3455 reason => Err(BlockchainError::EvmError(reason)),
3456 }
3457}
3458
3459fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3461 match transaction_request_to_typed(request.clone()) {
3462 Some(request) => match request {
3463 TypedTransactionRequest::Legacy(req) => match req.to {
3464 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3465 TxKind::Create => MIN_CREATE_GAS,
3466 },
3467 TypedTransactionRequest::EIP1559(req) => match req.to {
3468 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3469 TxKind::Create => MIN_CREATE_GAS,
3470 },
3471 TypedTransactionRequest::EIP7702(req) => {
3472 MIN_TRANSACTION_GAS
3473 + req.authorization_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3474 }
3475 TypedTransactionRequest::EIP2930(req) => match req.to {
3476 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3477 TxKind::Create => MIN_CREATE_GAS,
3478 },
3479 TypedTransactionRequest::EIP4844(_) => MIN_TRANSACTION_GAS,
3480 TypedTransactionRequest::Deposit(req) => match req.to {
3481 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3482 TxKind::Create => MIN_CREATE_GAS,
3483 },
3484 },
3485 _ => MIN_CREATE_GAS,
3488 }
3489}
3490
3491enum GasEstimationCallResult {
3493 Success(u128),
3494 OutOfGas,
3495 Revert(Option<Bytes>),
3496 EvmError(InstructionResult),
3497}
3498
3499impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3503 type Error = BlockchainError;
3504
3505 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3506 match res {
3507 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3509 Ok(Self::OutOfGas)
3510 }
3511 Err(err) => Err(err),
3512 Ok((exit, output, gas, _)) => match exit {
3513 return_ok!() => Ok(Self::Success(gas)),
3514
3515 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3517 InstructionResult::CallTooDeep
3518 | InstructionResult::OutOfFunds
3519 | InstructionResult::CreateInitCodeStartingEF00
3520 | InstructionResult::InvalidEOFInitCode
3521 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3522
3523 InstructionResult::OutOfGas
3525 | InstructionResult::MemoryOOG
3526 | InstructionResult::MemoryLimitOOG
3527 | InstructionResult::PrecompileOOG
3528 | InstructionResult::InvalidOperandOOG
3529 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3530
3531 InstructionResult::OpcodeNotFound
3533 | InstructionResult::CallNotAllowedInsideStatic
3534 | InstructionResult::StateChangeDuringStaticCall
3535 | InstructionResult::InvalidFEOpcode
3536 | InstructionResult::InvalidJump
3537 | InstructionResult::NotActivated
3538 | InstructionResult::StackUnderflow
3539 | InstructionResult::StackOverflow
3540 | InstructionResult::OutOfOffset
3541 | InstructionResult::CreateCollision
3542 | InstructionResult::OverflowPayment
3543 | InstructionResult::PrecompileError
3544 | InstructionResult::NonceOverflow
3545 | InstructionResult::CreateContractSizeLimit
3546 | InstructionResult::CreateContractStartingWithEF
3547 | InstructionResult::CreateInitCodeSizeLimit
3548 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3549 },
3550 }
3551 }
3552}