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 EthRequest::DebugCodeByHash(hash, block) => {
338 self.debug_code_by_hash(hash, block).await.to_rpc_result()
339 }
340 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
341 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
342 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
343 EthRequest::ImpersonateAccount(addr) => {
344 self.anvil_impersonate_account(addr).await.to_rpc_result()
345 }
346 EthRequest::StopImpersonatingAccount(addr) => {
347 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
348 }
349 EthRequest::AutoImpersonateAccount(enable) => {
350 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
351 }
352 EthRequest::ImpersonateSignature(signature, address) => {
353 self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
354 }
355 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
356 EthRequest::Mine(blocks, interval) => {
357 self.anvil_mine(blocks, interval).await.to_rpc_result()
358 }
359 EthRequest::SetAutomine(enabled) => {
360 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
361 }
362 EthRequest::SetIntervalMining(interval) => {
363 self.anvil_set_interval_mining(interval).to_rpc_result()
364 }
365 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
366 EthRequest::DropTransaction(tx) => {
367 self.anvil_drop_transaction(tx).await.to_rpc_result()
368 }
369 EthRequest::DropAllTransactions() => {
370 self.anvil_drop_all_transactions().await.to_rpc_result()
371 }
372 EthRequest::Reset(fork) => {
373 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
374 }
375 EthRequest::SetBalance(addr, val) => {
376 self.anvil_set_balance(addr, val).await.to_rpc_result()
377 }
378 EthRequest::AddBalance(addr, val) => {
379 self.anvil_add_balance(addr, val).await.to_rpc_result()
380 }
381 EthRequest::DealERC20(addr, token_addr, val) => {
382 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
383 }
384 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
385 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
386 .await
387 .to_rpc_result(),
388 EthRequest::SetCode(addr, code) => {
389 self.anvil_set_code(addr, code).await.to_rpc_result()
390 }
391 EthRequest::SetNonce(addr, nonce) => {
392 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
393 }
394 EthRequest::SetStorageAt(addr, slot, val) => {
395 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
396 }
397 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
398 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
399 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
400 EthRequest::SetMinGasPrice(gas) => {
401 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
402 }
403 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
404 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
405 }
406 EthRequest::DumpState(preserve_historical_states) => self
407 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
408 .await
409 .to_rpc_result(),
410 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
411 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
412 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
413 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
414 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
415 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
416 EthRequest::EvmSetNextBlockTimeStamp(time) => {
417 if time >= U256::from(u64::MAX) {
418 return ResponseResult::Error(RpcError::invalid_params(
419 "The timestamp is too big",
420 ));
421 }
422 let time = time.to::<u64>();
423 self.evm_set_next_block_timestamp(time).to_rpc_result()
424 }
425 EthRequest::EvmSetTime(timestamp) => {
426 if timestamp >= U256::from(u64::MAX) {
427 return ResponseResult::Error(RpcError::invalid_params(
428 "The timestamp is too big",
429 ));
430 }
431 let time = timestamp.to::<u64>();
432 self.evm_set_time(time).to_rpc_result()
433 }
434 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
435 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
436 }
437 EthRequest::EvmSetBlockTimeStampInterval(time) => {
438 self.evm_set_block_timestamp_interval(time).to_rpc_result()
439 }
440 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
441 self.evm_remove_block_timestamp_interval().to_rpc_result()
442 }
443 EthRequest::EvmMine(mine) => {
444 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
445 }
446 EthRequest::EvmMineDetailed(mine) => {
447 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
448 }
449 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
450 EthRequest::EthSendUnsignedTransaction(tx) => {
451 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
452 }
453 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
454 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
455 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
456 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
457 EthRequest::EthNewPendingTransactionFilter(_) => {
458 self.new_pending_transaction_filter().await.to_rpc_result()
459 }
460 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
461 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
462 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
463 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
464 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
465 EthRequest::ErigonGetHeaderByNumber(num) => {
466 self.erigon_get_header_by_number(num).await.to_rpc_result()
467 }
468 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
469 EthRequest::OtsGetInternalOperations(hash) => {
470 self.ots_get_internal_operations(hash).await.to_rpc_result()
471 }
472 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
473 EthRequest::OtsTraceTransaction(hash) => {
474 self.ots_trace_transaction(hash).await.to_rpc_result()
475 }
476 EthRequest::OtsGetTransactionError(hash) => {
477 self.ots_get_transaction_error(hash).await.to_rpc_result()
478 }
479 EthRequest::OtsGetBlockDetails(num) => {
480 self.ots_get_block_details(num).await.to_rpc_result()
481 }
482 EthRequest::OtsGetBlockDetailsByHash(hash) => {
483 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
484 }
485 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
486 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
487 }
488 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
489 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
490 }
491 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
492 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
493 }
494 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
495 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
496 }
497 EthRequest::OtsGetContractCreator(address) => {
498 self.ots_get_contract_creator(address).await.to_rpc_result()
499 }
500 EthRequest::RemovePoolTransactions(address) => {
501 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
502 }
503 EthRequest::Reorg(reorg_options) => {
504 self.anvil_reorg(reorg_options).await.to_rpc_result()
505 }
506 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
507 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
508 EthRequest::WalletSendTransaction(tx) => {
509 self.wallet_send_transaction(*tx).await.to_rpc_result()
510 }
511 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
512 EthRequest::AnvilSetExecutor(executor_pk) => {
513 self.anvil_set_executor(executor_pk).to_rpc_result()
514 }
515 };
516
517 if let ResponseResult::Error(err) = &response {
518 node_info!("\nRPC request failed:");
519 node_info!(" Request: {:?}", request);
520 node_info!(" Error: {}\n", err);
521 }
522
523 response
524 }
525
526 fn sign_request(
527 &self,
528 from: &Address,
529 request: TypedTransactionRequest,
530 ) -> Result<TypedTransaction> {
531 match request {
532 TypedTransactionRequest::Deposit(_) => {
533 let nil_signature = Signature::from_scalars_and_parity(
534 B256::with_last_byte(1),
535 B256::with_last_byte(1),
536 false,
537 );
538 return build_typed_transaction(request, nil_signature);
539 }
540 _ => {
541 for signer in self.signers.iter() {
542 if signer.accounts().contains(from) {
543 let signature = signer.sign_transaction(request.clone(), from)?;
544 return build_typed_transaction(request, signature);
545 }
546 }
547 }
548 }
549 Err(BlockchainError::NoSignerAvailable)
550 }
551
552 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
553 let block_request = match block_number {
554 Some(BlockId::Number(BlockNumber::Pending)) => {
555 let pending_txs = self.pool.ready_transactions().collect();
556 BlockRequest::Pending(pending_txs)
557 }
558 _ => {
559 let number = self.backend.ensure_block_number(block_number).await?;
560 BlockRequest::Number(number)
561 }
562 };
563 Ok(block_request)
564 }
565
566 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
567 match self.pool.get_transaction(hash) {
568 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
569 None => match self.backend.transaction_by_hash(hash).await? {
570 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
571 None => Ok(None),
572 },
573 }
574 }
575
576 pub fn client_version(&self) -> Result<String> {
580 node_info!("web3_clientVersion");
581 Ok(CLIENT_VERSION.to_string())
582 }
583
584 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
588 node_info!("web3_sha3");
589 let hash = alloy_primitives::keccak256(bytes.as_ref());
590 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
591 }
592
593 pub fn protocol_version(&self) -> Result<u64> {
597 node_info!("eth_protocolVersion");
598 Ok(1)
599 }
600
601 pub fn hashrate(&self) -> Result<U256> {
605 node_info!("eth_hashrate");
606 Ok(U256::ZERO)
607 }
608
609 pub fn author(&self) -> Result<Address> {
613 node_info!("eth_coinbase");
614 Ok(self.backend.coinbase())
615 }
616
617 pub fn is_mining(&self) -> Result<bool> {
621 node_info!("eth_mining");
622 Ok(self.is_mining)
623 }
624
625 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
631 node_info!("eth_chainId");
632 Ok(Some(self.backend.chain_id().to::<U64>()))
633 }
634
635 pub fn network_id(&self) -> Result<Option<String>> {
639 node_info!("eth_networkId");
640 let chain_id = self.backend.chain_id().to::<u64>();
641 Ok(Some(format!("{chain_id}")))
642 }
643
644 pub fn net_listening(&self) -> Result<bool> {
648 node_info!("net_listening");
649 Ok(self.net_listening)
650 }
651
652 fn eth_gas_price(&self) -> Result<U256> {
654 node_info!("eth_gasPrice");
655 Ok(U256::from(self.gas_price()))
656 }
657
658 pub fn gas_price(&self) -> u128 {
660 if self.backend.is_eip1559() {
661 if self.backend.is_min_priority_fee_enforced() {
662 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
663 } else {
664 self.backend.base_fee() as u128
665 }
666 } else {
667 self.backend.fees().raw_gas_price()
668 }
669 }
670
671 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
673 Ok(self.backend.excess_blob_gas_and_price())
674 }
675
676 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
681 self.max_priority_fee_per_gas()
682 }
683
684 pub fn blob_base_fee(&self) -> Result<U256> {
688 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
689 }
690
691 pub fn gas_limit(&self) -> U256 {
693 U256::from(self.backend.gas_limit())
694 }
695
696 pub fn accounts(&self) -> Result<Vec<Address>> {
700 node_info!("eth_accounts");
701 let mut unique = HashSet::new();
702 let mut accounts: Vec<Address> = Vec::new();
703 for signer in self.signers.iter() {
704 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
705 }
706 accounts.extend(
707 self.backend
708 .cheats()
709 .impersonated_accounts()
710 .into_iter()
711 .filter(|acc| unique.insert(*acc)),
712 );
713 Ok(accounts.into_iter().collect())
714 }
715
716 pub fn block_number(&self) -> Result<U256> {
720 node_info!("eth_blockNumber");
721 Ok(U256::from(self.backend.best_number()))
722 }
723
724 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
728 node_info!("eth_getBalance");
729 let block_request = self.block_request(block_number).await?;
730
731 if let BlockRequest::Number(number) = block_request
733 && let Some(fork) = self.get_fork()
734 && fork.predates_fork(number)
735 {
736 return Ok(fork.get_balance(address, number).await?);
737 }
738
739 self.backend.get_balance(address, Some(block_request)).await
740 }
741
742 pub async fn get_account(
746 &self,
747 address: Address,
748 block_number: Option<BlockId>,
749 ) -> Result<Account> {
750 node_info!("eth_getAccount");
751 let block_request = self.block_request(block_number).await?;
752
753 if let BlockRequest::Number(number) = block_request
755 && let Some(fork) = self.get_fork()
756 && fork.predates_fork(number)
757 {
758 return Ok(fork.get_account(address, number).await?);
759 }
760
761 self.backend.get_account_at_block(address, Some(block_request)).await
762 }
763
764 pub async fn get_account_info(
766 &self,
767 address: Address,
768 block_number: Option<BlockId>,
769 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
770 node_info!("eth_getAccountInfo");
771 let account = self.get_account(address, block_number);
772 let code = self.get_code(address, block_number);
773 let (account, code) = try_join!(account, code)?;
774 Ok(alloy_rpc_types::eth::AccountInfo {
775 balance: account.balance,
776 nonce: account.nonce,
777 code,
778 })
779 }
780 pub async fn storage_at(
784 &self,
785 address: Address,
786 index: U256,
787 block_number: Option<BlockId>,
788 ) -> Result<B256> {
789 node_info!("eth_getStorageAt");
790 let block_request = self.block_request(block_number).await?;
791
792 if let BlockRequest::Number(number) = block_request
794 && let Some(fork) = self.get_fork()
795 && fork.predates_fork(number)
796 {
797 return Ok(B256::from(
798 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
799 ));
800 }
801
802 self.backend.storage_at(address, index, Some(block_request)).await
803 }
804
805 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
809 node_info!("eth_getBlockByHash");
810 self.backend.block_by_hash(hash).await
811 }
812
813 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
817 node_info!("eth_getBlockByHash");
818 self.backend.block_by_hash_full(hash).await
819 }
820
821 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
825 node_info!("eth_getBlockByNumber");
826 if number == BlockNumber::Pending {
827 return Ok(Some(self.pending_block().await));
828 }
829
830 self.backend.block_by_number(number).await
831 }
832
833 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
837 node_info!("eth_getBlockByNumber");
838 if number == BlockNumber::Pending {
839 return Ok(self.pending_block_full().await);
840 }
841 self.backend.block_by_number_full(number).await
842 }
843
844 pub async fn transaction_count(
851 &self,
852 address: Address,
853 block_number: Option<BlockId>,
854 ) -> Result<U256> {
855 node_info!("eth_getTransactionCount");
856 self.get_transaction_count(address, block_number).await.map(U256::from)
857 }
858
859 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
863 node_info!("eth_getBlockTransactionCountByHash");
864 let block = self.backend.block_by_hash(hash).await?;
865 let txs = block.map(|b| match b.transactions() {
866 BlockTransactions::Full(txs) => U256::from(txs.len()),
867 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
868 BlockTransactions::Uncle => U256::from(0),
869 });
870 Ok(txs)
871 }
872
873 pub async fn block_transaction_count_by_number(
877 &self,
878 block_number: BlockNumber,
879 ) -> Result<Option<U256>> {
880 node_info!("eth_getBlockTransactionCountByNumber");
881 let block_request = self.block_request(Some(block_number.into())).await?;
882 if let BlockRequest::Pending(txs) = block_request {
883 let block = self.backend.pending_block(txs).await;
884 return Ok(Some(U256::from(block.transactions.len())));
885 }
886 let block = self.backend.block_by_number(block_number).await?;
887 let txs = block.map(|b| match b.transactions() {
888 BlockTransactions::Full(txs) => U256::from(txs.len()),
889 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
890 BlockTransactions::Uncle => U256::from(0),
891 });
892 Ok(txs)
893 }
894
895 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
899 node_info!("eth_getUncleCountByBlockHash");
900 let block =
901 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
902 Ok(U256::from(block.uncles.len()))
903 }
904
905 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
909 node_info!("eth_getUncleCountByBlockNumber");
910 let block = self
911 .backend
912 .block_by_number(block_number)
913 .await?
914 .ok_or(BlockchainError::BlockNotFound)?;
915 Ok(U256::from(block.uncles.len()))
916 }
917
918 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
922 node_info!("eth_getCode");
923 let block_request = self.block_request(block_number).await?;
924 if let BlockRequest::Number(number) = block_request
926 && let Some(fork) = self.get_fork()
927 && fork.predates_fork(number)
928 {
929 return Ok(fork.get_code(address, number).await?);
930 }
931 self.backend.get_code(address, Some(block_request)).await
932 }
933
934 pub async fn get_proof(
939 &self,
940 address: Address,
941 keys: Vec<B256>,
942 block_number: Option<BlockId>,
943 ) -> Result<EIP1186AccountProofResponse> {
944 node_info!("eth_getProof");
945 let block_request = self.block_request(block_number).await?;
946
947 if let BlockRequest::Number(number) = block_request
950 && let Some(fork) = self.get_fork()
951 && fork.predates_fork_inclusive(number)
952 {
953 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
954 }
955
956 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
957 Ok(proof)
958 }
959
960 pub async fn sign_typed_data(
964 &self,
965 _address: Address,
966 _data: serde_json::Value,
967 ) -> Result<String> {
968 node_info!("eth_signTypedData");
969 Err(BlockchainError::RpcUnimplemented)
970 }
971
972 pub async fn sign_typed_data_v3(
976 &self,
977 _address: Address,
978 _data: serde_json::Value,
979 ) -> Result<String> {
980 node_info!("eth_signTypedData_v3");
981 Err(BlockchainError::RpcUnimplemented)
982 }
983
984 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
988 node_info!("eth_signTypedData_v4");
989 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
990 let signature = signer.sign_typed_data(address, data).await?;
991 let signature = alloy_primitives::hex::encode(signature.as_bytes());
992 Ok(format!("0x{signature}"))
993 }
994
995 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
999 node_info!("eth_sign");
1000 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1001 let signature =
1002 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1003 Ok(format!("0x{signature}"))
1004 }
1005
1006 pub async fn sign_transaction(
1010 &self,
1011 mut request: WithOtherFields<TransactionRequest>,
1012 ) -> Result<String> {
1013 node_info!("eth_signTransaction");
1014
1015 let from = request.from.map(Ok).unwrap_or_else(|| {
1016 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1017 })?;
1018
1019 let (nonce, _) = self.request_nonce(&request, from).await?;
1020
1021 if request.gas.is_none() {
1022 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1024 {
1025 request.gas = Some(gas.to());
1026 }
1027 }
1028
1029 let request = self.build_typed_tx_request(request, nonce)?;
1030
1031 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1032 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1033 }
1034
1035 pub async fn send_transaction(
1039 &self,
1040 mut request: WithOtherFields<TransactionRequest>,
1041 ) -> Result<TxHash> {
1042 node_info!("eth_sendTransaction");
1043
1044 let from = request.from.map(Ok).unwrap_or_else(|| {
1045 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1046 })?;
1047 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1048
1049 if request.gas.is_none() {
1050 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1052 {
1053 request.gas = Some(gas.to());
1054 }
1055 }
1056
1057 let request = self.build_typed_tx_request(request, nonce)?;
1058
1059 let pending_transaction = if self.is_impersonated(from) {
1061 let bypass_signature = self.impersonated_signature(&request);
1062 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1063 self.ensure_typed_transaction_supported(&transaction)?;
1064 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1065 PendingTransaction::with_impersonated(transaction, from)
1066 } else {
1067 let transaction = self.sign_request(&from, request)?;
1068 self.ensure_typed_transaction_supported(&transaction)?;
1069 PendingTransaction::new(transaction)?
1070 };
1071 self.backend.validate_pool_transaction(&pending_transaction).await?;
1073
1074 let requires = required_marker(nonce, on_chain_nonce, from);
1075 let provides = vec![to_marker(nonce, from)];
1076 debug_assert!(requires != provides);
1077
1078 self.add_pending_transaction(pending_transaction, requires, provides)
1079 }
1080
1081 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1083 let mut stream = self.new_block_notifications();
1084 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1086 return Ok(receipt);
1087 }
1088 while let Some(notification) = stream.next().await {
1089 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1090 && block.transactions.iter().any(|tx| tx.hash() == hash)
1091 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1092 {
1093 return Ok(receipt);
1094 }
1095 }
1096
1097 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1098 }
1099
1100 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1102 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1103 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1104 .await
1105 .unwrap_or_else(|_elapsed| {
1106 Err(BlockchainError::TransactionConfirmationTimeout {
1107 hash,
1108 duration: TIMEOUT_DURATION,
1109 })
1110 })
1111 }
1112
1113 pub async fn send_transaction_sync(
1117 &self,
1118 request: WithOtherFields<TransactionRequest>,
1119 ) -> Result<ReceiptResponse> {
1120 node_info!("eth_sendTransactionSync");
1121 let hash = self.send_transaction(request).await?;
1122
1123 let receipt = self.check_transaction_inclusion(hash).await?;
1124
1125 Ok(ReceiptResponse::from(receipt))
1126 }
1127
1128 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1132 node_info!("eth_sendRawTransaction");
1133 let mut data = tx.as_ref();
1134 if data.is_empty() {
1135 return Err(BlockchainError::EmptyRawTransactionData);
1136 }
1137
1138 let transaction = TypedTransaction::decode_2718(&mut data)
1139 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1140
1141 self.ensure_typed_transaction_supported(&transaction)?;
1142
1143 let pending_transaction = PendingTransaction::new(transaction)?;
1144
1145 self.backend.validate_pool_transaction(&pending_transaction).await?;
1147
1148 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1149 let from = *pending_transaction.sender();
1150 let nonce = pending_transaction.transaction.nonce();
1151 let requires = required_marker(nonce, on_chain_nonce, from);
1152
1153 let priority = self.transaction_priority(&pending_transaction.transaction);
1154 let pool_transaction = PoolTransaction {
1155 requires,
1156 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1157 pending_transaction,
1158 priority,
1159 };
1160
1161 let tx = self.pool.add_transaction(pool_transaction)?;
1162 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1163 Ok(*tx.hash())
1164 }
1165
1166 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<ReceiptResponse> {
1170 node_info!("eth_sendRawTransactionSync");
1171
1172 let hash = self.send_raw_transaction(tx).await?;
1173 let receipt = self.check_transaction_inclusion(hash).await?;
1174
1175 Ok(ReceiptResponse::from(receipt))
1176 }
1177
1178 pub async fn call(
1182 &self,
1183 request: WithOtherFields<TransactionRequest>,
1184 block_number: Option<BlockId>,
1185 overrides: EvmOverrides,
1186 ) -> Result<Bytes> {
1187 node_info!("eth_call");
1188 let block_request = self.block_request(block_number).await?;
1189 if let BlockRequest::Number(number) = block_request
1191 && let Some(fork) = self.get_fork()
1192 && fork.predates_fork(number)
1193 {
1194 if overrides.has_state() || overrides.has_block() {
1195 return Err(BlockchainError::EvmOverrideError(
1196 "not available on past forked blocks".to_string(),
1197 ));
1198 }
1199 return Ok(fork.call(&request, Some(number.into())).await?);
1200 }
1201
1202 let fees = FeeDetails::new(
1203 request.gas_price,
1204 request.max_fee_per_gas,
1205 request.max_priority_fee_per_gas,
1206 request.max_fee_per_blob_gas,
1207 )?
1208 .or_zero_fees();
1209 self.on_blocking_task(|this| async move {
1212 let (exit, out, gas, _) =
1213 this.backend.call(request, fees, Some(block_request), overrides).await?;
1214 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1215
1216 ensure_return_ok(exit, &out)
1217 })
1218 .await
1219 }
1220
1221 pub async fn simulate_v1(
1222 &self,
1223 request: SimulatePayload,
1224 block_number: Option<BlockId>,
1225 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1226 node_info!("eth_simulateV1");
1227 let block_request = self.block_request(block_number).await?;
1228 if let BlockRequest::Number(number) = block_request
1230 && let Some(fork) = self.get_fork()
1231 && fork.predates_fork(number)
1232 {
1233 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1234 }
1235
1236 self.on_blocking_task(|this| async move {
1239 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1240 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1241
1242 Ok(simulated_blocks)
1243 })
1244 .await
1245 }
1246
1247 pub async fn create_access_list(
1261 &self,
1262 mut request: WithOtherFields<TransactionRequest>,
1263 block_number: Option<BlockId>,
1264 ) -> Result<AccessListResult> {
1265 node_info!("eth_createAccessList");
1266 let block_request = self.block_request(block_number).await?;
1267 if let BlockRequest::Number(number) = block_request
1269 && let Some(fork) = self.get_fork()
1270 && fork.predates_fork(number)
1271 {
1272 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1273 }
1274
1275 self.backend
1276 .with_database_at(Some(block_request), |state, block_env| {
1277 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1278 &state,
1279 request.clone(),
1280 FeeDetails::zero(),
1281 block_env.clone(),
1282 )?;
1283 ensure_return_ok(exit, &out)?;
1284
1285 request.access_list = Some(access_list.clone());
1287
1288 let (exit, out, gas_used, _) = self.backend.call_with_state(
1289 &state,
1290 request.clone(),
1291 FeeDetails::zero(),
1292 block_env,
1293 )?;
1294 ensure_return_ok(exit, &out)?;
1295
1296 Ok(AccessListResult {
1297 access_list: AccessList(access_list.0),
1298 gas_used: U256::from(gas_used),
1299 error: None,
1300 })
1301 })
1302 .await?
1303 }
1304
1305 pub async fn estimate_gas(
1310 &self,
1311 request: WithOtherFields<TransactionRequest>,
1312 block_number: Option<BlockId>,
1313 overrides: EvmOverrides,
1314 ) -> Result<U256> {
1315 node_info!("eth_estimateGas");
1316 self.do_estimate_gas(
1317 request,
1318 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1319 overrides,
1320 )
1321 .await
1322 .map(U256::from)
1323 }
1324
1325 pub fn anvil_get_blob_by_versioned_hash(
1327 &self,
1328 hash: B256,
1329 ) -> Result<Option<alloy_consensus::Blob>> {
1330 node_info!("anvil_getBlobByHash");
1331 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1332 }
1333
1334 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1336 node_info!("anvil_getBlobsByTransactionHash");
1337 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1338 }
1339
1340 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1347 node_info!("eth_getTransactionByHash");
1348 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1349 let from = *pending.sender();
1350 let tx = transaction_build(
1351 Some(*pending.hash()),
1352 pending.transaction,
1353 None,
1354 None,
1355 Some(self.backend.base_fee()),
1356 );
1357
1358 let WithOtherFields { inner: mut tx, other } = tx.0;
1359 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1362
1363 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1364 });
1365 if tx.is_none() {
1366 tx = self.backend.transaction_by_hash(hash).await?
1367 }
1368
1369 Ok(tx)
1370 }
1371
1372 pub async fn transaction_by_block_hash_and_index(
1376 &self,
1377 hash: B256,
1378 index: Index,
1379 ) -> Result<Option<AnyRpcTransaction>> {
1380 node_info!("eth_getTransactionByBlockHashAndIndex");
1381 self.backend.transaction_by_block_hash_and_index(hash, index).await
1382 }
1383
1384 pub async fn transaction_by_block_number_and_index(
1388 &self,
1389 block: BlockNumber,
1390 idx: Index,
1391 ) -> Result<Option<AnyRpcTransaction>> {
1392 node_info!("eth_getTransactionByBlockNumberAndIndex");
1393 self.backend.transaction_by_block_number_and_index(block, idx).await
1394 }
1395
1396 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1400 node_info!("eth_getTransactionReceipt");
1401 self.backend.transaction_receipt(hash).await
1402 }
1403
1404 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1408 node_info!("eth_getBlockReceipts");
1409 self.backend.block_receipts(number).await
1410 }
1411
1412 pub async fn uncle_by_block_hash_and_index(
1416 &self,
1417 block_hash: B256,
1418 idx: Index,
1419 ) -> Result<Option<AnyRpcBlock>> {
1420 node_info!("eth_getUncleByBlockHashAndIndex");
1421 let number =
1422 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1423 if let Some(fork) = self.get_fork()
1424 && fork.predates_fork_inclusive(number)
1425 {
1426 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1427 }
1428 Ok(None)
1430 }
1431
1432 pub async fn uncle_by_block_number_and_index(
1436 &self,
1437 block_number: BlockNumber,
1438 idx: Index,
1439 ) -> Result<Option<AnyRpcBlock>> {
1440 node_info!("eth_getUncleByBlockNumberAndIndex");
1441 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1442 if let Some(fork) = self.get_fork()
1443 && fork.predates_fork_inclusive(number)
1444 {
1445 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1446 }
1447 Ok(None)
1449 }
1450
1451 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1455 node_info!("eth_getLogs");
1456 self.backend.logs(filter).await
1457 }
1458
1459 pub fn work(&self) -> Result<Work> {
1463 node_info!("eth_getWork");
1464 Err(BlockchainError::RpcUnimplemented)
1465 }
1466
1467 pub fn syncing(&self) -> Result<bool> {
1471 node_info!("eth_syncing");
1472 Ok(false)
1473 }
1474
1475 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1479 node_info!("eth_submitWork");
1480 Err(BlockchainError::RpcUnimplemented)
1481 }
1482
1483 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1487 node_info!("eth_submitHashrate");
1488 Err(BlockchainError::RpcUnimplemented)
1489 }
1490
1491 pub async fn fee_history(
1495 &self,
1496 block_count: U256,
1497 newest_block: BlockNumber,
1498 reward_percentiles: Vec<f64>,
1499 ) -> Result<FeeHistory> {
1500 node_info!("eth_feeHistory");
1501 let current = self.backend.best_number();
1504 let slots_in_an_epoch = 32u64;
1505
1506 let number = match newest_block {
1507 BlockNumber::Latest | BlockNumber::Pending => current,
1508 BlockNumber::Earliest => 0,
1509 BlockNumber::Number(n) => n,
1510 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1511 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1512 };
1513
1514 if let Some(fork) = self.get_fork() {
1516 if fork.predates_fork_inclusive(number) {
1519 return fork
1520 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1521 .await
1522 .map_err(BlockchainError::AlloyForkProvider);
1523 }
1524 }
1525
1526 const MAX_BLOCK_COUNT: u64 = 1024u64;
1527 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1528
1529 let highest = number;
1531 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1532
1533 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1535 return Err(FeeHistoryError::InvalidBlockRange.into());
1536 }
1537
1538 let mut response = FeeHistory {
1539 oldest_block: lowest,
1540 base_fee_per_gas: Vec::new(),
1541 gas_used_ratio: Vec::new(),
1542 reward: Some(Default::default()),
1543 base_fee_per_blob_gas: Default::default(),
1544 blob_gas_used_ratio: Default::default(),
1545 };
1546 let mut rewards = Vec::new();
1547
1548 {
1549 let fee_history = self.fee_history_cache.lock();
1550
1551 for n in lowest..=highest {
1553 if let Some(block) = fee_history.get(&n) {
1555 response.base_fee_per_gas.push(block.base_fee);
1556 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1557 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1558 response.gas_used_ratio.push(block.gas_used_ratio);
1559
1560 if !reward_percentiles.is_empty() {
1562 let mut block_rewards = Vec::new();
1563 let resolution_per_percentile: f64 = 2.0;
1564 for p in &reward_percentiles {
1565 let p = p.clamp(0.0, 100.0);
1566 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1567 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1568 block_rewards.push(reward);
1569 }
1570 rewards.push(block_rewards);
1571 }
1572 }
1573 }
1574 }
1575
1576 response.reward = Some(rewards);
1577
1578 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1583
1584 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1588
1589 Ok(response)
1590 }
1591
1592 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1599 node_info!("eth_maxPriorityFeePerGas");
1600 Ok(U256::from(self.lowest_suggestion_tip()))
1601 }
1602
1603 fn lowest_suggestion_tip(&self) -> u128 {
1607 let block_number = self.backend.best_number();
1608 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1609
1610 match latest_cached_block {
1611 Some(block) => block.rewards.iter().copied().min(),
1612 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1613 }
1614 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1615 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1616 }
1617
1618 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1622 node_info!("eth_newFilter");
1623 let historic = if filter.block_option.get_from_block().is_some() {
1626 self.backend.logs(filter.clone()).await?
1627 } else {
1628 vec![]
1629 };
1630 let filter = EthFilter::Logs(Box::new(LogsFilter {
1631 blocks: self.new_block_notifications(),
1632 storage: self.storage_info(),
1633 filter: FilteredParams::new(Some(filter)),
1634 historic: Some(historic),
1635 }));
1636 Ok(self.filters.add_filter(filter).await)
1637 }
1638
1639 pub async fn new_block_filter(&self) -> Result<String> {
1643 node_info!("eth_newBlockFilter");
1644 let filter = EthFilter::Blocks(self.new_block_notifications());
1645 Ok(self.filters.add_filter(filter).await)
1646 }
1647
1648 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1652 node_info!("eth_newPendingTransactionFilter");
1653 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1654 Ok(self.filters.add_filter(filter).await)
1655 }
1656
1657 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1661 node_info!("eth_getFilterChanges");
1662 self.filters.get_filter_changes(id).await
1663 }
1664
1665 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1669 node_info!("eth_getFilterLogs");
1670 if let Some(filter) = self.filters.get_log_filter(id).await {
1671 self.backend.logs(filter).await
1672 } else {
1673 Ok(Vec::new())
1674 }
1675 }
1676
1677 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1679 node_info!("eth_uninstallFilter");
1680 Ok(self.filters.uninstall_filter(id).await.is_some())
1681 }
1682
1683 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1687 node_info!("debug_getRawTransaction");
1688 self.inner_raw_transaction(hash).await
1689 }
1690
1691 pub async fn raw_transaction_by_block_hash_and_index(
1695 &self,
1696 block_hash: B256,
1697 index: Index,
1698 ) -> Result<Option<Bytes>> {
1699 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1700 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1701 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1702 None => Ok(None),
1703 }
1704 }
1705
1706 pub async fn raw_transaction_by_block_number_and_index(
1710 &self,
1711 block_number: BlockNumber,
1712 index: Index,
1713 ) -> Result<Option<Bytes>> {
1714 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1715 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1716 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1717 None => Ok(None),
1718 }
1719 }
1720
1721 pub async fn debug_trace_transaction(
1725 &self,
1726 tx_hash: B256,
1727 opts: GethDebugTracingOptions,
1728 ) -> Result<GethTrace> {
1729 node_info!("debug_traceTransaction");
1730 self.backend.debug_trace_transaction(tx_hash, opts).await
1731 }
1732
1733 pub async fn debug_trace_call(
1737 &self,
1738 request: WithOtherFields<TransactionRequest>,
1739 block_number: Option<BlockId>,
1740 opts: GethDebugTracingCallOptions,
1741 ) -> Result<GethTrace> {
1742 node_info!("debug_traceCall");
1743 let block_request = self.block_request(block_number).await?;
1744 let fees = FeeDetails::new(
1745 request.gas_price,
1746 request.max_fee_per_gas,
1747 request.max_priority_fee_per_gas,
1748 request.max_fee_per_blob_gas,
1749 )?
1750 .or_zero_fees();
1751
1752 let result: std::result::Result<GethTrace, BlockchainError> =
1753 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1754 result
1755 }
1756
1757 pub async fn debug_code_by_hash(
1761 &self,
1762 hash: B256,
1763 block_id: Option<BlockId>,
1764 ) -> Result<Option<Bytes>> {
1765 node_info!("debug_codeByHash");
1766 self.backend.debug_code_by_hash(hash, block_id).await
1767 }
1768
1769 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1773 node_info!("trace_transaction");
1774 self.backend.trace_transaction(tx_hash).await
1775 }
1776
1777 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1781 node_info!("trace_block");
1782 self.backend.trace_block(block).await
1783 }
1784
1785 pub async fn trace_filter(
1789 &self,
1790 filter: TraceFilter,
1791 ) -> Result<Vec<LocalizedTransactionTrace>> {
1792 node_info!("trace_filter");
1793 self.backend.trace_filter(filter).await
1794 }
1795}
1796
1797impl EthApi {
1800 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
1804 node_info!("anvil_impersonateAccount");
1805 self.backend.impersonate(address);
1806 Ok(())
1807 }
1808
1809 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
1813 node_info!("anvil_stopImpersonatingAccount");
1814 self.backend.stop_impersonating(address);
1815 Ok(())
1816 }
1817
1818 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
1822 node_info!("anvil_autoImpersonateAccount");
1823 self.backend.auto_impersonate_account(enabled);
1824 Ok(())
1825 }
1826
1827 pub async fn anvil_impersonate_signature(
1829 &self,
1830 signature: Bytes,
1831 address: Address,
1832 ) -> Result<()> {
1833 node_info!("anvil_impersonateSignature");
1834 self.backend.impersonate_signature(signature, address).await
1835 }
1836
1837 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
1841 node_info!("anvil_getAutomine");
1842 Ok(self.miner.is_auto_mine())
1843 }
1844
1845 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
1849 node_info!("anvil_getIntervalMining");
1850 Ok(self.miner.get_interval())
1851 }
1852
1853 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
1858 node_info!("evm_setAutomine");
1859 if self.miner.is_auto_mine() {
1860 if enable_automine {
1861 return Ok(());
1862 }
1863 self.miner.set_mining_mode(MiningMode::None);
1864 } else if enable_automine {
1865 let listener = self.pool.add_ready_listener();
1866 let mode = MiningMode::instant(1_000, listener);
1867 self.miner.set_mining_mode(mode);
1868 }
1869 Ok(())
1870 }
1871
1872 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
1876 node_info!("anvil_mine");
1877 let interval = interval.map(|i| i.to::<u64>());
1878 let blocks = num_blocks.unwrap_or(U256::from(1));
1879 if blocks.is_zero() {
1880 return Ok(());
1881 }
1882
1883 self.on_blocking_task(|this| async move {
1884 for _ in 0..blocks.to::<u64>() {
1886 if let Some(interval) = interval {
1888 this.backend.time().increase_time(interval);
1889 }
1890 this.mine_one().await;
1891 }
1892 Ok(())
1893 })
1894 .await?;
1895
1896 Ok(())
1897 }
1898
1899 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
1903 node_info!("evm_setIntervalMining");
1904 let mining_mode = if secs == 0 {
1905 MiningMode::None
1906 } else {
1907 let block_time = Duration::from_secs(secs);
1908
1909 self.backend.update_interval_mine_block_time(block_time);
1911
1912 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
1913 };
1914 self.miner.set_mining_mode(mining_mode);
1915 Ok(())
1916 }
1917
1918 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
1922 node_info!("anvil_dropTransaction");
1923 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
1924 }
1925
1926 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
1930 node_info!("anvil_dropAllTransactions");
1931 self.pool.clear();
1932 Ok(())
1933 }
1934
1935 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
1941 self.reset_instance_id();
1942 node_info!("anvil_reset");
1943 if let Some(forking) = forking {
1944 self.backend.reset_fork(forking).await
1946 } else {
1947 self.backend.reset_to_in_mem().await
1950 }
1951 }
1952
1953 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
1954 node_info!("anvil_setChainId");
1955 self.backend.set_chain_id(chain_id);
1956 Ok(())
1957 }
1958
1959 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
1963 node_info!("anvil_setBalance");
1964 self.backend.set_balance(address, balance).await?;
1965 Ok(())
1966 }
1967
1968 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
1972 node_info!("anvil_addBalance");
1973 let current_balance = self.backend.get_balance(address, None).await?;
1974 self.backend.set_balance(address, current_balance + balance).await?;
1975 Ok(())
1976 }
1977
1978 async fn find_erc20_storage_slot(
1995 &self,
1996 token_address: Address,
1997 calldata: Bytes,
1998 expected_value: U256,
1999 ) -> Result<B256> {
2000 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2001
2002 let access_list_result =
2004 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2005 let access_list = access_list_result.access_list;
2006
2007 for item in access_list.0 {
2010 if item.address != token_address {
2011 continue;
2012 };
2013 for slot in &item.storage_keys {
2014 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2015 (*slot, B256::from(expected_value.to_be_bytes())),
2016 ));
2017
2018 let state_override = StateOverridesBuilder::default()
2019 .append(token_address, account_override)
2020 .build();
2021
2022 let evm_override = EvmOverrides::state(Some(state_override));
2023
2024 let Ok(result) =
2025 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2026 else {
2027 continue;
2029 };
2030
2031 let Ok(result_value) = U256::abi_decode(&result) else {
2032 continue;
2034 };
2035
2036 if result_value == expected_value {
2037 return Ok(*slot);
2038 }
2039 }
2040 }
2041
2042 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2043 }
2044
2045 pub async fn anvil_deal_erc20(
2049 &self,
2050 address: Address,
2051 token_address: Address,
2052 balance: U256,
2053 ) -> Result<()> {
2054 node_info!("anvil_dealERC20");
2055
2056 sol! {
2057 #[sol(rpc)]
2058 contract IERC20 {
2059 function balanceOf(address target) external view returns (uint256);
2060 }
2061 }
2062
2063 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2064
2065 let slot =
2067 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2068 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2069 })?;
2070
2071 self.anvil_set_storage_at(
2073 token_address,
2074 U256::from_be_bytes(slot.0),
2075 B256::from(balance.to_be_bytes()),
2076 )
2077 .await?;
2078
2079 Ok(())
2080 }
2081
2082 pub async fn anvil_set_erc20_allowance(
2086 &self,
2087 owner: Address,
2088 spender: Address,
2089 token_address: Address,
2090 amount: U256,
2091 ) -> Result<()> {
2092 node_info!("anvil_setERC20Allowance");
2093
2094 sol! {
2095 #[sol(rpc)]
2096 contract IERC20 {
2097 function allowance(address owner, address spender) external view returns (uint256);
2098 }
2099 }
2100
2101 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2102
2103 let slot =
2105 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2106 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2107 })?;
2108
2109 self.anvil_set_storage_at(
2111 token_address,
2112 U256::from_be_bytes(slot.0),
2113 B256::from(amount.to_be_bytes()),
2114 )
2115 .await?;
2116
2117 Ok(())
2118 }
2119
2120 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2124 node_info!("anvil_setCode");
2125 self.backend.set_code(address, code).await?;
2126 Ok(())
2127 }
2128
2129 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2133 node_info!("anvil_setNonce");
2134 self.backend.set_nonce(address, nonce).await?;
2135 Ok(())
2136 }
2137
2138 pub async fn anvil_set_storage_at(
2142 &self,
2143 address: Address,
2144 slot: U256,
2145 val: B256,
2146 ) -> Result<bool> {
2147 node_info!("anvil_setStorageAt");
2148 self.backend.set_storage_at(address, slot, val).await?;
2149 Ok(true)
2150 }
2151
2152 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2156 node_info!("anvil_setLoggingEnabled");
2157 self.logger.set_enabled(enable);
2158 Ok(())
2159 }
2160
2161 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2165 node_info!("anvil_setMinGasPrice");
2166 if self.backend.is_eip1559() {
2167 return Err(RpcError::invalid_params(
2168 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2169 )
2170 .into());
2171 }
2172 self.backend.set_gas_price(gas.to());
2173 Ok(())
2174 }
2175
2176 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2180 node_info!("anvil_setNextBlockBaseFeePerGas");
2181 if !self.backend.is_eip1559() {
2182 return Err(RpcError::invalid_params(
2183 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2184 )
2185 .into());
2186 }
2187 self.backend.set_base_fee(basefee.to());
2188 Ok(())
2189 }
2190
2191 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2195 node_info!("anvil_setCoinbase");
2196 self.backend.set_coinbase(address);
2197 Ok(())
2198 }
2199
2200 pub async fn anvil_dump_state(
2205 &self,
2206 preserve_historical_states: Option<bool>,
2207 ) -> Result<Bytes> {
2208 node_info!("anvil_dumpState");
2209 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2210 }
2211
2212 pub async fn serialized_state(
2214 &self,
2215 preserve_historical_states: bool,
2216 ) -> Result<SerializableState> {
2217 self.backend.serialized_state(preserve_historical_states).await
2218 }
2219
2220 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2225 node_info!("anvil_loadState");
2226 self.backend.load_state_bytes(buf).await
2227 }
2228
2229 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2233 node_info!("anvil_nodeInfo");
2234
2235 let env = self.backend.env().read();
2236 let fork_config = self.backend.get_fork();
2237 let tx_order = self.transaction_order.read();
2238 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2239
2240 Ok(NodeInfo {
2241 current_block_number: self.backend.best_number(),
2242 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2243 current_block_hash: self.backend.best_hash(),
2244 hard_fork: hard_fork.to_string(),
2245 transaction_order: match *tx_order {
2246 TransactionOrder::Fifo => "fifo".to_string(),
2247 TransactionOrder::Fees => "fees".to_string(),
2248 },
2249 environment: NodeEnvironment {
2250 base_fee: self.backend.base_fee() as u128,
2251 chain_id: self.backend.chain_id().to::<u64>(),
2252 gas_limit: self.backend.gas_limit(),
2253 gas_price: self.gas_price(),
2254 },
2255 fork_config: fork_config
2256 .map(|fork| {
2257 let config = fork.config.read();
2258
2259 NodeForkConfig {
2260 fork_url: Some(config.eth_rpc_url.clone()),
2261 fork_block_number: Some(config.block_number),
2262 fork_retry_backoff: Some(config.backoff.as_millis()),
2263 }
2264 })
2265 .unwrap_or_default(),
2266 })
2267 }
2268
2269 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2273 node_info!("anvil_metadata");
2274 let fork_config = self.backend.get_fork();
2275
2276 Ok(Metadata {
2277 client_version: CLIENT_VERSION.to_string(),
2278 chain_id: self.backend.chain_id().to::<u64>(),
2279 latest_block_hash: self.backend.best_hash(),
2280 latest_block_number: self.backend.best_number(),
2281 instance_id: *self.instance_id.read(),
2282 forked_network: fork_config.map(|cfg| ForkedNetwork {
2283 chain_id: cfg.chain_id(),
2284 fork_block_number: cfg.block_number(),
2285 fork_block_hash: cfg.block_hash(),
2286 }),
2287 snapshots: self.backend.list_state_snapshots(),
2288 })
2289 }
2290
2291 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2292 node_info!("anvil_removePoolTransactions");
2293 self.pool.remove_transactions_by_address(address);
2294 Ok(())
2295 }
2296
2297 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2311 node_info!("anvil_reorg");
2312 let depth = options.depth;
2313 let tx_block_pairs = options.tx_block_pairs;
2314
2315 let current_height = self.backend.best_number();
2317 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2318 RpcError::invalid_params(format!(
2319 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2320 )),
2321 ))?;
2322
2323 let common_block =
2325 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2326
2327 let block_pool_txs = if tx_block_pairs.is_empty() {
2330 HashMap::default()
2331 } else {
2332 let mut pairs = tx_block_pairs;
2333
2334 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2336 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2337 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2338 depth - 1
2339 ))));
2340 }
2341
2342 pairs.sort_by_key(|a| a.1);
2344
2345 let mut nonces: HashMap<Address, u64> = HashMap::default();
2348
2349 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2350 for pair in pairs {
2351 let (tx_data, block_index) = pair;
2352
2353 let pending = match tx_data {
2354 TransactionData::Raw(bytes) => {
2355 let mut data = bytes.as_ref();
2356 let decoded = TypedTransaction::decode_2718(&mut data)
2357 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2358 PendingTransaction::new(decoded)?
2359 }
2360
2361 TransactionData::JSON(req) => {
2362 let mut tx_req = WithOtherFields::new(req);
2363 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2364 self.accounts()?
2365 .first()
2366 .copied()
2367 .ok_or(BlockchainError::NoSignerAvailable)
2368 })?;
2369
2370 let curr_nonce = nonces.entry(from).or_insert(
2372 self.get_transaction_count(
2373 from,
2374 Some(common_block.header.number.into()),
2375 )
2376 .await?,
2377 );
2378
2379 if tx_req.gas.is_none()
2381 && let Ok(gas) = self
2382 .estimate_gas(tx_req.clone(), None, EvmOverrides::default())
2383 .await
2384 {
2385 tx_req.gas = Some(gas.to());
2386 }
2387
2388 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2390
2391 *curr_nonce += 1;
2393
2394 if self.is_impersonated(from) {
2396 let bypass_signature = self.impersonated_signature(&typed);
2397 let transaction =
2398 sign::build_typed_transaction(typed, bypass_signature)?;
2399 self.ensure_typed_transaction_supported(&transaction)?;
2400 PendingTransaction::with_impersonated(transaction, from)
2401 } else {
2402 let transaction = self.sign_request(&from, typed)?;
2403 self.ensure_typed_transaction_supported(&transaction)?;
2404 PendingTransaction::new(transaction)?
2405 }
2406 }
2407 };
2408
2409 let pooled = PoolTransaction::new(pending);
2410 txs.entry(block_index).or_default().push(Arc::new(pooled));
2411 }
2412
2413 txs
2414 };
2415
2416 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2417 Ok(())
2418 }
2419
2420 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2431 node_info!("anvil_rollback");
2432 let depth = depth.unwrap_or(1);
2433
2434 let current_height = self.backend.best_number();
2436 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2437 RpcError::invalid_params(format!(
2438 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2439 )),
2440 ))?;
2441
2442 let common_block =
2444 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2445
2446 self.backend.rollback(common_block).await?;
2447 Ok(())
2448 }
2449
2450 pub async fn evm_snapshot(&self) -> Result<U256> {
2454 node_info!("evm_snapshot");
2455 Ok(self.backend.create_state_snapshot().await)
2456 }
2457
2458 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2463 node_info!("evm_revert");
2464 self.backend.revert_state_snapshot(id).await
2465 }
2466
2467 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2471 node_info!("evm_increaseTime");
2472 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2473 }
2474
2475 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2479 node_info!("evm_setNextBlockTimestamp");
2480 self.backend.time().set_next_block_timestamp(seconds)
2481 }
2482
2483 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2488 node_info!("evm_setTime");
2489 let now = self.backend.time().current_call_timestamp();
2490 self.backend.time().reset(timestamp);
2491
2492 let offset = timestamp.saturating_sub(now);
2494 Ok(Duration::from_millis(offset).as_secs())
2495 }
2496
2497 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2501 node_info!("evm_setBlockGasLimit");
2502 self.backend.set_gas_limit(gas_limit.to());
2503 Ok(true)
2504 }
2505
2506 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2510 node_info!("anvil_setBlockTimestampInterval");
2511 self.backend.time().set_block_timestamp_interval(seconds);
2512 Ok(())
2513 }
2514
2515 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2519 node_info!("anvil_removeBlockTimestampInterval");
2520 Ok(self.backend.time().remove_block_timestamp_interval())
2521 }
2522
2523 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2530 node_info!("evm_mine");
2531
2532 self.do_evm_mine(opts).await?;
2533
2534 Ok("0x0".to_string())
2535 }
2536
2537 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2547 node_info!("evm_mine_detailed");
2548
2549 let mined_blocks = self.do_evm_mine(opts).await?;
2550
2551 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2552
2553 let latest = self.backend.best_number();
2554 for offset in (0..mined_blocks).rev() {
2555 let block_num = latest - offset;
2556 if let Some(mut block) =
2557 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2558 {
2559 let block_txs = match block.transactions_mut() {
2560 BlockTransactions::Full(txs) => txs,
2561 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2562 };
2563 for tx in block_txs.iter_mut() {
2564 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2565 && let Some(output) = receipt.out
2566 {
2567 if !receipt
2569 .inner
2570 .inner
2571 .as_receipt_with_bloom()
2572 .receipt
2573 .status
2574 .coerce_status()
2575 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2576 {
2577 tx.other.insert(
2578 "revertReason".to_string(),
2579 serde_json::to_value(reason).expect("Infallible"),
2580 );
2581 }
2582 tx.other.insert(
2583 "output".to_string(),
2584 serde_json::to_value(output).expect("Infallible"),
2585 );
2586 }
2587 }
2588 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2589 blocks.push(block);
2590 }
2591 }
2592
2593 Ok(blocks)
2594 }
2595
2596 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2600 node_info!("anvil_setBlock");
2601 self.backend.set_block_number(block_number);
2602 Ok(())
2603 }
2604
2605 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2609 node_info!("anvil_setRpcUrl");
2610 if let Some(fork) = self.backend.get_fork() {
2611 let mut config = fork.config.write();
2612 let new_provider = Arc::new(
2614 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2615 |_| {
2616 TransportErrorKind::custom_str(
2617 format!("Failed to parse invalid url {url}").as_str(),
2618 )
2619 },
2620 )?, );
2623 config.provider = new_provider;
2624 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2625 config.eth_rpc_url = url;
2626 }
2627 Ok(())
2628 }
2629
2630 pub async fn anvil_enable_traces(&self) -> Result<()> {
2635 node_info!("anvil_enableTraces");
2636 Err(BlockchainError::RpcUnimplemented)
2637 }
2638
2639 pub async fn eth_send_unsigned_transaction(
2643 &self,
2644 request: WithOtherFields<TransactionRequest>,
2645 ) -> Result<TxHash> {
2646 node_info!("eth_sendUnsignedTransaction");
2647 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2649
2650 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2651
2652 let request = self.build_typed_tx_request(request, nonce)?;
2653
2654 let bypass_signature = self.impersonated_signature(&request);
2655 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2656
2657 self.ensure_typed_transaction_supported(&transaction)?;
2658
2659 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2660
2661 self.backend.validate_pool_transaction(&pending_transaction).await?;
2663
2664 let requires = required_marker(nonce, on_chain_nonce, from);
2665 let provides = vec![to_marker(nonce, from)];
2666
2667 self.add_pending_transaction(pending_transaction, requires, provides)
2668 }
2669
2670 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2676 node_info!("txpool_status");
2677 Ok(self.pool.txpool_status())
2678 }
2679
2680 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2687 node_info!("txpool_inspect");
2688 let mut inspect = TxpoolInspect::default();
2689
2690 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2691 let tx = &tx.pending_transaction.transaction;
2692 let to = tx.to();
2693 let gas_price = tx.gas_price();
2694 let value = tx.value();
2695 let gas = tx.gas_limit();
2696 TxpoolInspectSummary { to, value, gas, gas_price }
2697 }
2698
2699 for pending in self.pool.ready_transactions() {
2706 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2707 let key = pending.pending_transaction.nonce().to_string();
2708 entry.insert(key, convert(pending));
2709 }
2710 for queued in self.pool.pending_transactions() {
2711 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2712 let key = queued.pending_transaction.nonce().to_string();
2713 entry.insert(key, convert(queued));
2714 }
2715 Ok(inspect)
2716 }
2717
2718 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2725 node_info!("txpool_content");
2726 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2727 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2728 let from = *tx.pending_transaction.sender();
2729 let tx = transaction_build(
2730 Some(tx.hash()),
2731 tx.pending_transaction.transaction.clone(),
2732 None,
2733 None,
2734 None,
2735 );
2736
2737 let WithOtherFields { inner: mut tx, other } = tx.0;
2738
2739 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2742
2743 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2744
2745 Ok(tx)
2746 }
2747
2748 for pending in self.pool.ready_transactions() {
2749 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2750 let key = pending.pending_transaction.nonce().to_string();
2751 entry.insert(key, convert(pending)?);
2752 }
2753 for queued in self.pool.pending_transactions() {
2754 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2755 let key = queued.pending_transaction.nonce().to_string();
2756 entry.insert(key, convert(queued)?);
2757 }
2758
2759 Ok(content)
2760 }
2761}
2762
2763impl EthApi {
2765 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2771 node_info!("wallet_getCapabilities");
2772 Ok(self.backend.get_capabilities())
2773 }
2774
2775 pub async fn wallet_send_transaction(
2776 &self,
2777 mut request: WithOtherFields<TransactionRequest>,
2778 ) -> Result<TxHash> {
2779 node_info!("wallet_sendTransaction");
2780
2781 if request.value.is_some_and(|val| val > U256::ZERO) {
2784 return Err(WalletError::ValueNotZero.into());
2785 }
2786
2787 if request.from.is_some() {
2789 return Err(WalletError::FromSet.into());
2790 }
2791
2792 if request.nonce.is_some() {
2794 return Err(WalletError::NonceSet.into());
2795 }
2796
2797 let capabilities = self.backend.get_capabilities();
2798 let valid_delegations: &[Address] = capabilities
2799 .get(self.chain_id())
2800 .map(|caps| caps.delegation.addresses.as_ref())
2801 .unwrap_or_default();
2802
2803 if let Some(authorizations) = &request.authorization_list
2804 && authorizations.iter().any(|auth| !valid_delegations.contains(&auth.address))
2805 {
2806 return Err(WalletError::InvalidAuthorization.into());
2807 }
2808
2809 match (request.authorization_list.is_some(), request.to) {
2811 (false, Some(TxKind::Call(addr))) => {
2814 let acc = self.backend.get_account(addr).await?;
2815
2816 let delegated_address = acc
2817 .code
2818 .map(|code| match code {
2819 Bytecode::Eip7702(c) => c.address(),
2820 _ => Address::ZERO,
2821 })
2822 .unwrap_or_default();
2823
2824 if delegated_address == Address::ZERO
2826 || !valid_delegations.contains(&delegated_address)
2827 {
2828 return Err(WalletError::IllegalDestination.into());
2829 }
2830 }
2831 (true, _) => (),
2833 _ => return Err(WalletError::IllegalDestination.into()),
2835 }
2836
2837 let wallet = self.backend.executor_wallet().ok_or(WalletError::InternalError)?;
2838
2839 let from = NetworkWallet::<Ethereum>::default_signer_address(&wallet);
2840
2841 let nonce = self.get_transaction_count(from, Some(BlockId::latest())).await?;
2842
2843 request.nonce = Some(nonce);
2844
2845 let chain_id = self.chain_id();
2846
2847 request.chain_id = Some(chain_id);
2848
2849 request.from = Some(from);
2850
2851 let gas_limit_fut =
2852 self.estimate_gas(request.clone(), Some(BlockId::latest()), EvmOverrides::default());
2853
2854 let fees_fut = self.fee_history(
2855 U256::from(EIP1559_FEE_ESTIMATION_PAST_BLOCKS),
2856 BlockNumber::Latest,
2857 vec![EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE],
2858 );
2859
2860 let (gas_limit, fees) = tokio::join!(gas_limit_fut, fees_fut);
2861
2862 let gas_limit = gas_limit?;
2863 let fees = fees?;
2864
2865 request.gas = Some(gas_limit.to());
2866
2867 let base_fee = fees.latest_block_base_fee().unwrap_or_default();
2868
2869 let estimation = eip1559_default_estimator(base_fee, &fees.reward.unwrap_or_default());
2870
2871 request.max_fee_per_gas = Some(estimation.max_fee_per_gas);
2872 request.max_priority_fee_per_gas = Some(estimation.max_priority_fee_per_gas);
2873 request.gas_price = None;
2874
2875 let envelope = request.build(&wallet).await.map_err(|_| WalletError::InternalError)?;
2876
2877 self.send_raw_transaction(envelope.encoded_2718().into()).await
2878 }
2879
2880 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2884 node_info!("anvil_addCapability");
2885 self.backend.add_capability(address);
2886 Ok(())
2887 }
2888
2889 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2890 node_info!("anvil_setExecutor");
2891 self.backend.set_executor(executor_pk)
2892 }
2893}
2894
2895impl EthApi {
2896 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2898 where
2899 C: FnOnce(Self) -> F,
2900 F: Future<Output = Result<R>> + Send + 'static,
2901 R: Send + 'static,
2902 {
2903 let (tx, rx) = oneshot::channel();
2904 let this = self.clone();
2905 let f = c(this);
2906 tokio::task::spawn_blocking(move || {
2907 tokio::runtime::Handle::current().block_on(async move {
2908 let res = f.await;
2909 let _ = tx.send(res);
2910 })
2911 });
2912 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2913 }
2914
2915 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2917 let mut blocks_to_mine = 1u64;
2918
2919 if let Some(opts) = opts {
2920 let timestamp = match opts {
2921 MineOptions::Timestamp(timestamp) => timestamp,
2922 MineOptions::Options { timestamp, blocks } => {
2923 if let Some(blocks) = blocks {
2924 blocks_to_mine = blocks;
2925 }
2926 timestamp
2927 }
2928 };
2929 if let Some(timestamp) = timestamp {
2930 self.evm_set_next_block_timestamp(timestamp)?;
2932 }
2933 }
2934
2935 self.on_blocking_task(|this| async move {
2938 for _ in 0..blocks_to_mine {
2940 this.mine_one().await;
2941 }
2942 Ok(())
2943 })
2944 .await?;
2945
2946 Ok(blocks_to_mine)
2947 }
2948
2949 async fn do_estimate_gas(
2950 &self,
2951 request: WithOtherFields<TransactionRequest>,
2952 block_number: Option<BlockId>,
2953 overrides: EvmOverrides,
2954 ) -> Result<u128> {
2955 let block_request = self.block_request(block_number).await?;
2956 if let BlockRequest::Number(number) = block_request
2958 && let Some(fork) = self.get_fork()
2959 && fork.predates_fork(number)
2960 {
2961 if overrides.has_state() || overrides.has_block() {
2962 return Err(BlockchainError::EvmOverrideError(
2963 "not available on past forked blocks".to_string(),
2964 ));
2965 }
2966 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
2967 }
2968
2969 self.on_blocking_task(|this| async move {
2972 this.backend
2973 .with_database_at(Some(block_request), |state, mut block| {
2974 let mut cache_db = CacheDB::new(state);
2975 if let Some(state_overrides) = overrides.state {
2976 apply_state_overrides(
2977 state_overrides.into_iter().collect(),
2978 &mut cache_db,
2979 )?;
2980 }
2981 if let Some(block_overrides) = overrides.block {
2982 cache_db.apply_block_overrides(*block_overrides, &mut block);
2983 }
2984 this.do_estimate_gas_with_state(request, &cache_db, block)
2985 })
2986 .await?
2987 })
2988 .await
2989 }
2990
2991 fn do_estimate_gas_with_state(
2995 &self,
2996 mut request: WithOtherFields<TransactionRequest>,
2997 state: &dyn DatabaseRef,
2998 block_env: BlockEnv,
2999 ) -> Result<u128> {
3000 let to = request.to.as_ref().and_then(TxKind::to);
3003
3004 let maybe_transfer = (request.input.input().is_none()
3006 || request.input.input().is_some_and(|data| data.is_empty()))
3007 && request.authorization_list.is_none()
3008 && request.access_list.is_none()
3009 && request.blob_versioned_hashes.is_none();
3010
3011 if maybe_transfer
3012 && let Some(to) = to
3013 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
3014 && target_code.as_ref().is_empty()
3015 {
3016 return Ok(MIN_TRANSACTION_GAS);
3017 }
3018
3019 let fees = FeeDetails::new(
3020 request.gas_price,
3021 request.max_fee_per_gas,
3022 request.max_priority_fee_per_gas,
3023 request.max_fee_per_blob_gas,
3024 )?
3025 .or_zero_fees();
3026
3027 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
3030
3031 let gas_price = fees.gas_price.unwrap_or_default();
3032 if gas_price > 0
3034 && let Some(from) = request.from
3035 {
3036 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
3037 if let Some(value) = request.value {
3038 if value > available_funds {
3039 return Err(InvalidTransactionError::InsufficientFunds.into());
3040 }
3041 available_funds -= value;
3043 }
3044 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
3046 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
3047 }
3048
3049 let mut call_to_estimate = request.clone();
3050 call_to_estimate.gas = Some(highest_gas_limit as u64);
3051
3052 let ethres =
3054 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3055
3056 let gas_used = match ethres.try_into()? {
3057 GasEstimationCallResult::Success(gas) => Ok(gas),
3058 GasEstimationCallResult::OutOfGas => {
3059 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3060 }
3061 GasEstimationCallResult::Revert(output) => {
3062 Err(InvalidTransactionError::Revert(output).into())
3063 }
3064 GasEstimationCallResult::EvmError(err) => {
3065 warn!(target: "node", "estimation failed due to {:?}", err);
3066 Err(BlockchainError::EvmError(err))
3067 }
3068 }?;
3069
3070 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3077
3078 let mut mid_gas_limit =
3080 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3081
3082 while (highest_gas_limit - lowest_gas_limit) > 1 {
3084 request.gas = Some(mid_gas_limit as u64);
3085 let ethres = self.backend.call_with_state(
3086 &state,
3087 request.clone(),
3088 fees.clone(),
3089 block_env.clone(),
3090 );
3091
3092 match ethres.try_into()? {
3093 GasEstimationCallResult::Success(_) => {
3094 highest_gas_limit = mid_gas_limit;
3098 }
3099 GasEstimationCallResult::OutOfGas
3100 | GasEstimationCallResult::Revert(_)
3101 | GasEstimationCallResult::EvmError(_) => {
3102 lowest_gas_limit = mid_gas_limit;
3109 }
3110 };
3111 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3113 }
3114
3115 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3116
3117 Ok(highest_gas_limit)
3118 }
3119
3120 pub fn set_transaction_order(&self, order: TransactionOrder) {
3122 *self.transaction_order.write() = order;
3123 }
3124
3125 fn transaction_priority(&self, tx: &TypedTransaction) -> TransactionPriority {
3127 self.transaction_order.read().priority(tx)
3128 }
3129
3130 pub fn chain_id(&self) -> u64 {
3132 self.backend.chain_id().to::<u64>()
3133 }
3134
3135 pub fn get_fork(&self) -> Option<ClientFork> {
3137 self.backend.get_fork()
3138 }
3139
3140 pub fn instance_id(&self) -> B256 {
3142 *self.instance_id.read()
3143 }
3144
3145 pub fn reset_instance_id(&self) {
3147 *self.instance_id.write() = B256::random();
3148 }
3149
3150 #[expect(clippy::borrowed_box)]
3152 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3153 self.signers.iter().find(|signer| signer.is_signer_for(address))
3154 }
3155
3156 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3158 self.backend.new_block_notifications()
3159 }
3160
3161 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3163 self.pool.add_ready_listener()
3164 }
3165
3166 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3168 let (tx, rx) = unbounded_channel();
3169 let mut hashes = self.new_ready_transactions();
3170
3171 let this = self.clone();
3172
3173 tokio::spawn(async move {
3174 while let Some(hash) = hashes.next().await {
3175 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3176 && tx.send(txn).is_err()
3177 {
3178 break;
3179 }
3180 }
3181 });
3182
3183 rx
3184 }
3185
3186 pub fn storage_info(&self) -> StorageInfo {
3188 StorageInfo::new(Arc::clone(&self.backend))
3189 }
3190
3191 pub fn is_fork(&self) -> bool {
3193 self.backend.is_fork()
3194 }
3195
3196 pub async fn mine_one(&self) {
3198 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3199 let outcome = self.backend.mine_block(transactions).await;
3200
3201 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3202 self.pool.on_mined_block(outcome);
3203 }
3204
3205 async fn pending_block(&self) -> AnyRpcBlock {
3207 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3208 let info = self.backend.pending_block(transactions).await;
3209 self.backend.convert_block(info.block)
3210 }
3211
3212 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3214 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3215 let BlockInfo { block, transactions, receipts: _ } =
3216 self.backend.pending_block(transactions).await;
3217
3218 let mut partial_block = self.backend.convert_block(block.clone());
3219
3220 let mut block_transactions = Vec::with_capacity(block.transactions.len());
3221 let base_fee = self.backend.base_fee();
3222
3223 for info in transactions {
3224 let tx = block.transactions.get(info.transaction_index as usize)?.clone();
3225
3226 let tx = transaction_build(
3227 Some(info.transaction_hash),
3228 tx,
3229 Some(&block),
3230 Some(info),
3231 Some(base_fee),
3232 );
3233 block_transactions.push(tx);
3234 }
3235
3236 partial_block.transactions = BlockTransactions::from(block_transactions);
3237
3238 Some(partial_block)
3239 }
3240
3241 fn build_typed_tx_request(
3242 &self,
3243 request: WithOtherFields<TransactionRequest>,
3244 nonce: u64,
3245 ) -> Result<TypedTransactionRequest> {
3246 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
3247 let max_fee_per_gas = request.max_fee_per_gas;
3248 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
3249 let gas_price = request.gas_price;
3250
3251 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
3252 let from = request.from;
3253
3254 let request = match transaction_request_to_typed(request) {
3255 Some(TypedTransactionRequest::Legacy(mut m)) => {
3256 m.nonce = nonce;
3257 m.chain_id = Some(chain_id);
3258 m.gas_limit = gas_limit;
3259 if gas_price.is_none() {
3260 m.gas_price = self.gas_price();
3261 }
3262 TypedTransactionRequest::Legacy(m)
3263 }
3264 Some(TypedTransactionRequest::EIP2930(mut m)) => {
3265 m.nonce = nonce;
3266 m.chain_id = chain_id;
3267 m.gas_limit = gas_limit;
3268 if gas_price.is_none() {
3269 m.gas_price = self.gas_price();
3270 }
3271 TypedTransactionRequest::EIP2930(m)
3272 }
3273 Some(TypedTransactionRequest::EIP1559(mut m)) => {
3274 m.nonce = nonce;
3275 m.chain_id = chain_id;
3276 m.gas_limit = gas_limit;
3277 if max_fee_per_gas.is_none() {
3278 m.max_fee_per_gas = self.gas_price();
3279 }
3280 TypedTransactionRequest::EIP1559(m)
3281 }
3282 Some(TypedTransactionRequest::EIP7702(mut m)) => {
3283 m.nonce = nonce;
3284 m.chain_id = chain_id;
3285 m.gas_limit = gas_limit;
3286 if max_fee_per_gas.is_none() {
3287 m.max_fee_per_gas = self.gas_price();
3288 }
3289 TypedTransactionRequest::EIP7702(m)
3290 }
3291 Some(TypedTransactionRequest::EIP4844(m)) => {
3292 TypedTransactionRequest::EIP4844(match m {
3293 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
3295 m.tx.nonce = nonce;
3296 m.tx.chain_id = chain_id;
3297 m.tx.gas_limit = gas_limit;
3298 if max_fee_per_gas.is_none() {
3299 m.tx.max_fee_per_gas = self.gas_price();
3300 }
3301 if max_fee_per_blob_gas.is_none() {
3302 m.tx.max_fee_per_blob_gas = self
3303 .excess_blob_gas_and_price()
3304 .unwrap_or_default()
3305 .map_or(0, |g| g.blob_gasprice)
3306 }
3307 TxEip4844Variant::TxEip4844WithSidecar(m)
3308 }
3309 TxEip4844Variant::TxEip4844(mut tx) => {
3310 if !self.backend.skip_blob_validation(from) {
3311 return Err(BlockchainError::FailedToDecodeTransaction);
3312 }
3313
3314 tx.nonce = nonce;
3316 tx.chain_id = chain_id;
3317 tx.gas_limit = gas_limit;
3318 if max_fee_per_gas.is_none() {
3319 tx.max_fee_per_gas = self.gas_price();
3320 }
3321 if max_fee_per_blob_gas.is_none() {
3322 tx.max_fee_per_blob_gas = self
3323 .excess_blob_gas_and_price()
3324 .unwrap_or_default()
3325 .map_or(0, |g| g.blob_gasprice)
3326 }
3327
3328 TxEip4844Variant::TxEip4844(tx)
3329 }
3330 })
3331 }
3332 Some(TypedTransactionRequest::Deposit(mut m)) => {
3333 m.gas_limit = gas_limit;
3334 TypedTransactionRequest::Deposit(m)
3335 }
3336 None => return Err(BlockchainError::FailedToDecodeTransaction),
3337 };
3338 Ok(request)
3339 }
3340
3341 pub fn is_impersonated(&self, addr: Address) -> bool {
3343 self.backend.cheats().is_impersonated(addr)
3344 }
3345
3346 fn impersonated_signature(&self, request: &TypedTransactionRequest) -> Signature {
3348 match request {
3349 TypedTransactionRequest::Legacy(_) => Signature::from_scalars_and_parity(
3352 B256::with_last_byte(1),
3353 B256::with_last_byte(1),
3354 false,
3355 ),
3356 TypedTransactionRequest::EIP2930(_)
3357 | TypedTransactionRequest::EIP1559(_)
3358 | TypedTransactionRequest::EIP7702(_)
3359 | TypedTransactionRequest::EIP4844(_)
3360 | TypedTransactionRequest::Deposit(_) => Signature::from_scalars_and_parity(
3361 B256::with_last_byte(1),
3362 B256::with_last_byte(1),
3363 false,
3364 ),
3365 }
3366 }
3367
3368 async fn get_transaction_count(
3370 &self,
3371 address: Address,
3372 block_number: Option<BlockId>,
3373 ) -> Result<u64> {
3374 let block_request = self.block_request(block_number).await?;
3375
3376 if let BlockRequest::Number(number) = block_request
3377 && let Some(fork) = self.get_fork()
3378 && fork.predates_fork(number)
3379 {
3380 return Ok(fork.get_nonce(address, number).await?);
3381 }
3382
3383 self.backend.get_nonce(address, block_request).await
3384 }
3385
3386 async fn request_nonce(
3394 &self,
3395 request: &TransactionRequest,
3396 from: Address,
3397 ) -> Result<(u64, u64)> {
3398 let highest_nonce =
3399 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3400 let nonce = request.nonce.unwrap_or(highest_nonce);
3401
3402 Ok((nonce, highest_nonce))
3403 }
3404
3405 fn add_pending_transaction(
3407 &self,
3408 pending_transaction: PendingTransaction,
3409 requires: Vec<TxMarker>,
3410 provides: Vec<TxMarker>,
3411 ) -> Result<TxHash> {
3412 let from = *pending_transaction.sender();
3413 let priority = self.transaction_priority(&pending_transaction.transaction);
3414 let pool_transaction =
3415 PoolTransaction { requires, provides, pending_transaction, priority };
3416 let tx = self.pool.add_transaction(pool_transaction)?;
3417 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3418 Ok(*tx.hash())
3419 }
3420
3421 pub async fn state_root(&self) -> Option<B256> {
3423 self.backend.get_db().read().await.maybe_state_root()
3424 }
3425
3426 fn ensure_typed_transaction_supported(&self, tx: &TypedTransaction) -> Result<()> {
3428 match &tx {
3429 TypedTransaction::EIP2930(_) => self.backend.ensure_eip2930_active(),
3430 TypedTransaction::EIP1559(_) => self.backend.ensure_eip1559_active(),
3431 TypedTransaction::EIP4844(_) => self.backend.ensure_eip4844_active(),
3432 TypedTransaction::EIP7702(_) => self.backend.ensure_eip7702_active(),
3433 TypedTransaction::Deposit(_) => self.backend.ensure_op_deposits_active(),
3434 TypedTransaction::Legacy(_) => Ok(()),
3435 }
3436 }
3437}
3438
3439fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3440 if provided_nonce == on_chain_nonce {
3441 return Vec::new();
3442 }
3443 let prev_nonce = provided_nonce.saturating_sub(1);
3444 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3445}
3446
3447fn convert_transact_out(out: &Option<Output>) -> Bytes {
3448 match out {
3449 None => Default::default(),
3450 Some(Output::Call(out)) => out.to_vec().into(),
3451 Some(Output::Create(out, _)) => out.to_vec().into(),
3452 }
3453}
3454
3455fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3457 let out = convert_transact_out(out);
3458 match exit {
3459 return_ok!() => Ok(out),
3460 return_revert!() => Err(InvalidTransactionError::Revert(Some(out.0.into())).into()),
3461 reason => Err(BlockchainError::EvmError(reason)),
3462 }
3463}
3464
3465fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3467 match transaction_request_to_typed(request.clone()) {
3468 Some(request) => match request {
3469 TypedTransactionRequest::Legacy(req) => match req.to {
3470 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3471 TxKind::Create => MIN_CREATE_GAS,
3472 },
3473 TypedTransactionRequest::EIP1559(req) => match req.to {
3474 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3475 TxKind::Create => MIN_CREATE_GAS,
3476 },
3477 TypedTransactionRequest::EIP7702(req) => {
3478 MIN_TRANSACTION_GAS
3479 + req.authorization_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3480 }
3481 TypedTransactionRequest::EIP2930(req) => match req.to {
3482 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3483 TxKind::Create => MIN_CREATE_GAS,
3484 },
3485 TypedTransactionRequest::EIP4844(_) => MIN_TRANSACTION_GAS,
3486 TypedTransactionRequest::Deposit(req) => match req.to {
3487 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3488 TxKind::Create => MIN_CREATE_GAS,
3489 },
3490 },
3491 _ => MIN_CREATE_GAS,
3494 }
3495}
3496
3497enum GasEstimationCallResult {
3499 Success(u128),
3500 OutOfGas,
3501 Revert(Option<Bytes>),
3502 EvmError(InstructionResult),
3503}
3504
3505impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3509 type Error = BlockchainError;
3510
3511 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3512 match res {
3513 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3515 Ok(Self::OutOfGas)
3516 }
3517 Err(err) => Err(err),
3518 Ok((exit, output, gas, _)) => match exit {
3519 return_ok!() => Ok(Self::Success(gas)),
3520
3521 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3523 InstructionResult::CallTooDeep
3524 | InstructionResult::OutOfFunds
3525 | InstructionResult::CreateInitCodeStartingEF00
3526 | InstructionResult::InvalidEOFInitCode
3527 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3528
3529 InstructionResult::OutOfGas
3531 | InstructionResult::MemoryOOG
3532 | InstructionResult::MemoryLimitOOG
3533 | InstructionResult::PrecompileOOG
3534 | InstructionResult::InvalidOperandOOG
3535 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3536
3537 InstructionResult::OpcodeNotFound
3539 | InstructionResult::CallNotAllowedInsideStatic
3540 | InstructionResult::StateChangeDuringStaticCall
3541 | InstructionResult::InvalidFEOpcode
3542 | InstructionResult::InvalidJump
3543 | InstructionResult::NotActivated
3544 | InstructionResult::StackUnderflow
3545 | InstructionResult::StackOverflow
3546 | InstructionResult::OutOfOffset
3547 | InstructionResult::CreateCollision
3548 | InstructionResult::OverflowPayment
3549 | InstructionResult::PrecompileError
3550 | InstructionResult::NonceOverflow
3551 | InstructionResult::CreateContractSizeLimit
3552 | InstructionResult::CreateContractStartingWithEF
3553 | InstructionResult::CreateInitCodeSizeLimit
3554 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3555 },
3556 }
3557 }
3558}