1use super::{
2 backend::mem::{BlockRequest, DatabaseRef, State, state},
3 sign::build_typed_transaction,
4};
5use crate::{
6 ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
7 eth::{
8 backend::{
9 self,
10 db::SerializableState,
11 mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
12 notifications::NewBlockNotifications,
13 validate::TransactionValidator,
14 },
15 error::{
16 BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
17 },
18 fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
19 macros::node_info,
20 miner::FixedBlockTimeMiner,
21 pool::{
22 Pool,
23 transactions::{
24 PoolTransaction, TransactionOrder, TransactionPriority, TxMarker, to_marker,
25 },
26 },
27 sign::{self, Signer},
28 },
29 filter::{EthFilter, Filters, LogsFilter},
30 mem::transaction_build,
31};
32use alloy_consensus::{
33 Account, Blob,
34 transaction::{Recovered, eip4844::TxEip4844Variant},
35};
36use alloy_dyn_abi::TypedData;
37use alloy_eips::eip2718::Encodable2718;
38use alloy_network::{
39 AnyRpcBlock, AnyRpcTransaction, BlockResponse, Ethereum, NetworkWallet, TransactionBuilder,
40 TransactionResponse, eip2718::Decodable2718,
41};
42use alloy_primitives::{
43 Address, B64, B256, Bytes, Signature, TxHash, TxKind, U64, U256,
44 map::{HashMap, HashSet},
45};
46use alloy_provider::utils::{
47 EIP1559_FEE_ESTIMATION_PAST_BLOCKS, EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE,
48 eip1559_default_estimator,
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, WalletError},
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,
86 channel::{mpsc::Receiver, oneshot},
87};
88use parking_lot::RwLock;
89use revm::{
90 bytecode::Bytecode,
91 context::BlockEnv,
92 context_interface::{block::BlobExcessGasAndPrice, result::Output},
93 database::CacheDB,
94 interpreter::{InstructionResult, return_ok, return_revert},
95 primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
96};
97use std::{sync::Arc, time::Duration};
98use tokio::sync::mpsc::{UnboundedReceiver, unbounded_channel};
99
100pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
102
103#[derive(Clone)]
107pub struct EthApi {
108 pool: Arc<Pool>,
110 pub backend: Arc<backend::mem::Backend>,
113 is_mining: bool,
115 signers: Arc<Vec<Box<dyn Signer>>>,
117 fee_history_cache: FeeHistoryCache,
119 fee_history_limit: u64,
121 miner: Miner,
126 logger: LoggingManager,
128 filters: Filters,
130 transaction_order: Arc<RwLock<TransactionOrder>>,
132 net_listening: bool,
134 instance_id: Arc<RwLock<B256>>,
136}
137
138impl EthApi {
139 #[expect(clippy::too_many_arguments)]
141 pub fn new(
142 pool: Arc<Pool>,
143 backend: Arc<backend::mem::Backend>,
144 signers: Arc<Vec<Box<dyn Signer>>>,
145 fee_history_cache: FeeHistoryCache,
146 fee_history_limit: u64,
147 miner: Miner,
148 logger: LoggingManager,
149 filters: Filters,
150 transactions_order: TransactionOrder,
151 ) -> Self {
152 Self {
153 pool,
154 backend,
155 is_mining: true,
156 signers,
157 fee_history_cache,
158 fee_history_limit,
159 miner,
160 logger,
161 filters,
162 net_listening: true,
163 transaction_order: Arc::new(RwLock::new(transactions_order)),
164 instance_id: Arc::new(RwLock::new(B256::random())),
165 }
166 }
167
168 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
170 trace!(target: "rpc::api", "executing eth request");
171 let response = match request.clone() {
172 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
173 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
174 EthRequest::EthGetAccount(addr, block) => {
175 self.get_account(addr, block).await.to_rpc_result()
176 }
177 EthRequest::EthGetAccountInfo(addr, block) => {
178 self.get_account_info(addr, block).await.to_rpc_result()
179 }
180 EthRequest::EthGetBalance(addr, block) => {
181 self.balance(addr, block).await.to_rpc_result()
182 }
183 EthRequest::EthGetTransactionByHash(hash) => {
184 self.transaction_by_hash(hash).await.to_rpc_result()
185 }
186 EthRequest::EthSendTransaction(request) => {
187 self.send_transaction(*request).await.to_rpc_result()
188 }
189 EthRequest::EthSendTransactionSync(request) => {
190 self.send_transaction_sync(*request).await.to_rpc_result()
191 }
192 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
193 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
194 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
195 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
196 EthRequest::EthMaxPriorityFeePerGas(_) => {
197 self.gas_max_priority_fee_per_gas().to_rpc_result()
198 }
199 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
200 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
201 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
202 EthRequest::EthGetStorageAt(addr, slot, block) => {
203 self.storage_at(addr, slot, block).await.to_rpc_result()
204 }
205 EthRequest::EthGetBlockByHash(hash, full) => {
206 if full {
207 self.block_by_hash_full(hash).await.to_rpc_result()
208 } else {
209 self.block_by_hash(hash).await.to_rpc_result()
210 }
211 }
212 EthRequest::EthGetBlockByNumber(num, full) => {
213 if full {
214 self.block_by_number_full(num).await.to_rpc_result()
215 } else {
216 self.block_by_number(num).await.to_rpc_result()
217 }
218 }
219 EthRequest::EthGetTransactionCount(addr, block) => {
220 self.transaction_count(addr, block).await.to_rpc_result()
221 }
222 EthRequest::EthGetTransactionCountByHash(hash) => {
223 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
224 }
225 EthRequest::EthGetTransactionCountByNumber(num) => {
226 self.block_transaction_count_by_number(num).await.to_rpc_result()
227 }
228 EthRequest::EthGetUnclesCountByHash(hash) => {
229 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
230 }
231 EthRequest::EthGetUnclesCountByNumber(num) => {
232 self.block_uncles_count_by_number(num).await.to_rpc_result()
233 }
234 EthRequest::EthGetCodeAt(addr, block) => {
235 self.get_code(addr, block).await.to_rpc_result()
236 }
237 EthRequest::EthGetProof(addr, keys, block) => {
238 self.get_proof(addr, keys, block).await.to_rpc_result()
239 }
240 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
241 EthRequest::PersonalSign(content, addr) => {
242 self.sign(addr, content).await.to_rpc_result()
243 }
244 EthRequest::EthSignTransaction(request) => {
245 self.sign_transaction(*request).await.to_rpc_result()
246 }
247 EthRequest::EthSignTypedData(addr, data) => {
248 self.sign_typed_data(addr, data).await.to_rpc_result()
249 }
250 EthRequest::EthSignTypedDataV3(addr, data) => {
251 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
252 }
253 EthRequest::EthSignTypedDataV4(addr, data) => {
254 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
255 }
256 EthRequest::EthSendRawTransaction(tx) => {
257 self.send_raw_transaction(tx).await.to_rpc_result()
258 }
259 EthRequest::EthSendRawTransactionSync(tx) => {
260 self.send_raw_transaction_sync(tx).await.to_rpc_result()
261 }
262 EthRequest::EthCall(call, block, state_override, block_overrides) => self
263 .call(call, block, EvmOverrides::new(state_override, block_overrides))
264 .await
265 .to_rpc_result(),
266 EthRequest::EthSimulateV1(simulation, block) => {
267 self.simulate_v1(simulation, block).await.to_rpc_result()
268 }
269 EthRequest::EthCreateAccessList(call, block) => {
270 self.create_access_list(call, block).await.to_rpc_result()
271 }
272 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
273 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
274 .await
275 .to_rpc_result(),
276 EthRequest::EthGetRawTransactionByHash(hash) => {
277 self.raw_transaction(hash).await.to_rpc_result()
278 }
279 EthRequest::GetBlobByHash(hash) => {
280 self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
281 }
282 EthRequest::GetBlobByTransactionHash(hash) => {
283 self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
284 }
285 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
286 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
287 }
288 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
289 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
290 }
291 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
292 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
293 }
294 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
295 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
296 }
297 EthRequest::EthGetTransactionReceipt(tx) => {
298 self.transaction_receipt(tx).await.to_rpc_result()
299 }
300 EthRequest::EthGetBlockReceipts(number) => {
301 self.block_receipts(number).await.to_rpc_result()
302 }
303 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
304 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
305 }
306 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
307 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
308 }
309 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
310 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
311 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
312 EthRequest::EthSubmitWork(nonce, pow, digest) => {
313 self.submit_work(nonce, pow, digest).to_rpc_result()
314 }
315 EthRequest::EthSubmitHashRate(rate, id) => {
316 self.submit_hashrate(rate, id).to_rpc_result()
317 }
318 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
319 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
320 }
321 EthRequest::DebugGetRawTransaction(hash) => {
323 self.raw_transaction(hash).await.to_rpc_result()
324 }
325 EthRequest::DebugTraceTransaction(tx, opts) => {
327 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
328 }
329 EthRequest::DebugTraceCall(tx, block, opts) => {
331 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
332 }
333 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
334 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
335 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
336 EthRequest::ImpersonateAccount(addr) => {
337 self.anvil_impersonate_account(addr).await.to_rpc_result()
338 }
339 EthRequest::StopImpersonatingAccount(addr) => {
340 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
341 }
342 EthRequest::AutoImpersonateAccount(enable) => {
343 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
344 }
345 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
346 EthRequest::Mine(blocks, interval) => {
347 self.anvil_mine(blocks, interval).await.to_rpc_result()
348 }
349 EthRequest::SetAutomine(enabled) => {
350 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
351 }
352 EthRequest::SetIntervalMining(interval) => {
353 self.anvil_set_interval_mining(interval).to_rpc_result()
354 }
355 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
356 EthRequest::DropTransaction(tx) => {
357 self.anvil_drop_transaction(tx).await.to_rpc_result()
358 }
359 EthRequest::DropAllTransactions() => {
360 self.anvil_drop_all_transactions().await.to_rpc_result()
361 }
362 EthRequest::Reset(fork) => {
363 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
364 }
365 EthRequest::SetBalance(addr, val) => {
366 self.anvil_set_balance(addr, val).await.to_rpc_result()
367 }
368 EthRequest::AddBalance(addr, val) => {
369 self.anvil_add_balance(addr, val).await.to_rpc_result()
370 }
371 EthRequest::DealERC20(addr, token_addr, val) => {
372 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
373 }
374 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
375 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
376 .await
377 .to_rpc_result(),
378 EthRequest::SetCode(addr, code) => {
379 self.anvil_set_code(addr, code).await.to_rpc_result()
380 }
381 EthRequest::SetNonce(addr, nonce) => {
382 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
383 }
384 EthRequest::SetStorageAt(addr, slot, val) => {
385 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
386 }
387 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
388 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
389 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
390 EthRequest::SetMinGasPrice(gas) => {
391 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
392 }
393 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
394 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
395 }
396 EthRequest::DumpState(preserve_historical_states) => self
397 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
398 .await
399 .to_rpc_result(),
400 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
401 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
402 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
403 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
404 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
405 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
406 EthRequest::EvmSetNextBlockTimeStamp(time) => {
407 if time >= U256::from(u64::MAX) {
408 return ResponseResult::Error(RpcError::invalid_params(
409 "The timestamp is too big",
410 ));
411 }
412 let time = time.to::<u64>();
413 self.evm_set_next_block_timestamp(time).to_rpc_result()
414 }
415 EthRequest::EvmSetTime(timestamp) => {
416 if timestamp >= U256::from(u64::MAX) {
417 return ResponseResult::Error(RpcError::invalid_params(
418 "The timestamp is too big",
419 ));
420 }
421 let time = timestamp.to::<u64>();
422 self.evm_set_time(time).to_rpc_result()
423 }
424 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
425 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
426 }
427 EthRequest::EvmSetBlockTimeStampInterval(time) => {
428 self.evm_set_block_timestamp_interval(time).to_rpc_result()
429 }
430 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
431 self.evm_remove_block_timestamp_interval().to_rpc_result()
432 }
433 EthRequest::EvmMine(mine) => {
434 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
435 }
436 EthRequest::EvmMineDetailed(mine) => {
437 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
438 }
439 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
440 EthRequest::EthSendUnsignedTransaction(tx) => {
441 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
442 }
443 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
444 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
445 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
446 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
447 EthRequest::EthNewPendingTransactionFilter(_) => {
448 self.new_pending_transaction_filter().await.to_rpc_result()
449 }
450 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
451 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
452 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
453 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
454 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
455 EthRequest::ErigonGetHeaderByNumber(num) => {
456 self.erigon_get_header_by_number(num).await.to_rpc_result()
457 }
458 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
459 EthRequest::OtsGetInternalOperations(hash) => {
460 self.ots_get_internal_operations(hash).await.to_rpc_result()
461 }
462 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
463 EthRequest::OtsTraceTransaction(hash) => {
464 self.ots_trace_transaction(hash).await.to_rpc_result()
465 }
466 EthRequest::OtsGetTransactionError(hash) => {
467 self.ots_get_transaction_error(hash).await.to_rpc_result()
468 }
469 EthRequest::OtsGetBlockDetails(num) => {
470 self.ots_get_block_details(num).await.to_rpc_result()
471 }
472 EthRequest::OtsGetBlockDetailsByHash(hash) => {
473 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
474 }
475 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
476 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
477 }
478 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
479 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
480 }
481 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
482 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
483 }
484 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
485 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
486 }
487 EthRequest::OtsGetContractCreator(address) => {
488 self.ots_get_contract_creator(address).await.to_rpc_result()
489 }
490 EthRequest::RemovePoolTransactions(address) => {
491 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
492 }
493 EthRequest::Reorg(reorg_options) => {
494 self.anvil_reorg(reorg_options).await.to_rpc_result()
495 }
496 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
497 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
498 EthRequest::WalletSendTransaction(tx) => {
499 self.wallet_send_transaction(*tx).await.to_rpc_result()
500 }
501 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
502 EthRequest::AnvilSetExecutor(executor_pk) => {
503 self.anvil_set_executor(executor_pk).to_rpc_result()
504 }
505 };
506
507 if let ResponseResult::Error(err) = &response {
508 node_info!("\nRPC request failed:");
509 node_info!(" Request: {:?}", request);
510 node_info!(" Error: {}\n", err);
511 }
512
513 response
514 }
515
516 fn sign_request(
517 &self,
518 from: &Address,
519 request: TypedTransactionRequest,
520 ) -> Result<TypedTransaction> {
521 match request {
522 TypedTransactionRequest::Deposit(_) => {
523 let nil_signature = Signature::from_scalars_and_parity(
524 B256::with_last_byte(1),
525 B256::with_last_byte(1),
526 false,
527 );
528 return build_typed_transaction(request, nil_signature);
529 }
530 _ => {
531 for signer in self.signers.iter() {
532 if signer.accounts().contains(from) {
533 let signature = signer.sign_transaction(request.clone(), from)?;
534 return build_typed_transaction(request, signature);
535 }
536 }
537 }
538 }
539 Err(BlockchainError::NoSignerAvailable)
540 }
541
542 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
543 let block_request = match block_number {
544 Some(BlockId::Number(BlockNumber::Pending)) => {
545 let pending_txs = self.pool.ready_transactions().collect();
546 BlockRequest::Pending(pending_txs)
547 }
548 _ => {
549 let number = self.backend.ensure_block_number(block_number).await?;
550 BlockRequest::Number(number)
551 }
552 };
553 Ok(block_request)
554 }
555
556 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
557 match self.pool.get_transaction(hash) {
558 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
559 None => match self.backend.transaction_by_hash(hash).await? {
560 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
561 None => Ok(None),
562 },
563 }
564 }
565
566 pub fn client_version(&self) -> Result<String> {
570 node_info!("web3_clientVersion");
571 Ok(CLIENT_VERSION.to_string())
572 }
573
574 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
578 node_info!("web3_sha3");
579 let hash = alloy_primitives::keccak256(bytes.as_ref());
580 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
581 }
582
583 pub fn protocol_version(&self) -> Result<u64> {
587 node_info!("eth_protocolVersion");
588 Ok(1)
589 }
590
591 pub fn hashrate(&self) -> Result<U256> {
595 node_info!("eth_hashrate");
596 Ok(U256::ZERO)
597 }
598
599 pub fn author(&self) -> Result<Address> {
603 node_info!("eth_coinbase");
604 Ok(self.backend.coinbase())
605 }
606
607 pub fn is_mining(&self) -> Result<bool> {
611 node_info!("eth_mining");
612 Ok(self.is_mining)
613 }
614
615 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
621 node_info!("eth_chainId");
622 Ok(Some(self.backend.chain_id().to::<U64>()))
623 }
624
625 pub fn network_id(&self) -> Result<Option<String>> {
629 node_info!("eth_networkId");
630 let chain_id = self.backend.chain_id().to::<u64>();
631 Ok(Some(format!("{chain_id}")))
632 }
633
634 pub fn net_listening(&self) -> Result<bool> {
638 node_info!("net_listening");
639 Ok(self.net_listening)
640 }
641
642 fn eth_gas_price(&self) -> Result<U256> {
644 node_info!("eth_gasPrice");
645 Ok(U256::from(self.gas_price()))
646 }
647
648 pub fn gas_price(&self) -> u128 {
650 if self.backend.is_eip1559() {
651 if self.backend.is_min_priority_fee_enforced() {
652 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
653 } else {
654 self.backend.base_fee() as u128
655 }
656 } else {
657 self.backend.fees().raw_gas_price()
658 }
659 }
660
661 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
663 Ok(self.backend.excess_blob_gas_and_price())
664 }
665
666 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
671 self.max_priority_fee_per_gas()
672 }
673
674 pub fn blob_base_fee(&self) -> Result<U256> {
678 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
679 }
680
681 pub fn gas_limit(&self) -> U256 {
683 U256::from(self.backend.gas_limit())
684 }
685
686 pub fn accounts(&self) -> Result<Vec<Address>> {
690 node_info!("eth_accounts");
691 let mut unique = HashSet::new();
692 let mut accounts: Vec<Address> = Vec::new();
693 for signer in self.signers.iter() {
694 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
695 }
696 accounts.extend(
697 self.backend
698 .cheats()
699 .impersonated_accounts()
700 .into_iter()
701 .filter(|acc| unique.insert(*acc)),
702 );
703 Ok(accounts.into_iter().collect())
704 }
705
706 pub fn block_number(&self) -> Result<U256> {
710 node_info!("eth_blockNumber");
711 Ok(U256::from(self.backend.best_number()))
712 }
713
714 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
718 node_info!("eth_getBalance");
719 let block_request = self.block_request(block_number).await?;
720
721 if let BlockRequest::Number(number) = block_request
723 && let Some(fork) = self.get_fork()
724 && fork.predates_fork(number)
725 {
726 return Ok(fork.get_balance(address, number).await?);
727 }
728
729 self.backend.get_balance(address, Some(block_request)).await
730 }
731
732 pub async fn get_account(
736 &self,
737 address: Address,
738 block_number: Option<BlockId>,
739 ) -> Result<Account> {
740 node_info!("eth_getAccount");
741 let block_request = self.block_request(block_number).await?;
742
743 if let BlockRequest::Number(number) = block_request
745 && let Some(fork) = self.get_fork()
746 && fork.predates_fork(number)
747 {
748 return Ok(fork.get_account(address, number).await?);
749 }
750
751 self.backend.get_account_at_block(address, Some(block_request)).await
752 }
753
754 pub async fn get_account_info(
756 &self,
757 address: Address,
758 block_number: Option<BlockId>,
759 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
760 node_info!("eth_getAccountInfo");
761 let account = self
762 .backend
763 .get_account_at_block(address, Some(self.block_request(block_number).await?))
764 .await?;
765 let code =
766 self.backend.get_code(address, Some(self.block_request(block_number).await?)).await?;
767 Ok(alloy_rpc_types::eth::AccountInfo {
768 balance: account.balance,
769 nonce: account.nonce,
770 code,
771 })
772 }
773 pub async fn storage_at(
777 &self,
778 address: Address,
779 index: U256,
780 block_number: Option<BlockId>,
781 ) -> Result<B256> {
782 node_info!("eth_getStorageAt");
783 let block_request = self.block_request(block_number).await?;
784
785 if let BlockRequest::Number(number) = block_request
787 && let Some(fork) = self.get_fork()
788 && fork.predates_fork(number)
789 {
790 return Ok(B256::from(
791 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
792 ));
793 }
794
795 self.backend.storage_at(address, index, Some(block_request)).await
796 }
797
798 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
802 node_info!("eth_getBlockByHash");
803 self.backend.block_by_hash(hash).await
804 }
805
806 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
810 node_info!("eth_getBlockByHash");
811 self.backend.block_by_hash_full(hash).await
812 }
813
814 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
818 node_info!("eth_getBlockByNumber");
819 if number == BlockNumber::Pending {
820 return Ok(Some(self.pending_block().await));
821 }
822
823 self.backend.block_by_number(number).await
824 }
825
826 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
830 node_info!("eth_getBlockByNumber");
831 if number == BlockNumber::Pending {
832 return Ok(self.pending_block_full().await);
833 }
834 self.backend.block_by_number_full(number).await
835 }
836
837 pub async fn transaction_count(
844 &self,
845 address: Address,
846 block_number: Option<BlockId>,
847 ) -> Result<U256> {
848 node_info!("eth_getTransactionCount");
849 self.get_transaction_count(address, block_number).await.map(U256::from)
850 }
851
852 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
856 node_info!("eth_getBlockTransactionCountByHash");
857 let block = self.backend.block_by_hash(hash).await?;
858 let txs = block.map(|b| match b.transactions() {
859 BlockTransactions::Full(txs) => U256::from(txs.len()),
860 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
861 BlockTransactions::Uncle => U256::from(0),
862 });
863 Ok(txs)
864 }
865
866 pub async fn block_transaction_count_by_number(
870 &self,
871 block_number: BlockNumber,
872 ) -> Result<Option<U256>> {
873 node_info!("eth_getBlockTransactionCountByNumber");
874 let block_request = self.block_request(Some(block_number.into())).await?;
875 if let BlockRequest::Pending(txs) = block_request {
876 let block = self.backend.pending_block(txs).await;
877 return Ok(Some(U256::from(block.transactions.len())));
878 }
879 let block = self.backend.block_by_number(block_number).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_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
892 node_info!("eth_getUncleCountByBlockHash");
893 let block =
894 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
895 Ok(U256::from(block.uncles.len()))
896 }
897
898 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
902 node_info!("eth_getUncleCountByBlockNumber");
903 let block = self
904 .backend
905 .block_by_number(block_number)
906 .await?
907 .ok_or(BlockchainError::BlockNotFound)?;
908 Ok(U256::from(block.uncles.len()))
909 }
910
911 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
915 node_info!("eth_getCode");
916 let block_request = self.block_request(block_number).await?;
917 if let BlockRequest::Number(number) = block_request
919 && let Some(fork) = self.get_fork()
920 && fork.predates_fork(number)
921 {
922 return Ok(fork.get_code(address, number).await?);
923 }
924 self.backend.get_code(address, Some(block_request)).await
925 }
926
927 pub async fn get_proof(
932 &self,
933 address: Address,
934 keys: Vec<B256>,
935 block_number: Option<BlockId>,
936 ) -> Result<EIP1186AccountProofResponse> {
937 node_info!("eth_getProof");
938 let block_request = self.block_request(block_number).await?;
939
940 if let BlockRequest::Number(number) = block_request
943 && let Some(fork) = self.get_fork()
944 && fork.predates_fork_inclusive(number)
945 {
946 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
947 }
948
949 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
950 Ok(proof)
951 }
952
953 pub async fn sign_typed_data(
957 &self,
958 _address: Address,
959 _data: serde_json::Value,
960 ) -> Result<String> {
961 node_info!("eth_signTypedData");
962 Err(BlockchainError::RpcUnimplemented)
963 }
964
965 pub async fn sign_typed_data_v3(
969 &self,
970 _address: Address,
971 _data: serde_json::Value,
972 ) -> Result<String> {
973 node_info!("eth_signTypedData_v3");
974 Err(BlockchainError::RpcUnimplemented)
975 }
976
977 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
981 node_info!("eth_signTypedData_v4");
982 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
983 let signature = signer.sign_typed_data(address, data).await?;
984 let signature = alloy_primitives::hex::encode(signature.as_bytes());
985 Ok(format!("0x{signature}"))
986 }
987
988 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
992 node_info!("eth_sign");
993 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
994 let signature =
995 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
996 Ok(format!("0x{signature}"))
997 }
998
999 pub async fn sign_transaction(
1003 &self,
1004 mut request: WithOtherFields<TransactionRequest>,
1005 ) -> Result<String> {
1006 node_info!("eth_signTransaction");
1007
1008 let from = request.from.map(Ok).unwrap_or_else(|| {
1009 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1010 })?;
1011
1012 let (nonce, _) = self.request_nonce(&request, from).await?;
1013
1014 if request.gas.is_none() {
1015 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1017 {
1018 request.gas = Some(gas.to());
1019 }
1020 }
1021
1022 let request = self.build_typed_tx_request(request, nonce)?;
1023
1024 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1025 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1026 }
1027
1028 pub async fn send_transaction(
1032 &self,
1033 mut request: WithOtherFields<TransactionRequest>,
1034 ) -> Result<TxHash> {
1035 node_info!("eth_sendTransaction");
1036
1037 let from = request.from.map(Ok).unwrap_or_else(|| {
1038 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1039 })?;
1040 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1041
1042 if request.gas.is_none() {
1043 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1045 {
1046 request.gas = Some(gas.to());
1047 }
1048 }
1049
1050 let request = self.build_typed_tx_request(request, nonce)?;
1051
1052 let pending_transaction = if self.is_impersonated(from) {
1054 let bypass_signature = self.impersonated_signature(&request);
1055 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1056 self.ensure_typed_transaction_supported(&transaction)?;
1057 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1058 PendingTransaction::with_impersonated(transaction, from)
1059 } else {
1060 let transaction = self.sign_request(&from, request)?;
1061 self.ensure_typed_transaction_supported(&transaction)?;
1062 PendingTransaction::new(transaction)?
1063 };
1064 self.backend.validate_pool_transaction(&pending_transaction).await?;
1066
1067 let requires = required_marker(nonce, on_chain_nonce, from);
1068 let provides = vec![to_marker(nonce, from)];
1069 debug_assert!(requires != provides);
1070
1071 self.add_pending_transaction(pending_transaction, requires, provides)
1072 }
1073
1074 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1076 let mut stream = self.new_block_notifications();
1077 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1079 return Ok(receipt);
1080 }
1081 while let Some(notification) = stream.next().await {
1082 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1083 && block.transactions.iter().any(|tx| tx.hash() == hash)
1084 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1085 {
1086 return Ok(receipt);
1087 }
1088 }
1089
1090 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1091 }
1092
1093 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1095 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1096 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1097 .await
1098 .unwrap_or_else(|_elapsed| {
1099 Err(BlockchainError::TransactionConfirmationTimeout {
1100 hash,
1101 duration: TIMEOUT_DURATION,
1102 })
1103 })
1104 }
1105
1106 pub async fn send_transaction_sync(
1110 &self,
1111 request: WithOtherFields<TransactionRequest>,
1112 ) -> Result<ReceiptResponse> {
1113 node_info!("eth_sendTransactionSync");
1114 let hash = self.send_transaction(request).await?;
1115
1116 let receipt = self.check_transaction_inclusion(hash).await?;
1117
1118 Ok(ReceiptResponse::from(receipt))
1119 }
1120
1121 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1125 node_info!("eth_sendRawTransaction");
1126 let mut data = tx.as_ref();
1127 if data.is_empty() {
1128 return Err(BlockchainError::EmptyRawTransactionData);
1129 }
1130
1131 let transaction = TypedTransaction::decode_2718(&mut data)
1132 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1133
1134 self.ensure_typed_transaction_supported(&transaction)?;
1135
1136 let pending_transaction = PendingTransaction::new(transaction)?;
1137
1138 self.backend.validate_pool_transaction(&pending_transaction).await?;
1140
1141 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1142 let from = *pending_transaction.sender();
1143 let nonce = pending_transaction.transaction.nonce();
1144 let requires = required_marker(nonce, on_chain_nonce, from);
1145
1146 let priority = self.transaction_priority(&pending_transaction.transaction);
1147 let pool_transaction = PoolTransaction {
1148 requires,
1149 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1150 pending_transaction,
1151 priority,
1152 };
1153
1154 let tx = self.pool.add_transaction(pool_transaction)?;
1155 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1156 Ok(*tx.hash())
1157 }
1158
1159 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<ReceiptResponse> {
1163 node_info!("eth_sendRawTransactionSync");
1164
1165 let hash = self.send_raw_transaction(tx).await?;
1166 let receipt = self.check_transaction_inclusion(hash).await?;
1167
1168 Ok(ReceiptResponse::from(receipt))
1169 }
1170
1171 pub async fn call(
1175 &self,
1176 request: WithOtherFields<TransactionRequest>,
1177 block_number: Option<BlockId>,
1178 overrides: EvmOverrides,
1179 ) -> Result<Bytes> {
1180 node_info!("eth_call");
1181 let block_request = self.block_request(block_number).await?;
1182 if let BlockRequest::Number(number) = block_request
1184 && let Some(fork) = self.get_fork()
1185 && fork.predates_fork(number)
1186 {
1187 if overrides.has_state() || overrides.has_block() {
1188 return Err(BlockchainError::EvmOverrideError(
1189 "not available on past forked blocks".to_string(),
1190 ));
1191 }
1192 return Ok(fork.call(&request, Some(number.into())).await?);
1193 }
1194
1195 let fees = FeeDetails::new(
1196 request.gas_price,
1197 request.max_fee_per_gas,
1198 request.max_priority_fee_per_gas,
1199 request.max_fee_per_blob_gas,
1200 )?
1201 .or_zero_fees();
1202 self.on_blocking_task(|this| async move {
1205 let (exit, out, gas, _) =
1206 this.backend.call(request, fees, Some(block_request), overrides).await?;
1207 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1208
1209 ensure_return_ok(exit, &out)
1210 })
1211 .await
1212 }
1213
1214 pub async fn simulate_v1(
1215 &self,
1216 request: SimulatePayload,
1217 block_number: Option<BlockId>,
1218 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1219 node_info!("eth_simulateV1");
1220 let block_request = self.block_request(block_number).await?;
1221 if let BlockRequest::Number(number) = block_request
1223 && let Some(fork) = self.get_fork()
1224 && fork.predates_fork(number)
1225 {
1226 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1227 }
1228
1229 self.on_blocking_task(|this| async move {
1232 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1233 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1234
1235 Ok(simulated_blocks)
1236 })
1237 .await
1238 }
1239
1240 pub async fn create_access_list(
1254 &self,
1255 mut request: WithOtherFields<TransactionRequest>,
1256 block_number: Option<BlockId>,
1257 ) -> Result<AccessListResult> {
1258 node_info!("eth_createAccessList");
1259 let block_request = self.block_request(block_number).await?;
1260 if let BlockRequest::Number(number) = block_request
1262 && let Some(fork) = self.get_fork()
1263 && fork.predates_fork(number)
1264 {
1265 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1266 }
1267
1268 self.backend
1269 .with_database_at(Some(block_request), |state, block_env| {
1270 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1271 &state,
1272 request.clone(),
1273 FeeDetails::zero(),
1274 block_env.clone(),
1275 )?;
1276 ensure_return_ok(exit, &out)?;
1277
1278 request.access_list = Some(access_list.clone());
1280
1281 let (exit, out, gas_used, _) = self.backend.call_with_state(
1282 &state,
1283 request.clone(),
1284 FeeDetails::zero(),
1285 block_env,
1286 )?;
1287 ensure_return_ok(exit, &out)?;
1288
1289 Ok(AccessListResult {
1290 access_list: AccessList(access_list.0),
1291 gas_used: U256::from(gas_used),
1292 error: None,
1293 })
1294 })
1295 .await?
1296 }
1297
1298 pub async fn estimate_gas(
1303 &self,
1304 request: WithOtherFields<TransactionRequest>,
1305 block_number: Option<BlockId>,
1306 overrides: EvmOverrides,
1307 ) -> Result<U256> {
1308 node_info!("eth_estimateGas");
1309 self.do_estimate_gas(
1310 request,
1311 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1312 overrides,
1313 )
1314 .await
1315 .map(U256::from)
1316 }
1317
1318 pub fn anvil_get_blob_by_versioned_hash(
1320 &self,
1321 hash: B256,
1322 ) -> Result<Option<alloy_consensus::Blob>> {
1323 node_info!("anvil_getBlobByHash");
1324 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1325 }
1326
1327 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1329 node_info!("anvil_getBlobsByTransactionHash");
1330 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1331 }
1332
1333 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1340 node_info!("eth_getTransactionByHash");
1341 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1342 let from = *pending.sender();
1343 let tx = transaction_build(
1344 Some(*pending.hash()),
1345 pending.transaction,
1346 None,
1347 None,
1348 Some(self.backend.base_fee()),
1349 );
1350
1351 let WithOtherFields { inner: mut tx, other } = tx.0;
1352 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1355
1356 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1357 });
1358 if tx.is_none() {
1359 tx = self.backend.transaction_by_hash(hash).await?
1360 }
1361
1362 Ok(tx)
1363 }
1364
1365 pub async fn transaction_by_block_hash_and_index(
1369 &self,
1370 hash: B256,
1371 index: Index,
1372 ) -> Result<Option<AnyRpcTransaction>> {
1373 node_info!("eth_getTransactionByBlockHashAndIndex");
1374 self.backend.transaction_by_block_hash_and_index(hash, index).await
1375 }
1376
1377 pub async fn transaction_by_block_number_and_index(
1381 &self,
1382 block: BlockNumber,
1383 idx: Index,
1384 ) -> Result<Option<AnyRpcTransaction>> {
1385 node_info!("eth_getTransactionByBlockNumberAndIndex");
1386 self.backend.transaction_by_block_number_and_index(block, idx).await
1387 }
1388
1389 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1393 node_info!("eth_getTransactionReceipt");
1394 self.backend.transaction_receipt(hash).await
1395 }
1396
1397 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1401 node_info!("eth_getBlockReceipts");
1402 self.backend.block_receipts(number).await
1403 }
1404
1405 pub async fn uncle_by_block_hash_and_index(
1409 &self,
1410 block_hash: B256,
1411 idx: Index,
1412 ) -> Result<Option<AnyRpcBlock>> {
1413 node_info!("eth_getUncleByBlockHashAndIndex");
1414 let number =
1415 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1416 if let Some(fork) = self.get_fork()
1417 && fork.predates_fork_inclusive(number)
1418 {
1419 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1420 }
1421 Ok(None)
1423 }
1424
1425 pub async fn uncle_by_block_number_and_index(
1429 &self,
1430 block_number: BlockNumber,
1431 idx: Index,
1432 ) -> Result<Option<AnyRpcBlock>> {
1433 node_info!("eth_getUncleByBlockNumberAndIndex");
1434 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1435 if let Some(fork) = self.get_fork()
1436 && fork.predates_fork_inclusive(number)
1437 {
1438 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1439 }
1440 Ok(None)
1442 }
1443
1444 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1448 node_info!("eth_getLogs");
1449 self.backend.logs(filter).await
1450 }
1451
1452 pub fn work(&self) -> Result<Work> {
1456 node_info!("eth_getWork");
1457 Err(BlockchainError::RpcUnimplemented)
1458 }
1459
1460 pub fn syncing(&self) -> Result<bool> {
1464 node_info!("eth_syncing");
1465 Ok(false)
1466 }
1467
1468 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1472 node_info!("eth_submitWork");
1473 Err(BlockchainError::RpcUnimplemented)
1474 }
1475
1476 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1480 node_info!("eth_submitHashrate");
1481 Err(BlockchainError::RpcUnimplemented)
1482 }
1483
1484 pub async fn fee_history(
1488 &self,
1489 block_count: U256,
1490 newest_block: BlockNumber,
1491 reward_percentiles: Vec<f64>,
1492 ) -> Result<FeeHistory> {
1493 node_info!("eth_feeHistory");
1494 let current = self.backend.best_number();
1497 let slots_in_an_epoch = 32u64;
1498
1499 let number = match newest_block {
1500 BlockNumber::Latest | BlockNumber::Pending => current,
1501 BlockNumber::Earliest => 0,
1502 BlockNumber::Number(n) => n,
1503 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1504 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1505 };
1506
1507 if let Some(fork) = self.get_fork() {
1509 if fork.predates_fork_inclusive(number) {
1512 return fork
1513 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1514 .await
1515 .map_err(BlockchainError::AlloyForkProvider);
1516 }
1517 }
1518
1519 const MAX_BLOCK_COUNT: u64 = 1024u64;
1520 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1521
1522 let highest = number;
1524 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1525
1526 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1528 return Err(FeeHistoryError::InvalidBlockRange.into());
1529 }
1530
1531 let mut response = FeeHistory {
1532 oldest_block: lowest,
1533 base_fee_per_gas: Vec::new(),
1534 gas_used_ratio: Vec::new(),
1535 reward: Some(Default::default()),
1536 base_fee_per_blob_gas: Default::default(),
1537 blob_gas_used_ratio: Default::default(),
1538 };
1539 let mut rewards = Vec::new();
1540
1541 {
1542 let fee_history = self.fee_history_cache.lock();
1543
1544 for n in lowest..=highest {
1546 if let Some(block) = fee_history.get(&n) {
1548 response.base_fee_per_gas.push(block.base_fee);
1549 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1550 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1551 response.gas_used_ratio.push(block.gas_used_ratio);
1552
1553 if !reward_percentiles.is_empty() {
1555 let mut block_rewards = Vec::new();
1556 let resolution_per_percentile: f64 = 2.0;
1557 for p in &reward_percentiles {
1558 let p = p.clamp(0.0, 100.0);
1559 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1560 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1561 block_rewards.push(reward);
1562 }
1563 rewards.push(block_rewards);
1564 }
1565 }
1566 }
1567 }
1568
1569 response.reward = Some(rewards);
1570
1571 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1576
1577 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1581
1582 Ok(response)
1583 }
1584
1585 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1592 node_info!("eth_maxPriorityFeePerGas");
1593 Ok(U256::from(self.lowest_suggestion_tip()))
1594 }
1595
1596 fn lowest_suggestion_tip(&self) -> u128 {
1600 let block_number = self.backend.best_number();
1601 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1602
1603 match latest_cached_block {
1604 Some(block) => block.rewards.iter().copied().min(),
1605 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1606 }
1607 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1608 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1609 }
1610
1611 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1615 node_info!("eth_newFilter");
1616 let historic = if filter.block_option.get_from_block().is_some() {
1619 self.backend.logs(filter.clone()).await?
1620 } else {
1621 vec![]
1622 };
1623 let filter = EthFilter::Logs(Box::new(LogsFilter {
1624 blocks: self.new_block_notifications(),
1625 storage: self.storage_info(),
1626 filter: FilteredParams::new(Some(filter)),
1627 historic: Some(historic),
1628 }));
1629 Ok(self.filters.add_filter(filter).await)
1630 }
1631
1632 pub async fn new_block_filter(&self) -> Result<String> {
1636 node_info!("eth_newBlockFilter");
1637 let filter = EthFilter::Blocks(self.new_block_notifications());
1638 Ok(self.filters.add_filter(filter).await)
1639 }
1640
1641 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1645 node_info!("eth_newPendingTransactionFilter");
1646 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1647 Ok(self.filters.add_filter(filter).await)
1648 }
1649
1650 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1654 node_info!("eth_getFilterChanges");
1655 self.filters.get_filter_changes(id).await
1656 }
1657
1658 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1662 node_info!("eth_getFilterLogs");
1663 if let Some(filter) = self.filters.get_log_filter(id).await {
1664 self.backend.logs(filter).await
1665 } else {
1666 Ok(Vec::new())
1667 }
1668 }
1669
1670 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1672 node_info!("eth_uninstallFilter");
1673 Ok(self.filters.uninstall_filter(id).await.is_some())
1674 }
1675
1676 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1680 node_info!("debug_getRawTransaction");
1681 self.inner_raw_transaction(hash).await
1682 }
1683
1684 pub async fn raw_transaction_by_block_hash_and_index(
1688 &self,
1689 block_hash: B256,
1690 index: Index,
1691 ) -> Result<Option<Bytes>> {
1692 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1693 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1694 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1695 None => Ok(None),
1696 }
1697 }
1698
1699 pub async fn raw_transaction_by_block_number_and_index(
1703 &self,
1704 block_number: BlockNumber,
1705 index: Index,
1706 ) -> Result<Option<Bytes>> {
1707 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1708 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1709 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1710 None => Ok(None),
1711 }
1712 }
1713
1714 pub async fn debug_trace_transaction(
1718 &self,
1719 tx_hash: B256,
1720 opts: GethDebugTracingOptions,
1721 ) -> Result<GethTrace> {
1722 node_info!("debug_traceTransaction");
1723 self.backend.debug_trace_transaction(tx_hash, opts).await
1724 }
1725
1726 pub async fn debug_trace_call(
1730 &self,
1731 request: WithOtherFields<TransactionRequest>,
1732 block_number: Option<BlockId>,
1733 opts: GethDebugTracingCallOptions,
1734 ) -> Result<GethTrace> {
1735 node_info!("debug_traceCall");
1736 let block_request = self.block_request(block_number).await?;
1737 let fees = FeeDetails::new(
1738 request.gas_price,
1739 request.max_fee_per_gas,
1740 request.max_priority_fee_per_gas,
1741 request.max_fee_per_blob_gas,
1742 )?
1743 .or_zero_fees();
1744
1745 let result: std::result::Result<GethTrace, BlockchainError> =
1746 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1747 result
1748 }
1749
1750 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1754 node_info!("trace_transaction");
1755 self.backend.trace_transaction(tx_hash).await
1756 }
1757
1758 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1762 node_info!("trace_block");
1763 self.backend.trace_block(block).await
1764 }
1765
1766 pub async fn trace_filter(
1770 &self,
1771 filter: TraceFilter,
1772 ) -> Result<Vec<LocalizedTransactionTrace>> {
1773 node_info!("trace_filter");
1774 self.backend.trace_filter(filter).await
1775 }
1776}
1777
1778impl EthApi {
1781 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
1785 node_info!("anvil_impersonateAccount");
1786 self.backend.impersonate(address);
1787 Ok(())
1788 }
1789
1790 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
1794 node_info!("anvil_stopImpersonatingAccount");
1795 self.backend.stop_impersonating(address);
1796 Ok(())
1797 }
1798
1799 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
1803 node_info!("anvil_autoImpersonateAccount");
1804 self.backend.auto_impersonate_account(enabled);
1805 Ok(())
1806 }
1807
1808 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
1812 node_info!("anvil_getAutomine");
1813 Ok(self.miner.is_auto_mine())
1814 }
1815
1816 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
1820 node_info!("anvil_getIntervalMining");
1821 Ok(self.miner.get_interval())
1822 }
1823
1824 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
1829 node_info!("evm_setAutomine");
1830 if self.miner.is_auto_mine() {
1831 if enable_automine {
1832 return Ok(());
1833 }
1834 self.miner.set_mining_mode(MiningMode::None);
1835 } else if enable_automine {
1836 let listener = self.pool.add_ready_listener();
1837 let mode = MiningMode::instant(1_000, listener);
1838 self.miner.set_mining_mode(mode);
1839 }
1840 Ok(())
1841 }
1842
1843 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
1847 node_info!("anvil_mine");
1848 let interval = interval.map(|i| i.to::<u64>());
1849 let blocks = num_blocks.unwrap_or(U256::from(1));
1850 if blocks.is_zero() {
1851 return Ok(());
1852 }
1853
1854 self.on_blocking_task(|this| async move {
1855 for _ in 0..blocks.to::<u64>() {
1857 if let Some(interval) = interval {
1859 this.backend.time().increase_time(interval);
1860 }
1861 this.mine_one().await;
1862 }
1863 Ok(())
1864 })
1865 .await?;
1866
1867 Ok(())
1868 }
1869
1870 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
1874 node_info!("evm_setIntervalMining");
1875 let mining_mode = if secs == 0 {
1876 MiningMode::None
1877 } else {
1878 let block_time = Duration::from_secs(secs);
1879
1880 self.backend.update_interval_mine_block_time(block_time);
1882
1883 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
1884 };
1885 self.miner.set_mining_mode(mining_mode);
1886 Ok(())
1887 }
1888
1889 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
1893 node_info!("anvil_dropTransaction");
1894 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
1895 }
1896
1897 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
1901 node_info!("anvil_dropAllTransactions");
1902 self.pool.clear();
1903 Ok(())
1904 }
1905
1906 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
1912 self.reset_instance_id();
1913 node_info!("anvil_reset");
1914 if let Some(forking) = forking {
1915 self.backend.reset_fork(forking).await
1917 } else {
1918 self.backend.reset_to_in_mem().await
1921 }
1922 }
1923
1924 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
1925 node_info!("anvil_setChainId");
1926 self.backend.set_chain_id(chain_id);
1927 Ok(())
1928 }
1929
1930 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
1934 node_info!("anvil_setBalance");
1935 self.backend.set_balance(address, balance).await?;
1936 Ok(())
1937 }
1938
1939 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
1943 node_info!("anvil_addBalance");
1944 let current_balance = self.backend.get_balance(address, None).await?;
1945 self.backend.set_balance(address, current_balance + balance).await?;
1946 Ok(())
1947 }
1948
1949 async fn find_erc20_storage_slot(
1966 &self,
1967 token_address: Address,
1968 calldata: Bytes,
1969 expected_value: U256,
1970 ) -> Result<B256> {
1971 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
1972
1973 let access_list_result =
1975 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
1976 let access_list = access_list_result.access_list;
1977
1978 for item in access_list.0 {
1981 if item.address != token_address {
1982 continue;
1983 };
1984 for slot in &item.storage_keys {
1985 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
1986 (*slot, B256::from(expected_value.to_be_bytes())),
1987 ));
1988
1989 let state_override = StateOverridesBuilder::default()
1990 .append(token_address, account_override)
1991 .build();
1992
1993 let evm_override = EvmOverrides::state(Some(state_override));
1994
1995 let Ok(result) =
1996 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
1997 else {
1998 continue;
2000 };
2001
2002 let Ok(result_value) = U256::abi_decode(&result) else {
2003 continue;
2005 };
2006
2007 if result_value == expected_value {
2008 return Ok(*slot);
2009 }
2010 }
2011 }
2012
2013 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2014 }
2015
2016 pub async fn anvil_deal_erc20(
2020 &self,
2021 address: Address,
2022 token_address: Address,
2023 balance: U256,
2024 ) -> Result<()> {
2025 node_info!("anvil_dealERC20");
2026
2027 sol! {
2028 #[sol(rpc)]
2029 contract IERC20 {
2030 function balanceOf(address target) external view returns (uint256);
2031 }
2032 }
2033
2034 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2035
2036 let slot =
2038 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2039 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2040 })?;
2041
2042 self.anvil_set_storage_at(
2044 token_address,
2045 U256::from_be_bytes(slot.0),
2046 B256::from(balance.to_be_bytes()),
2047 )
2048 .await?;
2049
2050 Ok(())
2051 }
2052
2053 pub async fn anvil_set_erc20_allowance(
2057 &self,
2058 owner: Address,
2059 spender: Address,
2060 token_address: Address,
2061 amount: U256,
2062 ) -> Result<()> {
2063 node_info!("anvil_setERC20Allowance");
2064
2065 sol! {
2066 #[sol(rpc)]
2067 contract IERC20 {
2068 function allowance(address owner, address spender) external view returns (uint256);
2069 }
2070 }
2071
2072 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2073
2074 let slot =
2076 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2077 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2078 })?;
2079
2080 self.anvil_set_storage_at(
2082 token_address,
2083 U256::from_be_bytes(slot.0),
2084 B256::from(amount.to_be_bytes()),
2085 )
2086 .await?;
2087
2088 Ok(())
2089 }
2090
2091 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2095 node_info!("anvil_setCode");
2096 self.backend.set_code(address, code).await?;
2097 Ok(())
2098 }
2099
2100 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2104 node_info!("anvil_setNonce");
2105 self.backend.set_nonce(address, nonce).await?;
2106 Ok(())
2107 }
2108
2109 pub async fn anvil_set_storage_at(
2113 &self,
2114 address: Address,
2115 slot: U256,
2116 val: B256,
2117 ) -> Result<bool> {
2118 node_info!("anvil_setStorageAt");
2119 self.backend.set_storage_at(address, slot, val).await?;
2120 Ok(true)
2121 }
2122
2123 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2127 node_info!("anvil_setLoggingEnabled");
2128 self.logger.set_enabled(enable);
2129 Ok(())
2130 }
2131
2132 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2136 node_info!("anvil_setMinGasPrice");
2137 if self.backend.is_eip1559() {
2138 return Err(RpcError::invalid_params(
2139 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2140 )
2141 .into());
2142 }
2143 self.backend.set_gas_price(gas.to());
2144 Ok(())
2145 }
2146
2147 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2151 node_info!("anvil_setNextBlockBaseFeePerGas");
2152 if !self.backend.is_eip1559() {
2153 return Err(RpcError::invalid_params(
2154 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2155 )
2156 .into());
2157 }
2158 self.backend.set_base_fee(basefee.to());
2159 Ok(())
2160 }
2161
2162 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2166 node_info!("anvil_setCoinbase");
2167 self.backend.set_coinbase(address);
2168 Ok(())
2169 }
2170
2171 pub async fn anvil_dump_state(
2176 &self,
2177 preserve_historical_states: Option<bool>,
2178 ) -> Result<Bytes> {
2179 node_info!("anvil_dumpState");
2180 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2181 }
2182
2183 pub async fn serialized_state(
2185 &self,
2186 preserve_historical_states: bool,
2187 ) -> Result<SerializableState> {
2188 self.backend.serialized_state(preserve_historical_states).await
2189 }
2190
2191 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2196 node_info!("anvil_loadState");
2197 self.backend.load_state_bytes(buf).await
2198 }
2199
2200 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2204 node_info!("anvil_nodeInfo");
2205
2206 let env = self.backend.env().read();
2207 let fork_config = self.backend.get_fork();
2208 let tx_order = self.transaction_order.read();
2209 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2210
2211 Ok(NodeInfo {
2212 current_block_number: self.backend.best_number(),
2213 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2214 current_block_hash: self.backend.best_hash(),
2215 hard_fork: hard_fork.to_string(),
2216 transaction_order: match *tx_order {
2217 TransactionOrder::Fifo => "fifo".to_string(),
2218 TransactionOrder::Fees => "fees".to_string(),
2219 },
2220 environment: NodeEnvironment {
2221 base_fee: self.backend.base_fee() as u128,
2222 chain_id: self.backend.chain_id().to::<u64>(),
2223 gas_limit: self.backend.gas_limit(),
2224 gas_price: self.gas_price(),
2225 },
2226 fork_config: fork_config
2227 .map(|fork| {
2228 let config = fork.config.read();
2229
2230 NodeForkConfig {
2231 fork_url: Some(config.eth_rpc_url.clone()),
2232 fork_block_number: Some(config.block_number),
2233 fork_retry_backoff: Some(config.backoff.as_millis()),
2234 }
2235 })
2236 .unwrap_or_default(),
2237 })
2238 }
2239
2240 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2244 node_info!("anvil_metadata");
2245 let fork_config = self.backend.get_fork();
2246
2247 Ok(Metadata {
2248 client_version: CLIENT_VERSION.to_string(),
2249 chain_id: self.backend.chain_id().to::<u64>(),
2250 latest_block_hash: self.backend.best_hash(),
2251 latest_block_number: self.backend.best_number(),
2252 instance_id: *self.instance_id.read(),
2253 forked_network: fork_config.map(|cfg| ForkedNetwork {
2254 chain_id: cfg.chain_id(),
2255 fork_block_number: cfg.block_number(),
2256 fork_block_hash: cfg.block_hash(),
2257 }),
2258 snapshots: self.backend.list_state_snapshots(),
2259 })
2260 }
2261
2262 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2263 node_info!("anvil_removePoolTransactions");
2264 self.pool.remove_transactions_by_address(address);
2265 Ok(())
2266 }
2267
2268 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2282 node_info!("anvil_reorg");
2283 let depth = options.depth;
2284 let tx_block_pairs = options.tx_block_pairs;
2285
2286 let current_height = self.backend.best_number();
2288 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2289 RpcError::invalid_params(format!(
2290 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2291 )),
2292 ))?;
2293
2294 let common_block =
2296 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2297
2298 let block_pool_txs = if tx_block_pairs.is_empty() {
2301 HashMap::default()
2302 } else {
2303 let mut pairs = tx_block_pairs;
2304
2305 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2307 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2308 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2309 depth - 1
2310 ))));
2311 }
2312
2313 pairs.sort_by_key(|a| a.1);
2315
2316 let mut nonces: HashMap<Address, u64> = HashMap::default();
2319
2320 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2321 for pair in pairs {
2322 let (tx_data, block_index) = pair;
2323
2324 let pending = match tx_data {
2325 TransactionData::Raw(bytes) => {
2326 let mut data = bytes.as_ref();
2327 let decoded = TypedTransaction::decode_2718(&mut data)
2328 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2329 PendingTransaction::new(decoded)?
2330 }
2331
2332 TransactionData::JSON(req) => {
2333 let mut tx_req = WithOtherFields::new(req);
2334 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2335 self.accounts()?
2336 .first()
2337 .copied()
2338 .ok_or(BlockchainError::NoSignerAvailable)
2339 })?;
2340
2341 let curr_nonce = nonces.entry(from).or_insert(
2343 self.get_transaction_count(
2344 from,
2345 Some(common_block.header.number.into()),
2346 )
2347 .await?,
2348 );
2349
2350 if tx_req.gas.is_none()
2352 && let Ok(gas) = self
2353 .estimate_gas(tx_req.clone(), None, EvmOverrides::default())
2354 .await
2355 {
2356 tx_req.gas = Some(gas.to());
2357 }
2358
2359 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2361
2362 *curr_nonce += 1;
2364
2365 if self.is_impersonated(from) {
2367 let bypass_signature = self.impersonated_signature(&typed);
2368 let transaction =
2369 sign::build_typed_transaction(typed, bypass_signature)?;
2370 self.ensure_typed_transaction_supported(&transaction)?;
2371 PendingTransaction::with_impersonated(transaction, from)
2372 } else {
2373 let transaction = self.sign_request(&from, typed)?;
2374 self.ensure_typed_transaction_supported(&transaction)?;
2375 PendingTransaction::new(transaction)?
2376 }
2377 }
2378 };
2379
2380 let pooled = PoolTransaction::new(pending);
2381 txs.entry(block_index).or_default().push(Arc::new(pooled));
2382 }
2383
2384 txs
2385 };
2386
2387 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2388 Ok(())
2389 }
2390
2391 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2402 node_info!("anvil_rollback");
2403 let depth = depth.unwrap_or(1);
2404
2405 let current_height = self.backend.best_number();
2407 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2408 RpcError::invalid_params(format!(
2409 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2410 )),
2411 ))?;
2412
2413 let common_block =
2415 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2416
2417 self.backend.rollback(common_block).await?;
2418 Ok(())
2419 }
2420
2421 pub async fn evm_snapshot(&self) -> Result<U256> {
2425 node_info!("evm_snapshot");
2426 Ok(self.backend.create_state_snapshot().await)
2427 }
2428
2429 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2434 node_info!("evm_revert");
2435 self.backend.revert_state_snapshot(id).await
2436 }
2437
2438 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2442 node_info!("evm_increaseTime");
2443 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2444 }
2445
2446 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2450 node_info!("evm_setNextBlockTimestamp");
2451 self.backend.time().set_next_block_timestamp(seconds)
2452 }
2453
2454 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2459 node_info!("evm_setTime");
2460 let now = self.backend.time().current_call_timestamp();
2461 self.backend.time().reset(timestamp);
2462
2463 let offset = timestamp.saturating_sub(now);
2465 Ok(Duration::from_millis(offset).as_secs())
2466 }
2467
2468 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2472 node_info!("evm_setBlockGasLimit");
2473 self.backend.set_gas_limit(gas_limit.to());
2474 Ok(true)
2475 }
2476
2477 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2481 node_info!("anvil_setBlockTimestampInterval");
2482 self.backend.time().set_block_timestamp_interval(seconds);
2483 Ok(())
2484 }
2485
2486 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2490 node_info!("anvil_removeBlockTimestampInterval");
2491 Ok(self.backend.time().remove_block_timestamp_interval())
2492 }
2493
2494 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2501 node_info!("evm_mine");
2502
2503 self.do_evm_mine(opts).await?;
2504
2505 Ok("0x0".to_string())
2506 }
2507
2508 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2518 node_info!("evm_mine_detailed");
2519
2520 let mined_blocks = self.do_evm_mine(opts).await?;
2521
2522 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2523
2524 let latest = self.backend.best_number();
2525 for offset in (0..mined_blocks).rev() {
2526 let block_num = latest - offset;
2527 if let Some(mut block) =
2528 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2529 {
2530 let block_txs = match block.transactions_mut() {
2531 BlockTransactions::Full(txs) => txs,
2532 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2533 };
2534 for tx in block_txs.iter_mut() {
2535 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2536 && let Some(output) = receipt.out
2537 {
2538 if !receipt
2540 .inner
2541 .inner
2542 .as_receipt_with_bloom()
2543 .receipt
2544 .status
2545 .coerce_status()
2546 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2547 {
2548 tx.other.insert(
2549 "revertReason".to_string(),
2550 serde_json::to_value(reason).expect("Infallible"),
2551 );
2552 }
2553 tx.other.insert(
2554 "output".to_string(),
2555 serde_json::to_value(output).expect("Infallible"),
2556 );
2557 }
2558 }
2559 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2560 blocks.push(block);
2561 }
2562 }
2563
2564 Ok(blocks)
2565 }
2566
2567 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2571 node_info!("anvil_setBlock");
2572 self.backend.set_block_number(block_number);
2573 Ok(())
2574 }
2575
2576 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2580 node_info!("anvil_setRpcUrl");
2581 if let Some(fork) = self.backend.get_fork() {
2582 let mut config = fork.config.write();
2583 let new_provider = Arc::new(
2585 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2586 |_| {
2587 TransportErrorKind::custom_str(
2588 format!("Failed to parse invalid url {url}").as_str(),
2589 )
2590 },
2591 )?, );
2594 config.provider = new_provider;
2595 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2596 config.eth_rpc_url = url;
2597 }
2598 Ok(())
2599 }
2600
2601 pub async fn anvil_enable_traces(&self) -> Result<()> {
2606 node_info!("anvil_enableTraces");
2607 Err(BlockchainError::RpcUnimplemented)
2608 }
2609
2610 pub async fn eth_send_unsigned_transaction(
2614 &self,
2615 request: WithOtherFields<TransactionRequest>,
2616 ) -> Result<TxHash> {
2617 node_info!("eth_sendUnsignedTransaction");
2618 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2620
2621 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2622
2623 let request = self.build_typed_tx_request(request, nonce)?;
2624
2625 let bypass_signature = self.impersonated_signature(&request);
2626 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2627
2628 self.ensure_typed_transaction_supported(&transaction)?;
2629
2630 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2631
2632 self.backend.validate_pool_transaction(&pending_transaction).await?;
2634
2635 let requires = required_marker(nonce, on_chain_nonce, from);
2636 let provides = vec![to_marker(nonce, from)];
2637
2638 self.add_pending_transaction(pending_transaction, requires, provides)
2639 }
2640
2641 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2647 node_info!("txpool_status");
2648 Ok(self.pool.txpool_status())
2649 }
2650
2651 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2658 node_info!("txpool_inspect");
2659 let mut inspect = TxpoolInspect::default();
2660
2661 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2662 let tx = &tx.pending_transaction.transaction;
2663 let to = tx.to();
2664 let gas_price = tx.gas_price();
2665 let value = tx.value();
2666 let gas = tx.gas_limit();
2667 TxpoolInspectSummary { to, value, gas, gas_price }
2668 }
2669
2670 for pending in self.pool.ready_transactions() {
2677 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2678 let key = pending.pending_transaction.nonce().to_string();
2679 entry.insert(key, convert(pending));
2680 }
2681 for queued in self.pool.pending_transactions() {
2682 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2683 let key = queued.pending_transaction.nonce().to_string();
2684 entry.insert(key, convert(queued));
2685 }
2686 Ok(inspect)
2687 }
2688
2689 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2696 node_info!("txpool_content");
2697 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2698 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2699 let from = *tx.pending_transaction.sender();
2700 let tx = transaction_build(
2701 Some(tx.hash()),
2702 tx.pending_transaction.transaction.clone(),
2703 None,
2704 None,
2705 None,
2706 );
2707
2708 let WithOtherFields { inner: mut tx, other } = tx.0;
2709
2710 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2713
2714 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2715
2716 Ok(tx)
2717 }
2718
2719 for pending in self.pool.ready_transactions() {
2720 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2721 let key = pending.pending_transaction.nonce().to_string();
2722 entry.insert(key, convert(pending)?);
2723 }
2724 for queued in self.pool.pending_transactions() {
2725 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2726 let key = queued.pending_transaction.nonce().to_string();
2727 entry.insert(key, convert(queued)?);
2728 }
2729
2730 Ok(content)
2731 }
2732}
2733
2734impl EthApi {
2736 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2742 node_info!("wallet_getCapabilities");
2743 Ok(self.backend.get_capabilities())
2744 }
2745
2746 pub async fn wallet_send_transaction(
2747 &self,
2748 mut request: WithOtherFields<TransactionRequest>,
2749 ) -> Result<TxHash> {
2750 node_info!("wallet_sendTransaction");
2751
2752 if request.value.is_some_and(|val| val > U256::ZERO) {
2755 return Err(WalletError::ValueNotZero.into());
2756 }
2757
2758 if request.from.is_some() {
2760 return Err(WalletError::FromSet.into());
2761 }
2762
2763 if request.nonce.is_some() {
2765 return Err(WalletError::NonceSet.into());
2766 }
2767
2768 let capabilities = self.backend.get_capabilities();
2769 let valid_delegations: &[Address] = capabilities
2770 .get(self.chain_id())
2771 .map(|caps| caps.delegation.addresses.as_ref())
2772 .unwrap_or_default();
2773
2774 if let Some(authorizations) = &request.authorization_list
2775 && authorizations.iter().any(|auth| !valid_delegations.contains(&auth.address))
2776 {
2777 return Err(WalletError::InvalidAuthorization.into());
2778 }
2779
2780 match (request.authorization_list.is_some(), request.to) {
2782 (false, Some(TxKind::Call(addr))) => {
2785 let acc = self.backend.get_account(addr).await?;
2786
2787 let delegated_address = acc
2788 .code
2789 .map(|code| match code {
2790 Bytecode::Eip7702(c) => c.address(),
2791 _ => Address::ZERO,
2792 })
2793 .unwrap_or_default();
2794
2795 if delegated_address == Address::ZERO
2797 || !valid_delegations.contains(&delegated_address)
2798 {
2799 return Err(WalletError::IllegalDestination.into());
2800 }
2801 }
2802 (true, _) => (),
2804 _ => return Err(WalletError::IllegalDestination.into()),
2806 }
2807
2808 let wallet = self.backend.executor_wallet().ok_or(WalletError::InternalError)?;
2809
2810 let from = NetworkWallet::<Ethereum>::default_signer_address(&wallet);
2811
2812 let nonce = self.get_transaction_count(from, Some(BlockId::latest())).await?;
2813
2814 request.nonce = Some(nonce);
2815
2816 let chain_id = self.chain_id();
2817
2818 request.chain_id = Some(chain_id);
2819
2820 request.from = Some(from);
2821
2822 let gas_limit_fut =
2823 self.estimate_gas(request.clone(), Some(BlockId::latest()), EvmOverrides::default());
2824
2825 let fees_fut = self.fee_history(
2826 U256::from(EIP1559_FEE_ESTIMATION_PAST_BLOCKS),
2827 BlockNumber::Latest,
2828 vec![EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE],
2829 );
2830
2831 let (gas_limit, fees) = tokio::join!(gas_limit_fut, fees_fut);
2832
2833 let gas_limit = gas_limit?;
2834 let fees = fees?;
2835
2836 request.gas = Some(gas_limit.to());
2837
2838 let base_fee = fees.latest_block_base_fee().unwrap_or_default();
2839
2840 let estimation = eip1559_default_estimator(base_fee, &fees.reward.unwrap_or_default());
2841
2842 request.max_fee_per_gas = Some(estimation.max_fee_per_gas);
2843 request.max_priority_fee_per_gas = Some(estimation.max_priority_fee_per_gas);
2844 request.gas_price = None;
2845
2846 let envelope = request.build(&wallet).await.map_err(|_| WalletError::InternalError)?;
2847
2848 self.send_raw_transaction(envelope.encoded_2718().into()).await
2849 }
2850
2851 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2855 node_info!("anvil_addCapability");
2856 self.backend.add_capability(address);
2857 Ok(())
2858 }
2859
2860 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2861 node_info!("anvil_setExecutor");
2862 self.backend.set_executor(executor_pk)
2863 }
2864}
2865
2866impl EthApi {
2867 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2869 where
2870 C: FnOnce(Self) -> F,
2871 F: Future<Output = Result<R>> + Send + 'static,
2872 R: Send + 'static,
2873 {
2874 let (tx, rx) = oneshot::channel();
2875 let this = self.clone();
2876 let f = c(this);
2877 tokio::task::spawn_blocking(move || {
2878 tokio::runtime::Handle::current().block_on(async move {
2879 let res = f.await;
2880 let _ = tx.send(res);
2881 })
2882 });
2883 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2884 }
2885
2886 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2888 let mut blocks_to_mine = 1u64;
2889
2890 if let Some(opts) = opts {
2891 let timestamp = match opts {
2892 MineOptions::Timestamp(timestamp) => timestamp,
2893 MineOptions::Options { timestamp, blocks } => {
2894 if let Some(blocks) = blocks {
2895 blocks_to_mine = blocks;
2896 }
2897 timestamp
2898 }
2899 };
2900 if let Some(timestamp) = timestamp {
2901 self.evm_set_next_block_timestamp(timestamp)?;
2903 }
2904 }
2905
2906 self.on_blocking_task(|this| async move {
2909 for _ in 0..blocks_to_mine {
2911 this.mine_one().await;
2912 }
2913 Ok(())
2914 })
2915 .await?;
2916
2917 Ok(blocks_to_mine)
2918 }
2919
2920 async fn do_estimate_gas(
2921 &self,
2922 request: WithOtherFields<TransactionRequest>,
2923 block_number: Option<BlockId>,
2924 overrides: EvmOverrides,
2925 ) -> Result<u128> {
2926 let block_request = self.block_request(block_number).await?;
2927 if let BlockRequest::Number(number) = block_request
2929 && let Some(fork) = self.get_fork()
2930 && fork.predates_fork(number)
2931 {
2932 if overrides.has_state() || overrides.has_block() {
2933 return Err(BlockchainError::EvmOverrideError(
2934 "not available on past forked blocks".to_string(),
2935 ));
2936 }
2937 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
2938 }
2939
2940 self.on_blocking_task(|this| async move {
2943 this.backend
2944 .with_database_at(Some(block_request), |state, mut block| {
2945 let mut cache_db = CacheDB::new(state);
2946 if let Some(state_overrides) = overrides.state {
2947 state::apply_state_overrides(
2948 state_overrides.into_iter().collect(),
2949 &mut cache_db,
2950 )?;
2951 }
2952 if let Some(block_overrides) = overrides.block {
2953 state::apply_block_overrides(*block_overrides, &mut cache_db, &mut block);
2954 }
2955 this.do_estimate_gas_with_state(request, &cache_db as &dyn DatabaseRef, block)
2956 })
2957 .await?
2958 })
2959 .await
2960 }
2961
2962 fn do_estimate_gas_with_state(
2966 &self,
2967 mut request: WithOtherFields<TransactionRequest>,
2968 state: &dyn DatabaseRef,
2969 block_env: BlockEnv,
2970 ) -> Result<u128> {
2971 let to = request.to.as_ref().and_then(TxKind::to);
2974
2975 let maybe_transfer = (request.input.input().is_none()
2977 || request.input.input().is_some_and(|data| data.is_empty()))
2978 && request.authorization_list.is_none()
2979 && request.access_list.is_none()
2980 && request.blob_versioned_hashes.is_none();
2981
2982 if maybe_transfer
2983 && let Some(to) = to
2984 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
2985 && target_code.as_ref().is_empty()
2986 {
2987 return Ok(MIN_TRANSACTION_GAS);
2988 }
2989
2990 let fees = FeeDetails::new(
2991 request.gas_price,
2992 request.max_fee_per_gas,
2993 request.max_priority_fee_per_gas,
2994 request.max_fee_per_blob_gas,
2995 )?
2996 .or_zero_fees();
2997
2998 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
3001
3002 let gas_price = fees.gas_price.unwrap_or_default();
3003 if gas_price > 0
3005 && let Some(from) = request.from
3006 {
3007 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
3008 if let Some(value) = request.value {
3009 if value > available_funds {
3010 return Err(InvalidTransactionError::InsufficientFunds.into());
3011 }
3012 available_funds -= value;
3014 }
3015 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
3017 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
3018 }
3019
3020 let mut call_to_estimate = request.clone();
3021 call_to_estimate.gas = Some(highest_gas_limit as u64);
3022
3023 let ethres =
3025 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3026
3027 let gas_used = match ethres.try_into()? {
3028 GasEstimationCallResult::Success(gas) => Ok(gas),
3029 GasEstimationCallResult::OutOfGas => {
3030 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3031 }
3032 GasEstimationCallResult::Revert(output) => {
3033 Err(InvalidTransactionError::Revert(output).into())
3034 }
3035 GasEstimationCallResult::EvmError(err) => {
3036 warn!(target: "node", "estimation failed due to {:?}", err);
3037 Err(BlockchainError::EvmError(err))
3038 }
3039 }?;
3040
3041 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3048
3049 let mut mid_gas_limit =
3051 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3052
3053 while (highest_gas_limit - lowest_gas_limit) > 1 {
3055 request.gas = Some(mid_gas_limit as u64);
3056 let ethres = self.backend.call_with_state(
3057 &state,
3058 request.clone(),
3059 fees.clone(),
3060 block_env.clone(),
3061 );
3062
3063 match ethres.try_into()? {
3064 GasEstimationCallResult::Success(_) => {
3065 highest_gas_limit = mid_gas_limit;
3069 }
3070 GasEstimationCallResult::OutOfGas
3071 | GasEstimationCallResult::Revert(_)
3072 | GasEstimationCallResult::EvmError(_) => {
3073 lowest_gas_limit = mid_gas_limit;
3080 }
3081 };
3082 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3084 }
3085
3086 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3087
3088 Ok(highest_gas_limit)
3089 }
3090
3091 pub fn set_transaction_order(&self, order: TransactionOrder) {
3093 *self.transaction_order.write() = order;
3094 }
3095
3096 fn transaction_priority(&self, tx: &TypedTransaction) -> TransactionPriority {
3098 self.transaction_order.read().priority(tx)
3099 }
3100
3101 pub fn chain_id(&self) -> u64 {
3103 self.backend.chain_id().to::<u64>()
3104 }
3105
3106 pub fn get_fork(&self) -> Option<ClientFork> {
3108 self.backend.get_fork()
3109 }
3110
3111 pub fn instance_id(&self) -> B256 {
3113 *self.instance_id.read()
3114 }
3115
3116 pub fn reset_instance_id(&self) {
3118 *self.instance_id.write() = B256::random();
3119 }
3120
3121 #[expect(clippy::borrowed_box)]
3123 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3124 self.signers.iter().find(|signer| signer.is_signer_for(address))
3125 }
3126
3127 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3129 self.backend.new_block_notifications()
3130 }
3131
3132 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3134 self.pool.add_ready_listener()
3135 }
3136
3137 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3139 let (tx, rx) = unbounded_channel();
3140 let mut hashes = self.new_ready_transactions();
3141
3142 let this = self.clone();
3143
3144 tokio::spawn(async move {
3145 while let Some(hash) = hashes.next().await {
3146 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3147 && tx.send(txn).is_err()
3148 {
3149 break;
3150 }
3151 }
3152 });
3153
3154 rx
3155 }
3156
3157 pub fn storage_info(&self) -> StorageInfo {
3159 StorageInfo::new(Arc::clone(&self.backend))
3160 }
3161
3162 pub fn is_fork(&self) -> bool {
3164 self.backend.is_fork()
3165 }
3166
3167 pub async fn mine_one(&self) {
3169 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3170 let outcome = self.backend.mine_block(transactions).await;
3171
3172 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3173 self.pool.on_mined_block(outcome);
3174 }
3175
3176 async fn pending_block(&self) -> AnyRpcBlock {
3178 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3179 let info = self.backend.pending_block(transactions).await;
3180 self.backend.convert_block(info.block)
3181 }
3182
3183 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3185 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3186 let BlockInfo { block, transactions, receipts: _ } =
3187 self.backend.pending_block(transactions).await;
3188
3189 let mut partial_block = self.backend.convert_block(block.clone());
3190
3191 let mut block_transactions = Vec::with_capacity(block.transactions.len());
3192 let base_fee = self.backend.base_fee();
3193
3194 for info in transactions {
3195 let tx = block.transactions.get(info.transaction_index as usize)?.clone();
3196
3197 let tx = transaction_build(
3198 Some(info.transaction_hash),
3199 tx,
3200 Some(&block),
3201 Some(info),
3202 Some(base_fee),
3203 );
3204 block_transactions.push(tx);
3205 }
3206
3207 partial_block.transactions = BlockTransactions::from(block_transactions);
3208
3209 Some(partial_block)
3210 }
3211
3212 fn build_typed_tx_request(
3213 &self,
3214 request: WithOtherFields<TransactionRequest>,
3215 nonce: u64,
3216 ) -> Result<TypedTransactionRequest> {
3217 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
3218 let max_fee_per_gas = request.max_fee_per_gas;
3219 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
3220 let gas_price = request.gas_price;
3221
3222 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
3223 let from = request.from;
3224
3225 let request = match transaction_request_to_typed(request) {
3226 Some(TypedTransactionRequest::Legacy(mut m)) => {
3227 m.nonce = nonce;
3228 m.chain_id = Some(chain_id);
3229 m.gas_limit = gas_limit;
3230 if gas_price.is_none() {
3231 m.gas_price = self.gas_price();
3232 }
3233 TypedTransactionRequest::Legacy(m)
3234 }
3235 Some(TypedTransactionRequest::EIP2930(mut m)) => {
3236 m.nonce = nonce;
3237 m.chain_id = chain_id;
3238 m.gas_limit = gas_limit;
3239 if gas_price.is_none() {
3240 m.gas_price = self.gas_price();
3241 }
3242 TypedTransactionRequest::EIP2930(m)
3243 }
3244 Some(TypedTransactionRequest::EIP1559(mut m)) => {
3245 m.nonce = nonce;
3246 m.chain_id = chain_id;
3247 m.gas_limit = gas_limit;
3248 if max_fee_per_gas.is_none() {
3249 m.max_fee_per_gas = self.gas_price();
3250 }
3251 TypedTransactionRequest::EIP1559(m)
3252 }
3253 Some(TypedTransactionRequest::EIP7702(mut m)) => {
3254 m.nonce = nonce;
3255 m.chain_id = chain_id;
3256 m.gas_limit = gas_limit;
3257 if max_fee_per_gas.is_none() {
3258 m.max_fee_per_gas = self.gas_price();
3259 }
3260 TypedTransactionRequest::EIP7702(m)
3261 }
3262 Some(TypedTransactionRequest::EIP4844(m)) => {
3263 TypedTransactionRequest::EIP4844(match m {
3264 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
3266 m.tx.nonce = nonce;
3267 m.tx.chain_id = chain_id;
3268 m.tx.gas_limit = gas_limit;
3269 if max_fee_per_gas.is_none() {
3270 m.tx.max_fee_per_gas = self.gas_price();
3271 }
3272 if max_fee_per_blob_gas.is_none() {
3273 m.tx.max_fee_per_blob_gas = self
3274 .excess_blob_gas_and_price()
3275 .unwrap_or_default()
3276 .map_or(0, |g| g.blob_gasprice)
3277 }
3278 TxEip4844Variant::TxEip4844WithSidecar(m)
3279 }
3280 TxEip4844Variant::TxEip4844(mut tx) => {
3281 if !self.backend.skip_blob_validation(from) {
3282 return Err(BlockchainError::FailedToDecodeTransaction);
3283 }
3284
3285 tx.nonce = nonce;
3287 tx.chain_id = chain_id;
3288 tx.gas_limit = gas_limit;
3289 if max_fee_per_gas.is_none() {
3290 tx.max_fee_per_gas = self.gas_price();
3291 }
3292 if max_fee_per_blob_gas.is_none() {
3293 tx.max_fee_per_blob_gas = self
3294 .excess_blob_gas_and_price()
3295 .unwrap_or_default()
3296 .map_or(0, |g| g.blob_gasprice)
3297 }
3298
3299 TxEip4844Variant::TxEip4844(tx)
3300 }
3301 })
3302 }
3303 Some(TypedTransactionRequest::Deposit(mut m)) => {
3304 m.gas_limit = gas_limit;
3305 TypedTransactionRequest::Deposit(m)
3306 }
3307 None => return Err(BlockchainError::FailedToDecodeTransaction),
3308 };
3309 Ok(request)
3310 }
3311
3312 pub fn is_impersonated(&self, addr: Address) -> bool {
3314 self.backend.cheats().is_impersonated(addr)
3315 }
3316
3317 fn impersonated_signature(&self, request: &TypedTransactionRequest) -> Signature {
3319 match request {
3320 TypedTransactionRequest::Legacy(_) => Signature::from_scalars_and_parity(
3323 B256::with_last_byte(1),
3324 B256::with_last_byte(1),
3325 false,
3326 ),
3327 TypedTransactionRequest::EIP2930(_)
3328 | TypedTransactionRequest::EIP1559(_)
3329 | TypedTransactionRequest::EIP7702(_)
3330 | TypedTransactionRequest::EIP4844(_)
3331 | TypedTransactionRequest::Deposit(_) => Signature::from_scalars_and_parity(
3332 B256::with_last_byte(1),
3333 B256::with_last_byte(1),
3334 false,
3335 ),
3336 }
3337 }
3338
3339 async fn get_transaction_count(
3341 &self,
3342 address: Address,
3343 block_number: Option<BlockId>,
3344 ) -> Result<u64> {
3345 let block_request = self.block_request(block_number).await?;
3346
3347 if let BlockRequest::Number(number) = block_request
3348 && let Some(fork) = self.get_fork()
3349 && fork.predates_fork(number)
3350 {
3351 return Ok(fork.get_nonce(address, number).await?);
3352 }
3353
3354 self.backend.get_nonce(address, block_request).await
3355 }
3356
3357 async fn request_nonce(
3365 &self,
3366 request: &TransactionRequest,
3367 from: Address,
3368 ) -> Result<(u64, u64)> {
3369 let highest_nonce =
3370 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3371 let nonce = request.nonce.unwrap_or(highest_nonce);
3372
3373 Ok((nonce, highest_nonce))
3374 }
3375
3376 fn add_pending_transaction(
3378 &self,
3379 pending_transaction: PendingTransaction,
3380 requires: Vec<TxMarker>,
3381 provides: Vec<TxMarker>,
3382 ) -> Result<TxHash> {
3383 let from = *pending_transaction.sender();
3384 let priority = self.transaction_priority(&pending_transaction.transaction);
3385 let pool_transaction =
3386 PoolTransaction { requires, provides, pending_transaction, priority };
3387 let tx = self.pool.add_transaction(pool_transaction)?;
3388 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3389 Ok(*tx.hash())
3390 }
3391
3392 pub async fn state_root(&self) -> Option<B256> {
3394 self.backend.get_db().read().await.maybe_state_root()
3395 }
3396
3397 fn ensure_typed_transaction_supported(&self, tx: &TypedTransaction) -> Result<()> {
3399 match &tx {
3400 TypedTransaction::EIP2930(_) => self.backend.ensure_eip2930_active(),
3401 TypedTransaction::EIP1559(_) => self.backend.ensure_eip1559_active(),
3402 TypedTransaction::EIP4844(_) => self.backend.ensure_eip4844_active(),
3403 TypedTransaction::EIP7702(_) => self.backend.ensure_eip7702_active(),
3404 TypedTransaction::Deposit(_) => self.backend.ensure_op_deposits_active(),
3405 TypedTransaction::Legacy(_) => Ok(()),
3406 }
3407 }
3408}
3409
3410fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3411 if provided_nonce == on_chain_nonce {
3412 return Vec::new();
3413 }
3414 let prev_nonce = provided_nonce.saturating_sub(1);
3415 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3416}
3417
3418fn convert_transact_out(out: &Option<Output>) -> Bytes {
3419 match out {
3420 None => Default::default(),
3421 Some(Output::Call(out)) => out.to_vec().into(),
3422 Some(Output::Create(out, _)) => out.to_vec().into(),
3423 }
3424}
3425
3426fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3428 let out = convert_transact_out(out);
3429 match exit {
3430 return_ok!() => Ok(out),
3431 return_revert!() => Err(InvalidTransactionError::Revert(Some(out.0.into())).into()),
3432 reason => Err(BlockchainError::EvmError(reason)),
3433 }
3434}
3435
3436fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3438 match transaction_request_to_typed(request.clone()) {
3439 Some(request) => match request {
3440 TypedTransactionRequest::Legacy(req) => match req.to {
3441 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3442 TxKind::Create => MIN_CREATE_GAS,
3443 },
3444 TypedTransactionRequest::EIP1559(req) => match req.to {
3445 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3446 TxKind::Create => MIN_CREATE_GAS,
3447 },
3448 TypedTransactionRequest::EIP7702(req) => {
3449 MIN_TRANSACTION_GAS
3450 + req.authorization_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3451 }
3452 TypedTransactionRequest::EIP2930(req) => match req.to {
3453 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3454 TxKind::Create => MIN_CREATE_GAS,
3455 },
3456 TypedTransactionRequest::EIP4844(_) => MIN_TRANSACTION_GAS,
3457 TypedTransactionRequest::Deposit(req) => match req.to {
3458 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3459 TxKind::Create => MIN_CREATE_GAS,
3460 },
3461 },
3462 _ => MIN_CREATE_GAS,
3465 }
3466}
3467
3468enum GasEstimationCallResult {
3470 Success(u128),
3471 OutOfGas,
3472 Revert(Option<Bytes>),
3473 EvmError(InstructionResult),
3474}
3475
3476impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3480 type Error = BlockchainError;
3481
3482 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3483 match res {
3484 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3486 Ok(Self::OutOfGas)
3487 }
3488 Err(err) => Err(err),
3489 Ok((exit, output, gas, _)) => match exit {
3490 return_ok!() => Ok(Self::Success(gas)),
3491
3492 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3494 InstructionResult::CallTooDeep
3495 | InstructionResult::OutOfFunds
3496 | InstructionResult::CreateInitCodeStartingEF00
3497 | InstructionResult::InvalidEOFInitCode
3498 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3499
3500 InstructionResult::OutOfGas
3502 | InstructionResult::MemoryOOG
3503 | InstructionResult::MemoryLimitOOG
3504 | InstructionResult::PrecompileOOG
3505 | InstructionResult::InvalidOperandOOG
3506 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3507
3508 InstructionResult::OpcodeNotFound
3510 | InstructionResult::CallNotAllowedInsideStatic
3511 | InstructionResult::StateChangeDuringStaticCall
3512 | InstructionResult::InvalidFEOpcode
3513 | InstructionResult::InvalidJump
3514 | InstructionResult::NotActivated
3515 | InstructionResult::StackUnderflow
3516 | InstructionResult::StackOverflow
3517 | InstructionResult::OutOfOffset
3518 | InstructionResult::CreateCollision
3519 | InstructionResult::OverflowPayment
3520 | InstructionResult::PrecompileError
3521 | InstructionResult::NonceOverflow
3522 | InstructionResult::CreateContractSizeLimit
3523 | InstructionResult::CreateContractStartingWithEF
3524 | InstructionResult::CreateInitCodeSizeLimit
3525 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3526 },
3527 }
3528 }
3529}