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::DebugDbGet(key) => self.debug_db_get(key).await.to_rpc_result(),
347 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
348 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
349 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
350 EthRequest::ImpersonateAccount(addr) => {
351 self.anvil_impersonate_account(addr).await.to_rpc_result()
352 }
353 EthRequest::StopImpersonatingAccount(addr) => {
354 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
355 }
356 EthRequest::AutoImpersonateAccount(enable) => {
357 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
358 }
359 EthRequest::ImpersonateSignature(signature, address) => {
360 self.anvil_impersonate_signature(signature, address).await.to_rpc_result()
361 }
362 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
363 EthRequest::Mine(blocks, interval) => {
364 self.anvil_mine(blocks, interval).await.to_rpc_result()
365 }
366 EthRequest::SetAutomine(enabled) => {
367 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
368 }
369 EthRequest::SetIntervalMining(interval) => {
370 self.anvil_set_interval_mining(interval).to_rpc_result()
371 }
372 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
373 EthRequest::DropTransaction(tx) => {
374 self.anvil_drop_transaction(tx).await.to_rpc_result()
375 }
376 EthRequest::DropAllTransactions() => {
377 self.anvil_drop_all_transactions().await.to_rpc_result()
378 }
379 EthRequest::Reset(fork) => {
380 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
381 }
382 EthRequest::SetBalance(addr, val) => {
383 self.anvil_set_balance(addr, val).await.to_rpc_result()
384 }
385 EthRequest::AddBalance(addr, val) => {
386 self.anvil_add_balance(addr, val).await.to_rpc_result()
387 }
388 EthRequest::DealERC20(addr, token_addr, val) => {
389 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
390 }
391 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
392 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
393 .await
394 .to_rpc_result(),
395 EthRequest::SetCode(addr, code) => {
396 self.anvil_set_code(addr, code).await.to_rpc_result()
397 }
398 EthRequest::SetNonce(addr, nonce) => {
399 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
400 }
401 EthRequest::SetStorageAt(addr, slot, val) => {
402 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
403 }
404 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
405 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
406 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
407 EthRequest::SetMinGasPrice(gas) => {
408 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
409 }
410 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
411 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
412 }
413 EthRequest::DumpState(preserve_historical_states) => self
414 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
415 .await
416 .to_rpc_result(),
417 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
418 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
419 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
420 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
421 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
422 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
423 EthRequest::EvmSetNextBlockTimeStamp(time) => {
424 if time >= U256::from(u64::MAX) {
425 return ResponseResult::Error(RpcError::invalid_params(
426 "The timestamp is too big",
427 ));
428 }
429 let time = time.to::<u64>();
430 self.evm_set_next_block_timestamp(time).to_rpc_result()
431 }
432 EthRequest::EvmSetTime(timestamp) => {
433 if timestamp >= U256::from(u64::MAX) {
434 return ResponseResult::Error(RpcError::invalid_params(
435 "The timestamp is too big",
436 ));
437 }
438 let time = timestamp.to::<u64>();
439 self.evm_set_time(time).to_rpc_result()
440 }
441 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
442 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
443 }
444 EthRequest::EvmSetBlockTimeStampInterval(time) => {
445 self.evm_set_block_timestamp_interval(time).to_rpc_result()
446 }
447 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
448 self.evm_remove_block_timestamp_interval().to_rpc_result()
449 }
450 EthRequest::EvmMine(mine) => {
451 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
452 }
453 EthRequest::EvmMineDetailed(mine) => {
454 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
455 }
456 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
457 EthRequest::EthSendUnsignedTransaction(tx) => {
458 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
459 }
460 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
461 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
462 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
463 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
464 EthRequest::EthNewPendingTransactionFilter(_) => {
465 self.new_pending_transaction_filter().await.to_rpc_result()
466 }
467 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
468 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
469 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
470 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
471 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
472 EthRequest::ErigonGetHeaderByNumber(num) => {
473 self.erigon_get_header_by_number(num).await.to_rpc_result()
474 }
475 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
476 EthRequest::OtsGetInternalOperations(hash) => {
477 self.ots_get_internal_operations(hash).await.to_rpc_result()
478 }
479 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
480 EthRequest::OtsTraceTransaction(hash) => {
481 self.ots_trace_transaction(hash).await.to_rpc_result()
482 }
483 EthRequest::OtsGetTransactionError(hash) => {
484 self.ots_get_transaction_error(hash).await.to_rpc_result()
485 }
486 EthRequest::OtsGetBlockDetails(num) => {
487 self.ots_get_block_details(num).await.to_rpc_result()
488 }
489 EthRequest::OtsGetBlockDetailsByHash(hash) => {
490 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
491 }
492 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
493 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
494 }
495 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
496 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
497 }
498 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
499 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
500 }
501 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
502 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
503 }
504 EthRequest::OtsGetContractCreator(address) => {
505 self.ots_get_contract_creator(address).await.to_rpc_result()
506 }
507 EthRequest::RemovePoolTransactions(address) => {
508 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
509 }
510 EthRequest::Reorg(reorg_options) => {
511 self.anvil_reorg(reorg_options).await.to_rpc_result()
512 }
513 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
514 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
515 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
516 EthRequest::AnvilSetExecutor(executor_pk) => {
517 self.anvil_set_executor(executor_pk).to_rpc_result()
518 }
519 };
520
521 if let ResponseResult::Error(err) = &response {
522 node_info!("\nRPC request failed:");
523 node_info!(" Request: {:?}", request);
524 node_info!(" Error: {}\n", err);
525 }
526
527 response
528 }
529
530 fn sign_request(
531 &self,
532 from: &Address,
533 request: TypedTransactionRequest,
534 ) -> Result<TypedTransaction> {
535 match request {
536 TypedTransactionRequest::Deposit(_) => {
537 let nil_signature = Signature::from_scalars_and_parity(
538 B256::with_last_byte(1),
539 B256::with_last_byte(1),
540 false,
541 );
542 return build_typed_transaction(request, nil_signature);
543 }
544 _ => {
545 for signer in self.signers.iter() {
546 if signer.accounts().contains(from) {
547 let signature = signer.sign_transaction(request.clone(), from)?;
548 return build_typed_transaction(request, signature);
549 }
550 }
551 }
552 }
553 Err(BlockchainError::NoSignerAvailable)
554 }
555
556 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
557 let block_request = match block_number {
558 Some(BlockId::Number(BlockNumber::Pending)) => {
559 let pending_txs = self.pool.ready_transactions().collect();
560 BlockRequest::Pending(pending_txs)
561 }
562 _ => {
563 let number = self.backend.ensure_block_number(block_number).await?;
564 BlockRequest::Number(number)
565 }
566 };
567 Ok(block_request)
568 }
569
570 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
571 match self.pool.get_transaction(hash) {
572 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
573 None => match self.backend.transaction_by_hash(hash).await? {
574 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
575 None => Ok(None),
576 },
577 }
578 }
579
580 pub fn client_version(&self) -> Result<String> {
584 node_info!("web3_clientVersion");
585 Ok(CLIENT_VERSION.to_string())
586 }
587
588 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
592 node_info!("web3_sha3");
593 let hash = alloy_primitives::keccak256(bytes.as_ref());
594 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
595 }
596
597 pub fn protocol_version(&self) -> Result<u64> {
601 node_info!("eth_protocolVersion");
602 Ok(1)
603 }
604
605 pub fn hashrate(&self) -> Result<U256> {
609 node_info!("eth_hashrate");
610 Ok(U256::ZERO)
611 }
612
613 pub fn author(&self) -> Result<Address> {
617 node_info!("eth_coinbase");
618 Ok(self.backend.coinbase())
619 }
620
621 pub fn is_mining(&self) -> Result<bool> {
625 node_info!("eth_mining");
626 Ok(self.is_mining)
627 }
628
629 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
635 node_info!("eth_chainId");
636 Ok(Some(self.backend.chain_id().to::<U64>()))
637 }
638
639 pub fn network_id(&self) -> Result<Option<String>> {
643 node_info!("eth_networkId");
644 let chain_id = self.backend.chain_id().to::<u64>();
645 Ok(Some(format!("{chain_id}")))
646 }
647
648 pub fn net_listening(&self) -> Result<bool> {
652 node_info!("net_listening");
653 Ok(self.net_listening)
654 }
655
656 fn eth_gas_price(&self) -> Result<U256> {
658 node_info!("eth_gasPrice");
659 Ok(U256::from(self.gas_price()))
660 }
661
662 pub fn gas_price(&self) -> u128 {
664 if self.backend.is_eip1559() {
665 if self.backend.is_min_priority_fee_enforced() {
666 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
667 } else {
668 self.backend.base_fee() as u128
669 }
670 } else {
671 self.backend.fees().raw_gas_price()
672 }
673 }
674
675 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
677 Ok(self.backend.excess_blob_gas_and_price())
678 }
679
680 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
685 self.max_priority_fee_per_gas()
686 }
687
688 pub fn blob_base_fee(&self) -> Result<U256> {
692 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
693 }
694
695 pub fn gas_limit(&self) -> U256 {
697 U256::from(self.backend.gas_limit())
698 }
699
700 pub fn accounts(&self) -> Result<Vec<Address>> {
704 node_info!("eth_accounts");
705 let mut unique = HashSet::new();
706 let mut accounts: Vec<Address> = Vec::new();
707 for signer in self.signers.iter() {
708 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
709 }
710 accounts.extend(
711 self.backend
712 .cheats()
713 .impersonated_accounts()
714 .into_iter()
715 .filter(|acc| unique.insert(*acc)),
716 );
717 Ok(accounts.into_iter().collect())
718 }
719
720 pub fn block_number(&self) -> Result<U256> {
724 node_info!("eth_blockNumber");
725 Ok(U256::from(self.backend.best_number()))
726 }
727
728 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
732 node_info!("eth_getBalance");
733 let block_request = self.block_request(block_number).await?;
734
735 if let BlockRequest::Number(number) = block_request
737 && let Some(fork) = self.get_fork()
738 && fork.predates_fork(number)
739 {
740 return Ok(fork.get_balance(address, number).await?);
741 }
742
743 self.backend.get_balance(address, Some(block_request)).await
744 }
745
746 pub async fn get_account(
750 &self,
751 address: Address,
752 block_number: Option<BlockId>,
753 ) -> Result<Account> {
754 node_info!("eth_getAccount");
755 let block_request = self.block_request(block_number).await?;
756
757 if let BlockRequest::Number(number) = block_request
759 && let Some(fork) = self.get_fork()
760 && fork.predates_fork(number)
761 {
762 return Ok(fork.get_account(address, number).await?);
763 }
764
765 self.backend.get_account_at_block(address, Some(block_request)).await
766 }
767
768 pub async fn get_account_info(
772 &self,
773 address: Address,
774 block_number: Option<BlockId>,
775 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
776 node_info!("eth_getAccountInfo");
777
778 if let Some(fork) = self.get_fork() {
779 let block_request = self.block_request(block_number).await?;
780 if let BlockRequest::Number(number) = block_request {
782 trace!(target: "node", "get_account_info: fork block {}, requested block {number}", fork.block_number());
783 return if fork.predates_fork(number) {
784 let balance = fork.get_balance(address, number).map_err(BlockchainError::from);
787 let code = fork.get_code(address, number).map_err(BlockchainError::from);
788 let nonce = self.get_transaction_count(address, Some(number.into()));
789 let (balance, code, nonce) = try_join!(balance, code, nonce)?;
790
791 Ok(alloy_rpc_types::eth::AccountInfo { balance, nonce, code })
792 } else {
793 let account_info = self.backend.get_account(address).await?;
796 let code = self.backend.get_code(address, Some(block_request)).await?;
797 Ok(alloy_rpc_types::eth::AccountInfo {
798 balance: account_info.balance,
799 nonce: account_info.nonce,
800 code,
801 })
802 };
803 }
804 }
805
806 let account = self.get_account(address, block_number);
807 let code = self.get_code(address, block_number);
808 let (account, code) = try_join!(account, code)?;
809 Ok(alloy_rpc_types::eth::AccountInfo {
810 balance: account.balance,
811 nonce: account.nonce,
812 code,
813 })
814 }
815 pub async fn storage_at(
819 &self,
820 address: Address,
821 index: U256,
822 block_number: Option<BlockId>,
823 ) -> Result<B256> {
824 node_info!("eth_getStorageAt");
825 let block_request = self.block_request(block_number).await?;
826
827 if let BlockRequest::Number(number) = block_request
829 && let Some(fork) = self.get_fork()
830 && fork.predates_fork(number)
831 {
832 return Ok(B256::from(
833 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
834 ));
835 }
836
837 self.backend.storage_at(address, index, Some(block_request)).await
838 }
839
840 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
844 node_info!("eth_getBlockByHash");
845 self.backend.block_by_hash(hash).await
846 }
847
848 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
852 node_info!("eth_getBlockByHash");
853 self.backend.block_by_hash_full(hash).await
854 }
855
856 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
860 node_info!("eth_getBlockByNumber");
861 if number == BlockNumber::Pending {
862 return Ok(Some(self.pending_block().await));
863 }
864
865 self.backend.block_by_number(number).await
866 }
867
868 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
872 node_info!("eth_getBlockByNumber");
873 if number == BlockNumber::Pending {
874 return Ok(self.pending_block_full().await);
875 }
876 self.backend.block_by_number_full(number).await
877 }
878
879 pub async fn transaction_count(
886 &self,
887 address: Address,
888 block_number: Option<BlockId>,
889 ) -> Result<U256> {
890 node_info!("eth_getTransactionCount");
891 self.get_transaction_count(address, block_number).await.map(U256::from)
892 }
893
894 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
898 node_info!("eth_getBlockTransactionCountByHash");
899 let block = self.backend.block_by_hash(hash).await?;
900 let txs = block.map(|b| match b.transactions() {
901 BlockTransactions::Full(txs) => U256::from(txs.len()),
902 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
903 BlockTransactions::Uncle => U256::from(0),
904 });
905 Ok(txs)
906 }
907
908 pub async fn block_transaction_count_by_number(
912 &self,
913 block_number: BlockNumber,
914 ) -> Result<Option<U256>> {
915 node_info!("eth_getBlockTransactionCountByNumber");
916 let block_request = self.block_request(Some(block_number.into())).await?;
917 if let BlockRequest::Pending(txs) = block_request {
918 let block = self.backend.pending_block(txs).await;
919 return Ok(Some(U256::from(block.transactions.len())));
920 }
921 let block = self.backend.block_by_number(block_number).await?;
922 let txs = block.map(|b| match b.transactions() {
923 BlockTransactions::Full(txs) => U256::from(txs.len()),
924 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
925 BlockTransactions::Uncle => U256::from(0),
926 });
927 Ok(txs)
928 }
929
930 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
934 node_info!("eth_getUncleCountByBlockHash");
935 let block =
936 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
937 Ok(U256::from(block.uncles.len()))
938 }
939
940 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
944 node_info!("eth_getUncleCountByBlockNumber");
945 let block = self
946 .backend
947 .block_by_number(block_number)
948 .await?
949 .ok_or(BlockchainError::BlockNotFound)?;
950 Ok(U256::from(block.uncles.len()))
951 }
952
953 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
957 node_info!("eth_getCode");
958 let block_request = self.block_request(block_number).await?;
959 if let BlockRequest::Number(number) = block_request
961 && let Some(fork) = self.get_fork()
962 && fork.predates_fork(number)
963 {
964 return Ok(fork.get_code(address, number).await?);
965 }
966 self.backend.get_code(address, Some(block_request)).await
967 }
968
969 pub async fn get_proof(
974 &self,
975 address: Address,
976 keys: Vec<B256>,
977 block_number: Option<BlockId>,
978 ) -> Result<EIP1186AccountProofResponse> {
979 node_info!("eth_getProof");
980 let block_request = self.block_request(block_number).await?;
981
982 if let BlockRequest::Number(number) = block_request
985 && let Some(fork) = self.get_fork()
986 && fork.predates_fork_inclusive(number)
987 {
988 return Ok(fork.get_proof(address, keys, Some(number.into())).await?);
989 }
990
991 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
992 Ok(proof)
993 }
994
995 pub async fn sign_typed_data(
999 &self,
1000 _address: Address,
1001 _data: serde_json::Value,
1002 ) -> Result<String> {
1003 node_info!("eth_signTypedData");
1004 Err(BlockchainError::RpcUnimplemented)
1005 }
1006
1007 pub async fn sign_typed_data_v3(
1011 &self,
1012 _address: Address,
1013 _data: serde_json::Value,
1014 ) -> Result<String> {
1015 node_info!("eth_signTypedData_v3");
1016 Err(BlockchainError::RpcUnimplemented)
1017 }
1018
1019 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
1023 node_info!("eth_signTypedData_v4");
1024 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1025 let signature = signer.sign_typed_data(address, data).await?;
1026 let signature = alloy_primitives::hex::encode(signature.as_bytes());
1027 Ok(format!("0x{signature}"))
1028 }
1029
1030 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
1034 node_info!("eth_sign");
1035 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
1036 let signature =
1037 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
1038 Ok(format!("0x{signature}"))
1039 }
1040
1041 pub async fn sign_transaction(
1045 &self,
1046 mut request: WithOtherFields<TransactionRequest>,
1047 ) -> Result<String> {
1048 node_info!("eth_signTransaction");
1049
1050 let from = request.from.map(Ok).unwrap_or_else(|| {
1051 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1052 })?;
1053
1054 let (nonce, _) = self.request_nonce(&request, from).await?;
1055
1056 if request.gas.is_none() {
1057 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1059 {
1060 request.gas = Some(gas.to());
1061 }
1062 }
1063
1064 let request = self.build_typed_tx_request(request, nonce)?;
1065
1066 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1067 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1068 }
1069
1070 pub async fn send_transaction(
1074 &self,
1075 mut request: WithOtherFields<TransactionRequest>,
1076 ) -> Result<TxHash> {
1077 node_info!("eth_sendTransaction");
1078
1079 let from = request.from.map(Ok).unwrap_or_else(|| {
1080 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1081 })?;
1082 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1083
1084 if request.gas.is_none() {
1085 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1087 {
1088 request.gas = Some(gas.to());
1089 }
1090 }
1091
1092 let request = self.build_typed_tx_request(request, nonce)?;
1093
1094 let pending_transaction = if self.is_impersonated(from) {
1096 let bypass_signature = self.impersonated_signature(&request);
1097 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1098 self.ensure_typed_transaction_supported(&transaction)?;
1099 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1100 PendingTransaction::with_impersonated(transaction, from)
1101 } else {
1102 let transaction = self.sign_request(&from, request)?;
1103 self.ensure_typed_transaction_supported(&transaction)?;
1104 PendingTransaction::new(transaction)?
1105 };
1106 self.backend.validate_pool_transaction(&pending_transaction).await?;
1108
1109 let requires = required_marker(nonce, on_chain_nonce, from);
1110 let provides = vec![to_marker(nonce, from)];
1111 debug_assert!(requires != provides);
1112
1113 self.add_pending_transaction(pending_transaction, requires, provides)
1114 }
1115
1116 async fn await_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1118 let mut stream = self.new_block_notifications();
1119 if let Some(receipt) = self.backend.transaction_receipt(hash).await? {
1121 return Ok(receipt);
1122 }
1123 while let Some(notification) = stream.next().await {
1124 if let Some(block) = self.backend.get_block_by_hash(notification.hash)
1125 && block.transactions.iter().any(|tx| tx.hash() == hash)
1126 && let Some(receipt) = self.backend.transaction_receipt(hash).await?
1127 {
1128 return Ok(receipt);
1129 }
1130 }
1131
1132 Err(BlockchainError::Message("Failed to await transaction inclusion".to_string()))
1133 }
1134
1135 async fn check_transaction_inclusion(&self, hash: TxHash) -> Result<ReceiptResponse> {
1137 const TIMEOUT_DURATION: Duration = Duration::from_secs(30);
1138 tokio::time::timeout(TIMEOUT_DURATION, self.await_transaction_inclusion(hash))
1139 .await
1140 .unwrap_or_else(|_elapsed| {
1141 Err(BlockchainError::TransactionConfirmationTimeout {
1142 hash,
1143 duration: TIMEOUT_DURATION,
1144 })
1145 })
1146 }
1147
1148 pub async fn send_transaction_sync(
1152 &self,
1153 request: WithOtherFields<TransactionRequest>,
1154 ) -> Result<ReceiptResponse> {
1155 node_info!("eth_sendTransactionSync");
1156 let hash = self.send_transaction(request).await?;
1157
1158 let receipt = self.check_transaction_inclusion(hash).await?;
1159
1160 Ok(ReceiptResponse::from(receipt))
1161 }
1162
1163 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1167 node_info!("eth_sendRawTransaction");
1168 let mut data = tx.as_ref();
1169 if data.is_empty() {
1170 return Err(BlockchainError::EmptyRawTransactionData);
1171 }
1172
1173 let transaction = TypedTransaction::decode_2718(&mut data)
1174 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1175
1176 self.ensure_typed_transaction_supported(&transaction)?;
1177
1178 let pending_transaction = PendingTransaction::new(transaction)?;
1179
1180 self.backend.validate_pool_transaction(&pending_transaction).await?;
1182
1183 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1184 let from = *pending_transaction.sender();
1185 let nonce = pending_transaction.transaction.nonce();
1186 let requires = required_marker(nonce, on_chain_nonce, from);
1187
1188 let priority = self.transaction_priority(&pending_transaction.transaction);
1189 let pool_transaction = PoolTransaction {
1190 requires,
1191 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1192 pending_transaction,
1193 priority,
1194 };
1195
1196 let tx = self.pool.add_transaction(pool_transaction)?;
1197 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1198 Ok(*tx.hash())
1199 }
1200
1201 pub async fn send_raw_transaction_sync(&self, tx: Bytes) -> Result<ReceiptResponse> {
1205 node_info!("eth_sendRawTransactionSync");
1206
1207 let hash = self.send_raw_transaction(tx).await?;
1208 let receipt = self.check_transaction_inclusion(hash).await?;
1209
1210 Ok(ReceiptResponse::from(receipt))
1211 }
1212
1213 pub async fn call(
1217 &self,
1218 request: WithOtherFields<TransactionRequest>,
1219 block_number: Option<BlockId>,
1220 overrides: EvmOverrides,
1221 ) -> Result<Bytes> {
1222 node_info!("eth_call");
1223 let block_request = self.block_request(block_number).await?;
1224 if let BlockRequest::Number(number) = block_request
1226 && let Some(fork) = self.get_fork()
1227 && fork.predates_fork(number)
1228 {
1229 if overrides.has_state() || overrides.has_block() {
1230 return Err(BlockchainError::EvmOverrideError(
1231 "not available on past forked blocks".to_string(),
1232 ));
1233 }
1234 return Ok(fork.call(&request, Some(number.into())).await?);
1235 }
1236
1237 let fees = FeeDetails::new(
1238 request.gas_price,
1239 request.max_fee_per_gas,
1240 request.max_priority_fee_per_gas,
1241 request.max_fee_per_blob_gas,
1242 )?
1243 .or_zero_fees();
1244 self.on_blocking_task(|this| async move {
1247 let (exit, out, gas, _) =
1248 this.backend.call(request, fees, Some(block_request), overrides).await?;
1249 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1250
1251 ensure_return_ok(exit, &out)
1252 })
1253 .await
1254 }
1255
1256 pub async fn simulate_v1(
1257 &self,
1258 request: SimulatePayload,
1259 block_number: Option<BlockId>,
1260 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1261 node_info!("eth_simulateV1");
1262 let block_request = self.block_request(block_number).await?;
1263 if let BlockRequest::Number(number) = block_request
1265 && let Some(fork) = self.get_fork()
1266 && fork.predates_fork(number)
1267 {
1268 return Ok(fork.simulate_v1(&request, Some(number.into())).await?);
1269 }
1270
1271 self.on_blocking_task(|this| async move {
1274 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1275 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1276
1277 Ok(simulated_blocks)
1278 })
1279 .await
1280 }
1281
1282 pub async fn create_access_list(
1296 &self,
1297 mut request: WithOtherFields<TransactionRequest>,
1298 block_number: Option<BlockId>,
1299 ) -> Result<AccessListResult> {
1300 node_info!("eth_createAccessList");
1301 let block_request = self.block_request(block_number).await?;
1302 if let BlockRequest::Number(number) = block_request
1304 && let Some(fork) = self.get_fork()
1305 && fork.predates_fork(number)
1306 {
1307 return Ok(fork.create_access_list(&request, Some(number.into())).await?);
1308 }
1309
1310 self.backend
1311 .with_database_at(Some(block_request), |state, block_env| {
1312 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1313 &state,
1314 request.clone(),
1315 FeeDetails::zero(),
1316 block_env.clone(),
1317 )?;
1318 ensure_return_ok(exit, &out)?;
1319
1320 request.access_list = Some(access_list.clone());
1322
1323 let (exit, out, gas_used, _) = self.backend.call_with_state(
1324 &state,
1325 request.clone(),
1326 FeeDetails::zero(),
1327 block_env,
1328 )?;
1329 ensure_return_ok(exit, &out)?;
1330
1331 Ok(AccessListResult {
1332 access_list: AccessList(access_list.0),
1333 gas_used: U256::from(gas_used),
1334 error: None,
1335 })
1336 })
1337 .await?
1338 }
1339
1340 pub async fn estimate_gas(
1345 &self,
1346 request: WithOtherFields<TransactionRequest>,
1347 block_number: Option<BlockId>,
1348 overrides: EvmOverrides,
1349 ) -> Result<U256> {
1350 node_info!("eth_estimateGas");
1351 self.do_estimate_gas(
1352 request,
1353 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1354 overrides,
1355 )
1356 .await
1357 .map(U256::from)
1358 }
1359
1360 pub fn anvil_get_blob_by_versioned_hash(
1362 &self,
1363 hash: B256,
1364 ) -> Result<Option<alloy_consensus::Blob>> {
1365 node_info!("anvil_getBlobByHash");
1366 Ok(self.backend.get_blob_by_versioned_hash(hash)?)
1367 }
1368
1369 pub fn anvil_get_blob_by_tx_hash(&self, hash: B256) -> Result<Option<Vec<Blob>>> {
1371 node_info!("anvil_getBlobsByTransactionHash");
1372 Ok(self.backend.get_blob_by_tx_hash(hash)?)
1373 }
1374
1375 pub fn anvil_get_blobs_by_block_id(
1377 &self,
1378 block_id: impl Into<BlockId>,
1379 versioned_hashes: Vec<B256>,
1380 ) -> Result<Option<Vec<Blob>>> {
1381 node_info!("anvil_getBlobsByBlockId");
1382 Ok(self.backend.get_blobs_by_block_id(block_id, versioned_hashes)?)
1383 }
1384
1385 pub fn anvil_get_blob_sidecars_by_block_id(
1387 &self,
1388 block_id: BlockId,
1389 ) -> Result<Option<BlobTransactionSidecar>> {
1390 node_info!("anvil_getBlobSidecarsByBlockId");
1391 Ok(self.backend.get_blob_sidecars_by_block_id(block_id)?)
1392 }
1393
1394 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1401 node_info!("eth_getTransactionByHash");
1402 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1403 let from = *pending.sender();
1404 let tx = transaction_build(
1405 Some(*pending.hash()),
1406 pending.transaction,
1407 None,
1408 None,
1409 Some(self.backend.base_fee()),
1410 );
1411
1412 let WithOtherFields { inner: mut tx, other } = tx.0;
1413 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1416
1417 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1418 });
1419 if tx.is_none() {
1420 tx = self.backend.transaction_by_hash(hash).await?
1421 }
1422
1423 Ok(tx)
1424 }
1425
1426 pub async fn transaction_by_block_hash_and_index(
1430 &self,
1431 hash: B256,
1432 index: Index,
1433 ) -> Result<Option<AnyRpcTransaction>> {
1434 node_info!("eth_getTransactionByBlockHashAndIndex");
1435 self.backend.transaction_by_block_hash_and_index(hash, index).await
1436 }
1437
1438 pub async fn transaction_by_block_number_and_index(
1442 &self,
1443 block: BlockNumber,
1444 idx: Index,
1445 ) -> Result<Option<AnyRpcTransaction>> {
1446 node_info!("eth_getTransactionByBlockNumberAndIndex");
1447 self.backend.transaction_by_block_number_and_index(block, idx).await
1448 }
1449
1450 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1454 node_info!("eth_getTransactionReceipt");
1455 self.backend.transaction_receipt(hash).await
1456 }
1457
1458 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1462 node_info!("eth_getBlockReceipts");
1463 self.backend.block_receipts(number).await
1464 }
1465
1466 pub async fn uncle_by_block_hash_and_index(
1470 &self,
1471 block_hash: B256,
1472 idx: Index,
1473 ) -> Result<Option<AnyRpcBlock>> {
1474 node_info!("eth_getUncleByBlockHashAndIndex");
1475 let number =
1476 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1477 if let Some(fork) = self.get_fork()
1478 && fork.predates_fork_inclusive(number)
1479 {
1480 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?);
1481 }
1482 Ok(None)
1484 }
1485
1486 pub async fn uncle_by_block_number_and_index(
1490 &self,
1491 block_number: BlockNumber,
1492 idx: Index,
1493 ) -> Result<Option<AnyRpcBlock>> {
1494 node_info!("eth_getUncleByBlockNumberAndIndex");
1495 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1496 if let Some(fork) = self.get_fork()
1497 && fork.predates_fork_inclusive(number)
1498 {
1499 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?);
1500 }
1501 Ok(None)
1503 }
1504
1505 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1509 node_info!("eth_getLogs");
1510 self.backend.logs(filter).await
1511 }
1512
1513 pub fn work(&self) -> Result<Work> {
1517 node_info!("eth_getWork");
1518 Err(BlockchainError::RpcUnimplemented)
1519 }
1520
1521 pub fn syncing(&self) -> Result<bool> {
1525 node_info!("eth_syncing");
1526 Ok(false)
1527 }
1528
1529 pub fn config(&self) -> Result<EthConfig> {
1540 node_info!("eth_config");
1541 Ok(EthConfig {
1542 current: EthForkConfig {
1543 activation_time: 0,
1544 blob_schedule: self.backend.blob_params(),
1545 chain_id: self.backend.env().read().evm_env.cfg_env.chain_id,
1546 fork_id: Bytes::from_static(&[0; 4]),
1547 precompiles: self.backend.precompiles(),
1548 system_contracts: self.backend.system_contracts(),
1549 },
1550 next: None,
1551 last: None,
1552 })
1553 }
1554
1555 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1559 node_info!("eth_submitWork");
1560 Err(BlockchainError::RpcUnimplemented)
1561 }
1562
1563 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1567 node_info!("eth_submitHashrate");
1568 Err(BlockchainError::RpcUnimplemented)
1569 }
1570
1571 pub async fn fee_history(
1575 &self,
1576 block_count: U256,
1577 newest_block: BlockNumber,
1578 reward_percentiles: Vec<f64>,
1579 ) -> Result<FeeHistory> {
1580 node_info!("eth_feeHistory");
1581 let current = self.backend.best_number();
1584 let slots_in_an_epoch = 32u64;
1585
1586 let number = match newest_block {
1587 BlockNumber::Latest | BlockNumber::Pending => current,
1588 BlockNumber::Earliest => 0,
1589 BlockNumber::Number(n) => n,
1590 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1591 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1592 };
1593
1594 if let Some(fork) = self.get_fork() {
1596 if fork.predates_fork_inclusive(number) {
1599 return fork
1600 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1601 .await
1602 .map_err(BlockchainError::AlloyForkProvider);
1603 }
1604 }
1605
1606 const MAX_BLOCK_COUNT: u64 = 1024u64;
1607 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1608
1609 let highest = number;
1611 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1612
1613 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1615 return Err(FeeHistoryError::InvalidBlockRange.into());
1616 }
1617
1618 let mut response = FeeHistory {
1619 oldest_block: lowest,
1620 base_fee_per_gas: Vec::new(),
1621 gas_used_ratio: Vec::new(),
1622 reward: Some(Default::default()),
1623 base_fee_per_blob_gas: Default::default(),
1624 blob_gas_used_ratio: Default::default(),
1625 };
1626 let mut rewards = Vec::new();
1627
1628 {
1629 let fee_history = self.fee_history_cache.lock();
1630
1631 for n in lowest..=highest {
1633 if let Some(block) = fee_history.get(&n) {
1635 response.base_fee_per_gas.push(block.base_fee);
1636 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1637 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1638 response.gas_used_ratio.push(block.gas_used_ratio);
1639
1640 if !reward_percentiles.is_empty() {
1642 let mut block_rewards = Vec::new();
1643 let resolution_per_percentile: f64 = 2.0;
1644 for p in &reward_percentiles {
1645 let p = p.clamp(0.0, 100.0);
1646 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1647 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1648 block_rewards.push(reward);
1649 }
1650 rewards.push(block_rewards);
1651 }
1652 }
1653 }
1654 }
1655
1656 response.reward = Some(rewards);
1657
1658 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1663
1664 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1668
1669 Ok(response)
1670 }
1671
1672 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1679 node_info!("eth_maxPriorityFeePerGas");
1680 Ok(U256::from(self.lowest_suggestion_tip()))
1681 }
1682
1683 fn lowest_suggestion_tip(&self) -> u128 {
1687 let block_number = self.backend.best_number();
1688 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1689
1690 match latest_cached_block {
1691 Some(block) => block.rewards.iter().copied().min(),
1692 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1693 }
1694 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1695 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1696 }
1697
1698 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1702 node_info!("eth_newFilter");
1703 let historic = if filter.block_option.get_from_block().is_some() {
1706 self.backend.logs(filter.clone()).await?
1707 } else {
1708 vec![]
1709 };
1710 let filter = EthFilter::Logs(Box::new(LogsFilter {
1711 blocks: self.new_block_notifications(),
1712 storage: self.storage_info(),
1713 filter: FilteredParams::new(Some(filter)),
1714 historic: Some(historic),
1715 }));
1716 Ok(self.filters.add_filter(filter).await)
1717 }
1718
1719 pub async fn new_block_filter(&self) -> Result<String> {
1723 node_info!("eth_newBlockFilter");
1724 let filter = EthFilter::Blocks(self.new_block_notifications());
1725 Ok(self.filters.add_filter(filter).await)
1726 }
1727
1728 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1732 node_info!("eth_newPendingTransactionFilter");
1733 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1734 Ok(self.filters.add_filter(filter).await)
1735 }
1736
1737 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1741 node_info!("eth_getFilterChanges");
1742 self.filters.get_filter_changes(id).await
1743 }
1744
1745 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1749 node_info!("eth_getFilterLogs");
1750 if let Some(filter) = self.filters.get_log_filter(id).await {
1751 self.backend.logs(filter).await
1752 } else {
1753 Ok(Vec::new())
1754 }
1755 }
1756
1757 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1759 node_info!("eth_uninstallFilter");
1760 Ok(self.filters.uninstall_filter(id).await.is_some())
1761 }
1762
1763 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1767 node_info!("debug_getRawTransaction");
1768 self.inner_raw_transaction(hash).await
1769 }
1770
1771 pub async fn raw_transaction_by_block_hash_and_index(
1775 &self,
1776 block_hash: B256,
1777 index: Index,
1778 ) -> Result<Option<Bytes>> {
1779 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1780 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1781 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1782 None => Ok(None),
1783 }
1784 }
1785
1786 pub async fn raw_transaction_by_block_number_and_index(
1790 &self,
1791 block_number: BlockNumber,
1792 index: Index,
1793 ) -> Result<Option<Bytes>> {
1794 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1795 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1796 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1797 None => Ok(None),
1798 }
1799 }
1800
1801 pub async fn debug_trace_transaction(
1805 &self,
1806 tx_hash: B256,
1807 opts: GethDebugTracingOptions,
1808 ) -> Result<GethTrace> {
1809 node_info!("debug_traceTransaction");
1810 self.backend.debug_trace_transaction(tx_hash, opts).await
1811 }
1812
1813 pub async fn debug_trace_call(
1817 &self,
1818 request: WithOtherFields<TransactionRequest>,
1819 block_number: Option<BlockId>,
1820 opts: GethDebugTracingCallOptions,
1821 ) -> Result<GethTrace> {
1822 node_info!("debug_traceCall");
1823 let block_request = self.block_request(block_number).await?;
1824 let fees = FeeDetails::new(
1825 request.gas_price,
1826 request.max_fee_per_gas,
1827 request.max_priority_fee_per_gas,
1828 request.max_fee_per_blob_gas,
1829 )?
1830 .or_zero_fees();
1831
1832 let result: std::result::Result<GethTrace, BlockchainError> =
1833 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1834 result
1835 }
1836
1837 pub async fn debug_code_by_hash(
1841 &self,
1842 hash: B256,
1843 block_id: Option<BlockId>,
1844 ) -> Result<Option<Bytes>> {
1845 node_info!("debug_codeByHash");
1846 self.backend.debug_code_by_hash(hash, block_id).await
1847 }
1848
1849 pub async fn debug_db_get(&self, key: String) -> Result<Option<Bytes>> {
1854 node_info!("debug_dbGet");
1855 self.backend.debug_db_get(key).await
1856 }
1857
1858 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1862 node_info!("trace_transaction");
1863 self.backend.trace_transaction(tx_hash).await
1864 }
1865
1866 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1870 node_info!("trace_block");
1871 self.backend.trace_block(block).await
1872 }
1873
1874 pub async fn trace_filter(
1878 &self,
1879 filter: TraceFilter,
1880 ) -> Result<Vec<LocalizedTransactionTrace>> {
1881 node_info!("trace_filter");
1882 self.backend.trace_filter(filter).await
1883 }
1884}
1885
1886impl EthApi {
1889 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
1893 node_info!("anvil_impersonateAccount");
1894 self.backend.impersonate(address);
1895 Ok(())
1896 }
1897
1898 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
1902 node_info!("anvil_stopImpersonatingAccount");
1903 self.backend.stop_impersonating(address);
1904 Ok(())
1905 }
1906
1907 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
1911 node_info!("anvil_autoImpersonateAccount");
1912 self.backend.auto_impersonate_account(enabled);
1913 Ok(())
1914 }
1915
1916 pub async fn anvil_impersonate_signature(
1918 &self,
1919 signature: Bytes,
1920 address: Address,
1921 ) -> Result<()> {
1922 node_info!("anvil_impersonateSignature");
1923 self.backend.impersonate_signature(signature, address).await
1924 }
1925
1926 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
1930 node_info!("anvil_getAutomine");
1931 Ok(self.miner.is_auto_mine())
1932 }
1933
1934 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
1938 node_info!("anvil_getIntervalMining");
1939 Ok(self.miner.get_interval())
1940 }
1941
1942 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
1947 node_info!("evm_setAutomine");
1948 if self.miner.is_auto_mine() {
1949 if enable_automine {
1950 return Ok(());
1951 }
1952 self.miner.set_mining_mode(MiningMode::None);
1953 } else if enable_automine {
1954 let listener = self.pool.add_ready_listener();
1955 let mode = MiningMode::instant(1_000, listener);
1956 self.miner.set_mining_mode(mode);
1957 }
1958 Ok(())
1959 }
1960
1961 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
1965 node_info!("anvil_mine");
1966 let interval = interval.map(|i| i.to::<u64>());
1967 let blocks = num_blocks.unwrap_or(U256::from(1));
1968 if blocks.is_zero() {
1969 return Ok(());
1970 }
1971
1972 self.on_blocking_task(|this| async move {
1973 for _ in 0..blocks.to::<u64>() {
1975 if let Some(interval) = interval {
1977 this.backend.time().increase_time(interval);
1978 }
1979 this.mine_one().await;
1980 }
1981 Ok(())
1982 })
1983 .await?;
1984
1985 Ok(())
1986 }
1987
1988 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
1992 node_info!("evm_setIntervalMining");
1993 let mining_mode = if secs == 0 {
1994 MiningMode::None
1995 } else {
1996 let block_time = Duration::from_secs(secs);
1997
1998 self.backend.update_interval_mine_block_time(block_time);
2000
2001 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
2002 };
2003 self.miner.set_mining_mode(mining_mode);
2004 Ok(())
2005 }
2006
2007 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
2011 node_info!("anvil_dropTransaction");
2012 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
2013 }
2014
2015 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
2019 node_info!("anvil_dropAllTransactions");
2020 self.pool.clear();
2021 Ok(())
2022 }
2023
2024 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
2030 self.reset_instance_id();
2031 node_info!("anvil_reset");
2032 if let Some(forking) = forking {
2033 self.backend.reset_fork(forking).await
2035 } else {
2036 self.backend.reset_to_in_mem().await
2039 }
2040 }
2041
2042 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
2043 node_info!("anvil_setChainId");
2044 self.backend.set_chain_id(chain_id);
2045 Ok(())
2046 }
2047
2048 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
2052 node_info!("anvil_setBalance");
2053 self.backend.set_balance(address, balance).await?;
2054 Ok(())
2055 }
2056
2057 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
2061 node_info!("anvil_addBalance");
2062 let current_balance = self.backend.get_balance(address, None).await?;
2063 self.backend.set_balance(address, current_balance + balance).await?;
2064 Ok(())
2065 }
2066
2067 async fn find_erc20_storage_slot(
2084 &self,
2085 token_address: Address,
2086 calldata: Bytes,
2087 expected_value: U256,
2088 ) -> Result<B256> {
2089 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
2090
2091 let access_list_result =
2093 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
2094 let access_list = access_list_result.access_list;
2095
2096 for item in access_list.0 {
2099 if item.address != token_address {
2100 continue;
2101 };
2102 for slot in &item.storage_keys {
2103 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
2104 (*slot, B256::from(expected_value.to_be_bytes())),
2105 ));
2106
2107 let state_override = StateOverridesBuilder::default()
2108 .append(token_address, account_override)
2109 .build();
2110
2111 let evm_override = EvmOverrides::state(Some(state_override));
2112
2113 let Ok(result) =
2114 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
2115 else {
2116 continue;
2118 };
2119
2120 let Ok(result_value) = U256::abi_decode(&result) else {
2121 continue;
2123 };
2124
2125 if result_value == expected_value {
2126 return Ok(*slot);
2127 }
2128 }
2129 }
2130
2131 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
2132 }
2133
2134 pub async fn anvil_deal_erc20(
2138 &self,
2139 address: Address,
2140 token_address: Address,
2141 balance: U256,
2142 ) -> Result<()> {
2143 node_info!("anvil_dealERC20");
2144
2145 sol! {
2146 #[sol(rpc)]
2147 contract IERC20 {
2148 function balanceOf(address target) external view returns (uint256);
2149 }
2150 }
2151
2152 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
2153
2154 let slot =
2156 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
2157 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
2158 })?;
2159
2160 self.anvil_set_storage_at(
2162 token_address,
2163 U256::from_be_bytes(slot.0),
2164 B256::from(balance.to_be_bytes()),
2165 )
2166 .await?;
2167
2168 Ok(())
2169 }
2170
2171 pub async fn anvil_set_erc20_allowance(
2175 &self,
2176 owner: Address,
2177 spender: Address,
2178 token_address: Address,
2179 amount: U256,
2180 ) -> Result<()> {
2181 node_info!("anvil_setERC20Allowance");
2182
2183 sol! {
2184 #[sol(rpc)]
2185 contract IERC20 {
2186 function allowance(address owner, address spender) external view returns (uint256);
2187 }
2188 }
2189
2190 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2191
2192 let slot =
2194 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2195 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2196 })?;
2197
2198 self.anvil_set_storage_at(
2200 token_address,
2201 U256::from_be_bytes(slot.0),
2202 B256::from(amount.to_be_bytes()),
2203 )
2204 .await?;
2205
2206 Ok(())
2207 }
2208
2209 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2213 node_info!("anvil_setCode");
2214 self.backend.set_code(address, code).await?;
2215 Ok(())
2216 }
2217
2218 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2222 node_info!("anvil_setNonce");
2223 self.backend.set_nonce(address, nonce).await?;
2224 Ok(())
2225 }
2226
2227 pub async fn anvil_set_storage_at(
2231 &self,
2232 address: Address,
2233 slot: U256,
2234 val: B256,
2235 ) -> Result<bool> {
2236 node_info!("anvil_setStorageAt");
2237 self.backend.set_storage_at(address, slot, val).await?;
2238 Ok(true)
2239 }
2240
2241 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2245 node_info!("anvil_setLoggingEnabled");
2246 self.logger.set_enabled(enable);
2247 Ok(())
2248 }
2249
2250 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2254 node_info!("anvil_setMinGasPrice");
2255 if self.backend.is_eip1559() {
2256 return Err(RpcError::invalid_params(
2257 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2258 )
2259 .into());
2260 }
2261 self.backend.set_gas_price(gas.to());
2262 Ok(())
2263 }
2264
2265 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2269 node_info!("anvil_setNextBlockBaseFeePerGas");
2270 if !self.backend.is_eip1559() {
2271 return Err(RpcError::invalid_params(
2272 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2273 )
2274 .into());
2275 }
2276 self.backend.set_base_fee(basefee.to());
2277 Ok(())
2278 }
2279
2280 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2284 node_info!("anvil_setCoinbase");
2285 self.backend.set_coinbase(address);
2286 Ok(())
2287 }
2288
2289 pub async fn anvil_dump_state(
2294 &self,
2295 preserve_historical_states: Option<bool>,
2296 ) -> Result<Bytes> {
2297 node_info!("anvil_dumpState");
2298 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2299 }
2300
2301 pub async fn serialized_state(
2303 &self,
2304 preserve_historical_states: bool,
2305 ) -> Result<SerializableState> {
2306 self.backend.serialized_state(preserve_historical_states).await
2307 }
2308
2309 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2314 node_info!("anvil_loadState");
2315 self.backend.load_state_bytes(buf).await
2316 }
2317
2318 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2322 node_info!("anvil_nodeInfo");
2323
2324 let env = self.backend.env().read();
2325 let fork_config = self.backend.get_fork();
2326 let tx_order = self.transaction_order.read();
2327 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2328
2329 Ok(NodeInfo {
2330 current_block_number: self.backend.best_number(),
2331 current_block_timestamp: env.evm_env.block_env.timestamp.saturating_to(),
2332 current_block_hash: self.backend.best_hash(),
2333 hard_fork: hard_fork.to_string(),
2334 transaction_order: match *tx_order {
2335 TransactionOrder::Fifo => "fifo".to_string(),
2336 TransactionOrder::Fees => "fees".to_string(),
2337 },
2338 environment: NodeEnvironment {
2339 base_fee: self.backend.base_fee() as u128,
2340 chain_id: self.backend.chain_id().to::<u64>(),
2341 gas_limit: self.backend.gas_limit(),
2342 gas_price: self.gas_price(),
2343 },
2344 fork_config: fork_config
2345 .map(|fork| {
2346 let config = fork.config.read();
2347
2348 NodeForkConfig {
2349 fork_url: Some(config.eth_rpc_url.clone()),
2350 fork_block_number: Some(config.block_number),
2351 fork_retry_backoff: Some(config.backoff.as_millis()),
2352 }
2353 })
2354 .unwrap_or_default(),
2355 })
2356 }
2357
2358 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2362 node_info!("anvil_metadata");
2363 let fork_config = self.backend.get_fork();
2364
2365 Ok(Metadata {
2366 client_version: CLIENT_VERSION.to_string(),
2367 chain_id: self.backend.chain_id().to::<u64>(),
2368 latest_block_hash: self.backend.best_hash(),
2369 latest_block_number: self.backend.best_number(),
2370 instance_id: *self.instance_id.read(),
2371 forked_network: fork_config.map(|cfg| ForkedNetwork {
2372 chain_id: cfg.chain_id(),
2373 fork_block_number: cfg.block_number(),
2374 fork_block_hash: cfg.block_hash(),
2375 }),
2376 snapshots: self.backend.list_state_snapshots(),
2377 })
2378 }
2379
2380 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2381 node_info!("anvil_removePoolTransactions");
2382 self.pool.remove_transactions_by_address(address);
2383 Ok(())
2384 }
2385
2386 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2400 node_info!("anvil_reorg");
2401 let depth = options.depth;
2402 let tx_block_pairs = options.tx_block_pairs;
2403
2404 let current_height = self.backend.best_number();
2406 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2407 RpcError::invalid_params(format!(
2408 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2409 )),
2410 ))?;
2411
2412 let common_block =
2414 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2415
2416 let block_pool_txs = if tx_block_pairs.is_empty() {
2419 HashMap::default()
2420 } else {
2421 let mut pairs = tx_block_pairs;
2422
2423 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2425 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2426 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2427 depth - 1
2428 ))));
2429 }
2430
2431 pairs.sort_by_key(|a| a.1);
2433
2434 let mut nonces: HashMap<Address, u64> = HashMap::default();
2437
2438 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2439 for pair in pairs {
2440 let (tx_data, block_index) = pair;
2441
2442 let pending = match tx_data {
2443 TransactionData::Raw(bytes) => {
2444 let mut data = bytes.as_ref();
2445 let decoded = TypedTransaction::decode_2718(&mut data)
2446 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2447 PendingTransaction::new(decoded)?
2448 }
2449
2450 TransactionData::JSON(req) => {
2451 let mut tx_req = WithOtherFields::new(req);
2452 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2453 self.accounts()?
2454 .first()
2455 .copied()
2456 .ok_or(BlockchainError::NoSignerAvailable)
2457 })?;
2458
2459 let curr_nonce = nonces.entry(from).or_insert(
2461 self.get_transaction_count(
2462 from,
2463 Some(common_block.header.number.into()),
2464 )
2465 .await?,
2466 );
2467
2468 if tx_req.gas.is_none()
2470 && let Ok(gas) = self
2471 .estimate_gas(tx_req.clone(), None, EvmOverrides::default())
2472 .await
2473 {
2474 tx_req.gas = Some(gas.to());
2475 }
2476
2477 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2479
2480 *curr_nonce += 1;
2482
2483 if self.is_impersonated(from) {
2485 let bypass_signature = self.impersonated_signature(&typed);
2486 let transaction =
2487 sign::build_typed_transaction(typed, bypass_signature)?;
2488 self.ensure_typed_transaction_supported(&transaction)?;
2489 PendingTransaction::with_impersonated(transaction, from)
2490 } else {
2491 let transaction = self.sign_request(&from, typed)?;
2492 self.ensure_typed_transaction_supported(&transaction)?;
2493 PendingTransaction::new(transaction)?
2494 }
2495 }
2496 };
2497
2498 let pooled = PoolTransaction::new(pending);
2499 txs.entry(block_index).or_default().push(Arc::new(pooled));
2500 }
2501
2502 txs
2503 };
2504
2505 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2506 Ok(())
2507 }
2508
2509 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2520 node_info!("anvil_rollback");
2521 let depth = depth.unwrap_or(1);
2522
2523 let current_height = self.backend.best_number();
2525 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2526 RpcError::invalid_params(format!(
2527 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2528 )),
2529 ))?;
2530
2531 let common_block =
2533 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2534
2535 self.backend.rollback(common_block).await?;
2536 Ok(())
2537 }
2538
2539 pub async fn evm_snapshot(&self) -> Result<U256> {
2543 node_info!("evm_snapshot");
2544 Ok(self.backend.create_state_snapshot().await)
2545 }
2546
2547 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2552 node_info!("evm_revert");
2553 self.backend.revert_state_snapshot(id).await
2554 }
2555
2556 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2560 node_info!("evm_increaseTime");
2561 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2562 }
2563
2564 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2568 node_info!("evm_setNextBlockTimestamp");
2569 self.backend.time().set_next_block_timestamp(seconds)
2570 }
2571
2572 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2577 node_info!("evm_setTime");
2578 let now = self.backend.time().current_call_timestamp();
2579 self.backend.time().reset(timestamp);
2580
2581 let offset = timestamp.saturating_sub(now);
2583 Ok(Duration::from_millis(offset).as_secs())
2584 }
2585
2586 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2590 node_info!("evm_setBlockGasLimit");
2591 self.backend.set_gas_limit(gas_limit.to());
2592 Ok(true)
2593 }
2594
2595 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2599 node_info!("anvil_setBlockTimestampInterval");
2600 self.backend.time().set_block_timestamp_interval(seconds);
2601 Ok(())
2602 }
2603
2604 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2608 node_info!("anvil_removeBlockTimestampInterval");
2609 Ok(self.backend.time().remove_block_timestamp_interval())
2610 }
2611
2612 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2619 node_info!("evm_mine");
2620
2621 self.do_evm_mine(opts).await?;
2622
2623 Ok("0x0".to_string())
2624 }
2625
2626 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2636 node_info!("evm_mine_detailed");
2637
2638 let mined_blocks = self.do_evm_mine(opts).await?;
2639
2640 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2641
2642 let latest = self.backend.best_number();
2643 for offset in (0..mined_blocks).rev() {
2644 let block_num = latest - offset;
2645 if let Some(mut block) =
2646 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2647 {
2648 let block_txs = match block.transactions_mut() {
2649 BlockTransactions::Full(txs) => txs,
2650 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2651 };
2652 for tx in block_txs.iter_mut() {
2653 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash())
2654 && let Some(output) = receipt.out
2655 {
2656 if !receipt
2658 .inner
2659 .inner
2660 .inner
2661 .as_receipt_with_bloom()
2662 .receipt
2663 .status
2664 .coerce_status()
2665 && let Some(reason) = RevertDecoder::new().maybe_decode(&output, None)
2666 {
2667 tx.other.insert(
2668 "revertReason".to_string(),
2669 serde_json::to_value(reason).expect("Infallible"),
2670 );
2671 }
2672 tx.other.insert(
2673 "output".to_string(),
2674 serde_json::to_value(output).expect("Infallible"),
2675 );
2676 }
2677 }
2678 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2679 blocks.push(block);
2680 }
2681 }
2682
2683 Ok(blocks)
2684 }
2685
2686 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2690 node_info!("anvil_setBlock");
2691 self.backend.set_block_number(block_number);
2692 Ok(())
2693 }
2694
2695 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2699 node_info!("anvil_setRpcUrl");
2700 if let Some(fork) = self.backend.get_fork() {
2701 let mut config = fork.config.write();
2702 let new_provider = Arc::new(
2704 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2705 |_| {
2706 TransportErrorKind::custom_str(
2707 format!("Failed to parse invalid url {url}").as_str(),
2708 )
2709 },
2710 )?, );
2713 config.provider = new_provider;
2714 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2715 config.eth_rpc_url = url;
2716 }
2717 Ok(())
2718 }
2719
2720 pub async fn anvil_enable_traces(&self) -> Result<()> {
2725 node_info!("anvil_enableTraces");
2726 Err(BlockchainError::RpcUnimplemented)
2727 }
2728
2729 pub async fn eth_send_unsigned_transaction(
2733 &self,
2734 request: WithOtherFields<TransactionRequest>,
2735 ) -> Result<TxHash> {
2736 node_info!("eth_sendUnsignedTransaction");
2737 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2739
2740 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2741
2742 let request = self.build_typed_tx_request(request, nonce)?;
2743
2744 let bypass_signature = self.impersonated_signature(&request);
2745 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2746
2747 self.ensure_typed_transaction_supported(&transaction)?;
2748
2749 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2750
2751 self.backend.validate_pool_transaction(&pending_transaction).await?;
2753
2754 let requires = required_marker(nonce, on_chain_nonce, from);
2755 let provides = vec![to_marker(nonce, from)];
2756
2757 self.add_pending_transaction(pending_transaction, requires, provides)
2758 }
2759
2760 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2766 node_info!("txpool_status");
2767 Ok(self.pool.txpool_status())
2768 }
2769
2770 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2777 node_info!("txpool_inspect");
2778 let mut inspect = TxpoolInspect::default();
2779
2780 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2781 let tx = &tx.pending_transaction.transaction;
2782 let to = tx.to();
2783 let gas_price = tx.gas_price();
2784 let value = tx.value();
2785 let gas = tx.gas_limit();
2786 TxpoolInspectSummary { to, value, gas, gas_price }
2787 }
2788
2789 for pending in self.pool.ready_transactions() {
2796 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2797 let key = pending.pending_transaction.nonce().to_string();
2798 entry.insert(key, convert(pending));
2799 }
2800 for queued in self.pool.pending_transactions() {
2801 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2802 let key = queued.pending_transaction.nonce().to_string();
2803 entry.insert(key, convert(queued));
2804 }
2805 Ok(inspect)
2806 }
2807
2808 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2815 node_info!("txpool_content");
2816 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2817 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2818 let from = *tx.pending_transaction.sender();
2819 let tx = transaction_build(
2820 Some(tx.hash()),
2821 tx.pending_transaction.transaction.clone(),
2822 None,
2823 None,
2824 None,
2825 );
2826
2827 let WithOtherFields { inner: mut tx, other } = tx.0;
2828
2829 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2832
2833 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2834
2835 Ok(tx)
2836 }
2837
2838 for pending in self.pool.ready_transactions() {
2839 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2840 let key = pending.pending_transaction.nonce().to_string();
2841 entry.insert(key, convert(pending)?);
2842 }
2843 for queued in self.pool.pending_transactions() {
2844 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2845 let key = queued.pending_transaction.nonce().to_string();
2846 entry.insert(key, convert(queued)?);
2847 }
2848
2849 Ok(content)
2850 }
2851}
2852
2853impl EthApi {
2855 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2861 node_info!("wallet_getCapabilities");
2862 Ok(self.backend.get_capabilities())
2863 }
2864
2865 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2869 node_info!("anvil_addCapability");
2870 self.backend.add_capability(address);
2871 Ok(())
2872 }
2873
2874 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2875 node_info!("anvil_setExecutor");
2876 self.backend.set_executor(executor_pk)
2877 }
2878}
2879
2880impl EthApi {
2881 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2883 where
2884 C: FnOnce(Self) -> F,
2885 F: Future<Output = Result<R>> + Send + 'static,
2886 R: Send + 'static,
2887 {
2888 let (tx, rx) = oneshot::channel();
2889 let this = self.clone();
2890 let f = c(this);
2891 tokio::task::spawn_blocking(move || {
2892 tokio::runtime::Handle::current().block_on(async move {
2893 let res = f.await;
2894 let _ = tx.send(res);
2895 })
2896 });
2897 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2898 }
2899
2900 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2902 let mut blocks_to_mine = 1u64;
2903
2904 if let Some(opts) = opts {
2905 let timestamp = match opts {
2906 MineOptions::Timestamp(timestamp) => timestamp,
2907 MineOptions::Options { timestamp, blocks } => {
2908 if let Some(blocks) = blocks {
2909 blocks_to_mine = blocks;
2910 }
2911 timestamp
2912 }
2913 };
2914 if let Some(timestamp) = timestamp {
2915 self.evm_set_next_block_timestamp(timestamp)?;
2917 }
2918 }
2919
2920 self.on_blocking_task(|this| async move {
2923 for _ in 0..blocks_to_mine {
2925 this.mine_one().await;
2926 }
2927 Ok(())
2928 })
2929 .await?;
2930
2931 Ok(blocks_to_mine)
2932 }
2933
2934 async fn do_estimate_gas(
2935 &self,
2936 request: WithOtherFields<TransactionRequest>,
2937 block_number: Option<BlockId>,
2938 overrides: EvmOverrides,
2939 ) -> Result<u128> {
2940 let block_request = self.block_request(block_number).await?;
2941 if let BlockRequest::Number(number) = block_request
2943 && let Some(fork) = self.get_fork()
2944 && fork.predates_fork(number)
2945 {
2946 if overrides.has_state() || overrides.has_block() {
2947 return Err(BlockchainError::EvmOverrideError(
2948 "not available on past forked blocks".to_string(),
2949 ));
2950 }
2951 return Ok(fork.estimate_gas(&request, Some(number.into())).await?);
2952 }
2953
2954 self.on_blocking_task(|this| async move {
2957 this.backend
2958 .with_database_at(Some(block_request), |state, mut block| {
2959 let mut cache_db = CacheDB::new(state);
2960 if let Some(state_overrides) = overrides.state {
2961 apply_state_overrides(
2962 state_overrides.into_iter().collect(),
2963 &mut cache_db,
2964 )?;
2965 }
2966 if let Some(block_overrides) = overrides.block {
2967 cache_db.apply_block_overrides(*block_overrides, &mut block);
2968 }
2969 this.do_estimate_gas_with_state(request, &cache_db, block)
2970 })
2971 .await?
2972 })
2973 .await
2974 }
2975
2976 fn do_estimate_gas_with_state(
2980 &self,
2981 mut request: WithOtherFields<TransactionRequest>,
2982 state: &dyn DatabaseRef,
2983 block_env: BlockEnv,
2984 ) -> Result<u128> {
2985 let to = request.to.as_ref().and_then(TxKind::to);
2988
2989 let maybe_transfer = (request.input.input().is_none()
2991 || request.input.input().is_some_and(|data| data.is_empty()))
2992 && request.authorization_list.is_none()
2993 && request.access_list.is_none()
2994 && request.blob_versioned_hashes.is_none();
2995
2996 if maybe_transfer
2997 && let Some(to) = to
2998 && let Ok(target_code) = self.backend.get_code_with_state(&state, *to)
2999 && target_code.as_ref().is_empty()
3000 {
3001 return Ok(MIN_TRANSACTION_GAS);
3002 }
3003
3004 let fees = FeeDetails::new(
3005 request.gas_price,
3006 request.max_fee_per_gas,
3007 request.max_priority_fee_per_gas,
3008 request.max_fee_per_blob_gas,
3009 )?
3010 .or_zero_fees();
3011
3012 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
3015
3016 let gas_price = fees.gas_price.unwrap_or_default();
3017 if gas_price > 0
3019 && let Some(from) = request.from
3020 {
3021 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
3022 if let Some(value) = request.value {
3023 if value > available_funds {
3024 return Err(InvalidTransactionError::InsufficientFunds.into());
3025 }
3026 available_funds -= value;
3028 }
3029 let allowance = available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
3031 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
3032 }
3033
3034 let mut call_to_estimate = request.clone();
3035 call_to_estimate.gas = Some(highest_gas_limit as u64);
3036
3037 let ethres =
3039 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
3040
3041 let gas_used = match ethres.try_into()? {
3042 GasEstimationCallResult::Success(gas) => Ok(gas),
3043 GasEstimationCallResult::OutOfGas => {
3044 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
3045 }
3046 GasEstimationCallResult::Revert(output) => {
3047 Err(InvalidTransactionError::Revert(output).into())
3048 }
3049 GasEstimationCallResult::EvmError(err) => {
3050 warn!(target: "node", "estimation failed due to {:?}", err);
3051 Err(BlockchainError::EvmError(err))
3052 }
3053 }?;
3054
3055 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
3062
3063 let mut mid_gas_limit =
3065 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
3066
3067 while (highest_gas_limit - lowest_gas_limit) > 1 {
3069 request.gas = Some(mid_gas_limit as u64);
3070 let ethres = self.backend.call_with_state(
3071 &state,
3072 request.clone(),
3073 fees.clone(),
3074 block_env.clone(),
3075 );
3076
3077 match ethres.try_into()? {
3078 GasEstimationCallResult::Success(_) => {
3079 highest_gas_limit = mid_gas_limit;
3083 }
3084 GasEstimationCallResult::OutOfGas
3085 | GasEstimationCallResult::Revert(_)
3086 | GasEstimationCallResult::EvmError(_) => {
3087 lowest_gas_limit = mid_gas_limit;
3094 }
3095 };
3096 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3098 }
3099
3100 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3101
3102 Ok(highest_gas_limit)
3103 }
3104
3105 pub fn set_transaction_order(&self, order: TransactionOrder) {
3107 *self.transaction_order.write() = order;
3108 }
3109
3110 fn transaction_priority(&self, tx: &TypedTransaction) -> TransactionPriority {
3112 self.transaction_order.read().priority(tx)
3113 }
3114
3115 pub fn chain_id(&self) -> u64 {
3117 self.backend.chain_id().to::<u64>()
3118 }
3119
3120 pub fn get_fork(&self) -> Option<ClientFork> {
3122 self.backend.get_fork()
3123 }
3124
3125 pub fn instance_id(&self) -> B256 {
3127 *self.instance_id.read()
3128 }
3129
3130 pub fn reset_instance_id(&self) {
3132 *self.instance_id.write() = B256::random();
3133 }
3134
3135 #[expect(clippy::borrowed_box)]
3137 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3138 self.signers.iter().find(|signer| signer.is_signer_for(address))
3139 }
3140
3141 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3143 self.backend.new_block_notifications()
3144 }
3145
3146 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3148 self.pool.add_ready_listener()
3149 }
3150
3151 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3153 let (tx, rx) = unbounded_channel();
3154 let mut hashes = self.new_ready_transactions();
3155
3156 let this = self.clone();
3157
3158 tokio::spawn(async move {
3159 while let Some(hash) = hashes.next().await {
3160 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await
3161 && tx.send(txn).is_err()
3162 {
3163 break;
3164 }
3165 }
3166 });
3167
3168 rx
3169 }
3170
3171 pub fn storage_info(&self) -> StorageInfo {
3173 StorageInfo::new(Arc::clone(&self.backend))
3174 }
3175
3176 pub fn is_fork(&self) -> bool {
3178 self.backend.is_fork()
3179 }
3180
3181 pub async fn mine_one(&self) {
3183 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3184 let outcome = self.backend.mine_block(transactions).await;
3185
3186 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3187 self.pool.on_mined_block(outcome);
3188 }
3189
3190 async fn pending_block(&self) -> AnyRpcBlock {
3192 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3193 let info = self.backend.pending_block(transactions).await;
3194 self.backend.convert_block(info.block)
3195 }
3196
3197 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3199 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3200 let BlockInfo { block, transactions, receipts: _ } =
3201 self.backend.pending_block(transactions).await;
3202
3203 let mut partial_block = self.backend.convert_block(block.clone());
3204
3205 let mut block_transactions = Vec::with_capacity(block.transactions.len());
3206 let base_fee = self.backend.base_fee();
3207
3208 for info in transactions {
3209 let tx = block.transactions.get(info.transaction_index as usize)?.clone();
3210
3211 let tx = transaction_build(
3212 Some(info.transaction_hash),
3213 tx,
3214 Some(&block),
3215 Some(info),
3216 Some(base_fee),
3217 );
3218 block_transactions.push(tx);
3219 }
3220
3221 partial_block.transactions = BlockTransactions::from(block_transactions);
3222
3223 Some(partial_block)
3224 }
3225
3226 fn build_typed_tx_request(
3227 &self,
3228 request: WithOtherFields<TransactionRequest>,
3229 nonce: u64,
3230 ) -> Result<TypedTransactionRequest> {
3231 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
3232 let max_fee_per_gas = request.max_fee_per_gas;
3233 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
3234 let gas_price = request.gas_price;
3235
3236 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
3237 let from = request.from;
3238
3239 let request = match transaction_request_to_typed(request) {
3240 Some(TypedTransactionRequest::Legacy(mut m)) => {
3241 m.nonce = nonce;
3242 m.chain_id = Some(chain_id);
3243 m.gas_limit = gas_limit;
3244 if gas_price.is_none() {
3245 m.gas_price = self.gas_price();
3246 }
3247 TypedTransactionRequest::Legacy(m)
3248 }
3249 Some(TypedTransactionRequest::EIP2930(mut m)) => {
3250 m.nonce = nonce;
3251 m.chain_id = chain_id;
3252 m.gas_limit = gas_limit;
3253 if gas_price.is_none() {
3254 m.gas_price = self.gas_price();
3255 }
3256 TypedTransactionRequest::EIP2930(m)
3257 }
3258 Some(TypedTransactionRequest::EIP1559(mut m)) => {
3259 m.nonce = nonce;
3260 m.chain_id = chain_id;
3261 m.gas_limit = gas_limit;
3262 if max_fee_per_gas.is_none() {
3263 m.max_fee_per_gas = self.gas_price();
3264 }
3265 TypedTransactionRequest::EIP1559(m)
3266 }
3267 Some(TypedTransactionRequest::EIP7702(mut m)) => {
3268 m.nonce = nonce;
3269 m.chain_id = chain_id;
3270 m.gas_limit = gas_limit;
3271 if max_fee_per_gas.is_none() {
3272 m.max_fee_per_gas = self.gas_price();
3273 }
3274 TypedTransactionRequest::EIP7702(m)
3275 }
3276 Some(TypedTransactionRequest::EIP4844(m)) => {
3277 TypedTransactionRequest::EIP4844(match m {
3278 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
3280 m.tx.nonce = nonce;
3281 m.tx.chain_id = chain_id;
3282 m.tx.gas_limit = gas_limit;
3283 if max_fee_per_gas.is_none() {
3284 m.tx.max_fee_per_gas = self.gas_price();
3285 }
3286 if max_fee_per_blob_gas.is_none() {
3287 m.tx.max_fee_per_blob_gas =
3288 self.backend.fees().get_next_block_blob_base_fee_per_gas();
3289 }
3290 TxEip4844Variant::TxEip4844WithSidecar(m)
3291 }
3292 TxEip4844Variant::TxEip4844(mut tx) => {
3293 if !self.backend.skip_blob_validation(from) {
3294 return Err(BlockchainError::FailedToDecodeTransaction);
3295 }
3296
3297 tx.nonce = nonce;
3299 tx.chain_id = chain_id;
3300 tx.gas_limit = gas_limit;
3301 if max_fee_per_gas.is_none() {
3302 tx.max_fee_per_gas = self.gas_price();
3303 }
3304 if max_fee_per_blob_gas.is_none() {
3305 tx.max_fee_per_blob_gas =
3306 self.backend.fees().get_next_block_blob_base_fee_per_gas();
3307 }
3308
3309 TxEip4844Variant::TxEip4844(tx)
3310 }
3311 })
3312 }
3313 Some(TypedTransactionRequest::Deposit(mut m)) => {
3314 m.gas_limit = gas_limit;
3315 TypedTransactionRequest::Deposit(m)
3316 }
3317 None => return Err(BlockchainError::FailedToDecodeTransaction),
3318 };
3319 Ok(request)
3320 }
3321
3322 pub fn is_impersonated(&self, addr: Address) -> bool {
3324 self.backend.cheats().is_impersonated(addr)
3325 }
3326
3327 fn impersonated_signature(&self, request: &TypedTransactionRequest) -> Signature {
3329 match request {
3330 TypedTransactionRequest::Legacy(_) => Signature::from_scalars_and_parity(
3333 B256::with_last_byte(1),
3334 B256::with_last_byte(1),
3335 false,
3336 ),
3337 TypedTransactionRequest::EIP2930(_)
3338 | TypedTransactionRequest::EIP1559(_)
3339 | TypedTransactionRequest::EIP7702(_)
3340 | TypedTransactionRequest::EIP4844(_)
3341 | TypedTransactionRequest::Deposit(_) => Signature::from_scalars_and_parity(
3342 B256::with_last_byte(1),
3343 B256::with_last_byte(1),
3344 false,
3345 ),
3346 }
3347 }
3348
3349 async fn get_transaction_count(
3351 &self,
3352 address: Address,
3353 block_number: Option<BlockId>,
3354 ) -> Result<u64> {
3355 let block_request = self.block_request(block_number).await?;
3356
3357 if let BlockRequest::Number(number) = block_request
3358 && let Some(fork) = self.get_fork()
3359 && fork.predates_fork(number)
3360 {
3361 return Ok(fork.get_nonce(address, number).await?);
3362 }
3363
3364 self.backend.get_nonce(address, block_request).await
3365 }
3366
3367 async fn request_nonce(
3375 &self,
3376 request: &TransactionRequest,
3377 from: Address,
3378 ) -> Result<(u64, u64)> {
3379 let highest_nonce =
3380 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3381 let nonce = request.nonce.unwrap_or(highest_nonce);
3382
3383 Ok((nonce, highest_nonce))
3384 }
3385
3386 fn add_pending_transaction(
3388 &self,
3389 pending_transaction: PendingTransaction,
3390 requires: Vec<TxMarker>,
3391 provides: Vec<TxMarker>,
3392 ) -> Result<TxHash> {
3393 let from = *pending_transaction.sender();
3394 let priority = self.transaction_priority(&pending_transaction.transaction);
3395 let pool_transaction =
3396 PoolTransaction { requires, provides, pending_transaction, priority };
3397 let tx = self.pool.add_transaction(pool_transaction)?;
3398 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3399 Ok(*tx.hash())
3400 }
3401
3402 pub async fn state_root(&self) -> Option<B256> {
3404 self.backend.get_db().read().await.maybe_state_root()
3405 }
3406
3407 fn ensure_typed_transaction_supported(&self, tx: &TypedTransaction) -> Result<()> {
3409 match &tx {
3410 TypedTransaction::EIP2930(_) => self.backend.ensure_eip2930_active(),
3411 TypedTransaction::EIP1559(_) => self.backend.ensure_eip1559_active(),
3412 TypedTransaction::EIP4844(_) => self.backend.ensure_eip4844_active(),
3413 TypedTransaction::EIP7702(_) => self.backend.ensure_eip7702_active(),
3414 TypedTransaction::Deposit(_) => self.backend.ensure_op_deposits_active(),
3415 TypedTransaction::Legacy(_) => Ok(()),
3416 }
3417 }
3418}
3419
3420fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3421 if provided_nonce == on_chain_nonce {
3422 return Vec::new();
3423 }
3424 let prev_nonce = provided_nonce.saturating_sub(1);
3425 if on_chain_nonce <= prev_nonce { vec![to_marker(prev_nonce, from)] } else { Vec::new() }
3426}
3427
3428fn convert_transact_out(out: &Option<Output>) -> Bytes {
3429 match out {
3430 None => Default::default(),
3431 Some(Output::Call(out)) => out.to_vec().into(),
3432 Some(Output::Create(out, _)) => out.to_vec().into(),
3433 }
3434}
3435
3436fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3438 let out = convert_transact_out(out);
3439 match exit {
3440 return_ok!() => Ok(out),
3441 return_revert!() => Err(InvalidTransactionError::Revert(Some(out)).into()),
3442 reason => Err(BlockchainError::EvmError(reason)),
3443 }
3444}
3445
3446fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3448 match transaction_request_to_typed(request.clone()) {
3449 Some(request) => match request {
3450 TypedTransactionRequest::Legacy(req) => match req.to {
3451 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3452 TxKind::Create => MIN_CREATE_GAS,
3453 },
3454 TypedTransactionRequest::EIP1559(req) => match req.to {
3455 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3456 TxKind::Create => MIN_CREATE_GAS,
3457 },
3458 TypedTransactionRequest::EIP7702(req) => {
3459 MIN_TRANSACTION_GAS
3460 + req.authorization_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3461 }
3462 TypedTransactionRequest::EIP2930(req) => match req.to {
3463 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3464 TxKind::Create => MIN_CREATE_GAS,
3465 },
3466 TypedTransactionRequest::EIP4844(_) => MIN_TRANSACTION_GAS,
3467 TypedTransactionRequest::Deposit(req) => match req.to {
3468 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3469 TxKind::Create => MIN_CREATE_GAS,
3470 },
3471 },
3472 _ => MIN_CREATE_GAS,
3475 }
3476}
3477
3478enum GasEstimationCallResult {
3480 Success(u128),
3481 OutOfGas,
3482 Revert(Option<Bytes>),
3483 EvmError(InstructionResult),
3484}
3485
3486impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3490 type Error = BlockchainError;
3491
3492 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3493 match res {
3494 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3496 Ok(Self::OutOfGas)
3497 }
3498 Err(err) => Err(err),
3499 Ok((exit, output, gas, _)) => match exit {
3500 return_ok!() => Ok(Self::Success(gas)),
3501
3502 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3504 InstructionResult::CallTooDeep
3505 | InstructionResult::OutOfFunds
3506 | InstructionResult::CreateInitCodeStartingEF00
3507 | InstructionResult::InvalidEOFInitCode
3508 | InstructionResult::InvalidExtDelegateCallTarget => Ok(Self::EvmError(exit)),
3509
3510 InstructionResult::OutOfGas
3512 | InstructionResult::MemoryOOG
3513 | InstructionResult::MemoryLimitOOG
3514 | InstructionResult::PrecompileOOG
3515 | InstructionResult::InvalidOperandOOG
3516 | InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3517
3518 InstructionResult::OpcodeNotFound
3520 | InstructionResult::CallNotAllowedInsideStatic
3521 | InstructionResult::StateChangeDuringStaticCall
3522 | InstructionResult::InvalidFEOpcode
3523 | InstructionResult::InvalidJump
3524 | InstructionResult::NotActivated
3525 | InstructionResult::StackUnderflow
3526 | InstructionResult::StackOverflow
3527 | InstructionResult::OutOfOffset
3528 | InstructionResult::CreateCollision
3529 | InstructionResult::OverflowPayment
3530 | InstructionResult::PrecompileError
3531 | InstructionResult::NonceOverflow
3532 | InstructionResult::CreateContractSizeLimit
3533 | InstructionResult::CreateContractStartingWithEF
3534 | InstructionResult::CreateInitCodeSizeLimit
3535 | InstructionResult::FatalExternalError => Ok(Self::EvmError(exit)),
3536 },
3537 }
3538 }
3539}