1use super::{
2 backend::mem::{BlockRequest, DatabaseRef, State},
3 sign::build_typed_transaction,
4};
5use crate::{
6 ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
7 eth::{
8 backend::{
9 self,
10 db::SerializableState,
11 mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
12 notifications::NewBlockNotifications,
13 validate::TransactionValidator,
14 },
15 error::{
16 BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
17 },
18 fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
19 macros::node_info,
20 miner::FixedBlockTimeMiner,
21 pool::{
22 Pool,
23 transactions::{
24 PoolTransaction, TransactionOrder, TransactionPriority, TxMarker, to_marker,
25 },
26 },
27 sign::{self, Signer},
28 },
29 filter::{EthFilter, Filters, LogsFilter},
30 mem::transaction_build,
31};
32use alloy_consensus::{
33 Account, Blob,
34 transaction::{Recovered, eip4844::TxEip4844Variant},
35};
36use alloy_dyn_abi::TypedData;
37use alloy_eips::{
38 eip2718::Encodable2718,
39 eip4844::BlobTransactionSidecar,
40 eip7910::{EthConfig, EthForkConfig},
41};
42use alloy_evm::overrides::{OverrideBlockHashes, apply_state_overrides};
43use alloy_network::{
44 AnyRpcBlock, AnyRpcTransaction, BlockResponse, TransactionBuilder, TransactionResponse,
45 eip2718::Decodable2718,
46};
47use alloy_primitives::{
48 Address, B64, B256, Bytes, Signature, TxHash, TxKind, U64, U256,
49 map::{HashMap, HashSet},
50};
51use alloy_rpc_types::{
52 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
53 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
54 anvil::{
55 ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
56 },
57 request::TransactionRequest,
58 simulate::{SimulatePayload, SimulatedBlock},
59 state::{AccountOverride, EvmOverrides, StateOverridesBuilder},
60 trace::{
61 filter::TraceFilter,
62 geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
63 parity::LocalizedTransactionTrace,
64 },
65 txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
66};
67use alloy_serde::WithOtherFields;
68use alloy_sol_types::{SolCall, SolValue, sol};
69use alloy_transport::TransportErrorKind;
70use anvil_core::{
71 eth::{
72 EthRequest,
73 block::BlockInfo,
74 transaction::{
75 PendingTransaction, ReceiptResponse, TypedTransaction, TypedTransactionRequest,
76 transaction_request_to_typed,
77 },
78 wallet::WalletCapabilities,
79 },
80 types::{ReorgOptions, TransactionData},
81};
82use anvil_rpc::{error::RpcError, response::ResponseResult};
83use foundry_common::provider::ProviderBuilder;
84use foundry_evm::decode::RevertDecoder;
85use futures::{
86 StreamExt, TryFutureExt,
87 channel::{mpsc::Receiver, oneshot},
88};
89use parking_lot::RwLock;
90use revm::{
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::{
99 sync::mpsc::{UnboundedReceiver, unbounded_channel},
100 try_join,
101};
102
103pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
105
106#[derive(Clone)]
110pub struct EthApi {
111 pool: Arc<Pool>,
113 pub backend: Arc<backend::mem::Backend>,
116 is_mining: bool,
118 signers: Arc<Vec<Box<dyn Signer>>>,
120 fee_history_cache: FeeHistoryCache,
122 fee_history_limit: u64,
124 miner: Miner,
129 logger: LoggingManager,
131 filters: Filters,
133 transaction_order: Arc<RwLock<TransactionOrder>>,
135 net_listening: bool,
137 instance_id: Arc<RwLock<B256>>,
139}
140
141impl EthApi {
142 #[expect(clippy::too_many_arguments)]
144 pub fn new(
145 pool: Arc<Pool>,
146 backend: Arc<backend::mem::Backend>,
147 signers: Arc<Vec<Box<dyn Signer>>>,
148 fee_history_cache: FeeHistoryCache,
149 fee_history_limit: u64,
150 miner: Miner,
151 logger: LoggingManager,
152 filters: Filters,
153 transactions_order: TransactionOrder,
154 ) -> Self {
155 Self {
156 pool,
157 backend,
158 is_mining: true,
159 signers,
160 fee_history_cache,
161 fee_history_limit,
162 miner,
163 logger,
164 filters,
165 net_listening: true,
166 transaction_order: Arc::new(RwLock::new(transactions_order)),
167 instance_id: Arc::new(RwLock::new(B256::random())),
168 }
169 }
170
171 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
173 trace!(target: "rpc::api", "executing eth request");
174 let response = match request.clone() {
175 EthRequest::EthProtocolVersion(()) => self.protocol_version().to_rpc_result(),
176 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
177 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
178 EthRequest::EthGetAccount(addr, block) => {
179 self.get_account(addr, block).await.to_rpc_result()
180 }
181 EthRequest::EthGetAccountInfo(addr, block) => {
182 self.get_account_info(addr, block).await.to_rpc_result()
183 }
184 EthRequest::EthGetBalance(addr, block) => {
185 self.balance(addr, block).await.to_rpc_result()
186 }
187 EthRequest::EthGetTransactionByHash(hash) => {
188 self.transaction_by_hash(hash).await.to_rpc_result()
189 }
190 EthRequest::EthSendTransaction(request) => {
191 self.send_transaction(*request).await.to_rpc_result()
192 }
193 EthRequest::EthSendTransactionSync(request) => {
194 self.send_transaction_sync(*request).await.to_rpc_result()
195 }
196 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
197 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
198 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
199 EthRequest::EthHashrate(()) => self.hashrate().to_rpc_result(),
200 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
201 EthRequest::EthMaxPriorityFeePerGas(_) => {
202 self.gas_max_priority_fee_per_gas().to_rpc_result()
203 }
204 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
205 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
206 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
207 EthRequest::EthCoinbase(()) => self.author().to_rpc_result(),
208 EthRequest::EthGetStorageAt(addr, slot, block) => {
209 self.storage_at(addr, slot, block).await.to_rpc_result()
210 }
211 EthRequest::EthGetBlockByHash(hash, full) => {
212 if full {
213 self.block_by_hash_full(hash).await.to_rpc_result()
214 } else {
215 self.block_by_hash(hash).await.to_rpc_result()
216 }
217 }
218 EthRequest::EthGetBlockByNumber(num, full) => {
219 if full {
220 self.block_by_number_full(num).await.to_rpc_result()
221 } else {
222 self.block_by_number(num).await.to_rpc_result()
223 }
224 }
225 EthRequest::EthGetTransactionCount(addr, block) => {
226 self.transaction_count(addr, block).await.to_rpc_result()
227 }
228 EthRequest::EthGetTransactionCountByHash(hash) => {
229 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
230 }
231 EthRequest::EthGetTransactionCountByNumber(num) => {
232 self.block_transaction_count_by_number(num).await.to_rpc_result()
233 }
234 EthRequest::EthGetUnclesCountByHash(hash) => {
235 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
236 }
237 EthRequest::EthGetUnclesCountByNumber(num) => {
238 self.block_uncles_count_by_number(num).await.to_rpc_result()
239 }
240 EthRequest::EthGetCodeAt(addr, block) => {
241 self.get_code(addr, block).await.to_rpc_result()
242 }
243 EthRequest::EthGetProof(addr, keys, block) => {
244 self.get_proof(addr, keys, block).await.to_rpc_result()
245 }
246 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
247 EthRequest::PersonalSign(content, addr) => {
248 self.sign(addr, content).await.to_rpc_result()
249 }
250 EthRequest::EthSignTransaction(request) => {
251 self.sign_transaction(*request).await.to_rpc_result()
252 }
253 EthRequest::EthSignTypedData(addr, data) => {
254 self.sign_typed_data(addr, data).await.to_rpc_result()
255 }
256 EthRequest::EthSignTypedDataV3(addr, data) => {
257 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
258 }
259 EthRequest::EthSignTypedDataV4(addr, data) => {
260 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
261 }
262 EthRequest::EthSendRawTransaction(tx) => {
263 self.send_raw_transaction(tx).await.to_rpc_result()
264 }
265 EthRequest::EthSendRawTransactionSync(tx) => {
266 self.send_raw_transaction_sync(tx).await.to_rpc_result()
267 }
268 EthRequest::EthCall(call, block, state_override, block_overrides) => self
269 .call(call, block, EvmOverrides::new(state_override, block_overrides))
270 .await
271 .to_rpc_result(),
272 EthRequest::EthSimulateV1(simulation, block) => {
273 self.simulate_v1(simulation, block).await.to_rpc_result()
274 }
275 EthRequest::EthCreateAccessList(call, block) => {
276 self.create_access_list(call, block).await.to_rpc_result()
277 }
278 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
279 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
280 .await
281 .to_rpc_result(),
282 EthRequest::EthGetRawTransactionByHash(hash) => {
283 self.raw_transaction(hash).await.to_rpc_result()
284 }
285 EthRequest::GetBlobByHash(hash) => {
286 self.anvil_get_blob_by_versioned_hash(hash).to_rpc_result()
287 }
288 EthRequest::GetBlobByTransactionHash(hash) => {
289 self.anvil_get_blob_by_tx_hash(hash).to_rpc_result()
290 }
291 EthRequest::GetBlobSidecarsByBlockId(block_id) => {
292 self.anvil_get_blob_sidecars_by_block_id(block_id).to_rpc_result()
293 }
294 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
295 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
296 }
297 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
298 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
299 }
300 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
301 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
302 }
303 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
304 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
305 }
306 EthRequest::EthGetTransactionReceipt(tx) => {
307 self.transaction_receipt(tx).await.to_rpc_result()
308 }
309 EthRequest::EthGetBlockReceipts(number) => {
310 self.block_receipts(number).await.to_rpc_result()
311 }
312 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
313 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
314 }
315 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
316 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
317 }
318 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
319 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
320 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
321 EthRequest::EthConfig(_) => self.config().to_rpc_result(),
322 EthRequest::EthSubmitWork(nonce, pow, digest) => {
323 self.submit_work(nonce, pow, digest).to_rpc_result()
324 }
325 EthRequest::EthSubmitHashRate(rate, id) => {
326 self.submit_hashrate(rate, id).to_rpc_result()
327 }
328 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
329 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
330 }
331 EthRequest::DebugGetRawTransaction(hash) => {
333 self.raw_transaction(hash).await.to_rpc_result()
334 }
335 EthRequest::DebugTraceTransaction(tx, opts) => {
337 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
338 }
339 EthRequest::DebugTraceCall(tx, block, opts) => {
341 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
342 }
343 EthRequest::DebugCodeByHash(hash, block) => {
344 self.debug_code_by_hash(hash, block).await.to_rpc_result()
345 }
346 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
347 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
348 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
349 EthRequest::ImpersonateAccount(addr) => {
350 self.anvil_impersonate_account(addr).await.to_rpc_result()
351 }
352 EthRequest::StopImpersonatingAccount(addr) => {
353 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
354 }
355 EthRequest::AutoImpersonateAccount(enable) => {
356 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
357 }
358 EthRequest::ImpersonateSignature(signature, address) => {
359 self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
360 }
361 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
362 EthRequest::Mine(blocks, interval) => {
363 self.anvil_mine(blocks, interval).await.to_rpc_result()
364 }
365 EthRequest::SetAutomine(enabled) => {
366 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
367 }
368 EthRequest::SetIntervalMining(interval) => {
369 self.anvil_set_interval_mining(interval).to_rpc_result()
370 }
371 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
372 EthRequest::DropTransaction(tx) => {
373 self.anvil_drop_transaction(tx).await.to_rpc_result()
374 }
375 EthRequest::DropAllTransactions() => {
376 self.anvil_drop_all_transactions().await.to_rpc_result()
377 }
378 EthRequest::Reset(fork) => {
379 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
380 }
381 EthRequest::SetBalance(addr, val) => {
382 self.anvil_set_balance(addr, val).await.to_rpc_result()
383 }
384 EthRequest::AddBalance(addr, val) => {
385 self.anvil_add_balance(addr, val).await.to_rpc_result()
386 }
387 EthRequest::DealERC20(addr, token_addr, val) => {
388 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
389 }
390 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
391 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
392 .await
393 .to_rpc_result(),
394 EthRequest::SetCode(addr, code) => {
395 self.anvil_set_code(addr, code).await.to_rpc_result()
396 }
397 EthRequest::SetNonce(addr, nonce) => {
398 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
399 }
400 EthRequest::SetStorageAt(addr, slot, val) => {
401 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
402 }
403 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
404 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
405 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
406 EthRequest::SetMinGasPrice(gas) => {
407 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
408 }
409 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
410 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
411 }
412 EthRequest::DumpState(preserve_historical_states) => self
413 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
414 .await
415 .to_rpc_result(),
416 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
417 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
418 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
419 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
420 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
421 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
422 EthRequest::EvmSetNextBlockTimeStamp(time) => {
423 if time >= U256::from(u64::MAX) {
424 return ResponseResult::Error(RpcError::invalid_params(
425 "The timestamp is too big",
426 ));
427 }
428 let time = time.to::<u64>();
429 self.evm_set_next_block_timestamp(time).to_rpc_result()
430 }
431 EthRequest::EvmSetTime(timestamp) => {
432 if timestamp >= U256::from(u64::MAX) {
433 return ResponseResult::Error(RpcError::invalid_params(
434 "The timestamp is too big",
435 ));
436 }
437 let time = timestamp.to::<u64>();
438 self.evm_set_time(time).to_rpc_result()
439 }
440 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
441 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
442 }
443 EthRequest::EvmSetBlockTimeStampInterval(time) => {
444 self.evm_set_block_timestamp_interval(time).to_rpc_result()
445 }
446 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
447 self.evm_remove_block_timestamp_interval().to_rpc_result()
448 }
449 EthRequest::EvmMine(mine) => {
450 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
451 }
452 EthRequest::EvmMineDetailed(mine) => {
453 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
454 }
455 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
456 EthRequest::EthSendUnsignedTransaction(tx) => {
457 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
458 }
459 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
460 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
461 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
462 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
463 EthRequest::EthNewPendingTransactionFilter(_) => {
464 self.new_pending_transaction_filter().await.to_rpc_result()
465 }
466 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
467 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
468 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
469 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
470 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
471 EthRequest::ErigonGetHeaderByNumber(num) => {
472 self.erigon_get_header_by_number(num).await.to_rpc_result()
473 }
474 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
475 EthRequest::OtsGetInternalOperations(hash) => {
476 self.ots_get_internal_operations(hash).await.to_rpc_result()
477 }
478 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
479 EthRequest::OtsTraceTransaction(hash) => {
480 self.ots_trace_transaction(hash).await.to_rpc_result()
481 }
482 EthRequest::OtsGetTransactionError(hash) => {
483 self.ots_get_transaction_error(hash).await.to_rpc_result()
484 }
485 EthRequest::OtsGetBlockDetails(num) => {
486 self.ots_get_block_details(num).await.to_rpc_result()
487 }
488 EthRequest::OtsGetBlockDetailsByHash(hash) => {
489 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
490 }
491 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
492 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
493 }
494 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
495 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
496 }
497 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
498 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
499 }
500 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
501 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
502 }
503 EthRequest::OtsGetContractCreator(address) => {
504 self.ots_get_contract_creator(address).await.to_rpc_result()
505 }
506 EthRequest::RemovePoolTransactions(address) => {
507 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
508 }
509 EthRequest::Reorg(reorg_options) => {
510 self.anvil_reorg(reorg_options).await.to_rpc_result()
511 }
512 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
513 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
514 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
515 EthRequest::AnvilSetExecutor(executor_pk) => {
516 self.anvil_set_executor(executor_pk).to_rpc_result()
517 }
518 };
519
520 if let ResponseResult::Error(err) = &response {
521 node_info!("\nRPC request failed:");
522 node_info!(" Request: {:?}", request);
523 node_info!(" Error: {}\n", err);
524 }
525
526 response
527 }
528
529 fn sign_request(
530 &self,
531 from: &Address,
532 request: TypedTransactionRequest,
533 ) -> Result<TypedTransaction> {
534 match request {
535 TypedTransactionRequest::Deposit(_) => {
536 let nil_signature = Signature::from_scalars_and_parity(
537 B256::with_last_byte(1),
538 B256::with_last_byte(1),
539 false,
540 );
541 return build_typed_transaction(request, nil_signature);
542 }
543 _ => {
544 for signer in self.signers.iter() {
545 if signer.accounts().contains(from) {
546 let signature = signer.sign_transaction(request.clone(), from)?;
547 return build_typed_transaction(request, signature);
548 }
549 }
550 }
551 }
552 Err(BlockchainError::NoSignerAvailable)
553 }
554
555 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
556 let block_request = match block_number {
557 Some(BlockId::Number(BlockNumber::Pending)) => {
558 let pending_txs = self.pool.ready_transactions().collect();
559 BlockRequest::Pending(pending_txs)
560 }
561 _ => {
562 let number = self.backend.ensure_block_number(block_number).await?;
563 BlockRequest::Number(number)
564 }
565 };
566 Ok(block_request)
567 }
568
569 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
570 match self.pool.get_transaction(hash) {
571 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
572 None => match self.backend.transaction_by_hash(hash).await? {
573 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
574 None => Ok(None),
575 },
576 }
577 }
578
579 pub fn client_version(&self) -> Result<String> {
583 node_info!("web3_clientVersion");
584 Ok(CLIENT_VERSION.to_string())
585 }
586
587 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
591 node_info!("web3_sha3");
592 let hash = alloy_primitives::keccak256(bytes.as_ref());
593 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
594 }
595
596 pub fn protocol_version(&self) -> Result<u64> {
600 node_info!("eth_protocolVersion");
601 Ok(1)
602 }
603
604 pub fn hashrate(&self) -> Result<U256> {
608 node_info!("eth_hashrate");
609 Ok(U256::ZERO)
610 }
611
612 pub fn author(&self) -> Result<Address> {
616 node_info!("eth_coinbase");
617 Ok(self.backend.coinbase())
618 }
619
620 pub fn is_mining(&self) -> Result<bool> {
624 node_info!("eth_mining");
625 Ok(self.is_mining)
626 }
627
628 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
634 node_info!("eth_chainId");
635 Ok(Some(self.backend.chain_id().to::<U64>()))
636 }
637
638 pub fn network_id(&self) -> Result<Option<String>> {
642 node_info!("eth_networkId");
643 let chain_id = self.backend.chain_id().to::<u64>();
644 Ok(Some(format!("{chain_id}")))
645 }
646
647 pub fn net_listening(&self) -> Result<bool> {
651 node_info!("net_listening");
652 Ok(self.net_listening)
653 }
654
655 fn eth_gas_price(&self) -> Result<U256> {
657 node_info!("eth_gasPrice");
658 Ok(U256::from(self.gas_price()))
659 }
660
661 pub fn gas_price(&self) -> u128 {
663 if self.backend.is_eip1559() {
664 if self.backend.is_min_priority_fee_enforced() {
665 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
666 } else {
667 self.backend.base_fee() as u128
668 }
669 } else {
670 self.backend.fees().raw_gas_price()
671 }
672 }
673
674 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
676 Ok(self.backend.excess_blob_gas_and_price())
677 }
678
679 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
684 self.max_priority_fee_per_gas()
685 }
686
687 pub fn blob_base_fee(&self) -> Result<U256> {
691 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
692 }
693
694 pub fn gas_limit(&self) -> U256 {
696 U256::from(self.backend.gas_limit())
697 }
698
699 pub fn accounts(&self) -> Result<Vec<Address>> {
703 node_info!("eth_accounts");
704 let mut unique = HashSet::new();
705 let mut accounts: Vec<Address> = Vec::new();
706 for signer in self.signers.iter() {
707 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
708 }
709 accounts.extend(
710 self.backend
711 .cheats()
712 .impersonated_accounts()
713 .into_iter()
714 .filter(|acc| unique.insert(*acc)),
715 );
716 Ok(accounts.into_iter().collect())
717 }
718
719 pub fn block_number(&self) -> Result<U256> {
723 node_info!("eth_blockNumber");
724 Ok(U256::from(self.backend.best_number()))
725 }
726
727 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
731 node_info!("eth_getBalance");
732 let block_request = self.block_request(block_number).await?;
733
734 if let BlockRequest::Number(number) = block_request
736 && let Some(fork) = self.get_fork()
737 && fork.predates_fork(number)
738 {
739 return Ok(fork.get_balance(address, number).await?);
740 }
741
742 self.backend.get_balance(address, Some(block_request)).await
743 }
744
745 pub async fn get_account(
749 &self,
750 address: Address,
751 block_number: Option<BlockId>,
752 ) -> Result<Account> {
753 node_info!("eth_getAccount");
754 let block_request = self.block_request(block_number).await?;
755
756 if let BlockRequest::Number(number) = block_request
758 && let Some(fork) = self.get_fork()
759 && fork.predates_fork(number)
760 {
761 return Ok(fork.get_account(address, number).await?);
762 }
763
764 self.backend.get_account_at_block(address, Some(block_request)).await
765 }
766
767 pub async fn get_account_info(
771 &self,
772 address: Address,
773 block_number: Option<BlockId>,
774 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
775 node_info!("eth_getAccountInfo");
776
777 if let Some(fork) = self.get_fork() {
778 if let BlockRequest::Number(number) = self.block_request(block_number).await?
780 && fork.predates_fork(number)
781 {
782 let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
785 let code = fork.get_code(address, number).map_err(BlockchainError::from);
786 let nonce = self.get_transaction_count(address, Some(number.into()));
787 let (balance, code, nonce) = try_join!(balance, code, nonce)?;
788
789 return Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code });
790 }
791 }
792
793 let account = self.get_account(address, block_number);
794 let code = self.get_code(address, block_number);
795 let (account, code) = try_join!(account, code)?;
796 Ok(alloy_rpc_types::eth::AccountInfo {
797 balance: account.balance,
798 nonce: account.nonce,
799 code,
800 })
801 }
802 pub async fn storage_at(
806 &self,
807 address: Address,
808 index: U256,
809 block_number: Option<BlockId>,
810 ) -> Result<B256> {
811 node_info!("eth_getStorageAt");
812 let block_request = self.block_request(block_number).await?;
813
814 if let BlockRequest::Number(number) = block_request
816 && let Some(fork) = self.get_fork()
817 && fork.predates_fork(number)
818 {
819 return Ok(B256::from(
820 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
821 ));
822 }
823
824 self.backend.storage_at(address, index, Some(block_request)).await
825 }
826
827 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
831 node_info!("eth_getBlockByHash");
832 self.backend.block_by_hash(hash).await
833 }
834
835 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
839 node_info!("eth_getBlockByHash");
840 self.backend.block_by_hash_full(hash).await
841 }
842
843 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
847 node_info!("eth_getBlockByNumber");
848 if number == BlockNumber::Pending {
849 return Ok(Some(self.pending_block().await));
850 }
851
852 self.backend.block_by_number(number).await
853 }
854
855 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
859 node_info!("eth_getBlockByNumber");
860 if number == BlockNumber::Pending {
861 return Ok(self.pending_block_full().await);
862 }
863 self.backend.block_by_number_full(number).await
864 }
865
866 pub async fn transaction_count(
873 &self,
874 address: Address,
875 block_number: Option<BlockId>,
876 ) -> Result<U256> {
877 node_info!("eth_getTransactionCount");
878 self.get_transaction_count(address, block_number).await.map(U256::from)
879 }
880
881 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
885 node_info!("eth_getBlockTransactionCountByHash");
886 let block = self.backend.block_by_hash(hash).await?;
887 let txs = block.map(|b| match b.transactions() {
888 BlockTransactions::Full(txs) => U256::from(txs.len()),
889 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
890 BlockTransactions::Uncle => U256::from(0),
891 });
892 Ok(txs)
893 }
894
895 pub async fn block_transaction_count_by_number(
899 &self,
900 block_number: BlockNumber,
901 ) -> Result<Option<U256>> {
902 node_info!("eth_getBlockTransactionCountByNumber");
903 let block_request = self.block_request(Some(block_number.into())).await?;
904 if let BlockRequest::Pending(txs) = block_request {
905 let block = self.backend.pending_block(txs).await;
906 return Ok(Some(U256::from(block.transactions.len())));
907 }
908 let block = self.backend.block_by_number(block_number).await?;
909 let txs = block.map(|b| match b.transactions() {
910 BlockTransactions::Full(txs) => U256::from(txs.len()),
911 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
912 BlockTransactions::Uncle => U256::from(0),
913 });
914 Ok(txs)
915 }
916
917 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
921 node_info!("eth_getUncleCountByBlockHash");
922 let block =
923 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
924 Ok(U256::from(block.uncles.len()))
925 }
926
927 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
931 node_info!("eth_getUncleCountByBlockNumber");
932 let block = self
933 .backend
934 .block_by_number(block_number)
935 .await?
936 .ok_or(BlockchainError::BlockNotFound)?;
937 Ok(U256::from(block.uncles.len()))
938 }
939
940 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
944 node_info!("eth_getCode");
945 let block_request = self.block_request(block_number).await?;
946 if let BlockRequest::Number(number) = block_request
948 && let Some(fork) = self.get_fork()
949 && fork.predates_fork(number)
950 {
951 return Ok(fork.get_code(address, number).await?);
952 }
953 self.backend.get_code(address, Some(block_request)).await
954 }
955
956 pub async fn get_proof(
961 &self,
962 address: Address,
963 keys: Vec<B256>,
964 block_number: Option<BlockId>,
965 ) -> Result<EIP1186AccountProofResponse> {
966 node_info!("eth_getProof");
967 let block_request = self.block_request(block_number).await?;
968
969 if let BlockRequest::Number(number) = block_request
972 && let Some(fork) = self.get_fork()
973 && fork.predates_fork_inclusive(number)
974 {
975 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
976 }
977
978 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
979 Ok(proof)
980 }
981
982 pub async fn sign_typed_data(
986 &self,
987 _address: Address,
988 _data: serde_json::Value,
989 ) -> Result<String> {
990 node_info!("eth_signTypedData");
991 Err(BlockchainError::RpcUnimplemented)
992 }
993
994 pub async fn sign_typed_data_v3(
998 &self,
999 _address: Address,
1000 _data: serde_json::Value,
1001 ) -> Result<String> {
1002 node_info!("eth_signTypedData_v3");
1003 Err(BlockchainError::RpcUnimplemented)
1004 }
1005
1006 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
1010 node_info!("eth_signTypedData_v4");
1011 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1012 let signature = signer.sign_typed_data(address, data).await?;
1013 let signature = alloy_primitives::hex::encode(signature.as_bytes());
1014 Ok(format!("0x{signature}"))
1015 }
1016
1017 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1021 node_info!("eth_sign");
1022 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1023 let signature =
1024 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1025 Ok(format!("0x{signature}"))
1026 }
1027
1028 pub async fn sign_transaction(
1032 &self,
1033 mut request: WithOtherFields<TransactionRequest>,
1034 ) -> Result<String> {
1035 node_info!("eth_signTransaction");
1036
1037 let from = request.from.map(Ok).unwrap_or_else(|| {
1038 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1039 })?;
1040
1041 let (nonce, _) = self.request_nonce(&request, from).await?;
1042
1043 if request.gas.is_none() {
1044 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1046 {
1047 request.gas = Some(gas.to());
1048 }
1049 }
1050
1051 let request = self.build_typed_tx_request(request, nonce)?;
1052
1053 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1054 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1055 }
1056
1057 pub async fn send_transaction(
1061 &self,
1062 mut request: WithOtherFields<TransactionRequest>,
1063 ) -> Result<TxHash> {
1064 node_info!("eth_sendTransaction");
1065
1066 let from = request.from.map(Ok).unwrap_or_else(|| {
1067 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1068 })?;
1069 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1070
1071 if request.gas.is_none() {
1072 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1074 {
1075 request.gas = Some(gas.to());
1076 }
1077 }
1078
1079 let request = self.build_typed_tx_request(request, nonce)?;
1080
1081 let pending_transaction = if self.is_impersonated(from) {
1083 let bypass_signature = self.impersonated_signature(&request);
1084 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1085 self.ensure_typed_transaction_supported(&transaction)?;
1086 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1087 PendingTransaction::with_impersonated(transaction, from)
1088 } else {
1089 let transaction = self.sign_request(&from, request)?;
1090 self.ensure_typed_transaction_supported(&transaction)?;
1091 PendingTransaction::new(transaction)?
1092 };
1093 self.backend.validate_pool_transaction(&pending_transaction).await?;
1095
1096 let requires = required_marker(nonce, on_chain_nonce, from);
1097 let provides = vec![to_marker(nonce, from)];
1098 debug_assert!(requires != provides);
1099
1100 self.add_pending_transaction(pending_transaction, requires, provides)
1101 }
1102
1103 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1105 let mut stream = self.new_block_notifications();
1106 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1108 return Ok(receipt);
1109 }
1110 while let Some(notification) = stream.next().await {
1111 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1112 && block.transactions.iter().any(|tx| tx.hash() == hash)
1113 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1114 {
1115 return Ok(receipt);
1116 }
1117 }
1118
1119 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1120 }
1121
1122 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1124 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1125 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1126 .await
1127 .unwrap_or_else(|_elapsed| {
1128 Err(BlockchainError::TransactionConfirmationTimeout {
1129 hash,
1130 duration: TIMEOUT_DURATION,
1131 })
1132 })
1133 }
1134
1135 pub async fn send_transaction_sync(
1139 &self,
1140 request: WithOtherFields<TransactionRequest>,
1141 ) -> Result<ReceiptResponse> {
1142 node_info!("eth_sendTransactionSync");
1143 let hash = self.send_transaction(request).await?;
1144
1145 let receipt = self.check_transaction_inclusion(hash).await?;
1146
1147 Ok(ReceiptResponse::from(receipt))
1148 }
1149
1150 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1154 node_info!("eth_sendRawTransaction");
1155 let mut data = tx.as_ref();
1156 if data.is_empty() {
1157 return Err(BlockchainError::EmptyRawTransactionData);
1158 }
1159
1160 let transaction = TypedTransaction::decode_2718(&mut data)
1161 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1162
1163 self.ensure_typed_transaction_supported(&transaction)?;
1164
1165 let pending_transaction = PendingTransaction::new(transaction)?;
1166
1167 self.backend.validate_pool_transaction(&pending_transaction).await?;
1169
1170 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1171 let from = *pending_transaction.sender();
1172 let nonce = pending_transaction.transaction.nonce();
1173 let requires = required_marker(nonce, on_chain_nonce, from);
1174
1175 let priority = self.transaction_priority(&pending_transaction.transaction);
1176 let pool_transaction = PoolTransaction {
1177 requires,
1178 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1179 pending_transaction,
1180 priority,
1181 };
1182
1183 let tx = self.pool.add_transaction(pool_transaction)?;
1184 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1185 Ok(*tx.hash())
1186 }
1187
1188 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<ReceiptResponse> {
1192 node_info!("eth_sendRawTransactionSync");
1193
1194 let hash = self.send_raw_transaction(tx).await?;
1195 let receipt = self.check_transaction_inclusion(hash).await?;
1196
1197 Ok(ReceiptResponse::from(receipt))
1198 }
1199
1200 pub async fn call(
1204 &self,
1205 request: WithOtherFields<TransactionRequest>,
1206 block_number: Option<BlockId>,
1207 overrides: EvmOverrides,
1208 ) -> Result<Bytes> {
1209 node_info!("eth_call");
1210 let block_request = self.block_request(block_number).await?;
1211 if let BlockRequest::Number(number) = block_request
1213 && let Some(fork) = self.get_fork()
1214 && fork.predates_fork(number)
1215 {
1216 if overrides.has_state() || overrides.has_block() {
1217 return Err(BlockchainError::EvmOverrideError(
1218 "not available on past forked blocks".to_string(),
1219 ));
1220 }
1221 return Ok(fork.call(&request, Some(number.into())).await?);
1222 }
1223
1224 let fees = FeeDetails::new(
1225 request.gas_price,
1226 request.max_fee_per_gas,
1227 request.max_priority_fee_per_gas,
1228 request.max_fee_per_blob_gas,
1229 )?
1230 .or_zero_fees();
1231 self.on_blocking_task(|this| async move {
1234 let (exit, out, gas, _) =
1235 this.backend.call(request, fees, Some(block_request), overrides).await?;
1236 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1237
1238 ensure_return_ok(exit, &out)
1239 })
1240 .await
1241 }
1242
1243 pub async fn simulate_v1(
1244 &self,
1245 request: SimulatePayload,
1246 block_number: Option<BlockId>,
1247 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1248 node_info!("eth_simulateV1");
1249 let block_request = self.block_request(block_number).await?;
1250 if let BlockRequest::Number(number) = block_request
1252 && let Some(fork) = self.get_fork()
1253 && fork.predates_fork(number)
1254 {
1255 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1256 }
1257
1258 self.on_blocking_task(|this| async move {
1261 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1262 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1263
1264 Ok(simulated_blocks)
1265 })
1266 .await
1267 }
1268
1269 pub async fn create_access_list(
1283 &self,
1284 mut request: WithOtherFields<TransactionRequest>,
1285 block_number: Option<BlockId>,
1286 ) -> Result<AccessListResult> {
1287 node_info!("eth_createAccessList");
1288 let block_request = self.block_request(block_number).await?;
1289 if let BlockRequest::Number(number) = block_request
1291 && let Some(fork) = self.get_fork()
1292 && fork.predates_fork(number)
1293 {
1294 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1295 }
1296
1297 self.backend
1298 .with_database_at(Some(block_request), |state, block_env| {
1299 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1300 &state,
1301 request.clone(),
1302 FeeDetails::zero(),
1303 block_env.clone(),
1304 )?;
1305 ensure_return_ok(exit, &out)?;
1306
1307 request.access_list = Some(access_list.clone());
1309
1310 let (exit, out, gas_used, _) = self.backend.call_with_state(
1311 &state,
1312 request.clone(),
1313 FeeDetails::zero(),
1314 block_env,
1315 )?;
1316 ensure_return_ok(exit, &out)?;
1317
1318 Ok(AccessListResult {
1319 access_list: AccessList(access_list.0),
1320 gas_used: U256::from(gas_used),
1321 error: None,
1322 })
1323 })
1324 .await?
1325 }
1326
1327 pub async fn estimate_gas(
1332 &self,
1333 request: WithOtherFields<TransactionRequest>,
1334 block_number: Option<BlockId>,
1335 overrides: EvmOverrides,
1336 ) -> Result<U256> {
1337 node_info!("eth_estimateGas");
1338 self.do_estimate_gas(
1339 request,
1340 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1341 overrides,
1342 )
1343 .await
1344 .map(U256::from)
1345 }
1346
1347 pub fn anvil_get_blob_by_versioned_hash(
1349 &self,
1350 hash: B256,
1351 ) -> Result<Option<alloy_consensus::Blob>> {
1352 node_info!("anvil_getBlobByHash");
1353 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1354 }
1355
1356 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1358 node_info!("anvil_getBlobsByTransactionHash");
1359 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1360 }
1361
1362 pub fn anvil_get_blob_sidecars_by_block_id(
1364 &self,
1365 block_id: BlockId,
1366 ) -> Result<Option<BlobTransactionSidecar>> {
1367 node_info!("anvil_getBlobSidecarsByBlockId");
1368 Ok(self.backend.get_blob_sidecars_by_block_id(block_id)?)
1369 }
1370
1371 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1378 node_info!("eth_getTransactionByHash");
1379 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1380 let from = *pending.sender();
1381 let tx = transaction_build(
1382 Some(*pending.hash()),
1383 pending.transaction,
1384 None,
1385 None,
1386 Some(self.backend.base_fee()),
1387 );
1388
1389 let WithOtherFields { inner: mut tx, other } = tx.0;
1390 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1393
1394 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1395 });
1396 if tx.is_none() {
1397 tx = self.backend.transaction_by_hash(hash).await?
1398 }
1399
1400 Ok(tx)
1401 }
1402
1403 pub async fn transaction_by_block_hash_and_index(
1407 &self,
1408 hash: B256,
1409 index: Index,
1410 ) -> Result<Option<AnyRpcTransaction>> {
1411 node_info!("eth_getTransactionByBlockHashAndIndex");
1412 self.backend.transaction_by_block_hash_and_index(hash, index).await
1413 }
1414
1415 pub async fn transaction_by_block_number_and_index(
1419 &self,
1420 block: BlockNumber,
1421 idx: Index,
1422 ) -> Result<Option<AnyRpcTransaction>> {
1423 node_info!("eth_getTransactionByBlockNumberAndIndex");
1424 self.backend.transaction_by_block_number_and_index(block, idx).await
1425 }
1426
1427 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1431 node_info!("eth_getTransactionReceipt");
1432 self.backend.transaction_receipt(hash).await
1433 }
1434
1435 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1439 node_info!("eth_getBlockReceipts");
1440 self.backend.block_receipts(number).await
1441 }
1442
1443 pub async fn uncle_by_block_hash_and_index(
1447 &self,
1448 block_hash: B256,
1449 idx: Index,
1450 ) -> Result<Option<AnyRpcBlock>> {
1451 node_info!("eth_getUncleByBlockHashAndIndex");
1452 let number =
1453 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1454 if let Some(fork) = self.get_fork()
1455 && fork.predates_fork_inclusive(number)
1456 {
1457 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1458 }
1459 Ok(None)
1461 }
1462
1463 pub async fn uncle_by_block_number_and_index(
1467 &self,
1468 block_number: BlockNumber,
1469 idx: Index,
1470 ) -> Result<Option<AnyRpcBlock>> {
1471 node_info!("eth_getUncleByBlockNumberAndIndex");
1472 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1473 if let Some(fork) = self.get_fork()
1474 && fork.predates_fork_inclusive(number)
1475 {
1476 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1477 }
1478 Ok(None)
1480 }
1481
1482 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1486 node_info!("eth_getLogs");
1487 self.backend.logs(filter).await
1488 }
1489
1490 pub fn work(&self) -> Result<Work> {
1494 node_info!("eth_getWork");
1495 Err(BlockchainError::RpcUnimplemented)
1496 }
1497
1498 pub fn syncing(&self) -> Result<bool> {
1502 node_info!("eth_syncing");
1503 Ok(false)
1504 }
1505
1506 pub fn config(&self) -> Result<EthConfig> {
1517 node_info!("eth_config");
1518 Ok(EthConfig {
1519 current: EthForkConfig {
1520 activation_time: 0,
1521 blob_schedule: self.backend.blob_params(),
1522 chain_id: self.backend.env().read().evm_env.cfg_env.chain_id,
1523 fork_id: Bytes::from_static(&[0; 4]),
1524 precompiles: self.backend.precompiles(),
1525 system_contracts: self.backend.system_contracts(),
1526 },
1527 next: None,
1528 last: None,
1529 })
1530 }
1531
1532 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1536 node_info!("eth_submitWork");
1537 Err(BlockchainError::RpcUnimplemented)
1538 }
1539
1540 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1544 node_info!("eth_submitHashrate");
1545 Err(BlockchainError::RpcUnimplemented)
1546 }
1547
1548 pub async fn fee_history(
1552 &self,
1553 block_count: U256,
1554 newest_block: BlockNumber,
1555 reward_percentiles: Vec<f64>,
1556 ) -> Result<FeeHistory> {
1557 node_info!("eth_feeHistory");
1558 let current = self.backend.best_number();
1561 let slots_in_an_epoch = 32u64;
1562
1563 let number = match newest_block {
1564 BlockNumber::Latest | BlockNumber::Pending => current,
1565 BlockNumber::Earliest => 0,
1566 BlockNumber::Number(n) => n,
1567 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1568 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1569 };
1570
1571 if let Some(fork) = self.get_fork() {
1573 if fork.predates_fork_inclusive(number) {
1576 return fork
1577 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1578 .await
1579 .map_err(BlockchainError::AlloyForkProvider);
1580 }
1581 }
1582
1583 const MAX_BLOCK_COUNT: u64 = 1024u64;
1584 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1585
1586 let highest = number;
1588 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1589
1590 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1592 return Err(FeeHistoryError::InvalidBlockRange.into());
1593 }
1594
1595 let mut response = FeeHistory {
1596 oldest_block: lowest,
1597 base_fee_per_gas: Vec::new(),
1598 gas_used_ratio: Vec::new(),
1599 reward: Some(Default::default()),
1600 base_fee_per_blob_gas: Default::default(),
1601 blob_gas_used_ratio: Default::default(),
1602 };
1603 let mut rewards = Vec::new();
1604
1605 {
1606 let fee_history = self.fee_history_cache.lock();
1607
1608 for n in lowest..=highest {
1610 if let Some(block) = fee_history.get(&n) {
1612 response.base_fee_per_gas.push(block.base_fee);
1613 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1614 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1615 response.gas_used_ratio.push(block.gas_used_ratio);
1616
1617 if !reward_percentiles.is_empty() {
1619 let mut block_rewards = Vec::new();
1620 let resolution_per_percentile: f64 = 2.0;
1621 for p in &reward_percentiles {
1622 let p = p.clamp(0.0, 100.0);
1623 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1624 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1625 block_rewards.push(reward);
1626 }
1627 rewards.push(block_rewards);
1628 }
1629 }
1630 }
1631 }
1632
1633 response.reward = Some(rewards);
1634
1635 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1640
1641 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1645
1646 Ok(response)
1647 }
1648
1649 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1656 node_info!("eth_maxPriorityFeePerGas");
1657 Ok(U256::from(self.lowest_suggestion_tip()))
1658 }
1659
1660 fn lowest_suggestion_tip(&self) -> u128 {
1664 let block_number = self.backend.best_number();
1665 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1666
1667 match latest_cached_block {
1668 Some(block) => block.rewards.iter().copied().min(),
1669 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1670 }
1671 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1672 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1673 }
1674
1675 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1679 node_info!("eth_newFilter");
1680 let historic = if filter.block_option.get_from_block().is_some() {
1683 self.backend.logs(filter.clone()).await?
1684 } else {
1685 vec![]
1686 };
1687 let filter = EthFilter::Logs(Box::new(LogsFilter {
1688 blocks: self.new_block_notifications(),
1689 storage: self.storage_info(),
1690 filter: FilteredParams::new(Some(filter)),
1691 historic: Some(historic),
1692 }));
1693 Ok(self.filters.add_filter(filter).await)
1694 }
1695
1696 pub async fn new_block_filter(&self) -> Result<String> {
1700 node_info!("eth_newBlockFilter");
1701 let filter = EthFilter::Blocks(self.new_block_notifications());
1702 Ok(self.filters.add_filter(filter).await)
1703 }
1704
1705 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1709 node_info!("eth_newPendingTransactionFilter");
1710 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1711 Ok(self.filters.add_filter(filter).await)
1712 }
1713
1714 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1718 node_info!("eth_getFilterChanges");
1719 self.filters.get_filter_changes(id).await
1720 }
1721
1722 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1726 node_info!("eth_getFilterLogs");
1727 if let Some(filter) = self.filters.get_log_filter(id).await {
1728 self.backend.logs(filter).await
1729 } else {
1730 Ok(Vec::new())
1731 }
1732 }
1733
1734 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1736 node_info!("eth_uninstallFilter");
1737 Ok(self.filters.uninstall_filter(id).await.is_some())
1738 }
1739
1740 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1744 node_info!("debug_getRawTransaction");
1745 self.inner_raw_transaction(hash).await
1746 }
1747
1748 pub async fn raw_transaction_by_block_hash_and_index(
1752 &self,
1753 block_hash: B256,
1754 index: Index,
1755 ) -> Result<Option<Bytes>> {
1756 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1757 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1758 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1759 None => Ok(None),
1760 }
1761 }
1762
1763 pub async fn raw_transaction_by_block_number_and_index(
1767 &self,
1768 block_number: BlockNumber,
1769 index: Index,
1770 ) -> Result<Option<Bytes>> {
1771 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1772 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1773 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1774 None => Ok(None),
1775 }
1776 }
1777
1778 pub async fn debug_trace_transaction(
1782 &self,
1783 tx_hash: B256,
1784 opts: GethDebugTracingOptions,
1785 ) -> Result<GethTrace> {
1786 node_info!("debug_traceTransaction");
1787 self.backend.debug_trace_transaction(tx_hash, opts).await
1788 }
1789
1790 pub async fn debug_trace_call(
1794 &self,
1795 request: WithOtherFields<TransactionRequest>,
1796 block_number: Option<BlockId>,
1797 opts: GethDebugTracingCallOptions,
1798 ) -> Result<GethTrace> {
1799 node_info!("debug_traceCall");
1800 let block_request = self.block_request(block_number).await?;
1801 let fees = FeeDetails::new(
1802 request.gas_price,
1803 request.max_fee_per_gas,
1804 request.max_priority_fee_per_gas,
1805 request.max_fee_per_blob_gas,
1806 )?
1807 .or_zero_fees();
1808
1809 let result: std::result::Result<GethTrace, BlockchainError> =
1810 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1811 result
1812 }
1813
1814 pub async fn debug_code_by_hash(
1818 &self,
1819 hash: B256,
1820 block_id: Option<BlockId>,
1821 ) -> Result<Option<Bytes>> {
1822 node_info!("debug_codeByHash");
1823 self.backend.debug_code_by_hash(hash, block_id).await
1824 }
1825
1826 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1830 node_info!("trace_transaction");
1831 self.backend.trace_transaction(tx_hash).await
1832 }
1833
1834 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1838 node_info!("trace_block");
1839 self.backend.trace_block(block).await
1840 }
1841
1842 pub async fn trace_filter(
1846 &self,
1847 filter: TraceFilter,
1848 ) -> Result<Vec<LocalizedTransactionTrace>> {
1849 node_info!("trace_filter");
1850 self.backend.trace_filter(filter).await
1851 }
1852}
1853
1854impl EthApi {
1857 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
1861 node_info!("anvil_impersonateAccount");
1862 self.backend.impersonate(address);
1863 Ok(())
1864 }
1865
1866 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
1870 node_info!("anvil_stopImpersonatingAccount");
1871 self.backend.stop_impersonating(address);
1872 Ok(())
1873 }
1874
1875 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
1879 node_info!("anvil_autoImpersonateAccount");
1880 self.backend.auto_impersonate_account(enabled);
1881 Ok(())
1882 }
1883
1884 pub async fn anvil_impersonate_signature(
1886 &self,
1887 signature: Bytes,
1888 address: Address,
1889 ) -> Result<()> {
1890 node_info!("anvil_impersonateSignature");
1891 self.backend.impersonate_signature(signature, address).await
1892 }
1893
1894 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
1898 node_info!("anvil_getAutomine");
1899 Ok(self.miner.is_auto_mine())
1900 }
1901
1902 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
1906 node_info!("anvil_getIntervalMining");
1907 Ok(self.miner.get_interval())
1908 }
1909
1910 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
1915 node_info!("evm_setAutomine");
1916 if self.miner.is_auto_mine() {
1917 if enable_automine {
1918 return Ok(());
1919 }
1920 self.miner.set_mining_mode(MiningMode::None);
1921 } else if enable_automine {
1922 let listener = self.pool.add_ready_listener();
1923 let mode = MiningMode::instant(1_000, listener);
1924 self.miner.set_mining_mode(mode);
1925 }
1926 Ok(())
1927 }
1928
1929 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
1933 node_info!("anvil_mine");
1934 let interval = interval.map(|i| i.to::<u64>());
1935 let blocks = num_blocks.unwrap_or(U256::from(1));
1936 if blocks.is_zero() {
1937 return Ok(());
1938 }
1939
1940 self.on_blocking_task(|this| async move {
1941 for _ in 0..blocks.to::<u64>() {
1943 if let Some(interval) = interval {
1945 this.backend.time().increase_time(interval);
1946 }
1947 this.mine_one().await;
1948 }
1949 Ok(())
1950 })
1951 .await?;
1952
1953 Ok(())
1954 }
1955
1956 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
1960 node_info!("evm_setIntervalMining");
1961 let mining_mode = if secs == 0 {
1962 MiningMode::None
1963 } else {
1964 let block_time = Duration::from_secs(secs);
1965
1966 self.backend.update_interval_mine_block_time(block_time);
1968
1969 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
1970 };
1971 self.miner.set_mining_mode(mining_mode);
1972 Ok(())
1973 }
1974
1975 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
1979 node_info!("anvil_dropTransaction");
1980 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
1981 }
1982
1983 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
1987 node_info!("anvil_dropAllTransactions");
1988 self.pool.clear();
1989 Ok(())
1990 }
1991
1992 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
1998 self.reset_instance_id();
1999 node_info!("anvil_reset");
2000 if let Some(forking) = forking {
2001 self.backend.reset_fork(forking).await
2003 } else {
2004 self.backend.reset_to_in_mem().await
2007 }
2008 }
2009
2010 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
2011 node_info!("anvil_setChainId");
2012 self.backend.set_chain_id(chain_id);
2013 Ok(())
2014 }
2015
2016 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
2020 node_info!("anvil_setBalance");
2021 self.backend.set_balance(address, balance).await?;
2022 Ok(())
2023 }
2024
2025 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
2029 node_info!("anvil_addBalance");
2030 let current_balance = self.backend.get_balance(address, None).await?;
2031 self.backend.set_balance(address, current_balance + balance).await?;
2032 Ok(())
2033 }
2034
2035 async fn find_erc20_storage_slot(
2052 &self,
2053 token_address: Address,
2054 calldata: Bytes,
2055 expected_value: U256,
2056 ) -> Result<B256> {
2057 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2058
2059 let access_list_result =
2061 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2062 let access_list = access_list_result.access_list;
2063
2064 for item in access_list.0 {
2067 if item.address != token_address {
2068 continue;
2069 };
2070 for slot in &item.storage_keys {
2071 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2072 (*slot, B256::from(expected_value.to_be_bytes())),
2073 ));
2074
2075 let state_override = StateOverridesBuilder::default()
2076 .append(token_address, account_override)
2077 .build();
2078
2079 let evm_override = EvmOverrides::state(Some(state_override));
2080
2081 let Ok(result) =
2082 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2083 else {
2084 continue;
2086 };
2087
2088 let Ok(result_value) = U256::abi_decode(&result) else {
2089 continue;
2091 };
2092
2093 if result_value == expected_value {
2094 return Ok(*slot);
2095 }
2096 }
2097 }
2098
2099 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2100 }
2101
2102 pub async fn anvil_deal_erc20(
2106 &self,
2107 address: Address,
2108 token_address: Address,
2109 balance: U256,
2110 ) -> Result<()> {
2111 node_info!("anvil_dealERC20");
2112
2113 sol! {
2114 #[sol(rpc)]
2115 contract IERC20 {
2116 function balanceOf(address target) external view returns (uint256);
2117 }
2118 }
2119
2120 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2121
2122 let slot =
2124 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2125 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2126 })?;
2127
2128 self.anvil_set_storage_at(
2130 token_address,
2131 U256::from_be_bytes(slot.0),
2132 B256::from(balance.to_be_bytes()),
2133 )
2134 .await?;
2135
2136 Ok(())
2137 }
2138
2139 pub async fn anvil_set_erc20_allowance(
2143 &self,
2144 owner: Address,
2145 spender: Address,
2146 token_address: Address,
2147 amount: U256,
2148 ) -> Result<()> {
2149 node_info!("anvil_setERC20Allowance");
2150
2151 sol! {
2152 #[sol(rpc)]
2153 contract IERC20 {
2154 function allowance(address owner, address spender) external view returns (uint256);
2155 }
2156 }
2157
2158 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2159
2160 let slot =
2162 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2163 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2164 })?;
2165
2166 self.anvil_set_storage_at(
2168 token_address,
2169 U256::from_be_bytes(slot.0),
2170 B256::from(amount.to_be_bytes()),
2171 )
2172 .await?;
2173
2174 Ok(())
2175 }
2176
2177 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2181 node_info!("anvil_setCode");
2182 self.backend.set_code(address, code).await?;
2183 Ok(())
2184 }
2185
2186 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2190 node_info!("anvil_setNonce");
2191 self.backend.set_nonce(address, nonce).await?;
2192 Ok(())
2193 }
2194
2195 pub async fn anvil_set_storage_at(
2199 &self,
2200 address: Address,
2201 slot: U256,
2202 val: B256,
2203 ) -> Result<bool> {
2204 node_info!("anvil_setStorageAt");
2205 self.backend.set_storage_at(address, slot, val).await?;
2206 Ok(true)
2207 }
2208
2209 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2213 node_info!("anvil_setLoggingEnabled");
2214 self.logger.set_enabled(enable);
2215 Ok(())
2216 }
2217
2218 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2222 node_info!("anvil_setMinGasPrice");
2223 if self.backend.is_eip1559() {
2224 return Err(RpcError::invalid_params(
2225 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2226 )
2227 .into());
2228 }
2229 self.backend.set_gas_price(gas.to());
2230 Ok(())
2231 }
2232
2233 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2237 node_info!("anvil_setNextBlockBaseFeePerGas");
2238 if !self.backend.is_eip1559() {
2239 return Err(RpcError::invalid_params(
2240 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2241 )
2242 .into());
2243 }
2244 self.backend.set_base_fee(basefee.to());
2245 Ok(())
2246 }
2247
2248 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2252 node_info!("anvil_setCoinbase");
2253 self.backend.set_coinbase(address);
2254 Ok(())
2255 }
2256
2257 pub async fn anvil_dump_state(
2262 &self,
2263 preserve_historical_states: Option<bool>,
2264 ) -> Result<Bytes> {
2265 node_info!("anvil_dumpState");
2266 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2267 }
2268
2269 pub async fn serialized_state(
2271 &self,
2272 preserve_historical_states: bool,
2273 ) -> Result<SerializableState> {
2274 self.backend.serialized_state(preserve_historical_states).await
2275 }
2276
2277 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2282 node_info!("anvil_loadState");
2283 self.backend.load_state_bytes(buf).await
2284 }
2285
2286 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2290 node_info!("anvil_nodeInfo");
2291
2292 let env = self.backend.env().read();
2293 let fork_config = self.backend.get_fork();
2294 let tx_order = self.transaction_order.read();
2295 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2296
2297 Ok(NodeInfo {
2298 current_block_number: self.backend.best_number(),
2299 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2300 current_block_hash: self.backend.best_hash(),
2301 hard_fork: hard_fork.to_string(),
2302 transaction_order: match *tx_order {
2303 TransactionOrder::Fifo => "fifo".to_string(),
2304 TransactionOrder::Fees => "fees".to_string(),
2305 },
2306 environment: NodeEnvironment {
2307 base_fee: self.backend.base_fee() as u128,
2308 chain_id: self.backend.chain_id().to::<u64>(),
2309 gas_limit: self.backend.gas_limit(),
2310 gas_price: self.gas_price(),
2311 },
2312 fork_config: fork_config
2313 .map(|fork| {
2314 let config = fork.config.read();
2315
2316 NodeForkConfig {
2317 fork_url: Some(config.eth_rpc_url.clone()),
2318 fork_block_number: Some(config.block_number),
2319 fork_retry_backoff: Some(config.backoff.as_millis()),
2320 }
2321 })
2322 .unwrap_or_default(),
2323 })
2324 }
2325
2326 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2330 node_info!("anvil_metadata");
2331 let fork_config = self.backend.get_fork();
2332
2333 Ok(Metadata {
2334 client_version: CLIENT_VERSION.to_string(),
2335 chain_id: self.backend.chain_id().to::<u64>(),
2336 latest_block_hash: self.backend.best_hash(),
2337 latest_block_number: self.backend.best_number(),
2338 instance_id: *self.instance_id.read(),
2339 forked_network: fork_config.map(|cfg| ForkedNetwork {
2340 chain_id: cfg.chain_id(),
2341 fork_block_number: cfg.block_number(),
2342 fork_block_hash: cfg.block_hash(),
2343 }),
2344 snapshots: self.backend.list_state_snapshots(),
2345 })
2346 }
2347
2348 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2349 node_info!("anvil_removePoolTransactions");
2350 self.pool.remove_transactions_by_address(address);
2351 Ok(())
2352 }
2353
2354 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2368 node_info!("anvil_reorg");
2369 let depth = options.depth;
2370 let tx_block_pairs = options.tx_block_pairs;
2371
2372 let current_height = self.backend.best_number();
2374 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2375 RpcError::invalid_params(format!(
2376 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2377 )),
2378 ))?;
2379
2380 let common_block =
2382 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2383
2384 let block_pool_txs = if tx_block_pairs.is_empty() {
2387 HashMap::default()
2388 } else {
2389 let mut pairs = tx_block_pairs;
2390
2391 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2393 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2394 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2395 depth - 1
2396 ))));
2397 }
2398
2399 pairs.sort_by_key(|a| a.1);
2401
2402 let mut nonces: HashMap<Address, u64> = HashMap::default();
2405
2406 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2407 for pair in pairs {
2408 let (tx_data, block_index) = pair;
2409
2410 let pending = match tx_data {
2411 TransactionData::Raw(bytes) => {
2412 let mut data = bytes.as_ref();
2413 let decoded = TypedTransaction::decode_2718(&mut data)
2414 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2415 PendingTransaction::new(decoded)?
2416 }
2417
2418 TransactionData::JSON(req) => {
2419 let mut tx_req = WithOtherFields::new(req);
2420 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2421 self.accounts()?
2422 .first()
2423 .copied()
2424 .ok_or(BlockchainError::NoSignerAvailable)
2425 })?;
2426
2427 let curr_nonce = nonces.entry(from).or_insert(
2429 self.get_transaction_count(
2430 from,
2431 Some(common_block.header.number.into()),
2432 )
2433 .await?,
2434 );
2435
2436 if tx_req.gas.is_none()
2438 && let Ok(gas) = self
2439 .estimate_gas(tx_req.clone(), None, EvmOverrides::default())
2440 .await
2441 {
2442 tx_req.gas = Some(gas.to());
2443 }
2444
2445 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2447
2448 *curr_nonce += 1;
2450
2451 if self.is_impersonated(from) {
2453 let bypass_signature = self.impersonated_signature(&typed);
2454 let transaction =
2455 sign::build_typed_transaction(typed, bypass_signature)?;
2456 self.ensure_typed_transaction_supported(&transaction)?;
2457 PendingTransaction::with_impersonated(transaction, from)
2458 } else {
2459 let transaction = self.sign_request(&from, typed)?;
2460 self.ensure_typed_transaction_supported(&transaction)?;
2461 PendingTransaction::new(transaction)?
2462 }
2463 }
2464 };
2465
2466 let pooled = PoolTransaction::new(pending);
2467 txs.entry(block_index).or_default().push(Arc::new(pooled));
2468 }
2469
2470 txs
2471 };
2472
2473 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2474 Ok(())
2475 }
2476
2477 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2488 node_info!("anvil_rollback");
2489 let depth = depth.unwrap_or(1);
2490
2491 let current_height = self.backend.best_number();
2493 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2494 RpcError::invalid_params(format!(
2495 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2496 )),
2497 ))?;
2498
2499 let common_block =
2501 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2502
2503 self.backend.rollback(common_block).await?;
2504 Ok(())
2505 }
2506
2507 pub async fn evm_snapshot(&self) -> Result<U256> {
2511 node_info!("evm_snapshot");
2512 Ok(self.backend.create_state_snapshot().await)
2513 }
2514
2515 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2520 node_info!("evm_revert");
2521 self.backend.revert_state_snapshot(id).await
2522 }
2523
2524 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2528 node_info!("evm_increaseTime");
2529 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2530 }
2531
2532 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2536 node_info!("evm_setNextBlockTimestamp");
2537 self.backend.time().set_next_block_timestamp(seconds)
2538 }
2539
2540 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2545 node_info!("evm_setTime");
2546 let now = self.backend.time().current_call_timestamp();
2547 self.backend.time().reset(timestamp);
2548
2549 let offset = timestamp.saturating_sub(now);
2551 Ok(Duration::from_millis(offset).as_secs())
2552 }
2553
2554 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2558 node_info!("evm_setBlockGasLimit");
2559 self.backend.set_gas_limit(gas_limit.to());
2560 Ok(true)
2561 }
2562
2563 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2567 node_info!("anvil_setBlockTimestampInterval");
2568 self.backend.time().set_block_timestamp_interval(seconds);
2569 Ok(())
2570 }
2571
2572 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2576 node_info!("anvil_removeBlockTimestampInterval");
2577 Ok(self.backend.time().remove_block_timestamp_interval())
2578 }
2579
2580 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2587 node_info!("evm_mine");
2588
2589 self.do_evm_mine(opts).await?;
2590
2591 Ok("0x0".to_string())
2592 }
2593
2594 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2604 node_info!("evm_mine_detailed");
2605
2606 let mined_blocks = self.do_evm_mine(opts).await?;
2607
2608 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2609
2610 let latest = self.backend.best_number();
2611 for offset in (0..mined_blocks).rev() {
2612 let block_num = latest - offset;
2613 if let Some(mut block) =
2614 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2615 {
2616 let block_txs = match block.transactions_mut() {
2617 BlockTransactions::Full(txs) => txs,
2618 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2619 };
2620 for tx in block_txs.iter_mut() {
2621 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2622 && let Some(output) = receipt.out
2623 {
2624 if !receipt
2626 .inner
2627 .inner
2628 .as_receipt_with_bloom()
2629 .receipt
2630 .status
2631 .coerce_status()
2632 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2633 {
2634 tx.other.insert(
2635 "revertReason".to_string(),
2636 serde_json::to_value(reason).expect("Infallible"),
2637 );
2638 }
2639 tx.other.insert(
2640 "output".to_string(),
2641 serde_json::to_value(output).expect("Infallible"),
2642 );
2643 }
2644 }
2645 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2646 blocks.push(block);
2647 }
2648 }
2649
2650 Ok(blocks)
2651 }
2652
2653 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2657 node_info!("anvil_setBlock");
2658 self.backend.set_block_number(block_number);
2659 Ok(())
2660 }
2661
2662 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2666 node_info!("anvil_setRpcUrl");
2667 if let Some(fork) = self.backend.get_fork() {
2668 let mut config = fork.config.write();
2669 let new_provider = Arc::new(
2671 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2672 |_| {
2673 TransportErrorKind::custom_str(
2674 format!("Failed to parse invalid url {url}").as_str(),
2675 )
2676 },
2677 )?, );
2680 config.provider = new_provider;
2681 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2682 config.eth_rpc_url = url;
2683 }
2684 Ok(())
2685 }
2686
2687 pub async fn anvil_enable_traces(&self) -> Result<()> {
2692 node_info!("anvil_enableTraces");
2693 Err(BlockchainError::RpcUnimplemented)
2694 }
2695
2696 pub async fn eth_send_unsigned_transaction(
2700 &self,
2701 request: WithOtherFields<TransactionRequest>,
2702 ) -> Result<TxHash> {
2703 node_info!("eth_sendUnsignedTransaction");
2704 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2706
2707 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2708
2709 let request = self.build_typed_tx_request(request, nonce)?;
2710
2711 let bypass_signature = self.impersonated_signature(&request);
2712 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2713
2714 self.ensure_typed_transaction_supported(&transaction)?;
2715
2716 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2717
2718 self.backend.validate_pool_transaction(&pending_transaction).await?;
2720
2721 let requires = required_marker(nonce, on_chain_nonce, from);
2722 let provides = vec![to_marker(nonce, from)];
2723
2724 self.add_pending_transaction(pending_transaction, requires, provides)
2725 }
2726
2727 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2733 node_info!("txpool_status");
2734 Ok(self.pool.txpool_status())
2735 }
2736
2737 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2744 node_info!("txpool_inspect");
2745 let mut inspect = TxpoolInspect::default();
2746
2747 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2748 let tx = &tx.pending_transaction.transaction;
2749 let to = tx.to();
2750 let gas_price = tx.gas_price();
2751 let value = tx.value();
2752 let gas = tx.gas_limit();
2753 TxpoolInspectSummary { to, value, gas, gas_price }
2754 }
2755
2756 for pending in self.pool.ready_transactions() {
2763 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2764 let key = pending.pending_transaction.nonce().to_string();
2765 entry.insert(key, convert(pending));
2766 }
2767 for queued in self.pool.pending_transactions() {
2768 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2769 let key = queued.pending_transaction.nonce().to_string();
2770 entry.insert(key, convert(queued));
2771 }
2772 Ok(inspect)
2773 }
2774
2775 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2782 node_info!("txpool_content");
2783 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2784 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2785 let from = *tx.pending_transaction.sender();
2786 let tx = transaction_build(
2787 Some(tx.hash()),
2788 tx.pending_transaction.transaction.clone(),
2789 None,
2790 None,
2791 None,
2792 );
2793
2794 let WithOtherFields { inner: mut tx, other } = tx.0;
2795
2796 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2799
2800 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2801
2802 Ok(tx)
2803 }
2804
2805 for pending in self.pool.ready_transactions() {
2806 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2807 let key = pending.pending_transaction.nonce().to_string();
2808 entry.insert(key, convert(pending)?);
2809 }
2810 for queued in self.pool.pending_transactions() {
2811 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2812 let key = queued.pending_transaction.nonce().to_string();
2813 entry.insert(key, convert(queued)?);
2814 }
2815
2816 Ok(content)
2817 }
2818}
2819
2820impl EthApi {
2822 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2828 node_info!("wallet_getCapabilities");
2829 Ok(self.backend.get_capabilities())
2830 }
2831
2832 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2836 node_info!("anvil_addCapability");
2837 self.backend.add_capability(address);
2838 Ok(())
2839 }
2840
2841 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2842 node_info!("anvil_setExecutor");
2843 self.backend.set_executor(executor_pk)
2844 }
2845}
2846
2847impl EthApi {
2848 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2850 where
2851 C: FnOnce(Self) -> F,
2852 F: Future<Output = Result<R>> + Send + 'static,
2853 R: Send + 'static,
2854 {
2855 let (tx, rx) = oneshot::channel();
2856 let this = self.clone();
2857 let f = c(this);
2858 tokio::task::spawn_blocking(move || {
2859 tokio::runtime::Handle::current().block_on(async move {
2860 let res = f.await;
2861 let _ = tx.send(res);
2862 })
2863 });
2864 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2865 }
2866
2867 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2869 let mut blocks_to_mine = 1u64;
2870
2871 if let Some(opts) = opts {
2872 let timestamp = match opts {
2873 MineOptions::Timestamp(timestamp) => timestamp,
2874 MineOptions::Options { timestamp, blocks } => {
2875 if let Some(blocks) = blocks {
2876 blocks_to_mine = blocks;
2877 }
2878 timestamp
2879 }
2880 };
2881 if let Some(timestamp) = timestamp {
2882 self.evm_set_next_block_timestamp(timestamp)?;
2884 }
2885 }
2886
2887 self.on_blocking_task(|this| async move {
2890 for _ in 0..blocks_to_mine {
2892 this.mine_one().await;
2893 }
2894 Ok(())
2895 })
2896 .await?;
2897
2898 Ok(blocks_to_mine)
2899 }
2900
2901 async fn do_estimate_gas(
2902 &self,
2903 request: WithOtherFields<TransactionRequest>,
2904 block_number: Option<BlockId>,
2905 overrides: EvmOverrides,
2906 ) -> Result<u128> {
2907 let block_request = self.block_request(block_number).await?;
2908 if let BlockRequest::Number(number) = block_request
2910 && let Some(fork) = self.get_fork()
2911 && fork.predates_fork(number)
2912 {
2913 if overrides.has_state() || overrides.has_block() {
2914 return Err(BlockchainError::EvmOverrideError(
2915 "not available on past forked blocks".to_string(),
2916 ));
2917 }
2918 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
2919 }
2920
2921 self.on_blocking_task(|this| async move {
2924 this.backend
2925 .with_database_at(Some(block_request), |state, mut block| {
2926 let mut cache_db = CacheDB::new(state);
2927 if let Some(state_overrides) = overrides.state {
2928 apply_state_overrides(
2929 state_overrides.into_iter().collect(),
2930 &mut cache_db,
2931 )?;
2932 }
2933 if let Some(block_overrides) = overrides.block {
2934 cache_db.apply_block_overrides(*block_overrides, &mut block);
2935 }
2936 this.do_estimate_gas_with_state(request, &cache_db, block)
2937 })
2938 .await?
2939 })
2940 .await
2941 }
2942
2943 fn do_estimate_gas_with_state(
2947 &self,
2948 mut request: WithOtherFields<TransactionRequest>,
2949 state: &dyn DatabaseRef,
2950 block_env: BlockEnv,
2951 ) -> Result<u128> {
2952 let to = request.to.as_ref().and_then(TxKind::to);
2955
2956 let maybe_transfer = (request.input.input().is_none()
2958 || request.input.input().is_some_and(|data| data.is_empty()))
2959 && request.authorization_list.is_none()
2960 && request.access_list.is_none()
2961 && request.blob_versioned_hashes.is_none();
2962
2963 if maybe_transfer
2964 && let Some(to) = to
2965 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
2966 && target_code.as_ref().is_empty()
2967 {
2968 return Ok(MIN_TRANSACTION_GAS);
2969 }
2970
2971 let fees = FeeDetails::new(
2972 request.gas_price,
2973 request.max_fee_per_gas,
2974 request.max_priority_fee_per_gas,
2975 request.max_fee_per_blob_gas,
2976 )?
2977 .or_zero_fees();
2978
2979 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
2982
2983 let gas_price = fees.gas_price.unwrap_or_default();
2984 if gas_price > 0
2986 && let Some(from) = request.from
2987 {
2988 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
2989 if let Some(value) = request.value {
2990 if value > available_funds {
2991 return Err(InvalidTransactionError::InsufficientFunds.into());
2992 }
2993 available_funds -= value;
2995 }
2996 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
2998 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
2999 }
3000
3001 let mut call_to_estimate = request.clone();
3002 call_to_estimate.gas = Some(highest_gas_limit as u64);
3003
3004 let ethres =
3006 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3007
3008 let gas_used = match ethres.try_into()? {
3009 GasEstimationCallResult::Success(gas) => Ok(gas),
3010 GasEstimationCallResult::OutOfGas => {
3011 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3012 }
3013 GasEstimationCallResult::Revert(output) => {
3014 Err(InvalidTransactionError::Revert(output).into())
3015 }
3016 GasEstimationCallResult::EvmError(err) => {
3017 warn!(target: "node", "estimation failed due to {:?}", err);
3018 Err(BlockchainError::EvmError(err))
3019 }
3020 }?;
3021
3022 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3029
3030 let mut mid_gas_limit =
3032 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3033
3034 while (highest_gas_limit - lowest_gas_limit) > 1 {
3036 request.gas = Some(mid_gas_limit as u64);
3037 let ethres = self.backend.call_with_state(
3038 &state,
3039 request.clone(),
3040 fees.clone(),
3041 block_env.clone(),
3042 );
3043
3044 match ethres.try_into()? {
3045 GasEstimationCallResult::Success(_) => {
3046 highest_gas_limit = mid_gas_limit;
3050 }
3051 GasEstimationCallResult::OutOfGas
3052 | GasEstimationCallResult::Revert(_)
3053 | GasEstimationCallResult::EvmError(_) => {
3054 lowest_gas_limit = mid_gas_limit;
3061 }
3062 };
3063 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3065 }
3066
3067 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3068
3069 Ok(highest_gas_limit)
3070 }
3071
3072 pub fn set_transaction_order(&self, order: TransactionOrder) {
3074 *self.transaction_order.write() = order;
3075 }
3076
3077 fn transaction_priority(&self, tx: &TypedTransaction) -> TransactionPriority {
3079 self.transaction_order.read().priority(tx)
3080 }
3081
3082 pub fn chain_id(&self) -> u64 {
3084 self.backend.chain_id().to::<u64>()
3085 }
3086
3087 pub fn get_fork(&self) -> Option<ClientFork> {
3089 self.backend.get_fork()
3090 }
3091
3092 pub fn instance_id(&self) -> B256 {
3094 *self.instance_id.read()
3095 }
3096
3097 pub fn reset_instance_id(&self) {
3099 *self.instance_id.write() = B256::random();
3100 }
3101
3102 #[expect(clippy::borrowed_box)]
3104 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3105 self.signers.iter().find(|signer| signer.is_signer_for(address))
3106 }
3107
3108 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3110 self.backend.new_block_notifications()
3111 }
3112
3113 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3115 self.pool.add_ready_listener()
3116 }
3117
3118 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3120 let (tx, rx) = unbounded_channel();
3121 let mut hashes = self.new_ready_transactions();
3122
3123 let this = self.clone();
3124
3125 tokio::spawn(async move {
3126 while let Some(hash) = hashes.next().await {
3127 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3128 && tx.send(txn).is_err()
3129 {
3130 break;
3131 }
3132 }
3133 });
3134
3135 rx
3136 }
3137
3138 pub fn storage_info(&self) -> StorageInfo {
3140 StorageInfo::new(Arc::clone(&self.backend))
3141 }
3142
3143 pub fn is_fork(&self) -> bool {
3145 self.backend.is_fork()
3146 }
3147
3148 pub async fn mine_one(&self) {
3150 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3151 let outcome = self.backend.mine_block(transactions).await;
3152
3153 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3154 self.pool.on_mined_block(outcome);
3155 }
3156
3157 async fn pending_block(&self) -> AnyRpcBlock {
3159 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3160 let info = self.backend.pending_block(transactions).await;
3161 self.backend.convert_block(info.block)
3162 }
3163
3164 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3166 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3167 let BlockInfo { block, transactions, receipts: _ } =
3168 self.backend.pending_block(transactions).await;
3169
3170 let mut partial_block = self.backend.convert_block(block.clone());
3171
3172 let mut block_transactions = Vec::with_capacity(block.transactions.len());
3173 let base_fee = self.backend.base_fee();
3174
3175 for info in transactions {
3176 let tx = block.transactions.get(info.transaction_index as usize)?.clone();
3177
3178 let tx = transaction_build(
3179 Some(info.transaction_hash),
3180 tx,
3181 Some(&block),
3182 Some(info),
3183 Some(base_fee),
3184 );
3185 block_transactions.push(tx);
3186 }
3187
3188 partial_block.transactions = BlockTransactions::from(block_transactions);
3189
3190 Some(partial_block)
3191 }
3192
3193 fn build_typed_tx_request(
3194 &self,
3195 request: WithOtherFields<TransactionRequest>,
3196 nonce: u64,
3197 ) -> Result<TypedTransactionRequest> {
3198 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
3199 let max_fee_per_gas = request.max_fee_per_gas;
3200 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
3201 let gas_price = request.gas_price;
3202
3203 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
3204 let from = request.from;
3205
3206 let request = match transaction_request_to_typed(request) {
3207 Some(TypedTransactionRequest::Legacy(mut m)) => {
3208 m.nonce = nonce;
3209 m.chain_id = Some(chain_id);
3210 m.gas_limit = gas_limit;
3211 if gas_price.is_none() {
3212 m.gas_price = self.gas_price();
3213 }
3214 TypedTransactionRequest::Legacy(m)
3215 }
3216 Some(TypedTransactionRequest::EIP2930(mut m)) => {
3217 m.nonce = nonce;
3218 m.chain_id = chain_id;
3219 m.gas_limit = gas_limit;
3220 if gas_price.is_none() {
3221 m.gas_price = self.gas_price();
3222 }
3223 TypedTransactionRequest::EIP2930(m)
3224 }
3225 Some(TypedTransactionRequest::EIP1559(mut m)) => {
3226 m.nonce = nonce;
3227 m.chain_id = chain_id;
3228 m.gas_limit = gas_limit;
3229 if max_fee_per_gas.is_none() {
3230 m.max_fee_per_gas = self.gas_price();
3231 }
3232 TypedTransactionRequest::EIP1559(m)
3233 }
3234 Some(TypedTransactionRequest::EIP7702(mut m)) => {
3235 m.nonce = nonce;
3236 m.chain_id = chain_id;
3237 m.gas_limit = gas_limit;
3238 if max_fee_per_gas.is_none() {
3239 m.max_fee_per_gas = self.gas_price();
3240 }
3241 TypedTransactionRequest::EIP7702(m)
3242 }
3243 Some(TypedTransactionRequest::EIP4844(m)) => {
3244 TypedTransactionRequest::EIP4844(match m {
3245 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
3247 m.tx.nonce = nonce;
3248 m.tx.chain_id = chain_id;
3249 m.tx.gas_limit = gas_limit;
3250 if max_fee_per_gas.is_none() {
3251 m.tx.max_fee_per_gas = self.gas_price();
3252 }
3253 if max_fee_per_blob_gas.is_none() {
3254 m.tx.max_fee_per_blob_gas =
3255 self.backend.fees().get_next_block_blob_base_fee_per_gas();
3256 }
3257 TxEip4844Variant::TxEip4844WithSidecar(m)
3258 }
3259 TxEip4844Variant::TxEip4844(mut tx) => {
3260 if !self.backend.skip_blob_validation(from) {
3261 return Err(BlockchainError::FailedToDecodeTransaction);
3262 }
3263
3264 tx.nonce = nonce;
3266 tx.chain_id = chain_id;
3267 tx.gas_limit = gas_limit;
3268 if max_fee_per_gas.is_none() {
3269 tx.max_fee_per_gas = self.gas_price();
3270 }
3271 if max_fee_per_blob_gas.is_none() {
3272 tx.max_fee_per_blob_gas =
3273 self.backend.fees().get_next_block_blob_base_fee_per_gas();
3274 }
3275
3276 TxEip4844Variant::TxEip4844(tx)
3277 }
3278 })
3279 }
3280 Some(TypedTransactionRequest::Deposit(mut m)) => {
3281 m.gas_limit = gas_limit;
3282 TypedTransactionRequest::Deposit(m)
3283 }
3284 None => return Err(BlockchainError::FailedToDecodeTransaction),
3285 };
3286 Ok(request)
3287 }
3288
3289 pub fn is_impersonated(&self, addr: Address) -> bool {
3291 self.backend.cheats().is_impersonated(addr)
3292 }
3293
3294 fn impersonated_signature(&self, request: &TypedTransactionRequest) -> Signature {
3296 match request {
3297 TypedTransactionRequest::Legacy(_) => Signature::from_scalars_and_parity(
3300 B256::with_last_byte(1),
3301 B256::with_last_byte(1),
3302 false,
3303 ),
3304 TypedTransactionRequest::EIP2930(_)
3305 | TypedTransactionRequest::EIP1559(_)
3306 | TypedTransactionRequest::EIP7702(_)
3307 | TypedTransactionRequest::EIP4844(_)
3308 | TypedTransactionRequest::Deposit(_) => Signature::from_scalars_and_parity(
3309 B256::with_last_byte(1),
3310 B256::with_last_byte(1),
3311 false,
3312 ),
3313 }
3314 }
3315
3316 async fn get_transaction_count(
3318 &self,
3319 address: Address,
3320 block_number: Option<BlockId>,
3321 ) -> Result<u64> {
3322 let block_request = self.block_request(block_number).await?;
3323
3324 if let BlockRequest::Number(number) = block_request
3325 && let Some(fork) = self.get_fork()
3326 && fork.predates_fork(number)
3327 {
3328 return Ok(fork.get_nonce(address, number).await?);
3329 }
3330
3331 self.backend.get_nonce(address, block_request).await
3332 }
3333
3334 async fn request_nonce(
3342 &self,
3343 request: &TransactionRequest,
3344 from: Address,
3345 ) -> Result<(u64, u64)> {
3346 let highest_nonce =
3347 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3348 let nonce = request.nonce.unwrap_or(highest_nonce);
3349
3350 Ok((nonce, highest_nonce))
3351 }
3352
3353 fn add_pending_transaction(
3355 &self,
3356 pending_transaction: PendingTransaction,
3357 requires: Vec<TxMarker>,
3358 provides: Vec<TxMarker>,
3359 ) -> Result<TxHash> {
3360 let from = *pending_transaction.sender();
3361 let priority = self.transaction_priority(&pending_transaction.transaction);
3362 let pool_transaction =
3363 PoolTransaction { requires, provides, pending_transaction, priority };
3364 let tx = self.pool.add_transaction(pool_transaction)?;
3365 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3366 Ok(*tx.hash())
3367 }
3368
3369 pub async fn state_root(&self) -> Option<B256> {
3371 self.backend.get_db().read().await.maybe_state_root()
3372 }
3373
3374 fn ensure_typed_transaction_supported(&self, tx: &TypedTransaction) -> Result<()> {
3376 match &tx {
3377 TypedTransaction::EIP2930(_) => self.backend.ensure_eip2930_active(),
3378 TypedTransaction::EIP1559(_) => self.backend.ensure_eip1559_active(),
3379 TypedTransaction::EIP4844(_) => self.backend.ensure_eip4844_active(),
3380 TypedTransaction::EIP7702(_) => self.backend.ensure_eip7702_active(),
3381 TypedTransaction::Deposit(_) => self.backend.ensure_op_deposits_active(),
3382 TypedTransaction::Legacy(_) => Ok(()),
3383 }
3384 }
3385}
3386
3387fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3388 if provided_nonce == on_chain_nonce {
3389 return Vec::new();
3390 }
3391 let prev_nonce = provided_nonce.saturating_sub(1);
3392 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3393}
3394
3395fn convert_transact_out(out: &Option<Output>) -> Bytes {
3396 match out {
3397 None => Default::default(),
3398 Some(Output::Call(out)) => out.to_vec().into(),
3399 Some(Output::Create(out, _)) => out.to_vec().into(),
3400 }
3401}
3402
3403fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3405 let out = convert_transact_out(out);
3406 match exit {
3407 return_ok!() => Ok(out),
3408 return_revert!() => Err(InvalidTransactionError::Revert(Some(out.0.into())).into()),
3409 reason => Err(BlockchainError::EvmError(reason)),
3410 }
3411}
3412
3413fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3415 match transaction_request_to_typed(request.clone()) {
3416 Some(request) => match request {
3417 TypedTransactionRequest::Legacy(req) => match req.to {
3418 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3419 TxKind::Create => MIN_CREATE_GAS,
3420 },
3421 TypedTransactionRequest::EIP1559(req) => match req.to {
3422 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3423 TxKind::Create => MIN_CREATE_GAS,
3424 },
3425 TypedTransactionRequest::EIP7702(req) => {
3426 MIN_TRANSACTION_GAS
3427 + req.authorization_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3428 }
3429 TypedTransactionRequest::EIP2930(req) => match req.to {
3430 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3431 TxKind::Create => MIN_CREATE_GAS,
3432 },
3433 TypedTransactionRequest::EIP4844(_) => MIN_TRANSACTION_GAS,
3434 TypedTransactionRequest::Deposit(req) => match req.to {
3435 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3436 TxKind::Create => MIN_CREATE_GAS,
3437 },
3438 },
3439 _ => MIN_CREATE_GAS,
3442 }
3443}
3444
3445enum GasEstimationCallResult {
3447 Success(u128),
3448 OutOfGas,
3449 Revert(Option<Bytes>),
3450 EvmError(InstructionResult),
3451}
3452
3453impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3457 type Error = BlockchainError;
3458
3459 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3460 match res {
3461 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3463 Ok(Self::OutOfGas)
3464 }
3465 Err(err) => Err(err),
3466 Ok((exit, output, gas, _)) => match exit {
3467 return_ok!() => Ok(Self::Success(gas)),
3468
3469 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3471 InstructionResult::CallTooDeep
3472 | InstructionResult::OutOfFunds
3473 | InstructionResult::CreateInitCodeStartingEF00
3474 | InstructionResult::InvalidEOFInitCode
3475 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3476
3477 InstructionResult::OutOfGas
3479 | InstructionResult::MemoryOOG
3480 | InstructionResult::MemoryLimitOOG
3481 | InstructionResult::PrecompileOOG
3482 | InstructionResult::InvalidOperandOOG
3483 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3484
3485 InstructionResult::OpcodeNotFound
3487 | InstructionResult::CallNotAllowedInsideStatic
3488 | InstructionResult::StateChangeDuringStaticCall
3489 | InstructionResult::InvalidFEOpcode
3490 | InstructionResult::InvalidJump
3491 | InstructionResult::NotActivated
3492 | InstructionResult::StackUnderflow
3493 | InstructionResult::StackOverflow
3494 | InstructionResult::OutOfOffset
3495 | InstructionResult::CreateCollision
3496 | InstructionResult::OverflowPayment
3497 | InstructionResult::PrecompileError
3498 | InstructionResult::NonceOverflow
3499 | InstructionResult::CreateContractSizeLimit
3500 | InstructionResult::CreateContractStartingWithEF
3501 | InstructionResult::CreateInitCodeSizeLimit
3502 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3503 },
3504 }
3505 }
3506}