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::{
38 eip2718::Encodable2718,
39 eip7910::{EthConfig, EthForkConfig},
40};
41use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
42use alloy_network::{
43 AnyRpcBlock, AnyRpcTransaction, BlockResponse, TransactionBuilder, TransactionResponse,
44 eip2718::Decodable2718,
45};
46use alloy_primitives::{
47 Address, B64, B256, Bytes, Signature, TxHash, TxKind, U64, U256,
48 map::{HashMap, HashSet},
49};
50use alloy_rpc_types::{
51 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
52 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
53 anvil::{
54 ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
55 },
56 request::TransactionRequest,
57 simulate::{SimulatePayload, SimulatedBlock},
58 state::{AccountOverride, EvmOverrides, StateOverridesBuilder},
59 trace::{
60 filter::TraceFilter,
61 geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
62 parity::LocalizedTransactionTrace,
63 },
64 txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
65};
66use alloy_serde::WithOtherFields;
67use alloy_sol_types::{SolCall, SolValue, sol};
68use alloy_transport::TransportErrorKind;
69use anvil_core::{
70 eth::{
71 EthRequest,
72 block::BlockInfo,
73 transaction::{
74 PendingTransaction, ReceiptResponse, TypedTransaction, TypedTransactionRequest,
75 transaction_request_to_typed,
76 },
77 wallet::WalletCapabilities,
78 },
79 types::{ReorgOptions, TransactionData},
80};
81use anvil_rpc::{error::RpcError, response::ResponseResult};
82use foundry_common::provider::ProviderBuilder;
83use foundry_evm::decode::RevertDecoder;
84use futures::{
85 StreamExt, TryFutureExt,
86 channel::{mpsc::Receiver, oneshot},
87};
88use parking_lot::RwLock;
89use revm::{
90 context::BlockEnv,
91 context_interface::{block::BlobExcessGasAndPrice, result::Output},
92 database::CacheDB,
93 interpreter::{InstructionResult, return_ok, return_revert},
94 primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
95};
96use std::{sync::Arc, time::Duration};
97use tokio::{
98 sync::mpsc::{UnboundedReceiver, unbounded_channel},
99 try_join,
100};
101
102pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
104
105#[derive(Clone)]
109pub struct EthApi {
110 pool: Arc<Pool>,
112 pub backend: Arc<backend::mem::Backend>,
115 is_mining: bool,
117 signers: Arc<Vec<Box<dyn Signer>>>,
119 fee_history_cache: FeeHistoryCache,
121 fee_history_limit: u64,
123 miner: Miner,
128 logger: LoggingManager,
130 filters: Filters,
132 transaction_order: Arc<RwLock<TransactionOrder>>,
134 net_listening: bool,
136 instance_id: Arc<RwLock<B256>>,
138}
139
140impl EthApi {
141 #[expect(clippy::too_many_arguments)]
143 pub fn new(
144 pool: Arc<Pool>,
145 backend: Arc<backend::mem::Backend>,
146 signers: Arc<Vec<Box<dyn Signer>>>,
147 fee_history_cache: FeeHistoryCache,
148 fee_history_limit: u64,
149 miner: Miner,
150 logger: LoggingManager,
151 filters: Filters,
152 transactions_order: TransactionOrder,
153 ) -> Self {
154 Self {
155 pool,
156 backend,
157 is_mining: true,
158 signers,
159 fee_history_cache,
160 fee_history_limit,
161 miner,
162 logger,
163 filters,
164 net_listening: true,
165 transaction_order: Arc::new(RwLock::new(transactions_order)),
166 instance_id: Arc::new(RwLock::new(B256::random())),
167 }
168 }
169
170 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
172 trace!(target: "rpc::api", "executing eth request");
173 let response = match request.clone() {
174 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
175 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
176 EthRequest::EthGetAccount(addr, block) => {
177 self.get_account(addr, block).await.to_rpc_result()
178 }
179 EthRequest::EthGetAccountInfo(addr, block) => {
180 self.get_account_info(addr, block).await.to_rpc_result()
181 }
182 EthRequest::EthGetBalance(addr, block) => {
183 self.balance(addr, block).await.to_rpc_result()
184 }
185 EthRequest::EthGetTransactionByHash(hash) => {
186 self.transaction_by_hash(hash).await.to_rpc_result()
187 }
188 EthRequest::EthSendTransaction(request) => {
189 self.send_transaction(*request).await.to_rpc_result()
190 }
191 EthRequest::EthSendTransactionSync(request) => {
192 self.send_transaction_sync(*request).await.to_rpc_result()
193 }
194 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
195 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
196 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
197 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
198 EthRequest::EthMaxPriorityFeePerGas(_) => {
199 self.gas_max_priority_fee_per_gas().to_rpc_result()
200 }
201 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
202 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
203 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
204 EthRequest::EthGetStorageAt(addr, slot, block) => {
205 self.storage_at(addr, slot, block).await.to_rpc_result()
206 }
207 EthRequest::EthGetBlockByHash(hash, full) => {
208 if full {
209 self.block_by_hash_full(hash).await.to_rpc_result()
210 } else {
211 self.block_by_hash(hash).await.to_rpc_result()
212 }
213 }
214 EthRequest::EthGetBlockByNumber(num, full) => {
215 if full {
216 self.block_by_number_full(num).await.to_rpc_result()
217 } else {
218 self.block_by_number(num).await.to_rpc_result()
219 }
220 }
221 EthRequest::EthGetTransactionCount(addr, block) => {
222 self.transaction_count(addr, block).await.to_rpc_result()
223 }
224 EthRequest::EthGetTransactionCountByHash(hash) => {
225 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
226 }
227 EthRequest::EthGetTransactionCountByNumber(num) => {
228 self.block_transaction_count_by_number(num).await.to_rpc_result()
229 }
230 EthRequest::EthGetUnclesCountByHash(hash) => {
231 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
232 }
233 EthRequest::EthGetUnclesCountByNumber(num) => {
234 self.block_uncles_count_by_number(num).await.to_rpc_result()
235 }
236 EthRequest::EthGetCodeAt(addr, block) => {
237 self.get_code(addr, block).await.to_rpc_result()
238 }
239 EthRequest::EthGetProof(addr, keys, block) => {
240 self.get_proof(addr, keys, block).await.to_rpc_result()
241 }
242 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
243 EthRequest::PersonalSign(content, addr) => {
244 self.sign(addr, content).await.to_rpc_result()
245 }
246 EthRequest::EthSignTransaction(request) => {
247 self.sign_transaction(*request).await.to_rpc_result()
248 }
249 EthRequest::EthSignTypedData(addr, data) => {
250 self.sign_typed_data(addr, data).await.to_rpc_result()
251 }
252 EthRequest::EthSignTypedDataV3(addr, data) => {
253 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
254 }
255 EthRequest::EthSignTypedDataV4(addr, data) => {
256 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
257 }
258 EthRequest::EthSendRawTransaction(tx) => {
259 self.send_raw_transaction(tx).await.to_rpc_result()
260 }
261 EthRequest::EthSendRawTransactionSync(tx) => {
262 self.send_raw_transaction_sync(tx).await.to_rpc_result()
263 }
264 EthRequest::EthCall(call, block, state_override, block_overrides) => self
265 .call(call, block, EvmOverrides::new(state_override, block_overrides))
266 .await
267 .to_rpc_result(),
268 EthRequest::EthSimulateV1(simulation, block) => {
269 self.simulate_v1(simulation, block).await.to_rpc_result()
270 }
271 EthRequest::EthCreateAccessList(call, block) => {
272 self.create_access_list(call, block).await.to_rpc_result()
273 }
274 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
275 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
276 .await
277 .to_rpc_result(),
278 EthRequest::EthGetRawTransactionByHash(hash) => {
279 self.raw_transaction(hash).await.to_rpc_result()
280 }
281 EthRequest::GetBlobByHash(hash) => {
282 self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
283 }
284 EthRequest::GetBlobByTransactionHash(hash) => {
285 self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
286 }
287 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
288 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
289 }
290 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
291 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
292 }
293 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
294 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
295 }
296 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
297 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
298 }
299 EthRequest::EthGetTransactionReceipt(tx) => {
300 self.transaction_receipt(tx).await.to_rpc_result()
301 }
302 EthRequest::EthGetBlockReceipts(number) => {
303 self.block_receipts(number).await.to_rpc_result()
304 }
305 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
306 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
307 }
308 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
309 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
310 }
311 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
312 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
313 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
314 EthRequest::EthConfig(_) => self.config().to_rpc_result(),
315 EthRequest::EthSubmitWork(nonce, pow, digest) => {
316 self.submit_work(nonce, pow, digest).to_rpc_result()
317 }
318 EthRequest::EthSubmitHashRate(rate, id) => {
319 self.submit_hashrate(rate, id).to_rpc_result()
320 }
321 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
322 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
323 }
324 EthRequest::DebugGetRawTransaction(hash) => {
326 self.raw_transaction(hash).await.to_rpc_result()
327 }
328 EthRequest::DebugTraceTransaction(tx, opts) => {
330 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
331 }
332 EthRequest::DebugTraceCall(tx, block, opts) => {
334 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
335 }
336 EthRequest::DebugCodeByHash(hash, block) => {
337 self.debug_code_by_hash(hash, block).await.to_rpc_result()
338 }
339 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
340 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
341 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
342 EthRequest::ImpersonateAccount(addr) => {
343 self.anvil_impersonate_account(addr).await.to_rpc_result()
344 }
345 EthRequest::StopImpersonatingAccount(addr) => {
346 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
347 }
348 EthRequest::AutoImpersonateAccount(enable) => {
349 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
350 }
351 EthRequest::ImpersonateSignature(signature, address) => {
352 self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
353 }
354 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
355 EthRequest::Mine(blocks, interval) => {
356 self.anvil_mine(blocks, interval).await.to_rpc_result()
357 }
358 EthRequest::SetAutomine(enabled) => {
359 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
360 }
361 EthRequest::SetIntervalMining(interval) => {
362 self.anvil_set_interval_mining(interval).to_rpc_result()
363 }
364 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
365 EthRequest::DropTransaction(tx) => {
366 self.anvil_drop_transaction(tx).await.to_rpc_result()
367 }
368 EthRequest::DropAllTransactions() => {
369 self.anvil_drop_all_transactions().await.to_rpc_result()
370 }
371 EthRequest::Reset(fork) => {
372 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
373 }
374 EthRequest::SetBalance(addr, val) => {
375 self.anvil_set_balance(addr, val).await.to_rpc_result()
376 }
377 EthRequest::AddBalance(addr, val) => {
378 self.anvil_add_balance(addr, val).await.to_rpc_result()
379 }
380 EthRequest::DealERC20(addr, token_addr, val) => {
381 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
382 }
383 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
384 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
385 .await
386 .to_rpc_result(),
387 EthRequest::SetCode(addr, code) => {
388 self.anvil_set_code(addr, code).await.to_rpc_result()
389 }
390 EthRequest::SetNonce(addr, nonce) => {
391 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
392 }
393 EthRequest::SetStorageAt(addr, slot, val) => {
394 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
395 }
396 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
397 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
398 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
399 EthRequest::SetMinGasPrice(gas) => {
400 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
401 }
402 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
403 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
404 }
405 EthRequest::DumpState(preserve_historical_states) => self
406 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
407 .await
408 .to_rpc_result(),
409 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
410 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
411 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
412 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
413 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
414 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
415 EthRequest::EvmSetNextBlockTimeStamp(time) => {
416 if time >= U256::from(u64::MAX) {
417 return ResponseResult::Error(RpcError::invalid_params(
418 "The timestamp is too big",
419 ));
420 }
421 let time = time.to::<u64>();
422 self.evm_set_next_block_timestamp(time).to_rpc_result()
423 }
424 EthRequest::EvmSetTime(timestamp) => {
425 if timestamp >= U256::from(u64::MAX) {
426 return ResponseResult::Error(RpcError::invalid_params(
427 "The timestamp is too big",
428 ));
429 }
430 let time = timestamp.to::<u64>();
431 self.evm_set_time(time).to_rpc_result()
432 }
433 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
434 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
435 }
436 EthRequest::EvmSetBlockTimeStampInterval(time) => {
437 self.evm_set_block_timestamp_interval(time).to_rpc_result()
438 }
439 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
440 self.evm_remove_block_timestamp_interval().to_rpc_result()
441 }
442 EthRequest::EvmMine(mine) => {
443 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
444 }
445 EthRequest::EvmMineDetailed(mine) => {
446 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
447 }
448 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
449 EthRequest::EthSendUnsignedTransaction(tx) => {
450 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
451 }
452 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
453 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
454 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
455 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
456 EthRequest::EthNewPendingTransactionFilter(_) => {
457 self.new_pending_transaction_filter().await.to_rpc_result()
458 }
459 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
460 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
461 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
462 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
463 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
464 EthRequest::ErigonGetHeaderByNumber(num) => {
465 self.erigon_get_header_by_number(num).await.to_rpc_result()
466 }
467 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
468 EthRequest::OtsGetInternalOperations(hash) => {
469 self.ots_get_internal_operations(hash).await.to_rpc_result()
470 }
471 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
472 EthRequest::OtsTraceTransaction(hash) => {
473 self.ots_trace_transaction(hash).await.to_rpc_result()
474 }
475 EthRequest::OtsGetTransactionError(hash) => {
476 self.ots_get_transaction_error(hash).await.to_rpc_result()
477 }
478 EthRequest::OtsGetBlockDetails(num) => {
479 self.ots_get_block_details(num).await.to_rpc_result()
480 }
481 EthRequest::OtsGetBlockDetailsByHash(hash) => {
482 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
483 }
484 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
485 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
486 }
487 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
488 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
489 }
490 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
491 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
492 }
493 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
494 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
495 }
496 EthRequest::OtsGetContractCreator(address) => {
497 self.ots_get_contract_creator(address).await.to_rpc_result()
498 }
499 EthRequest::RemovePoolTransactions(address) => {
500 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
501 }
502 EthRequest::Reorg(reorg_options) => {
503 self.anvil_reorg(reorg_options).await.to_rpc_result()
504 }
505 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
506 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
507 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
508 EthRequest::AnvilSetExecutor(executor_pk) => {
509 self.anvil_set_executor(executor_pk).to_rpc_result()
510 }
511 };
512
513 if let ResponseResult::Error(err) = &response {
514 node_info!("\nRPC request failed:");
515 node_info!(" Request: {:?}", request);
516 node_info!(" Error: {}\n", err);
517 }
518
519 response
520 }
521
522 fn sign_request(
523 &self,
524 from: &Address,
525 request: TypedTransactionRequest,
526 ) -> Result<TypedTransaction> {
527 match request {
528 TypedTransactionRequest::Deposit(_) => {
529 let nil_signature = Signature::from_scalars_and_parity(
530 B256::with_last_byte(1),
531 B256::with_last_byte(1),
532 false,
533 );
534 return build_typed_transaction(request, nil_signature);
535 }
536 _ => {
537 for signer in self.signers.iter() {
538 if signer.accounts().contains(from) {
539 let signature = signer.sign_transaction(request.clone(), from)?;
540 return build_typed_transaction(request, signature);
541 }
542 }
543 }
544 }
545 Err(BlockchainError::NoSignerAvailable)
546 }
547
548 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
549 let block_request = match block_number {
550 Some(BlockId::Number(BlockNumber::Pending)) => {
551 let pending_txs = self.pool.ready_transactions().collect();
552 BlockRequest::Pending(pending_txs)
553 }
554 _ => {
555 let number = self.backend.ensure_block_number(block_number).await?;
556 BlockRequest::Number(number)
557 }
558 };
559 Ok(block_request)
560 }
561
562 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
563 match self.pool.get_transaction(hash) {
564 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
565 None => match self.backend.transaction_by_hash(hash).await? {
566 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
567 None => Ok(None),
568 },
569 }
570 }
571
572 pub fn client_version(&self) -> Result<String> {
576 node_info!("web3_clientVersion");
577 Ok(CLIENT_VERSION.to_string())
578 }
579
580 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
584 node_info!("web3_sha3");
585 let hash = alloy_primitives::keccak256(bytes.as_ref());
586 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
587 }
588
589 pub fn protocol_version(&self) -> Result<u64> {
593 node_info!("eth_protocolVersion");
594 Ok(1)
595 }
596
597 pub fn hashrate(&self) -> Result<U256> {
601 node_info!("eth_hashrate");
602 Ok(U256::ZERO)
603 }
604
605 pub fn author(&self) -> Result<Address> {
609 node_info!("eth_coinbase");
610 Ok(self.backend.coinbase())
611 }
612
613 pub fn is_mining(&self) -> Result<bool> {
617 node_info!("eth_mining");
618 Ok(self.is_mining)
619 }
620
621 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
627 node_info!("eth_chainId");
628 Ok(Some(self.backend.chain_id().to::<U64>()))
629 }
630
631 pub fn network_id(&self) -> Result<Option<String>> {
635 node_info!("eth_networkId");
636 let chain_id = self.backend.chain_id().to::<u64>();
637 Ok(Some(format!("{chain_id}")))
638 }
639
640 pub fn net_listening(&self) -> Result<bool> {
644 node_info!("net_listening");
645 Ok(self.net_listening)
646 }
647
648 fn eth_gas_price(&self) -> Result<U256> {
650 node_info!("eth_gasPrice");
651 Ok(U256::from(self.gas_price()))
652 }
653
654 pub fn gas_price(&self) -> u128 {
656 if self.backend.is_eip1559() {
657 if self.backend.is_min_priority_fee_enforced() {
658 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
659 } else {
660 self.backend.base_fee() as u128
661 }
662 } else {
663 self.backend.fees().raw_gas_price()
664 }
665 }
666
667 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
669 Ok(self.backend.excess_blob_gas_and_price())
670 }
671
672 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
677 self.max_priority_fee_per_gas()
678 }
679
680 pub fn blob_base_fee(&self) -> Result<U256> {
684 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
685 }
686
687 pub fn gas_limit(&self) -> U256 {
689 U256::from(self.backend.gas_limit())
690 }
691
692 pub fn accounts(&self) -> Result<Vec<Address>> {
696 node_info!("eth_accounts");
697 let mut unique = HashSet::new();
698 let mut accounts: Vec<Address> = Vec::new();
699 for signer in self.signers.iter() {
700 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
701 }
702 accounts.extend(
703 self.backend
704 .cheats()
705 .impersonated_accounts()
706 .into_iter()
707 .filter(|acc| unique.insert(*acc)),
708 );
709 Ok(accounts.into_iter().collect())
710 }
711
712 pub fn block_number(&self) -> Result<U256> {
716 node_info!("eth_blockNumber");
717 Ok(U256::from(self.backend.best_number()))
718 }
719
720 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
724 node_info!("eth_getBalance");
725 let block_request = self.block_request(block_number).await?;
726
727 if let BlockRequest::Number(number) = block_request
729 && let Some(fork) = self.get_fork()
730 && fork.predates_fork(number)
731 {
732 return Ok(fork.get_balance(address, number).await?);
733 }
734
735 self.backend.get_balance(address, Some(block_request)).await
736 }
737
738 pub async fn get_account(
742 &self,
743 address: Address,
744 block_number: Option<BlockId>,
745 ) -> Result<Account> {
746 node_info!("eth_getAccount");
747 let block_request = self.block_request(block_number).await?;
748
749 if let BlockRequest::Number(number) = block_request
751 && let Some(fork) = self.get_fork()
752 && fork.predates_fork(number)
753 {
754 return Ok(fork.get_account(address, number).await?);
755 }
756
757 self.backend.get_account_at_block(address, Some(block_request)).await
758 }
759
760 pub async fn get_account_info(
764 &self,
765 address: Address,
766 block_number: Option<BlockId>,
767 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
768 node_info!("eth_getAccountInfo");
769
770 if let Some(fork) = self.get_fork() {
771 if let BlockRequest::Number(number) = self.block_request(block_number).await?
773 && fork.predates_fork(number)
774 {
775 let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
778 let code = fork.get_code(address, number).map_err(BlockchainError::from);
779 let nonce = self.get_transaction_count(address, Some(number.into()));
780 let (balance, code, nonce) = try_join!(balance, code, nonce)?;
781
782 return Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code });
783 }
784 }
785
786 let account = self.get_account(address, block_number);
787 let code = self.get_code(address, block_number);
788 let (account, code) = try_join!(account, code)?;
789 Ok(alloy_rpc_types::eth::AccountInfo {
790 balance: account.balance,
791 nonce: account.nonce,
792 code,
793 })
794 }
795 pub async fn storage_at(
799 &self,
800 address: Address,
801 index: U256,
802 block_number: Option<BlockId>,
803 ) -> Result<B256> {
804 node_info!("eth_getStorageAt");
805 let block_request = self.block_request(block_number).await?;
806
807 if let BlockRequest::Number(number) = block_request
809 && let Some(fork) = self.get_fork()
810 && fork.predates_fork(number)
811 {
812 return Ok(B256::from(
813 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
814 ));
815 }
816
817 self.backend.storage_at(address, index, Some(block_request)).await
818 }
819
820 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
824 node_info!("eth_getBlockByHash");
825 self.backend.block_by_hash(hash).await
826 }
827
828 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
832 node_info!("eth_getBlockByHash");
833 self.backend.block_by_hash_full(hash).await
834 }
835
836 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
840 node_info!("eth_getBlockByNumber");
841 if number == BlockNumber::Pending {
842 return Ok(Some(self.pending_block().await));
843 }
844
845 self.backend.block_by_number(number).await
846 }
847
848 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
852 node_info!("eth_getBlockByNumber");
853 if number == BlockNumber::Pending {
854 return Ok(self.pending_block_full().await);
855 }
856 self.backend.block_by_number_full(number).await
857 }
858
859 pub async fn transaction_count(
866 &self,
867 address: Address,
868 block_number: Option<BlockId>,
869 ) -> Result<U256> {
870 node_info!("eth_getTransactionCount");
871 self.get_transaction_count(address, block_number).await.map(U256::from)
872 }
873
874 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
878 node_info!("eth_getBlockTransactionCountByHash");
879 let block = self.backend.block_by_hash(hash).await?;
880 let txs = block.map(|b| match b.transactions() {
881 BlockTransactions::Full(txs) => U256::from(txs.len()),
882 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
883 BlockTransactions::Uncle => U256::from(0),
884 });
885 Ok(txs)
886 }
887
888 pub async fn block_transaction_count_by_number(
892 &self,
893 block_number: BlockNumber,
894 ) -> Result<Option<U256>> {
895 node_info!("eth_getBlockTransactionCountByNumber");
896 let block_request = self.block_request(Some(block_number.into())).await?;
897 if let BlockRequest::Pending(txs) = block_request {
898 let block = self.backend.pending_block(txs).await;
899 return Ok(Some(U256::from(block.transactions.len())));
900 }
901 let block = self.backend.block_by_number(block_number).await?;
902 let txs = block.map(|b| match b.transactions() {
903 BlockTransactions::Full(txs) => U256::from(txs.len()),
904 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
905 BlockTransactions::Uncle => U256::from(0),
906 });
907 Ok(txs)
908 }
909
910 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
914 node_info!("eth_getUncleCountByBlockHash");
915 let block =
916 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
917 Ok(U256::from(block.uncles.len()))
918 }
919
920 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
924 node_info!("eth_getUncleCountByBlockNumber");
925 let block = self
926 .backend
927 .block_by_number(block_number)
928 .await?
929 .ok_or(BlockchainError::BlockNotFound)?;
930 Ok(U256::from(block.uncles.len()))
931 }
932
933 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
937 node_info!("eth_getCode");
938 let block_request = self.block_request(block_number).await?;
939 if let BlockRequest::Number(number) = block_request
941 && let Some(fork) = self.get_fork()
942 && fork.predates_fork(number)
943 {
944 return Ok(fork.get_code(address, number).await?);
945 }
946 self.backend.get_code(address, Some(block_request)).await
947 }
948
949 pub async fn get_proof(
954 &self,
955 address: Address,
956 keys: Vec<B256>,
957 block_number: Option<BlockId>,
958 ) -> Result<EIP1186AccountProofResponse> {
959 node_info!("eth_getProof");
960 let block_request = self.block_request(block_number).await?;
961
962 if let BlockRequest::Number(number) = block_request
965 && let Some(fork) = self.get_fork()
966 && fork.predates_fork_inclusive(number)
967 {
968 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
969 }
970
971 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
972 Ok(proof)
973 }
974
975 pub async fn sign_typed_data(
979 &self,
980 _address: Address,
981 _data: serde_json::Value,
982 ) -> Result<String> {
983 node_info!("eth_signTypedData");
984 Err(BlockchainError::RpcUnimplemented)
985 }
986
987 pub async fn sign_typed_data_v3(
991 &self,
992 _address: Address,
993 _data: serde_json::Value,
994 ) -> Result<String> {
995 node_info!("eth_signTypedData_v3");
996 Err(BlockchainError::RpcUnimplemented)
997 }
998
999 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
1003 node_info!("eth_signTypedData_v4");
1004 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1005 let signature = signer.sign_typed_data(address, data).await?;
1006 let signature = alloy_primitives::hex::encode(signature.as_bytes());
1007 Ok(format!("0x{signature}"))
1008 }
1009
1010 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1014 node_info!("eth_sign");
1015 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1016 let signature =
1017 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1018 Ok(format!("0x{signature}"))
1019 }
1020
1021 pub async fn sign_transaction(
1025 &self,
1026 mut request: WithOtherFields<TransactionRequest>,
1027 ) -> Result<String> {
1028 node_info!("eth_signTransaction");
1029
1030 let from = request.from.map(Ok).unwrap_or_else(|| {
1031 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1032 })?;
1033
1034 let (nonce, _) = self.request_nonce(&request, from).await?;
1035
1036 if request.gas.is_none() {
1037 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1039 {
1040 request.gas = Some(gas.to());
1041 }
1042 }
1043
1044 let request = self.build_typed_tx_request(request, nonce)?;
1045
1046 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1047 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1048 }
1049
1050 pub async fn send_transaction(
1054 &self,
1055 mut request: WithOtherFields<TransactionRequest>,
1056 ) -> Result<TxHash> {
1057 node_info!("eth_sendTransaction");
1058
1059 let from = request.from.map(Ok).unwrap_or_else(|| {
1060 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1061 })?;
1062 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1063
1064 if request.gas.is_none() {
1065 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1067 {
1068 request.gas = Some(gas.to());
1069 }
1070 }
1071
1072 let request = self.build_typed_tx_request(request, nonce)?;
1073
1074 let pending_transaction = if self.is_impersonated(from) {
1076 let bypass_signature = self.impersonated_signature(&request);
1077 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1078 self.ensure_typed_transaction_supported(&transaction)?;
1079 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1080 PendingTransaction::with_impersonated(transaction, from)
1081 } else {
1082 let transaction = self.sign_request(&from, request)?;
1083 self.ensure_typed_transaction_supported(&transaction)?;
1084 PendingTransaction::new(transaction)?
1085 };
1086 self.backend.validate_pool_transaction(&pending_transaction).await?;
1088
1089 let requires = required_marker(nonce, on_chain_nonce, from);
1090 let provides = vec![to_marker(nonce, from)];
1091 debug_assert!(requires != provides);
1092
1093 self.add_pending_transaction(pending_transaction, requires, provides)
1094 }
1095
1096 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1098 let mut stream = self.new_block_notifications();
1099 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1101 return Ok(receipt);
1102 }
1103 while let Some(notification) = stream.next().await {
1104 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1105 && block.transactions.iter().any(|tx| tx.hash() == hash)
1106 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1107 {
1108 return Ok(receipt);
1109 }
1110 }
1111
1112 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1113 }
1114
1115 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1117 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1118 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1119 .await
1120 .unwrap_or_else(|_elapsed| {
1121 Err(BlockchainError::TransactionConfirmationTimeout {
1122 hash,
1123 duration: TIMEOUT_DURATION,
1124 })
1125 })
1126 }
1127
1128 pub async fn send_transaction_sync(
1132 &self,
1133 request: WithOtherFields<TransactionRequest>,
1134 ) -> Result<ReceiptResponse> {
1135 node_info!("eth_sendTransactionSync");
1136 let hash = self.send_transaction(request).await?;
1137
1138 let receipt = self.check_transaction_inclusion(hash).await?;
1139
1140 Ok(ReceiptResponse::from(receipt))
1141 }
1142
1143 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1147 node_info!("eth_sendRawTransaction");
1148 let mut data = tx.as_ref();
1149 if data.is_empty() {
1150 return Err(BlockchainError::EmptyRawTransactionData);
1151 }
1152
1153 let transaction = TypedTransaction::decode_2718(&mut data)
1154 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1155
1156 self.ensure_typed_transaction_supported(&transaction)?;
1157
1158 let pending_transaction = PendingTransaction::new(transaction)?;
1159
1160 self.backend.validate_pool_transaction(&pending_transaction).await?;
1162
1163 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1164 let from = *pending_transaction.sender();
1165 let nonce = pending_transaction.transaction.nonce();
1166 let requires = required_marker(nonce, on_chain_nonce, from);
1167
1168 let priority = self.transaction_priority(&pending_transaction.transaction);
1169 let pool_transaction = PoolTransaction {
1170 requires,
1171 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1172 pending_transaction,
1173 priority,
1174 };
1175
1176 let tx = self.pool.add_transaction(pool_transaction)?;
1177 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1178 Ok(*tx.hash())
1179 }
1180
1181 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<ReceiptResponse> {
1185 node_info!("eth_sendRawTransactionSync");
1186
1187 let hash = self.send_raw_transaction(tx).await?;
1188 let receipt = self.check_transaction_inclusion(hash).await?;
1189
1190 Ok(ReceiptResponse::from(receipt))
1191 }
1192
1193 pub async fn call(
1197 &self,
1198 request: WithOtherFields<TransactionRequest>,
1199 block_number: Option<BlockId>,
1200 overrides: EvmOverrides,
1201 ) -> Result<Bytes> {
1202 node_info!("eth_call");
1203 let block_request = self.block_request(block_number).await?;
1204 if let BlockRequest::Number(number) = block_request
1206 && let Some(fork) = self.get_fork()
1207 && fork.predates_fork(number)
1208 {
1209 if overrides.has_state() || overrides.has_block() {
1210 return Err(BlockchainError::EvmOverrideError(
1211 "not available on past forked blocks".to_string(),
1212 ));
1213 }
1214 return Ok(fork.call(&request, Some(number.into())).await?);
1215 }
1216
1217 let fees = FeeDetails::new(
1218 request.gas_price,
1219 request.max_fee_per_gas,
1220 request.max_priority_fee_per_gas,
1221 request.max_fee_per_blob_gas,
1222 )?
1223 .or_zero_fees();
1224 self.on_blocking_task(|this| async move {
1227 let (exit, out, gas, _) =
1228 this.backend.call(request, fees, Some(block_request), overrides).await?;
1229 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1230
1231 ensure_return_ok(exit, &out)
1232 })
1233 .await
1234 }
1235
1236 pub async fn simulate_v1(
1237 &self,
1238 request: SimulatePayload,
1239 block_number: Option<BlockId>,
1240 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1241 node_info!("eth_simulateV1");
1242 let block_request = self.block_request(block_number).await?;
1243 if let BlockRequest::Number(number) = block_request
1245 && let Some(fork) = self.get_fork()
1246 && fork.predates_fork(number)
1247 {
1248 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1249 }
1250
1251 self.on_blocking_task(|this| async move {
1254 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1255 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1256
1257 Ok(simulated_blocks)
1258 })
1259 .await
1260 }
1261
1262 pub async fn create_access_list(
1276 &self,
1277 mut request: WithOtherFields<TransactionRequest>,
1278 block_number: Option<BlockId>,
1279 ) -> Result<AccessListResult> {
1280 node_info!("eth_createAccessList");
1281 let block_request = self.block_request(block_number).await?;
1282 if let BlockRequest::Number(number) = block_request
1284 && let Some(fork) = self.get_fork()
1285 && fork.predates_fork(number)
1286 {
1287 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1288 }
1289
1290 self.backend
1291 .with_database_at(Some(block_request), |state, block_env| {
1292 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1293 &state,
1294 request.clone(),
1295 FeeDetails::zero(),
1296 block_env.clone(),
1297 )?;
1298 ensure_return_ok(exit, &out)?;
1299
1300 request.access_list = Some(access_list.clone());
1302
1303 let (exit, out, gas_used, _) = self.backend.call_with_state(
1304 &state,
1305 request.clone(),
1306 FeeDetails::zero(),
1307 block_env,
1308 )?;
1309 ensure_return_ok(exit, &out)?;
1310
1311 Ok(AccessListResult {
1312 access_list: AccessList(access_list.0),
1313 gas_used: U256::from(gas_used),
1314 error: None,
1315 })
1316 })
1317 .await?
1318 }
1319
1320 pub async fn estimate_gas(
1325 &self,
1326 request: WithOtherFields<TransactionRequest>,
1327 block_number: Option<BlockId>,
1328 overrides: EvmOverrides,
1329 ) -> Result<U256> {
1330 node_info!("eth_estimateGas");
1331 self.do_estimate_gas(
1332 request,
1333 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1334 overrides,
1335 )
1336 .await
1337 .map(U256::from)
1338 }
1339
1340 pub fn anvil_get_blob_by_versioned_hash(
1342 &self,
1343 hash: B256,
1344 ) -> Result<Option<alloy_consensus::Blob>> {
1345 node_info!("anvil_getBlobByHash");
1346 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1347 }
1348
1349 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1351 node_info!("anvil_getBlobsByTransactionHash");
1352 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1353 }
1354
1355 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1362 node_info!("eth_getTransactionByHash");
1363 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1364 let from = *pending.sender();
1365 let tx = transaction_build(
1366 Some(*pending.hash()),
1367 pending.transaction,
1368 None,
1369 None,
1370 Some(self.backend.base_fee()),
1371 );
1372
1373 let WithOtherFields { inner: mut tx, other } = tx.0;
1374 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1377
1378 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1379 });
1380 if tx.is_none() {
1381 tx = self.backend.transaction_by_hash(hash).await?
1382 }
1383
1384 Ok(tx)
1385 }
1386
1387 pub async fn transaction_by_block_hash_and_index(
1391 &self,
1392 hash: B256,
1393 index: Index,
1394 ) -> Result<Option<AnyRpcTransaction>> {
1395 node_info!("eth_getTransactionByBlockHashAndIndex");
1396 self.backend.transaction_by_block_hash_and_index(hash, index).await
1397 }
1398
1399 pub async fn transaction_by_block_number_and_index(
1403 &self,
1404 block: BlockNumber,
1405 idx: Index,
1406 ) -> Result<Option<AnyRpcTransaction>> {
1407 node_info!("eth_getTransactionByBlockNumberAndIndex");
1408 self.backend.transaction_by_block_number_and_index(block, idx).await
1409 }
1410
1411 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1415 node_info!("eth_getTransactionReceipt");
1416 self.backend.transaction_receipt(hash).await
1417 }
1418
1419 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1423 node_info!("eth_getBlockReceipts");
1424 self.backend.block_receipts(number).await
1425 }
1426
1427 pub async fn uncle_by_block_hash_and_index(
1431 &self,
1432 block_hash: B256,
1433 idx: Index,
1434 ) -> Result<Option<AnyRpcBlock>> {
1435 node_info!("eth_getUncleByBlockHashAndIndex");
1436 let number =
1437 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1438 if let Some(fork) = self.get_fork()
1439 && fork.predates_fork_inclusive(number)
1440 {
1441 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1442 }
1443 Ok(None)
1445 }
1446
1447 pub async fn uncle_by_block_number_and_index(
1451 &self,
1452 block_number: BlockNumber,
1453 idx: Index,
1454 ) -> Result<Option<AnyRpcBlock>> {
1455 node_info!("eth_getUncleByBlockNumberAndIndex");
1456 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1457 if let Some(fork) = self.get_fork()
1458 && fork.predates_fork_inclusive(number)
1459 {
1460 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1461 }
1462 Ok(None)
1464 }
1465
1466 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1470 node_info!("eth_getLogs");
1471 self.backend.logs(filter).await
1472 }
1473
1474 pub fn work(&self) -> Result<Work> {
1478 node_info!("eth_getWork");
1479 Err(BlockchainError::RpcUnimplemented)
1480 }
1481
1482 pub fn syncing(&self) -> Result<bool> {
1486 node_info!("eth_syncing");
1487 Ok(false)
1488 }
1489
1490 pub fn config(&self) -> Result<EthConfig> {
1501 node_info!("eth_config");
1502 Ok(EthConfig {
1503 current: EthForkConfig {
1504 activation_time: 0,
1505 blob_schedule: self.backend.blob_params(),
1506 chain_id: self.backend.env().read().evm_env.cfg_env.chain_id,
1507 fork_id: Bytes::from_static(&[0; 4]),
1508 precompiles: self.backend.precompiles(),
1509 system_contracts: self.backend.system_contracts(),
1510 },
1511 next: None,
1512 last: None,
1513 })
1514 }
1515
1516 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1520 node_info!("eth_submitWork");
1521 Err(BlockchainError::RpcUnimplemented)
1522 }
1523
1524 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1528 node_info!("eth_submitHashrate");
1529 Err(BlockchainError::RpcUnimplemented)
1530 }
1531
1532 pub async fn fee_history(
1536 &self,
1537 block_count: U256,
1538 newest_block: BlockNumber,
1539 reward_percentiles: Vec<f64>,
1540 ) -> Result<FeeHistory> {
1541 node_info!("eth_feeHistory");
1542 let current = self.backend.best_number();
1545 let slots_in_an_epoch = 32u64;
1546
1547 let number = match newest_block {
1548 BlockNumber::Latest | BlockNumber::Pending => current,
1549 BlockNumber::Earliest => 0,
1550 BlockNumber::Number(n) => n,
1551 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1552 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1553 };
1554
1555 if let Some(fork) = self.get_fork() {
1557 if fork.predates_fork_inclusive(number) {
1560 return fork
1561 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1562 .await
1563 .map_err(BlockchainError::AlloyForkProvider);
1564 }
1565 }
1566
1567 const MAX_BLOCK_COUNT: u64 = 1024u64;
1568 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1569
1570 let highest = number;
1572 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1573
1574 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1576 return Err(FeeHistoryError::InvalidBlockRange.into());
1577 }
1578
1579 let mut response = FeeHistory {
1580 oldest_block: lowest,
1581 base_fee_per_gas: Vec::new(),
1582 gas_used_ratio: Vec::new(),
1583 reward: Some(Default::default()),
1584 base_fee_per_blob_gas: Default::default(),
1585 blob_gas_used_ratio: Default::default(),
1586 };
1587 let mut rewards = Vec::new();
1588
1589 {
1590 let fee_history = self.fee_history_cache.lock();
1591
1592 for n in lowest..=highest {
1594 if let Some(block) = fee_history.get(&n) {
1596 response.base_fee_per_gas.push(block.base_fee);
1597 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1598 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1599 response.gas_used_ratio.push(block.gas_used_ratio);
1600
1601 if !reward_percentiles.is_empty() {
1603 let mut block_rewards = Vec::new();
1604 let resolution_per_percentile: f64 = 2.0;
1605 for p in &reward_percentiles {
1606 let p = p.clamp(0.0, 100.0);
1607 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1608 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1609 block_rewards.push(reward);
1610 }
1611 rewards.push(block_rewards);
1612 }
1613 }
1614 }
1615 }
1616
1617 response.reward = Some(rewards);
1618
1619 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1624
1625 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1629
1630 Ok(response)
1631 }
1632
1633 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1640 node_info!("eth_maxPriorityFeePerGas");
1641 Ok(U256::from(self.lowest_suggestion_tip()))
1642 }
1643
1644 fn lowest_suggestion_tip(&self) -> u128 {
1648 let block_number = self.backend.best_number();
1649 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1650
1651 match latest_cached_block {
1652 Some(block) => block.rewards.iter().copied().min(),
1653 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1654 }
1655 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1656 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1657 }
1658
1659 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1663 node_info!("eth_newFilter");
1664 let historic = if filter.block_option.get_from_block().is_some() {
1667 self.backend.logs(filter.clone()).await?
1668 } else {
1669 vec![]
1670 };
1671 let filter = EthFilter::Logs(Box::new(LogsFilter {
1672 blocks: self.new_block_notifications(),
1673 storage: self.storage_info(),
1674 filter: FilteredParams::new(Some(filter)),
1675 historic: Some(historic),
1676 }));
1677 Ok(self.filters.add_filter(filter).await)
1678 }
1679
1680 pub async fn new_block_filter(&self) -> Result<String> {
1684 node_info!("eth_newBlockFilter");
1685 let filter = EthFilter::Blocks(self.new_block_notifications());
1686 Ok(self.filters.add_filter(filter).await)
1687 }
1688
1689 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1693 node_info!("eth_newPendingTransactionFilter");
1694 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1695 Ok(self.filters.add_filter(filter).await)
1696 }
1697
1698 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1702 node_info!("eth_getFilterChanges");
1703 self.filters.get_filter_changes(id).await
1704 }
1705
1706 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1710 node_info!("eth_getFilterLogs");
1711 if let Some(filter) = self.filters.get_log_filter(id).await {
1712 self.backend.logs(filter).await
1713 } else {
1714 Ok(Vec::new())
1715 }
1716 }
1717
1718 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1720 node_info!("eth_uninstallFilter");
1721 Ok(self.filters.uninstall_filter(id).await.is_some())
1722 }
1723
1724 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1728 node_info!("debug_getRawTransaction");
1729 self.inner_raw_transaction(hash).await
1730 }
1731
1732 pub async fn raw_transaction_by_block_hash_and_index(
1736 &self,
1737 block_hash: B256,
1738 index: Index,
1739 ) -> Result<Option<Bytes>> {
1740 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1741 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1742 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1743 None => Ok(None),
1744 }
1745 }
1746
1747 pub async fn raw_transaction_by_block_number_and_index(
1751 &self,
1752 block_number: BlockNumber,
1753 index: Index,
1754 ) -> Result<Option<Bytes>> {
1755 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1756 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1757 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1758 None => Ok(None),
1759 }
1760 }
1761
1762 pub async fn debug_trace_transaction(
1766 &self,
1767 tx_hash: B256,
1768 opts: GethDebugTracingOptions,
1769 ) -> Result<GethTrace> {
1770 node_info!("debug_traceTransaction");
1771 self.backend.debug_trace_transaction(tx_hash, opts).await
1772 }
1773
1774 pub async fn debug_trace_call(
1778 &self,
1779 request: WithOtherFields<TransactionRequest>,
1780 block_number: Option<BlockId>,
1781 opts: GethDebugTracingCallOptions,
1782 ) -> Result<GethTrace> {
1783 node_info!("debug_traceCall");
1784 let block_request = self.block_request(block_number).await?;
1785 let fees = FeeDetails::new(
1786 request.gas_price,
1787 request.max_fee_per_gas,
1788 request.max_priority_fee_per_gas,
1789 request.max_fee_per_blob_gas,
1790 )?
1791 .or_zero_fees();
1792
1793 let result: std::result::Result<GethTrace, BlockchainError> =
1794 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1795 result
1796 }
1797
1798 pub async fn debug_code_by_hash(
1802 &self,
1803 hash: B256,
1804 block_id: Option<BlockId>,
1805 ) -> Result<Option<Bytes>> {
1806 node_info!("debug_codeByHash");
1807 self.backend.debug_code_by_hash(hash, block_id).await
1808 }
1809
1810 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1814 node_info!("trace_transaction");
1815 self.backend.trace_transaction(tx_hash).await
1816 }
1817
1818 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1822 node_info!("trace_block");
1823 self.backend.trace_block(block).await
1824 }
1825
1826 pub async fn trace_filter(
1830 &self,
1831 filter: TraceFilter,
1832 ) -> Result<Vec<LocalizedTransactionTrace>> {
1833 node_info!("trace_filter");
1834 self.backend.trace_filter(filter).await
1835 }
1836}
1837
1838impl EthApi {
1841 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
1845 node_info!("anvil_impersonateAccount");
1846 self.backend.impersonate(address);
1847 Ok(())
1848 }
1849
1850 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
1854 node_info!("anvil_stopImpersonatingAccount");
1855 self.backend.stop_impersonating(address);
1856 Ok(())
1857 }
1858
1859 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
1863 node_info!("anvil_autoImpersonateAccount");
1864 self.backend.auto_impersonate_account(enabled);
1865 Ok(())
1866 }
1867
1868 pub async fn anvil_impersonate_signature(
1870 &self,
1871 signature: Bytes,
1872 address: Address,
1873 ) -> Result<()> {
1874 node_info!("anvil_impersonateSignature");
1875 self.backend.impersonate_signature(signature, address).await
1876 }
1877
1878 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
1882 node_info!("anvil_getAutomine");
1883 Ok(self.miner.is_auto_mine())
1884 }
1885
1886 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
1890 node_info!("anvil_getIntervalMining");
1891 Ok(self.miner.get_interval())
1892 }
1893
1894 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
1899 node_info!("evm_setAutomine");
1900 if self.miner.is_auto_mine() {
1901 if enable_automine {
1902 return Ok(());
1903 }
1904 self.miner.set_mining_mode(MiningMode::None);
1905 } else if enable_automine {
1906 let listener = self.pool.add_ready_listener();
1907 let mode = MiningMode::instant(1_000, listener);
1908 self.miner.set_mining_mode(mode);
1909 }
1910 Ok(())
1911 }
1912
1913 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
1917 node_info!("anvil_mine");
1918 let interval = interval.map(|i| i.to::<u64>());
1919 let blocks = num_blocks.unwrap_or(U256::from(1));
1920 if blocks.is_zero() {
1921 return Ok(());
1922 }
1923
1924 self.on_blocking_task(|this| async move {
1925 for _ in 0..blocks.to::<u64>() {
1927 if let Some(interval) = interval {
1929 this.backend.time().increase_time(interval);
1930 }
1931 this.mine_one().await;
1932 }
1933 Ok(())
1934 })
1935 .await?;
1936
1937 Ok(())
1938 }
1939
1940 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
1944 node_info!("evm_setIntervalMining");
1945 let mining_mode = if secs == 0 {
1946 MiningMode::None
1947 } else {
1948 let block_time = Duration::from_secs(secs);
1949
1950 self.backend.update_interval_mine_block_time(block_time);
1952
1953 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
1954 };
1955 self.miner.set_mining_mode(mining_mode);
1956 Ok(())
1957 }
1958
1959 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
1963 node_info!("anvil_dropTransaction");
1964 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
1965 }
1966
1967 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
1971 node_info!("anvil_dropAllTransactions");
1972 self.pool.clear();
1973 Ok(())
1974 }
1975
1976 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
1982 self.reset_instance_id();
1983 node_info!("anvil_reset");
1984 if let Some(forking) = forking {
1985 self.backend.reset_fork(forking).await
1987 } else {
1988 self.backend.reset_to_in_mem().await
1991 }
1992 }
1993
1994 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
1995 node_info!("anvil_setChainId");
1996 self.backend.set_chain_id(chain_id);
1997 Ok(())
1998 }
1999
2000 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
2004 node_info!("anvil_setBalance");
2005 self.backend.set_balance(address, balance).await?;
2006 Ok(())
2007 }
2008
2009 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
2013 node_info!("anvil_addBalance");
2014 let current_balance = self.backend.get_balance(address, None).await?;
2015 self.backend.set_balance(address, current_balance + balance).await?;
2016 Ok(())
2017 }
2018
2019 async fn find_erc20_storage_slot(
2036 &self,
2037 token_address: Address,
2038 calldata: Bytes,
2039 expected_value: U256,
2040 ) -> Result<B256> {
2041 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2042
2043 let access_list_result =
2045 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2046 let access_list = access_list_result.access_list;
2047
2048 for item in access_list.0 {
2051 if item.address != token_address {
2052 continue;
2053 };
2054 for slot in &item.storage_keys {
2055 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2056 (*slot, B256::from(expected_value.to_be_bytes())),
2057 ));
2058
2059 let state_override = StateOverridesBuilder::default()
2060 .append(token_address, account_override)
2061 .build();
2062
2063 let evm_override = EvmOverrides::state(Some(state_override));
2064
2065 let Ok(result) =
2066 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2067 else {
2068 continue;
2070 };
2071
2072 let Ok(result_value) = U256::abi_decode(&result) else {
2073 continue;
2075 };
2076
2077 if result_value == expected_value {
2078 return Ok(*slot);
2079 }
2080 }
2081 }
2082
2083 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2084 }
2085
2086 pub async fn anvil_deal_erc20(
2090 &self,
2091 address: Address,
2092 token_address: Address,
2093 balance: U256,
2094 ) -> Result<()> {
2095 node_info!("anvil_dealERC20");
2096
2097 sol! {
2098 #[sol(rpc)]
2099 contract IERC20 {
2100 function balanceOf(address target) external view returns (uint256);
2101 }
2102 }
2103
2104 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2105
2106 let slot =
2108 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2109 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2110 })?;
2111
2112 self.anvil_set_storage_at(
2114 token_address,
2115 U256::from_be_bytes(slot.0),
2116 B256::from(balance.to_be_bytes()),
2117 )
2118 .await?;
2119
2120 Ok(())
2121 }
2122
2123 pub async fn anvil_set_erc20_allowance(
2127 &self,
2128 owner: Address,
2129 spender: Address,
2130 token_address: Address,
2131 amount: U256,
2132 ) -> Result<()> {
2133 node_info!("anvil_setERC20Allowance");
2134
2135 sol! {
2136 #[sol(rpc)]
2137 contract IERC20 {
2138 function allowance(address owner, address spender) external view returns (uint256);
2139 }
2140 }
2141
2142 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2143
2144 let slot =
2146 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2147 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2148 })?;
2149
2150 self.anvil_set_storage_at(
2152 token_address,
2153 U256::from_be_bytes(slot.0),
2154 B256::from(amount.to_be_bytes()),
2155 )
2156 .await?;
2157
2158 Ok(())
2159 }
2160
2161 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2165 node_info!("anvil_setCode");
2166 self.backend.set_code(address, code).await?;
2167 Ok(())
2168 }
2169
2170 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2174 node_info!("anvil_setNonce");
2175 self.backend.set_nonce(address, nonce).await?;
2176 Ok(())
2177 }
2178
2179 pub async fn anvil_set_storage_at(
2183 &self,
2184 address: Address,
2185 slot: U256,
2186 val: B256,
2187 ) -> Result<bool> {
2188 node_info!("anvil_setStorageAt");
2189 self.backend.set_storage_at(address, slot, val).await?;
2190 Ok(true)
2191 }
2192
2193 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2197 node_info!("anvil_setLoggingEnabled");
2198 self.logger.set_enabled(enable);
2199 Ok(())
2200 }
2201
2202 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2206 node_info!("anvil_setMinGasPrice");
2207 if self.backend.is_eip1559() {
2208 return Err(RpcError::invalid_params(
2209 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2210 )
2211 .into());
2212 }
2213 self.backend.set_gas_price(gas.to());
2214 Ok(())
2215 }
2216
2217 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2221 node_info!("anvil_setNextBlockBaseFeePerGas");
2222 if !self.backend.is_eip1559() {
2223 return Err(RpcError::invalid_params(
2224 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2225 )
2226 .into());
2227 }
2228 self.backend.set_base_fee(basefee.to());
2229 Ok(())
2230 }
2231
2232 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2236 node_info!("anvil_setCoinbase");
2237 self.backend.set_coinbase(address);
2238 Ok(())
2239 }
2240
2241 pub async fn anvil_dump_state(
2246 &self,
2247 preserve_historical_states: Option<bool>,
2248 ) -> Result<Bytes> {
2249 node_info!("anvil_dumpState");
2250 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2251 }
2252
2253 pub async fn serialized_state(
2255 &self,
2256 preserve_historical_states: bool,
2257 ) -> Result<SerializableState> {
2258 self.backend.serialized_state(preserve_historical_states).await
2259 }
2260
2261 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2266 node_info!("anvil_loadState");
2267 self.backend.load_state_bytes(buf).await
2268 }
2269
2270 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2274 node_info!("anvil_nodeInfo");
2275
2276 let env = self.backend.env().read();
2277 let fork_config = self.backend.get_fork();
2278 let tx_order = self.transaction_order.read();
2279 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2280
2281 Ok(NodeInfo {
2282 current_block_number: self.backend.best_number(),
2283 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2284 current_block_hash: self.backend.best_hash(),
2285 hard_fork: hard_fork.to_string(),
2286 transaction_order: match *tx_order {
2287 TransactionOrder::Fifo => "fifo".to_string(),
2288 TransactionOrder::Fees => "fees".to_string(),
2289 },
2290 environment: NodeEnvironment {
2291 base_fee: self.backend.base_fee() as u128,
2292 chain_id: self.backend.chain_id().to::<u64>(),
2293 gas_limit: self.backend.gas_limit(),
2294 gas_price: self.gas_price(),
2295 },
2296 fork_config: fork_config
2297 .map(|fork| {
2298 let config = fork.config.read();
2299
2300 NodeForkConfig {
2301 fork_url: Some(config.eth_rpc_url.clone()),
2302 fork_block_number: Some(config.block_number),
2303 fork_retry_backoff: Some(config.backoff.as_millis()),
2304 }
2305 })
2306 .unwrap_or_default(),
2307 })
2308 }
2309
2310 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2314 node_info!("anvil_metadata");
2315 let fork_config = self.backend.get_fork();
2316
2317 Ok(Metadata {
2318 client_version: CLIENT_VERSION.to_string(),
2319 chain_id: self.backend.chain_id().to::<u64>(),
2320 latest_block_hash: self.backend.best_hash(),
2321 latest_block_number: self.backend.best_number(),
2322 instance_id: *self.instance_id.read(),
2323 forked_network: fork_config.map(|cfg| ForkedNetwork {
2324 chain_id: cfg.chain_id(),
2325 fork_block_number: cfg.block_number(),
2326 fork_block_hash: cfg.block_hash(),
2327 }),
2328 snapshots: self.backend.list_state_snapshots(),
2329 })
2330 }
2331
2332 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2333 node_info!("anvil_removePoolTransactions");
2334 self.pool.remove_transactions_by_address(address);
2335 Ok(())
2336 }
2337
2338 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2352 node_info!("anvil_reorg");
2353 let depth = options.depth;
2354 let tx_block_pairs = options.tx_block_pairs;
2355
2356 let current_height = self.backend.best_number();
2358 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2359 RpcError::invalid_params(format!(
2360 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2361 )),
2362 ))?;
2363
2364 let common_block =
2366 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2367
2368 let block_pool_txs = if tx_block_pairs.is_empty() {
2371 HashMap::default()
2372 } else {
2373 let mut pairs = tx_block_pairs;
2374
2375 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2377 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2378 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2379 depth - 1
2380 ))));
2381 }
2382
2383 pairs.sort_by_key(|a| a.1);
2385
2386 let mut nonces: HashMap<Address, u64> = HashMap::default();
2389
2390 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2391 for pair in pairs {
2392 let (tx_data, block_index) = pair;
2393
2394 let pending = match tx_data {
2395 TransactionData::Raw(bytes) => {
2396 let mut data = bytes.as_ref();
2397 let decoded = TypedTransaction::decode_2718(&mut data)
2398 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2399 PendingTransaction::new(decoded)?
2400 }
2401
2402 TransactionData::JSON(req) => {
2403 let mut tx_req = WithOtherFields::new(req);
2404 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2405 self.accounts()?
2406 .first()
2407 .copied()
2408 .ok_or(BlockchainError::NoSignerAvailable)
2409 })?;
2410
2411 let curr_nonce = nonces.entry(from).or_insert(
2413 self.get_transaction_count(
2414 from,
2415 Some(common_block.header.number.into()),
2416 )
2417 .await?,
2418 );
2419
2420 if tx_req.gas.is_none()
2422 && let Ok(gas) = self
2423 .estimate_gas(tx_req.clone(), None, EvmOverrides::default())
2424 .await
2425 {
2426 tx_req.gas = Some(gas.to());
2427 }
2428
2429 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2431
2432 *curr_nonce += 1;
2434
2435 if self.is_impersonated(from) {
2437 let bypass_signature = self.impersonated_signature(&typed);
2438 let transaction =
2439 sign::build_typed_transaction(typed, bypass_signature)?;
2440 self.ensure_typed_transaction_supported(&transaction)?;
2441 PendingTransaction::with_impersonated(transaction, from)
2442 } else {
2443 let transaction = self.sign_request(&from, typed)?;
2444 self.ensure_typed_transaction_supported(&transaction)?;
2445 PendingTransaction::new(transaction)?
2446 }
2447 }
2448 };
2449
2450 let pooled = PoolTransaction::new(pending);
2451 txs.entry(block_index).or_default().push(Arc::new(pooled));
2452 }
2453
2454 txs
2455 };
2456
2457 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2458 Ok(())
2459 }
2460
2461 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2472 node_info!("anvil_rollback");
2473 let depth = depth.unwrap_or(1);
2474
2475 let current_height = self.backend.best_number();
2477 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2478 RpcError::invalid_params(format!(
2479 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2480 )),
2481 ))?;
2482
2483 let common_block =
2485 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2486
2487 self.backend.rollback(common_block).await?;
2488 Ok(())
2489 }
2490
2491 pub async fn evm_snapshot(&self) -> Result<U256> {
2495 node_info!("evm_snapshot");
2496 Ok(self.backend.create_state_snapshot().await)
2497 }
2498
2499 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2504 node_info!("evm_revert");
2505 self.backend.revert_state_snapshot(id).await
2506 }
2507
2508 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2512 node_info!("evm_increaseTime");
2513 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2514 }
2515
2516 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2520 node_info!("evm_setNextBlockTimestamp");
2521 self.backend.time().set_next_block_timestamp(seconds)
2522 }
2523
2524 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2529 node_info!("evm_setTime");
2530 let now = self.backend.time().current_call_timestamp();
2531 self.backend.time().reset(timestamp);
2532
2533 let offset = timestamp.saturating_sub(now);
2535 Ok(Duration::from_millis(offset).as_secs())
2536 }
2537
2538 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2542 node_info!("evm_setBlockGasLimit");
2543 self.backend.set_gas_limit(gas_limit.to());
2544 Ok(true)
2545 }
2546
2547 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2551 node_info!("anvil_setBlockTimestampInterval");
2552 self.backend.time().set_block_timestamp_interval(seconds);
2553 Ok(())
2554 }
2555
2556 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2560 node_info!("anvil_removeBlockTimestampInterval");
2561 Ok(self.backend.time().remove_block_timestamp_interval())
2562 }
2563
2564 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2571 node_info!("evm_mine");
2572
2573 self.do_evm_mine(opts).await?;
2574
2575 Ok("0x0".to_string())
2576 }
2577
2578 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2588 node_info!("evm_mine_detailed");
2589
2590 let mined_blocks = self.do_evm_mine(opts).await?;
2591
2592 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2593
2594 let latest = self.backend.best_number();
2595 for offset in (0..mined_blocks).rev() {
2596 let block_num = latest - offset;
2597 if let Some(mut block) =
2598 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2599 {
2600 let block_txs = match block.transactions_mut() {
2601 BlockTransactions::Full(txs) => txs,
2602 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2603 };
2604 for tx in block_txs.iter_mut() {
2605 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2606 && let Some(output) = receipt.out
2607 {
2608 if !receipt
2610 .inner
2611 .inner
2612 .as_receipt_with_bloom()
2613 .receipt
2614 .status
2615 .coerce_status()
2616 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2617 {
2618 tx.other.insert(
2619 "revertReason".to_string(),
2620 serde_json::to_value(reason).expect("Infallible"),
2621 );
2622 }
2623 tx.other.insert(
2624 "output".to_string(),
2625 serde_json::to_value(output).expect("Infallible"),
2626 );
2627 }
2628 }
2629 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2630 blocks.push(block);
2631 }
2632 }
2633
2634 Ok(blocks)
2635 }
2636
2637 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2641 node_info!("anvil_setBlock");
2642 self.backend.set_block_number(block_number);
2643 Ok(())
2644 }
2645
2646 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2650 node_info!("anvil_setRpcUrl");
2651 if let Some(fork) = self.backend.get_fork() {
2652 let mut config = fork.config.write();
2653 let new_provider = Arc::new(
2655 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2656 |_| {
2657 TransportErrorKind::custom_str(
2658 format!("Failed to parse invalid url {url}").as_str(),
2659 )
2660 },
2661 )?, );
2664 config.provider = new_provider;
2665 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2666 config.eth_rpc_url = url;
2667 }
2668 Ok(())
2669 }
2670
2671 pub async fn anvil_enable_traces(&self) -> Result<()> {
2676 node_info!("anvil_enableTraces");
2677 Err(BlockchainError::RpcUnimplemented)
2678 }
2679
2680 pub async fn eth_send_unsigned_transaction(
2684 &self,
2685 request: WithOtherFields<TransactionRequest>,
2686 ) -> Result<TxHash> {
2687 node_info!("eth_sendUnsignedTransaction");
2688 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2690
2691 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2692
2693 let request = self.build_typed_tx_request(request, nonce)?;
2694
2695 let bypass_signature = self.impersonated_signature(&request);
2696 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2697
2698 self.ensure_typed_transaction_supported(&transaction)?;
2699
2700 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2701
2702 self.backend.validate_pool_transaction(&pending_transaction).await?;
2704
2705 let requires = required_marker(nonce, on_chain_nonce, from);
2706 let provides = vec![to_marker(nonce, from)];
2707
2708 self.add_pending_transaction(pending_transaction, requires, provides)
2709 }
2710
2711 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2717 node_info!("txpool_status");
2718 Ok(self.pool.txpool_status())
2719 }
2720
2721 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2728 node_info!("txpool_inspect");
2729 let mut inspect = TxpoolInspect::default();
2730
2731 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2732 let tx = &tx.pending_transaction.transaction;
2733 let to = tx.to();
2734 let gas_price = tx.gas_price();
2735 let value = tx.value();
2736 let gas = tx.gas_limit();
2737 TxpoolInspectSummary { to, value, gas, gas_price }
2738 }
2739
2740 for pending in self.pool.ready_transactions() {
2747 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2748 let key = pending.pending_transaction.nonce().to_string();
2749 entry.insert(key, convert(pending));
2750 }
2751 for queued in self.pool.pending_transactions() {
2752 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2753 let key = queued.pending_transaction.nonce().to_string();
2754 entry.insert(key, convert(queued));
2755 }
2756 Ok(inspect)
2757 }
2758
2759 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2766 node_info!("txpool_content");
2767 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2768 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2769 let from = *tx.pending_transaction.sender();
2770 let tx = transaction_build(
2771 Some(tx.hash()),
2772 tx.pending_transaction.transaction.clone(),
2773 None,
2774 None,
2775 None,
2776 );
2777
2778 let WithOtherFields { inner: mut tx, other } = tx.0;
2779
2780 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2783
2784 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2785
2786 Ok(tx)
2787 }
2788
2789 for pending in self.pool.ready_transactions() {
2790 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2791 let key = pending.pending_transaction.nonce().to_string();
2792 entry.insert(key, convert(pending)?);
2793 }
2794 for queued in self.pool.pending_transactions() {
2795 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2796 let key = queued.pending_transaction.nonce().to_string();
2797 entry.insert(key, convert(queued)?);
2798 }
2799
2800 Ok(content)
2801 }
2802}
2803
2804impl EthApi {
2806 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2812 node_info!("wallet_getCapabilities");
2813 Ok(self.backend.get_capabilities())
2814 }
2815
2816 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2820 node_info!("anvil_addCapability");
2821 self.backend.add_capability(address);
2822 Ok(())
2823 }
2824
2825 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2826 node_info!("anvil_setExecutor");
2827 self.backend.set_executor(executor_pk)
2828 }
2829}
2830
2831impl EthApi {
2832 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2834 where
2835 C: FnOnce(Self) -> F,
2836 F: Future<Output = Result<R>> + Send + 'static,
2837 R: Send + 'static,
2838 {
2839 let (tx, rx) = oneshot::channel();
2840 let this = self.clone();
2841 let f = c(this);
2842 tokio::task::spawn_blocking(move || {
2843 tokio::runtime::Handle::current().block_on(async move {
2844 let res = f.await;
2845 let _ = tx.send(res);
2846 })
2847 });
2848 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2849 }
2850
2851 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2853 let mut blocks_to_mine = 1u64;
2854
2855 if let Some(opts) = opts {
2856 let timestamp = match opts {
2857 MineOptions::Timestamp(timestamp) => timestamp,
2858 MineOptions::Options { timestamp, blocks } => {
2859 if let Some(blocks) = blocks {
2860 blocks_to_mine = blocks;
2861 }
2862 timestamp
2863 }
2864 };
2865 if let Some(timestamp) = timestamp {
2866 self.evm_set_next_block_timestamp(timestamp)?;
2868 }
2869 }
2870
2871 self.on_blocking_task(|this| async move {
2874 for _ in 0..blocks_to_mine {
2876 this.mine_one().await;
2877 }
2878 Ok(())
2879 })
2880 .await?;
2881
2882 Ok(blocks_to_mine)
2883 }
2884
2885 async fn do_estimate_gas(
2886 &self,
2887 request: WithOtherFields<TransactionRequest>,
2888 block_number: Option<BlockId>,
2889 overrides: EvmOverrides,
2890 ) -> Result<u128> {
2891 let block_request = self.block_request(block_number).await?;
2892 if let BlockRequest::Number(number) = block_request
2894 && let Some(fork) = self.get_fork()
2895 && fork.predates_fork(number)
2896 {
2897 if overrides.has_state() || overrides.has_block() {
2898 return Err(BlockchainError::EvmOverrideError(
2899 "not available on past forked blocks".to_string(),
2900 ));
2901 }
2902 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
2903 }
2904
2905 self.on_blocking_task(|this| async move {
2908 this.backend
2909 .with_database_at(Some(block_request), |state, mut block| {
2910 let mut cache_db = CacheDB::new(state);
2911 if let Some(state_overrides) = overrides.state {
2912 apply_state_overrides(
2913 state_overrides.into_iter().collect(),
2914 &mut cache_db,
2915 )?;
2916 }
2917 if let Some(block_overrides) = overrides.block {
2918 cache_db.apply_block_overrides(*block_overrides, &mut block);
2919 }
2920 this.do_estimate_gas_with_state(request, &cache_db, block)
2921 })
2922 .await?
2923 })
2924 .await
2925 }
2926
2927 fn do_estimate_gas_with_state(
2931 &self,
2932 mut request: WithOtherFields<TransactionRequest>,
2933 state: &dyn DatabaseRef,
2934 block_env: BlockEnv,
2935 ) -> Result<u128> {
2936 let to = request.to.as_ref().and_then(TxKind::to);
2939
2940 let maybe_transfer = (request.input.input().is_none()
2942 || request.input.input().is_some_and(|data| data.is_empty()))
2943 && request.authorization_list.is_none()
2944 && request.access_list.is_none()
2945 && request.blob_versioned_hashes.is_none();
2946
2947 if maybe_transfer
2948 && let Some(to) = to
2949 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
2950 && target_code.as_ref().is_empty()
2951 {
2952 return Ok(MIN_TRANSACTION_GAS);
2953 }
2954
2955 let fees = FeeDetails::new(
2956 request.gas_price,
2957 request.max_fee_per_gas,
2958 request.max_priority_fee_per_gas,
2959 request.max_fee_per_blob_gas,
2960 )?
2961 .or_zero_fees();
2962
2963 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
2966
2967 let gas_price = fees.gas_price.unwrap_or_default();
2968 if gas_price > 0
2970 && let Some(from) = request.from
2971 {
2972 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
2973 if let Some(value) = request.value {
2974 if value > available_funds {
2975 return Err(InvalidTransactionError::InsufficientFunds.into());
2976 }
2977 available_funds -= value;
2979 }
2980 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
2982 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
2983 }
2984
2985 let mut call_to_estimate = request.clone();
2986 call_to_estimate.gas = Some(highest_gas_limit as u64);
2987
2988 let ethres =
2990 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
2991
2992 let gas_used = match ethres.try_into()? {
2993 GasEstimationCallResult::Success(gas) => Ok(gas),
2994 GasEstimationCallResult::OutOfGas => {
2995 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
2996 }
2997 GasEstimationCallResult::Revert(output) => {
2998 Err(InvalidTransactionError::Revert(output).into())
2999 }
3000 GasEstimationCallResult::EvmError(err) => {
3001 warn!(target: "node", "estimation failed due to {:?}", err);
3002 Err(BlockchainError::EvmError(err))
3003 }
3004 }?;
3005
3006 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3013
3014 let mut mid_gas_limit =
3016 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3017
3018 while (highest_gas_limit - lowest_gas_limit) > 1 {
3020 request.gas = Some(mid_gas_limit as u64);
3021 let ethres = self.backend.call_with_state(
3022 &state,
3023 request.clone(),
3024 fees.clone(),
3025 block_env.clone(),
3026 );
3027
3028 match ethres.try_into()? {
3029 GasEstimationCallResult::Success(_) => {
3030 highest_gas_limit = mid_gas_limit;
3034 }
3035 GasEstimationCallResult::OutOfGas
3036 | GasEstimationCallResult::Revert(_)
3037 | GasEstimationCallResult::EvmError(_) => {
3038 lowest_gas_limit = mid_gas_limit;
3045 }
3046 };
3047 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3049 }
3050
3051 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3052
3053 Ok(highest_gas_limit)
3054 }
3055
3056 pub fn set_transaction_order(&self, order: TransactionOrder) {
3058 *self.transaction_order.write() = order;
3059 }
3060
3061 fn transaction_priority(&self, tx: &TypedTransaction) -> TransactionPriority {
3063 self.transaction_order.read().priority(tx)
3064 }
3065
3066 pub fn chain_id(&self) -> u64 {
3068 self.backend.chain_id().to::<u64>()
3069 }
3070
3071 pub fn get_fork(&self) -> Option<ClientFork> {
3073 self.backend.get_fork()
3074 }
3075
3076 pub fn instance_id(&self) -> B256 {
3078 *self.instance_id.read()
3079 }
3080
3081 pub fn reset_instance_id(&self) {
3083 *self.instance_id.write() = B256::random();
3084 }
3085
3086 #[expect(clippy::borrowed_box)]
3088 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3089 self.signers.iter().find(|signer| signer.is_signer_for(address))
3090 }
3091
3092 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3094 self.backend.new_block_notifications()
3095 }
3096
3097 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3099 self.pool.add_ready_listener()
3100 }
3101
3102 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3104 let (tx, rx) = unbounded_channel();
3105 let mut hashes = self.new_ready_transactions();
3106
3107 let this = self.clone();
3108
3109 tokio::spawn(async move {
3110 while let Some(hash) = hashes.next().await {
3111 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3112 && tx.send(txn).is_err()
3113 {
3114 break;
3115 }
3116 }
3117 });
3118
3119 rx
3120 }
3121
3122 pub fn storage_info(&self) -> StorageInfo {
3124 StorageInfo::new(Arc::clone(&self.backend))
3125 }
3126
3127 pub fn is_fork(&self) -> bool {
3129 self.backend.is_fork()
3130 }
3131
3132 pub async fn mine_one(&self) {
3134 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3135 let outcome = self.backend.mine_block(transactions).await;
3136
3137 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3138 self.pool.on_mined_block(outcome);
3139 }
3140
3141 async fn pending_block(&self) -> AnyRpcBlock {
3143 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3144 let info = self.backend.pending_block(transactions).await;
3145 self.backend.convert_block(info.block)
3146 }
3147
3148 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3150 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3151 let BlockInfo { block, transactions, receipts: _ } =
3152 self.backend.pending_block(transactions).await;
3153
3154 let mut partial_block = self.backend.convert_block(block.clone());
3155
3156 let mut block_transactions = Vec::with_capacity(block.transactions.len());
3157 let base_fee = self.backend.base_fee();
3158
3159 for info in transactions {
3160 let tx = block.transactions.get(info.transaction_index as usize)?.clone();
3161
3162 let tx = transaction_build(
3163 Some(info.transaction_hash),
3164 tx,
3165 Some(&block),
3166 Some(info),
3167 Some(base_fee),
3168 );
3169 block_transactions.push(tx);
3170 }
3171
3172 partial_block.transactions = BlockTransactions::from(block_transactions);
3173
3174 Some(partial_block)
3175 }
3176
3177 fn build_typed_tx_request(
3178 &self,
3179 request: WithOtherFields<TransactionRequest>,
3180 nonce: u64,
3181 ) -> Result<TypedTransactionRequest> {
3182 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
3183 let max_fee_per_gas = request.max_fee_per_gas;
3184 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
3185 let gas_price = request.gas_price;
3186
3187 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
3188 let from = request.from;
3189
3190 let request = match transaction_request_to_typed(request) {
3191 Some(TypedTransactionRequest::Legacy(mut m)) => {
3192 m.nonce = nonce;
3193 m.chain_id = Some(chain_id);
3194 m.gas_limit = gas_limit;
3195 if gas_price.is_none() {
3196 m.gas_price = self.gas_price();
3197 }
3198 TypedTransactionRequest::Legacy(m)
3199 }
3200 Some(TypedTransactionRequest::EIP2930(mut m)) => {
3201 m.nonce = nonce;
3202 m.chain_id = chain_id;
3203 m.gas_limit = gas_limit;
3204 if gas_price.is_none() {
3205 m.gas_price = self.gas_price();
3206 }
3207 TypedTransactionRequest::EIP2930(m)
3208 }
3209 Some(TypedTransactionRequest::EIP1559(mut m)) => {
3210 m.nonce = nonce;
3211 m.chain_id = chain_id;
3212 m.gas_limit = gas_limit;
3213 if max_fee_per_gas.is_none() {
3214 m.max_fee_per_gas = self.gas_price();
3215 }
3216 TypedTransactionRequest::EIP1559(m)
3217 }
3218 Some(TypedTransactionRequest::EIP7702(mut m)) => {
3219 m.nonce = nonce;
3220 m.chain_id = chain_id;
3221 m.gas_limit = gas_limit;
3222 if max_fee_per_gas.is_none() {
3223 m.max_fee_per_gas = self.gas_price();
3224 }
3225 TypedTransactionRequest::EIP7702(m)
3226 }
3227 Some(TypedTransactionRequest::EIP4844(m)) => {
3228 TypedTransactionRequest::EIP4844(match m {
3229 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
3231 m.tx.nonce = nonce;
3232 m.tx.chain_id = chain_id;
3233 m.tx.gas_limit = gas_limit;
3234 if max_fee_per_gas.is_none() {
3235 m.tx.max_fee_per_gas = self.gas_price();
3236 }
3237 if max_fee_per_blob_gas.is_none() {
3238 m.tx.max_fee_per_blob_gas = self
3239 .excess_blob_gas_and_price()
3240 .unwrap_or_default()
3241 .map_or(0, |g| g.blob_gasprice)
3242 }
3243 TxEip4844Variant::TxEip4844WithSidecar(m)
3244 }
3245 TxEip4844Variant::TxEip4844(mut tx) => {
3246 if !self.backend.skip_blob_validation(from) {
3247 return Err(BlockchainError::FailedToDecodeTransaction);
3248 }
3249
3250 tx.nonce = nonce;
3252 tx.chain_id = chain_id;
3253 tx.gas_limit = gas_limit;
3254 if max_fee_per_gas.is_none() {
3255 tx.max_fee_per_gas = self.gas_price();
3256 }
3257 if max_fee_per_blob_gas.is_none() {
3258 tx.max_fee_per_blob_gas = self
3259 .excess_blob_gas_and_price()
3260 .unwrap_or_default()
3261 .map_or(0, |g| g.blob_gasprice)
3262 }
3263
3264 TxEip4844Variant::TxEip4844(tx)
3265 }
3266 })
3267 }
3268 Some(TypedTransactionRequest::Deposit(mut m)) => {
3269 m.gas_limit = gas_limit;
3270 TypedTransactionRequest::Deposit(m)
3271 }
3272 None => return Err(BlockchainError::FailedToDecodeTransaction),
3273 };
3274 Ok(request)
3275 }
3276
3277 pub fn is_impersonated(&self, addr: Address) -> bool {
3279 self.backend.cheats().is_impersonated(addr)
3280 }
3281
3282 fn impersonated_signature(&self, request: &TypedTransactionRequest) -> Signature {
3284 match request {
3285 TypedTransactionRequest::Legacy(_) => Signature::from_scalars_and_parity(
3288 B256::with_last_byte(1),
3289 B256::with_last_byte(1),
3290 false,
3291 ),
3292 TypedTransactionRequest::EIP2930(_)
3293 | TypedTransactionRequest::EIP1559(_)
3294 | TypedTransactionRequest::EIP7702(_)
3295 | TypedTransactionRequest::EIP4844(_)
3296 | TypedTransactionRequest::Deposit(_) => Signature::from_scalars_and_parity(
3297 B256::with_last_byte(1),
3298 B256::with_last_byte(1),
3299 false,
3300 ),
3301 }
3302 }
3303
3304 async fn get_transaction_count(
3306 &self,
3307 address: Address,
3308 block_number: Option<BlockId>,
3309 ) -> Result<u64> {
3310 let block_request = self.block_request(block_number).await?;
3311
3312 if let BlockRequest::Number(number) = block_request
3313 && let Some(fork) = self.get_fork()
3314 && fork.predates_fork(number)
3315 {
3316 return Ok(fork.get_nonce(address, number).await?);
3317 }
3318
3319 self.backend.get_nonce(address, block_request).await
3320 }
3321
3322 async fn request_nonce(
3330 &self,
3331 request: &TransactionRequest,
3332 from: Address,
3333 ) -> Result<(u64, u64)> {
3334 let highest_nonce =
3335 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3336 let nonce = request.nonce.unwrap_or(highest_nonce);
3337
3338 Ok((nonce, highest_nonce))
3339 }
3340
3341 fn add_pending_transaction(
3343 &self,
3344 pending_transaction: PendingTransaction,
3345 requires: Vec<TxMarker>,
3346 provides: Vec<TxMarker>,
3347 ) -> Result<TxHash> {
3348 let from = *pending_transaction.sender();
3349 let priority = self.transaction_priority(&pending_transaction.transaction);
3350 let pool_transaction =
3351 PoolTransaction { requires, provides, pending_transaction, priority };
3352 let tx = self.pool.add_transaction(pool_transaction)?;
3353 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3354 Ok(*tx.hash())
3355 }
3356
3357 pub async fn state_root(&self) -> Option<B256> {
3359 self.backend.get_db().read().await.maybe_state_root()
3360 }
3361
3362 fn ensure_typed_transaction_supported(&self, tx: &TypedTransaction) -> Result<()> {
3364 match &tx {
3365 TypedTransaction::EIP2930(_) => self.backend.ensure_eip2930_active(),
3366 TypedTransaction::EIP1559(_) => self.backend.ensure_eip1559_active(),
3367 TypedTransaction::EIP4844(_) => self.backend.ensure_eip4844_active(),
3368 TypedTransaction::EIP7702(_) => self.backend.ensure_eip7702_active(),
3369 TypedTransaction::Deposit(_) => self.backend.ensure_op_deposits_active(),
3370 TypedTransaction::Legacy(_) => Ok(()),
3371 }
3372 }
3373}
3374
3375fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3376 if provided_nonce == on_chain_nonce {
3377 return Vec::new();
3378 }
3379 let prev_nonce = provided_nonce.saturating_sub(1);
3380 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3381}
3382
3383fn convert_transact_out(out: &Option<Output>) -> Bytes {
3384 match out {
3385 None => Default::default(),
3386 Some(Output::Call(out)) => out.to_vec().into(),
3387 Some(Output::Create(out, _)) => out.to_vec().into(),
3388 }
3389}
3390
3391fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3393 let out = convert_transact_out(out);
3394 match exit {
3395 return_ok!() => Ok(out),
3396 return_revert!() => Err(InvalidTransactionError::Revert(Some(out.0.into())).into()),
3397 reason => Err(BlockchainError::EvmError(reason)),
3398 }
3399}
3400
3401fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3403 match transaction_request_to_typed(request.clone()) {
3404 Some(request) => match request {
3405 TypedTransactionRequest::Legacy(req) => match req.to {
3406 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3407 TxKind::Create => MIN_CREATE_GAS,
3408 },
3409 TypedTransactionRequest::EIP1559(req) => match req.to {
3410 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3411 TxKind::Create => MIN_CREATE_GAS,
3412 },
3413 TypedTransactionRequest::EIP7702(req) => {
3414 MIN_TRANSACTION_GAS
3415 + req.authorization_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3416 }
3417 TypedTransactionRequest::EIP2930(req) => match req.to {
3418 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3419 TxKind::Create => MIN_CREATE_GAS,
3420 },
3421 TypedTransactionRequest::EIP4844(_) => MIN_TRANSACTION_GAS,
3422 TypedTransactionRequest::Deposit(req) => match req.to {
3423 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3424 TxKind::Create => MIN_CREATE_GAS,
3425 },
3426 },
3427 _ => MIN_CREATE_GAS,
3430 }
3431}
3432
3433enum GasEstimationCallResult {
3435 Success(u128),
3436 OutOfGas,
3437 Revert(Option<Bytes>),
3438 EvmError(InstructionResult),
3439}
3440
3441impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3445 type Error = BlockchainError;
3446
3447 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3448 match res {
3449 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3451 Ok(Self::OutOfGas)
3452 }
3453 Err(err) => Err(err),
3454 Ok((exit, output, gas, _)) => match exit {
3455 return_ok!() => Ok(Self::Success(gas)),
3456
3457 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3459 InstructionResult::CallTooDeep
3460 | InstructionResult::OutOfFunds
3461 | InstructionResult::CreateInitCodeStartingEF00
3462 | InstructionResult::InvalidEOFInitCode
3463 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3464
3465 InstructionResult::OutOfGas
3467 | InstructionResult::MemoryOOG
3468 | InstructionResult::MemoryLimitOOG
3469 | InstructionResult::PrecompileOOG
3470 | InstructionResult::InvalidOperandOOG
3471 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3472
3473 InstructionResult::OpcodeNotFound
3475 | InstructionResult::CallNotAllowedInsideStatic
3476 | InstructionResult::StateChangeDuringStaticCall
3477 | InstructionResult::InvalidFEOpcode
3478 | InstructionResult::InvalidJump
3479 | InstructionResult::NotActivated
3480 | InstructionResult::StackUnderflow
3481 | InstructionResult::StackOverflow
3482 | InstructionResult::OutOfOffset
3483 | InstructionResult::CreateCollision
3484 | InstructionResult::OverflowPayment
3485 | InstructionResult::PrecompileError
3486 | InstructionResult::NonceOverflow
3487 | InstructionResult::CreateContractSizeLimit
3488 | InstructionResult::CreateContractStartingWithEF
3489 | InstructionResult::CreateInitCodeSizeLimit
3490 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3491 },
3492 }
3493 }
3494}