1use super::{
2 backend::{
3 db::MaybeFullDatabase,
4 mem::{state, BlockRequest, State},
5 },
6 sign::build_typed_transaction,
7};
8use crate::{
9 eth::{
10 backend::{
11 self,
12 db::SerializableState,
13 mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
14 notifications::NewBlockNotifications,
15 validate::TransactionValidator,
16 },
17 error::{
18 BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
19 },
20 fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
21 macros::node_info,
22 miner::FixedBlockTimeMiner,
23 pool::{
24 transactions::{
25 to_marker, PoolTransaction, TransactionOrder, TransactionPriority, TxMarker,
26 },
27 Pool,
28 },
29 sign::{self, Signer},
30 },
31 filter::{EthFilter, Filters, LogsFilter},
32 mem::transaction_build,
33 ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
34};
35use alloy_consensus::{
36 transaction::{eip4844::TxEip4844Variant, Recovered},
37 Account,
38};
39use alloy_dyn_abi::TypedData;
40use alloy_eips::eip2718::Encodable2718;
41use alloy_network::{
42 eip2718::Decodable2718, AnyRpcBlock, AnyRpcTransaction, BlockResponse, Ethereum, NetworkWallet,
43 TransactionBuilder, TransactionResponse,
44};
45use alloy_primitives::{
46 map::{HashMap, HashSet},
47 Address, Bytes, Signature, TxHash, TxKind, B256, B64, U256, U64,
48};
49use alloy_provider::utils::{
50 eip1559_default_estimator, EIP1559_FEE_ESTIMATION_PAST_BLOCKS,
51 EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE,
52};
53use alloy_rpc_types::{
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 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
67 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log, Work,
68};
69use alloy_serde::WithOtherFields;
70use alloy_sol_types::{sol, SolCall, SolValue};
71use alloy_transport::TransportErrorKind;
72use anvil_core::{
73 eth::{
74 block::BlockInfo,
75 transaction::{
76 transaction_request_to_typed, PendingTransaction, ReceiptResponse, TypedTransaction,
77 TypedTransactionRequest,
78 },
79 wallet::{WalletCapabilities, WalletError},
80 EthRequest,
81 },
82 types::{ReorgOptions, TransactionData},
83};
84use anvil_rpc::{error::RpcError, response::ResponseResult};
85use foundry_common::provider::ProviderBuilder;
86use foundry_evm::{backend::DatabaseError, decode::RevertDecoder};
87use futures::{
88 channel::{mpsc::Receiver, oneshot},
89 StreamExt,
90};
91use parking_lot::RwLock;
92use revm::{
93 bytecode::Bytecode,
94 context::BlockEnv,
95 context_interface::{block::BlobExcessGasAndPrice, result::Output},
96 database::{CacheDB, DatabaseRef},
97 interpreter::{return_ok, return_revert, InstructionResult},
98 primitives::eip7702::PER_EMPTY_ACCOUNT_COST,
99};
100use std::{future::Future, sync::Arc, time::Duration};
101use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
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::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
176 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
177 EthRequest::EthGetAccount(addr, block) => {
178 self.get_account(addr, block).await.to_rpc_result()
179 }
180 EthRequest::EthGetAccountInfo(addr, block) => {
181 self.get_account_info(addr, block).await.to_rpc_result()
182 }
183 EthRequest::EthGetBalance(addr, block) => {
184 self.balance(addr, block).await.to_rpc_result()
185 }
186 EthRequest::EthGetTransactionByHash(hash) => {
187 self.transaction_by_hash(hash).await.to_rpc_result()
188 }
189 EthRequest::EthSendTransaction(request) => {
190 self.send_transaction(*request).await.to_rpc_result()
191 }
192 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
193 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
194 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
195 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
196 EthRequest::EthMaxPriorityFeePerGas(_) => {
197 self.gas_max_priority_fee_per_gas().to_rpc_result()
198 }
199 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
200 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
201 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
202 EthRequest::EthGetStorageAt(addr, slot, block) => {
203 self.storage_at(addr, slot, block).await.to_rpc_result()
204 }
205 EthRequest::EthGetBlockByHash(hash, full) => {
206 if full {
207 self.block_by_hash_full(hash).await.to_rpc_result()
208 } else {
209 self.block_by_hash(hash).await.to_rpc_result()
210 }
211 }
212 EthRequest::EthGetBlockByNumber(num, full) => {
213 if full {
214 self.block_by_number_full(num).await.to_rpc_result()
215 } else {
216 self.block_by_number(num).await.to_rpc_result()
217 }
218 }
219 EthRequest::EthGetTransactionCount(addr, block) => {
220 self.transaction_count(addr, block).await.to_rpc_result()
221 }
222 EthRequest::EthGetTransactionCountByHash(hash) => {
223 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
224 }
225 EthRequest::EthGetTransactionCountByNumber(num) => {
226 self.block_transaction_count_by_number(num).await.to_rpc_result()
227 }
228 EthRequest::EthGetUnclesCountByHash(hash) => {
229 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
230 }
231 EthRequest::EthGetUnclesCountByNumber(num) => {
232 self.block_uncles_count_by_number(num).await.to_rpc_result()
233 }
234 EthRequest::EthGetCodeAt(addr, block) => {
235 self.get_code(addr, block).await.to_rpc_result()
236 }
237 EthRequest::EthGetProof(addr, keys, block) => {
238 self.get_proof(addr, keys, block).await.to_rpc_result()
239 }
240 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
241 EthRequest::PersonalSign(content, addr) => {
242 self.sign(addr, content).await.to_rpc_result()
243 }
244 EthRequest::EthSignTransaction(request) => {
245 self.sign_transaction(*request).await.to_rpc_result()
246 }
247 EthRequest::EthSignTypedData(addr, data) => {
248 self.sign_typed_data(addr, data).await.to_rpc_result()
249 }
250 EthRequest::EthSignTypedDataV3(addr, data) => {
251 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
252 }
253 EthRequest::EthSignTypedDataV4(addr, data) => {
254 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
255 }
256 EthRequest::EthSendRawTransaction(tx) => {
257 self.send_raw_transaction(tx).await.to_rpc_result()
258 }
259 EthRequest::EthCall(call, block, state_override, block_overrides) => self
260 .call(call, block, EvmOverrides::new(state_override, block_overrides))
261 .await
262 .to_rpc_result(),
263 EthRequest::EthSimulateV1(simulation, block) => {
264 self.simulate_v1(simulation, block).await.to_rpc_result()
265 }
266 EthRequest::EthCreateAccessList(call, block) => {
267 self.create_access_list(call, block).await.to_rpc_result()
268 }
269 EthRequest::EthEstimateGas(call, block, state_override, block_overrides) => self
270 .estimate_gas(call, block, EvmOverrides::new(state_override, block_overrides))
271 .await
272 .to_rpc_result(),
273 EthRequest::EthGetRawTransactionByHash(hash) => {
274 self.raw_transaction(hash).await.to_rpc_result()
275 }
276 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
277 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
278 }
279 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
280 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
281 }
282 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
283 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
284 }
285 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
286 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
287 }
288 EthRequest::EthGetTransactionReceipt(tx) => {
289 self.transaction_receipt(tx).await.to_rpc_result()
290 }
291 EthRequest::EthGetBlockReceipts(number) => {
292 self.block_receipts(number).await.to_rpc_result()
293 }
294 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
295 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
296 }
297 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
298 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
299 }
300 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
301 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
302 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
303 EthRequest::EthSubmitWork(nonce, pow, digest) => {
304 self.submit_work(nonce, pow, digest).to_rpc_result()
305 }
306 EthRequest::EthSubmitHashRate(rate, id) => {
307 self.submit_hashrate(rate, id).to_rpc_result()
308 }
309 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
310 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
311 }
312 EthRequest::DebugGetRawTransaction(hash) => {
314 self.raw_transaction(hash).await.to_rpc_result()
315 }
316 EthRequest::DebugTraceTransaction(tx, opts) => {
318 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
319 }
320 EthRequest::DebugTraceCall(tx, block, opts) => {
322 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
323 }
324 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
325 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
326 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
327 EthRequest::ImpersonateAccount(addr) => {
328 self.anvil_impersonate_account(addr).await.to_rpc_result()
329 }
330 EthRequest::StopImpersonatingAccount(addr) => {
331 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
332 }
333 EthRequest::AutoImpersonateAccount(enable) => {
334 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
335 }
336 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
337 EthRequest::Mine(blocks, interval) => {
338 self.anvil_mine(blocks, interval).await.to_rpc_result()
339 }
340 EthRequest::SetAutomine(enabled) => {
341 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
342 }
343 EthRequest::SetIntervalMining(interval) => {
344 self.anvil_set_interval_mining(interval).to_rpc_result()
345 }
346 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
347 EthRequest::DropTransaction(tx) => {
348 self.anvil_drop_transaction(tx).await.to_rpc_result()
349 }
350 EthRequest::DropAllTransactions() => {
351 self.anvil_drop_all_transactions().await.to_rpc_result()
352 }
353 EthRequest::Reset(fork) => {
354 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
355 }
356 EthRequest::SetBalance(addr, val) => {
357 self.anvil_set_balance(addr, val).await.to_rpc_result()
358 }
359 EthRequest::AddBalance(addr, val) => {
360 self.anvil_add_balance(addr, val).await.to_rpc_result()
361 }
362 EthRequest::DealERC20(addr, token_addr, val) => {
363 self.anvil_deal_erc20(addr, token_addr, val).await.to_rpc_result()
364 }
365 EthRequest::SetERC20Allowance(owner, spender, token_addr, val) => self
366 .anvil_set_erc20_allowance(owner, spender, token_addr, val)
367 .await
368 .to_rpc_result(),
369 EthRequest::SetCode(addr, code) => {
370 self.anvil_set_code(addr, code).await.to_rpc_result()
371 }
372 EthRequest::SetNonce(addr, nonce) => {
373 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
374 }
375 EthRequest::SetStorageAt(addr, slot, val) => {
376 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
377 }
378 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
379 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
380 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
381 EthRequest::SetMinGasPrice(gas) => {
382 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
383 }
384 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
385 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
386 }
387 EthRequest::DumpState(preserve_historical_states) => self
388 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
389 .await
390 .to_rpc_result(),
391 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
392 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
393 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
394 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
395 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
396 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
397 EthRequest::EvmSetNextBlockTimeStamp(time) => {
398 if time >= U256::from(u64::MAX) {
399 return ResponseResult::Error(RpcError::invalid_params(
400 "The timestamp is too big",
401 ))
402 }
403 let time = time.to::<u64>();
404 self.evm_set_next_block_timestamp(time).to_rpc_result()
405 }
406 EthRequest::EvmSetTime(timestamp) => {
407 if timestamp >= U256::from(u64::MAX) {
408 return ResponseResult::Error(RpcError::invalid_params(
409 "The timestamp is too big",
410 ))
411 }
412 let time = timestamp.to::<u64>();
413 self.evm_set_time(time).to_rpc_result()
414 }
415 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
416 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
417 }
418 EthRequest::EvmSetBlockTimeStampInterval(time) => {
419 self.evm_set_block_timestamp_interval(time).to_rpc_result()
420 }
421 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
422 self.evm_remove_block_timestamp_interval().to_rpc_result()
423 }
424 EthRequest::EvmMine(mine) => {
425 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
426 }
427 EthRequest::EvmMineDetailed(mine) => {
428 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
429 }
430 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
431 EthRequest::EthSendUnsignedTransaction(tx) => {
432 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
433 }
434 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
435 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
436 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
437 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
438 EthRequest::EthNewPendingTransactionFilter(_) => {
439 self.new_pending_transaction_filter().await.to_rpc_result()
440 }
441 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
442 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
443 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
444 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
445 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
446 EthRequest::ErigonGetHeaderByNumber(num) => {
447 self.erigon_get_header_by_number(num).await.to_rpc_result()
448 }
449 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
450 EthRequest::OtsGetInternalOperations(hash) => {
451 self.ots_get_internal_operations(hash).await.to_rpc_result()
452 }
453 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
454 EthRequest::OtsTraceTransaction(hash) => {
455 self.ots_trace_transaction(hash).await.to_rpc_result()
456 }
457 EthRequest::OtsGetTransactionError(hash) => {
458 self.ots_get_transaction_error(hash).await.to_rpc_result()
459 }
460 EthRequest::OtsGetBlockDetails(num) => {
461 self.ots_get_block_details(num).await.to_rpc_result()
462 }
463 EthRequest::OtsGetBlockDetailsByHash(hash) => {
464 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
465 }
466 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
467 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
468 }
469 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
470 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
471 }
472 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
473 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
474 }
475 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
476 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
477 }
478 EthRequest::OtsGetContractCreator(address) => {
479 self.ots_get_contract_creator(address).await.to_rpc_result()
480 }
481 EthRequest::RemovePoolTransactions(address) => {
482 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
483 }
484 EthRequest::Reorg(reorg_options) => {
485 self.anvil_reorg(reorg_options).await.to_rpc_result()
486 }
487 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
488 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
489 EthRequest::WalletSendTransaction(tx) => {
490 self.wallet_send_transaction(*tx).await.to_rpc_result()
491 }
492 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
493 EthRequest::AnvilSetExecutor(executor_pk) => {
494 self.anvil_set_executor(executor_pk).to_rpc_result()
495 }
496 };
497
498 if let ResponseResult::Error(err) = &response {
499 node_info!("\nRPC request failed:");
500 node_info!(" Request: {:?}", request);
501 node_info!(" Error: {}\n", err);
502 }
503
504 response
505 }
506
507 fn sign_request(
508 &self,
509 from: &Address,
510 request: TypedTransactionRequest,
511 ) -> Result<TypedTransaction> {
512 match request {
513 TypedTransactionRequest::Deposit(_) => {
514 let nil_signature = Signature::from_scalars_and_parity(
515 B256::with_last_byte(1),
516 B256::with_last_byte(1),
517 false,
518 );
519 return build_typed_transaction(request, nil_signature)
520 }
521 _ => {
522 for signer in self.signers.iter() {
523 if signer.accounts().contains(from) {
524 let signature = signer.sign_transaction(request.clone(), from)?;
525 return build_typed_transaction(request, signature)
526 }
527 }
528 }
529 }
530 Err(BlockchainError::NoSignerAvailable)
531 }
532
533 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
534 let block_request = match block_number {
535 Some(BlockId::Number(BlockNumber::Pending)) => {
536 let pending_txs = self.pool.ready_transactions().collect();
537 BlockRequest::Pending(pending_txs)
538 }
539 _ => {
540 let number = self.backend.ensure_block_number(block_number).await?;
541 BlockRequest::Number(number)
542 }
543 };
544 Ok(block_request)
545 }
546
547 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
548 match self.pool.get_transaction(hash) {
549 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
550 None => match self.backend.transaction_by_hash(hash).await? {
551 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
552 None => Ok(None),
553 },
554 }
555 }
556
557 pub fn client_version(&self) -> Result<String> {
561 node_info!("web3_clientVersion");
562 Ok(CLIENT_VERSION.to_string())
563 }
564
565 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
569 node_info!("web3_sha3");
570 let hash = alloy_primitives::keccak256(bytes.as_ref());
571 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
572 }
573
574 pub fn protocol_version(&self) -> Result<u64> {
578 node_info!("eth_protocolVersion");
579 Ok(1)
580 }
581
582 pub fn hashrate(&self) -> Result<U256> {
586 node_info!("eth_hashrate");
587 Ok(U256::ZERO)
588 }
589
590 pub fn author(&self) -> Result<Address> {
594 node_info!("eth_coinbase");
595 Ok(self.backend.coinbase())
596 }
597
598 pub fn is_mining(&self) -> Result<bool> {
602 node_info!("eth_mining");
603 Ok(self.is_mining)
604 }
605
606 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
612 node_info!("eth_chainId");
613 Ok(Some(self.backend.chain_id().to::<U64>()))
614 }
615
616 pub fn network_id(&self) -> Result<Option<String>> {
620 node_info!("eth_networkId");
621 let chain_id = self.backend.chain_id().to::<u64>();
622 Ok(Some(format!("{chain_id}")))
623 }
624
625 pub fn net_listening(&self) -> Result<bool> {
629 node_info!("net_listening");
630 Ok(self.net_listening)
631 }
632
633 fn eth_gas_price(&self) -> Result<U256> {
635 node_info!("eth_gasPrice");
636 Ok(U256::from(self.gas_price()))
637 }
638
639 pub fn gas_price(&self) -> u128 {
641 if self.backend.is_eip1559() {
642 if self.backend.is_min_priority_fee_enforced() {
643 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
644 } else {
645 self.backend.base_fee() as u128
646 }
647 } else {
648 self.backend.fees().raw_gas_price()
649 }
650 }
651
652 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
654 Ok(self.backend.excess_blob_gas_and_price())
655 }
656
657 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
662 self.max_priority_fee_per_gas()
663 }
664
665 pub fn blob_base_fee(&self) -> Result<U256> {
669 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
670 }
671
672 pub fn gas_limit(&self) -> U256 {
674 U256::from(self.backend.gas_limit())
675 }
676
677 pub fn accounts(&self) -> Result<Vec<Address>> {
681 node_info!("eth_accounts");
682 let mut unique = HashSet::new();
683 let mut accounts: Vec<Address> = Vec::new();
684 for signer in self.signers.iter() {
685 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
686 }
687 accounts.extend(
688 self.backend
689 .cheats()
690 .impersonated_accounts()
691 .into_iter()
692 .filter(|acc| unique.insert(*acc)),
693 );
694 Ok(accounts.into_iter().collect())
695 }
696
697 pub fn block_number(&self) -> Result<U256> {
701 node_info!("eth_blockNumber");
702 Ok(U256::from(self.backend.best_number()))
703 }
704
705 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
709 node_info!("eth_getBalance");
710 let block_request = self.block_request(block_number).await?;
711
712 if let BlockRequest::Number(number) = block_request {
714 if let Some(fork) = self.get_fork() {
715 if fork.predates_fork(number) {
716 return Ok(fork.get_balance(address, number).await?)
717 }
718 }
719 }
720
721 self.backend.get_balance(address, Some(block_request)).await
722 }
723
724 pub async fn get_account(
728 &self,
729 address: Address,
730 block_number: Option<BlockId>,
731 ) -> Result<Account> {
732 node_info!("eth_getAccount");
733 let block_request = self.block_request(block_number).await?;
734
735 if let BlockRequest::Number(number) = block_request {
737 if let Some(fork) = self.get_fork() {
738 if fork.predates_fork(number) {
739 return Ok(fork.get_account(address, number).await?)
740 }
741 }
742 }
743
744 self.backend.get_account_at_block(address, Some(block_request)).await
745 }
746
747 pub async fn get_account_info(
749 &self,
750 address: Address,
751 block_number: Option<BlockId>,
752 ) -> Result<alloy_rpc_types::eth::AccountInfo> {
753 node_info!("eth_getAccountInfo");
754 let account = self
755 .backend
756 .get_account_at_block(address, Some(self.block_request(block_number).await?))
757 .await?;
758 let code =
759 self.backend.get_code(address, Some(self.block_request(block_number).await?)).await?;
760 Ok(alloy_rpc_types::eth::AccountInfo {
761 balance: account.balance,
762 nonce: account.nonce,
763 code,
764 })
765 }
766 pub async fn storage_at(
770 &self,
771 address: Address,
772 index: U256,
773 block_number: Option<BlockId>,
774 ) -> Result<B256> {
775 node_info!("eth_getStorageAt");
776 let block_request = self.block_request(block_number).await?;
777
778 if let BlockRequest::Number(number) = block_request {
780 if let Some(fork) = self.get_fork() {
781 if fork.predates_fork(number) {
782 return Ok(B256::from(
783 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
784 ));
785 }
786 }
787 }
788
789 self.backend.storage_at(address, index, Some(block_request)).await
790 }
791
792 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
796 node_info!("eth_getBlockByHash");
797 self.backend.block_by_hash(hash).await
798 }
799
800 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
804 node_info!("eth_getBlockByHash");
805 self.backend.block_by_hash_full(hash).await
806 }
807
808 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
812 node_info!("eth_getBlockByNumber");
813 if number == BlockNumber::Pending {
814 return Ok(Some(self.pending_block().await));
815 }
816
817 self.backend.block_by_number(number).await
818 }
819
820 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
824 node_info!("eth_getBlockByNumber");
825 if number == BlockNumber::Pending {
826 return Ok(self.pending_block_full().await);
827 }
828 self.backend.block_by_number_full(number).await
829 }
830
831 pub async fn transaction_count(
838 &self,
839 address: Address,
840 block_number: Option<BlockId>,
841 ) -> Result<U256> {
842 node_info!("eth_getTransactionCount");
843 self.get_transaction_count(address, block_number).await.map(U256::from)
844 }
845
846 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
850 node_info!("eth_getBlockTransactionCountByHash");
851 let block = self.backend.block_by_hash(hash).await?;
852 let txs = block.map(|b| match b.transactions() {
853 BlockTransactions::Full(txs) => U256::from(txs.len()),
854 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
855 BlockTransactions::Uncle => U256::from(0),
856 });
857 Ok(txs)
858 }
859
860 pub async fn block_transaction_count_by_number(
864 &self,
865 block_number: BlockNumber,
866 ) -> Result<Option<U256>> {
867 node_info!("eth_getBlockTransactionCountByNumber");
868 let block_request = self.block_request(Some(block_number.into())).await?;
869 if let BlockRequest::Pending(txs) = block_request {
870 let block = self.backend.pending_block(txs).await;
871 return Ok(Some(U256::from(block.transactions.len())));
872 }
873 let block = self.backend.block_by_number(block_number).await?;
874 let txs = block.map(|b| match b.transactions() {
875 BlockTransactions::Full(txs) => U256::from(txs.len()),
876 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
877 BlockTransactions::Uncle => U256::from(0),
878 });
879 Ok(txs)
880 }
881
882 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
886 node_info!("eth_getUncleCountByBlockHash");
887 let block =
888 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
889 Ok(U256::from(block.uncles.len()))
890 }
891
892 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
896 node_info!("eth_getUncleCountByBlockNumber");
897 let block = self
898 .backend
899 .block_by_number(block_number)
900 .await?
901 .ok_or(BlockchainError::BlockNotFound)?;
902 Ok(U256::from(block.uncles.len()))
903 }
904
905 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
909 node_info!("eth_getCode");
910 let block_request = self.block_request(block_number).await?;
911 if let BlockRequest::Number(number) = block_request {
913 if let Some(fork) = self.get_fork() {
914 if fork.predates_fork(number) {
915 return Ok(fork.get_code(address, number).await?)
916 }
917 }
918 }
919 self.backend.get_code(address, Some(block_request)).await
920 }
921
922 pub async fn get_proof(
927 &self,
928 address: Address,
929 keys: Vec<B256>,
930 block_number: Option<BlockId>,
931 ) -> Result<EIP1186AccountProofResponse> {
932 node_info!("eth_getProof");
933 let block_request = self.block_request(block_number).await?;
934
935 if let BlockRequest::Number(number) = block_request {
938 if let Some(fork) = self.get_fork() {
939 if fork.predates_fork_inclusive(number) {
940 return Ok(fork.get_proof(address, keys, Some(number.into())).await?)
941 }
942 }
943 }
944
945 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
946 Ok(proof)
947 }
948
949 pub async fn sign_typed_data(
953 &self,
954 _address: Address,
955 _data: serde_json::Value,
956 ) -> Result<String> {
957 node_info!("eth_signTypedData");
958 Err(BlockchainError::RpcUnimplemented)
959 }
960
961 pub async fn sign_typed_data_v3(
965 &self,
966 _address: Address,
967 _data: serde_json::Value,
968 ) -> Result<String> {
969 node_info!("eth_signTypedData_v3");
970 Err(BlockchainError::RpcUnimplemented)
971 }
972
973 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
977 node_info!("eth_signTypedData_v4");
978 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
979 let signature = signer.sign_typed_data(address, data).await?;
980 let signature = alloy_primitives::hex::encode(signature.as_bytes());
981 Ok(format!("0x{signature}"))
982 }
983
984 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
988 node_info!("eth_sign");
989 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
990 let signature =
991 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
992 Ok(format!("0x{signature}"))
993 }
994
995 pub async fn sign_transaction(
999 &self,
1000 mut request: WithOtherFields<TransactionRequest>,
1001 ) -> Result<String> {
1002 node_info!("eth_signTransaction");
1003
1004 let from = request.from.map(Ok).unwrap_or_else(|| {
1005 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1006 })?;
1007
1008 let (nonce, _) = self.request_nonce(&request, from).await?;
1009
1010 if request.gas.is_none() {
1011 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1013 {
1014 request.gas = Some(gas.to());
1015 }
1016 }
1017
1018 let request = self.build_typed_tx_request(request, nonce)?;
1019
1020 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
1021 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
1022 }
1023
1024 pub async fn send_transaction(
1028 &self,
1029 mut request: WithOtherFields<TransactionRequest>,
1030 ) -> Result<TxHash> {
1031 node_info!("eth_sendTransaction");
1032
1033 let from = request.from.map(Ok).unwrap_or_else(|| {
1034 self.accounts()?.first().copied().ok_or(BlockchainError::NoSignerAvailable)
1035 })?;
1036 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
1037
1038 if request.gas.is_none() {
1039 if let Ok(gas) = self.estimate_gas(request.clone(), None, EvmOverrides::default()).await
1041 {
1042 request.gas = Some(gas.to());
1043 }
1044 }
1045
1046 let request = self.build_typed_tx_request(request, nonce)?;
1047
1048 let pending_transaction = if self.is_impersonated(from) {
1050 let bypass_signature = self.impersonated_signature(&request);
1051 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1052 self.ensure_typed_transaction_supported(&transaction)?;
1053 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1054 PendingTransaction::with_impersonated(transaction, from)
1055 } else {
1056 let transaction = self.sign_request(&from, request)?;
1057 self.ensure_typed_transaction_supported(&transaction)?;
1058 PendingTransaction::new(transaction)?
1059 };
1060 self.backend.validate_pool_transaction(&pending_transaction).await?;
1062
1063 let requires = required_marker(nonce, on_chain_nonce, from);
1064 let provides = vec![to_marker(nonce, from)];
1065 debug_assert!(requires != provides);
1066
1067 self.add_pending_transaction(pending_transaction, requires, provides)
1068 }
1069
1070 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1074 node_info!("eth_sendRawTransaction");
1075 let mut data = tx.as_ref();
1076 if data.is_empty() {
1077 return Err(BlockchainError::EmptyRawTransactionData);
1078 }
1079
1080 let transaction = TypedTransaction::decode_2718(&mut data)
1081 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1082
1083 self.ensure_typed_transaction_supported(&transaction)?;
1084
1085 let pending_transaction = PendingTransaction::new(transaction)?;
1086
1087 self.backend.validate_pool_transaction(&pending_transaction).await?;
1089
1090 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1091 let from = *pending_transaction.sender();
1092 let nonce = pending_transaction.transaction.nonce();
1093 let requires = required_marker(nonce, on_chain_nonce, from);
1094
1095 let priority = self.transaction_priority(&pending_transaction.transaction);
1096 let pool_transaction = PoolTransaction {
1097 requires,
1098 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1099 pending_transaction,
1100 priority,
1101 };
1102
1103 let tx = self.pool.add_transaction(pool_transaction)?;
1104 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1105 Ok(*tx.hash())
1106 }
1107
1108 pub async fn call(
1112 &self,
1113 request: WithOtherFields<TransactionRequest>,
1114 block_number: Option<BlockId>,
1115 overrides: EvmOverrides,
1116 ) -> Result<Bytes> {
1117 node_info!("eth_call");
1118 let block_request = self.block_request(block_number).await?;
1119 if let BlockRequest::Number(number) = block_request {
1121 if let Some(fork) = self.get_fork() {
1122 if fork.predates_fork(number) {
1123 if overrides.has_state() || overrides.has_block() {
1124 return Err(BlockchainError::EvmOverrideError(
1125 "not available on past forked blocks".to_string(),
1126 ));
1127 }
1128 return Ok(fork.call(&request, Some(number.into())).await?)
1129 }
1130 }
1131 }
1132
1133 let fees = FeeDetails::new(
1134 request.gas_price,
1135 request.max_fee_per_gas,
1136 request.max_priority_fee_per_gas,
1137 request.max_fee_per_blob_gas,
1138 )?
1139 .or_zero_fees();
1140 self.on_blocking_task(|this| async move {
1143 let (exit, out, gas, _) =
1144 this.backend.call(request, fees, Some(block_request), overrides).await?;
1145 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1146
1147 ensure_return_ok(exit, &out)
1148 })
1149 .await
1150 }
1151
1152 pub async fn simulate_v1(
1153 &self,
1154 request: SimulatePayload,
1155 block_number: Option<BlockId>,
1156 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1157 node_info!("eth_simulateV1");
1158 let block_request = self.block_request(block_number).await?;
1159 if let BlockRequest::Number(number) = block_request {
1161 if let Some(fork) = self.get_fork() {
1162 if fork.predates_fork(number) {
1163 return Ok(fork.simulate_v1(&request, Some(number.into())).await?)
1164 }
1165 }
1166 }
1167
1168 self.on_blocking_task(|this| async move {
1171 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1172 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1173
1174 Ok(simulated_blocks)
1175 })
1176 .await
1177 }
1178
1179 pub async fn create_access_list(
1193 &self,
1194 mut request: WithOtherFields<TransactionRequest>,
1195 block_number: Option<BlockId>,
1196 ) -> Result<AccessListResult> {
1197 node_info!("eth_createAccessList");
1198 let block_request = self.block_request(block_number).await?;
1199 if let BlockRequest::Number(number) = block_request {
1201 if let Some(fork) = self.get_fork() {
1202 if fork.predates_fork(number) {
1203 return Ok(fork.create_access_list(&request, Some(number.into())).await?)
1204 }
1205 }
1206 }
1207
1208 self.backend
1209 .with_database_at(Some(block_request), |state, block_env| {
1210 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1211 &state,
1212 request.clone(),
1213 FeeDetails::zero(),
1214 block_env.clone(),
1215 )?;
1216 ensure_return_ok(exit, &out)?;
1217
1218 request.access_list = Some(access_list.clone());
1220
1221 let (exit, out, gas_used, _) = self.backend.call_with_state(
1222 &state,
1223 request.clone(),
1224 FeeDetails::zero(),
1225 block_env,
1226 )?;
1227 ensure_return_ok(exit, &out)?;
1228
1229 Ok(AccessListResult {
1230 access_list: AccessList(access_list.0),
1231 gas_used: U256::from(gas_used),
1232 error: None,
1233 })
1234 })
1235 .await?
1236 }
1237
1238 pub async fn estimate_gas(
1243 &self,
1244 request: WithOtherFields<TransactionRequest>,
1245 block_number: Option<BlockId>,
1246 overrides: EvmOverrides,
1247 ) -> Result<U256> {
1248 node_info!("eth_estimateGas");
1249 self.do_estimate_gas(
1250 request,
1251 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1252 overrides,
1253 )
1254 .await
1255 .map(U256::from)
1256 }
1257
1258 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1265 node_info!("eth_getTransactionByHash");
1266 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1267 let from = *pending.sender();
1268 let tx = transaction_build(
1269 Some(*pending.hash()),
1270 pending.transaction,
1271 None,
1272 None,
1273 Some(self.backend.base_fee()),
1274 );
1275
1276 let WithOtherFields { inner: mut tx, other } = tx.0;
1277 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1280
1281 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1282 });
1283 if tx.is_none() {
1284 tx = self.backend.transaction_by_hash(hash).await?
1285 }
1286
1287 Ok(tx)
1288 }
1289
1290 pub async fn transaction_by_block_hash_and_index(
1294 &self,
1295 hash: B256,
1296 index: Index,
1297 ) -> Result<Option<AnyRpcTransaction>> {
1298 node_info!("eth_getTransactionByBlockHashAndIndex");
1299 self.backend.transaction_by_block_hash_and_index(hash, index).await
1300 }
1301
1302 pub async fn transaction_by_block_number_and_index(
1306 &self,
1307 block: BlockNumber,
1308 idx: Index,
1309 ) -> Result<Option<AnyRpcTransaction>> {
1310 node_info!("eth_getTransactionByBlockNumberAndIndex");
1311 self.backend.transaction_by_block_number_and_index(block, idx).await
1312 }
1313
1314 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1318 node_info!("eth_getTransactionReceipt");
1319 let tx = self.pool.get_transaction(hash);
1320 if tx.is_some() {
1321 return Ok(None);
1322 }
1323 self.backend.transaction_receipt(hash).await
1324 }
1325
1326 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1330 node_info!("eth_getBlockReceipts");
1331 self.backend.block_receipts(number).await
1332 }
1333
1334 pub async fn uncle_by_block_hash_and_index(
1338 &self,
1339 block_hash: B256,
1340 idx: Index,
1341 ) -> Result<Option<AnyRpcBlock>> {
1342 node_info!("eth_getUncleByBlockHashAndIndex");
1343 let number =
1344 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1345 if let Some(fork) = self.get_fork() {
1346 if fork.predates_fork_inclusive(number) {
1347 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?)
1348 }
1349 }
1350 Ok(None)
1352 }
1353
1354 pub async fn uncle_by_block_number_and_index(
1358 &self,
1359 block_number: BlockNumber,
1360 idx: Index,
1361 ) -> Result<Option<AnyRpcBlock>> {
1362 node_info!("eth_getUncleByBlockNumberAndIndex");
1363 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1364 if let Some(fork) = self.get_fork() {
1365 if fork.predates_fork_inclusive(number) {
1366 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?)
1367 }
1368 }
1369 Ok(None)
1371 }
1372
1373 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1377 node_info!("eth_getLogs");
1378 self.backend.logs(filter).await
1379 }
1380
1381 pub fn work(&self) -> Result<Work> {
1385 node_info!("eth_getWork");
1386 Err(BlockchainError::RpcUnimplemented)
1387 }
1388
1389 pub fn syncing(&self) -> Result<bool> {
1393 node_info!("eth_syncing");
1394 Ok(false)
1395 }
1396
1397 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1401 node_info!("eth_submitWork");
1402 Err(BlockchainError::RpcUnimplemented)
1403 }
1404
1405 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1409 node_info!("eth_submitHashrate");
1410 Err(BlockchainError::RpcUnimplemented)
1411 }
1412
1413 pub async fn fee_history(
1417 &self,
1418 block_count: U256,
1419 newest_block: BlockNumber,
1420 reward_percentiles: Vec<f64>,
1421 ) -> Result<FeeHistory> {
1422 node_info!("eth_feeHistory");
1423 let current = self.backend.best_number();
1426 let slots_in_an_epoch = 32u64;
1427
1428 let number = match newest_block {
1429 BlockNumber::Latest | BlockNumber::Pending => current,
1430 BlockNumber::Earliest => 0,
1431 BlockNumber::Number(n) => n,
1432 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1433 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1434 };
1435
1436 if let Some(fork) = self.get_fork() {
1438 if fork.predates_fork_inclusive(number) {
1441 return fork
1442 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1443 .await
1444 .map_err(BlockchainError::AlloyForkProvider);
1445 }
1446 }
1447
1448 const MAX_BLOCK_COUNT: u64 = 1024u64;
1449 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1450
1451 let highest = number;
1453 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1454
1455 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1457 return Err(FeeHistoryError::InvalidBlockRange.into());
1458 }
1459
1460 let mut response = FeeHistory {
1461 oldest_block: lowest,
1462 base_fee_per_gas: Vec::new(),
1463 gas_used_ratio: Vec::new(),
1464 reward: Some(Default::default()),
1465 base_fee_per_blob_gas: Default::default(),
1466 blob_gas_used_ratio: Default::default(),
1467 };
1468 let mut rewards = Vec::new();
1469
1470 {
1471 let fee_history = self.fee_history_cache.lock();
1472
1473 for n in lowest..=highest {
1475 if let Some(block) = fee_history.get(&n) {
1477 response.base_fee_per_gas.push(block.base_fee);
1478 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1479 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1480 response.gas_used_ratio.push(block.gas_used_ratio);
1481
1482 if !reward_percentiles.is_empty() {
1484 let mut block_rewards = Vec::new();
1485 let resolution_per_percentile: f64 = 2.0;
1486 for p in &reward_percentiles {
1487 let p = p.clamp(0.0, 100.0);
1488 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1489 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1490 block_rewards.push(reward);
1491 }
1492 rewards.push(block_rewards);
1493 }
1494 }
1495 }
1496 }
1497
1498 response.reward = Some(rewards);
1499
1500 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1505
1506 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1510
1511 Ok(response)
1512 }
1513
1514 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1521 node_info!("eth_maxPriorityFeePerGas");
1522 Ok(U256::from(self.lowest_suggestion_tip()))
1523 }
1524
1525 fn lowest_suggestion_tip(&self) -> u128 {
1529 let block_number = self.backend.best_number();
1530 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1531
1532 match latest_cached_block {
1533 Some(block) => block.rewards.iter().copied().min(),
1534 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1535 }
1536 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1537 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1538 }
1539
1540 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1544 node_info!("eth_newFilter");
1545 let historic = if filter.block_option.get_from_block().is_some() {
1548 self.backend.logs(filter.clone()).await?
1549 } else {
1550 vec![]
1551 };
1552 let filter = EthFilter::Logs(Box::new(LogsFilter {
1553 blocks: self.new_block_notifications(),
1554 storage: self.storage_info(),
1555 filter: FilteredParams::new(Some(filter)),
1556 historic: Some(historic),
1557 }));
1558 Ok(self.filters.add_filter(filter).await)
1559 }
1560
1561 pub async fn new_block_filter(&self) -> Result<String> {
1565 node_info!("eth_newBlockFilter");
1566 let filter = EthFilter::Blocks(self.new_block_notifications());
1567 Ok(self.filters.add_filter(filter).await)
1568 }
1569
1570 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1574 node_info!("eth_newPendingTransactionFilter");
1575 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1576 Ok(self.filters.add_filter(filter).await)
1577 }
1578
1579 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1583 node_info!("eth_getFilterChanges");
1584 self.filters.get_filter_changes(id).await
1585 }
1586
1587 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1591 node_info!("eth_getFilterLogs");
1592 if let Some(filter) = self.filters.get_log_filter(id).await {
1593 self.backend.logs(filter).await
1594 } else {
1595 Ok(Vec::new())
1596 }
1597 }
1598
1599 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1601 node_info!("eth_uninstallFilter");
1602 Ok(self.filters.uninstall_filter(id).await.is_some())
1603 }
1604
1605 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1609 node_info!("debug_getRawTransaction");
1610 self.inner_raw_transaction(hash).await
1611 }
1612
1613 pub async fn raw_transaction_by_block_hash_and_index(
1617 &self,
1618 block_hash: B256,
1619 index: Index,
1620 ) -> Result<Option<Bytes>> {
1621 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1622 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1623 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1624 None => Ok(None),
1625 }
1626 }
1627
1628 pub async fn raw_transaction_by_block_number_and_index(
1632 &self,
1633 block_number: BlockNumber,
1634 index: Index,
1635 ) -> Result<Option<Bytes>> {
1636 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1637 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1638 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1639 None => Ok(None),
1640 }
1641 }
1642
1643 pub async fn debug_trace_transaction(
1647 &self,
1648 tx_hash: B256,
1649 opts: GethDebugTracingOptions,
1650 ) -> Result<GethTrace> {
1651 node_info!("debug_traceTransaction");
1652 self.backend.debug_trace_transaction(tx_hash, opts).await
1653 }
1654
1655 pub async fn debug_trace_call(
1659 &self,
1660 request: WithOtherFields<TransactionRequest>,
1661 block_number: Option<BlockId>,
1662 opts: GethDebugTracingCallOptions,
1663 ) -> Result<GethTrace> {
1664 node_info!("debug_traceCall");
1665 let block_request = self.block_request(block_number).await?;
1666 let fees = FeeDetails::new(
1667 request.gas_price,
1668 request.max_fee_per_gas,
1669 request.max_priority_fee_per_gas,
1670 request.max_fee_per_blob_gas,
1671 )?
1672 .or_zero_fees();
1673
1674 let result: std::result::Result<GethTrace, BlockchainError> =
1675 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1676 result
1677 }
1678
1679 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1683 node_info!("trace_transaction");
1684 self.backend.trace_transaction(tx_hash).await
1685 }
1686
1687 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1691 node_info!("trace_block");
1692 self.backend.trace_block(block).await
1693 }
1694
1695 pub async fn trace_filter(
1699 &self,
1700 filter: TraceFilter,
1701 ) -> Result<Vec<LocalizedTransactionTrace>> {
1702 node_info!("trace_filter");
1703 self.backend.trace_filter(filter).await
1704 }
1705}
1706
1707impl EthApi {
1710 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
1714 node_info!("anvil_impersonateAccount");
1715 self.backend.impersonate(address);
1716 Ok(())
1717 }
1718
1719 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
1723 node_info!("anvil_stopImpersonatingAccount");
1724 self.backend.stop_impersonating(address);
1725 Ok(())
1726 }
1727
1728 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
1732 node_info!("anvil_autoImpersonateAccount");
1733 self.backend.auto_impersonate_account(enabled);
1734 Ok(())
1735 }
1736
1737 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
1741 node_info!("anvil_getAutomine");
1742 Ok(self.miner.is_auto_mine())
1743 }
1744
1745 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
1749 node_info!("anvil_getIntervalMining");
1750 Ok(self.miner.get_interval())
1751 }
1752
1753 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
1758 node_info!("evm_setAutomine");
1759 if self.miner.is_auto_mine() {
1760 if enable_automine {
1761 return Ok(());
1762 }
1763 self.miner.set_mining_mode(MiningMode::None);
1764 } else if enable_automine {
1765 let listener = self.pool.add_ready_listener();
1766 let mode = MiningMode::instant(1_000, listener);
1767 self.miner.set_mining_mode(mode);
1768 }
1769 Ok(())
1770 }
1771
1772 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
1776 node_info!("anvil_mine");
1777 let interval = interval.map(|i| i.to::<u64>());
1778 let blocks = num_blocks.unwrap_or(U256::from(1));
1779 if blocks.is_zero() {
1780 return Ok(());
1781 }
1782
1783 self.on_blocking_task(|this| async move {
1784 for _ in 0..blocks.to::<u64>() {
1786 if let Some(interval) = interval {
1788 this.backend.time().increase_time(interval);
1789 }
1790 this.mine_one().await;
1791 }
1792 Ok(())
1793 })
1794 .await?;
1795
1796 Ok(())
1797 }
1798
1799 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
1803 node_info!("evm_setIntervalMining");
1804 let mining_mode = if secs == 0 {
1805 MiningMode::None
1806 } else {
1807 let block_time = Duration::from_secs(secs);
1808
1809 self.backend.update_interval_mine_block_time(block_time);
1811
1812 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
1813 };
1814 self.miner.set_mining_mode(mining_mode);
1815 Ok(())
1816 }
1817
1818 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
1822 node_info!("anvil_dropTransaction");
1823 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
1824 }
1825
1826 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
1830 node_info!("anvil_dropAllTransactions");
1831 self.pool.clear();
1832 Ok(())
1833 }
1834
1835 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
1841 node_info!("anvil_reset");
1842 if let Some(forking) = forking {
1843 self.reset_instance_id();
1845 self.backend.reset_fork(forking).await
1846 } else {
1847 Err(BlockchainError::RpcUnimplemented)
1848 }
1849 }
1850
1851 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
1852 node_info!("anvil_setChainId");
1853 self.backend.set_chain_id(chain_id);
1854 Ok(())
1855 }
1856
1857 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
1861 node_info!("anvil_setBalance");
1862 self.backend.set_balance(address, balance).await?;
1863 Ok(())
1864 }
1865
1866 pub async fn anvil_add_balance(&self, address: Address, balance: U256) -> Result<()> {
1870 node_info!("anvil_addBalance");
1871 let current_balance = self.backend.get_balance(address, None).await?;
1872 self.backend.set_balance(address, current_balance + balance).await?;
1873 Ok(())
1874 }
1875
1876 async fn find_erc20_storage_slot(
1893 &self,
1894 token_address: Address,
1895 calldata: Bytes,
1896 expected_value: U256,
1897 ) -> Result<B256> {
1898 let tx = TransactionRequest::default().with_to(token_address).with_input(calldata.clone());
1899
1900 let access_list_result =
1902 self.create_access_list(WithOtherFields::new(tx.clone()), None).await?;
1903 let access_list = access_list_result.access_list;
1904
1905 for item in access_list.0 {
1908 if item.address != token_address {
1909 continue;
1910 };
1911 for slot in &item.storage_keys {
1912 let account_override = AccountOverride::default().with_state_diff(std::iter::once(
1913 (*slot, B256::from(expected_value.to_be_bytes())),
1914 ));
1915
1916 let state_override = StateOverridesBuilder::default()
1917 .append(token_address, account_override)
1918 .build();
1919
1920 let evm_override = EvmOverrides::state(Some(state_override));
1921
1922 let Ok(result) =
1923 self.call(WithOtherFields::new(tx.clone()), None, evm_override).await
1924 else {
1925 continue;
1927 };
1928
1929 let Ok(result_value) = U256::abi_decode(&result) else {
1930 continue;
1932 };
1933
1934 if result_value == expected_value {
1935 return Ok(*slot);
1936 }
1937 }
1938 }
1939
1940 Err(BlockchainError::Message("Unable to find storage slot".to_string()))
1941 }
1942
1943 pub async fn anvil_deal_erc20(
1947 &self,
1948 address: Address,
1949 token_address: Address,
1950 balance: U256,
1951 ) -> Result<()> {
1952 node_info!("anvil_dealERC20");
1953
1954 sol! {
1955 #[sol(rpc)]
1956 contract IERC20 {
1957 function balanceOf(address target) external view returns (uint256);
1958 }
1959 }
1960
1961 let calldata = IERC20::balanceOfCall { target: address }.abi_encode().into();
1962
1963 let slot =
1965 self.find_erc20_storage_slot(token_address, calldata, balance).await.map_err(|_| {
1966 BlockchainError::Message("Unable to set ERC20 balance, no slot found".to_string())
1967 })?;
1968
1969 self.anvil_set_storage_at(
1971 token_address,
1972 U256::from_be_bytes(slot.0),
1973 B256::from(balance.to_be_bytes()),
1974 )
1975 .await?;
1976
1977 Ok(())
1978 }
1979
1980 pub async fn anvil_set_erc20_allowance(
1984 &self,
1985 owner: Address,
1986 spender: Address,
1987 token_address: Address,
1988 amount: U256,
1989 ) -> Result<()> {
1990 node_info!("anvil_setERC20Allowance");
1991
1992 sol! {
1993 #[sol(rpc)]
1994 contract IERC20 {
1995 function allowance(address owner, address spender) external view returns (uint256);
1996 }
1997 }
1998
1999 let calldata = IERC20::allowanceCall { owner, spender }.abi_encode().into();
2000
2001 let slot =
2003 self.find_erc20_storage_slot(token_address, calldata, amount).await.map_err(|_| {
2004 BlockchainError::Message("Unable to set ERC20 allowance, no slot found".to_string())
2005 })?;
2006
2007 self.anvil_set_storage_at(
2009 token_address,
2010 U256::from_be_bytes(slot.0),
2011 B256::from(amount.to_be_bytes()),
2012 )
2013 .await?;
2014
2015 Ok(())
2016 }
2017
2018 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
2022 node_info!("anvil_setCode");
2023 self.backend.set_code(address, code).await?;
2024 Ok(())
2025 }
2026
2027 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
2031 node_info!("anvil_setNonce");
2032 self.backend.set_nonce(address, nonce).await?;
2033 Ok(())
2034 }
2035
2036 pub async fn anvil_set_storage_at(
2040 &self,
2041 address: Address,
2042 slot: U256,
2043 val: B256,
2044 ) -> Result<bool> {
2045 node_info!("anvil_setStorageAt");
2046 self.backend.set_storage_at(address, slot, val).await?;
2047 Ok(true)
2048 }
2049
2050 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
2054 node_info!("anvil_setLoggingEnabled");
2055 self.logger.set_enabled(enable);
2056 Ok(())
2057 }
2058
2059 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
2063 node_info!("anvil_setMinGasPrice");
2064 if self.backend.is_eip1559() {
2065 return Err(RpcError::invalid_params(
2066 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
2067 )
2068 .into());
2069 }
2070 self.backend.set_gas_price(gas.to());
2071 Ok(())
2072 }
2073
2074 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
2078 node_info!("anvil_setNextBlockBaseFeePerGas");
2079 if !self.backend.is_eip1559() {
2080 return Err(RpcError::invalid_params(
2081 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
2082 )
2083 .into());
2084 }
2085 self.backend.set_base_fee(basefee.to());
2086 Ok(())
2087 }
2088
2089 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
2093 node_info!("anvil_setCoinbase");
2094 self.backend.set_coinbase(address);
2095 Ok(())
2096 }
2097
2098 pub async fn anvil_dump_state(
2103 &self,
2104 preserve_historical_states: Option<bool>,
2105 ) -> Result<Bytes> {
2106 node_info!("anvil_dumpState");
2107 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
2108 }
2109
2110 pub async fn serialized_state(
2112 &self,
2113 preserve_historical_states: bool,
2114 ) -> Result<SerializableState> {
2115 self.backend.serialized_state(preserve_historical_states).await
2116 }
2117
2118 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
2123 node_info!("anvil_loadState");
2124 self.backend.load_state_bytes(buf).await
2125 }
2126
2127 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
2131 node_info!("anvil_nodeInfo");
2132
2133 let env = self.backend.env().read();
2134 let fork_config = self.backend.get_fork();
2135 let tx_order = self.transaction_order.read();
2136 let hard_fork: &str = env.evm_env.cfg_env.spec.into();
2137
2138 Ok(NodeInfo {
2139 current_block_number: self.backend.best_number(),
2140 current_block_timestamp: env.evm_env.block_env.timestamp,
2141 current_block_hash: self.backend.best_hash(),
2142 hard_fork: hard_fork.to_string(),
2143 transaction_order: match *tx_order {
2144 TransactionOrder::Fifo => "fifo".to_string(),
2145 TransactionOrder::Fees => "fees".to_string(),
2146 },
2147 environment: NodeEnvironment {
2148 base_fee: self.backend.base_fee() as u128,
2149 chain_id: self.backend.chain_id().to::<u64>(),
2150 gas_limit: self.backend.gas_limit(),
2151 gas_price: self.gas_price(),
2152 },
2153 fork_config: fork_config
2154 .map(|fork| {
2155 let config = fork.config.read();
2156
2157 NodeForkConfig {
2158 fork_url: Some(config.eth_rpc_url.clone()),
2159 fork_block_number: Some(config.block_number),
2160 fork_retry_backoff: Some(config.backoff.as_millis()),
2161 }
2162 })
2163 .unwrap_or_default(),
2164 })
2165 }
2166
2167 pub async fn anvil_metadata(&self) -> Result<Metadata> {
2171 node_info!("anvil_metadata");
2172 let fork_config = self.backend.get_fork();
2173
2174 Ok(Metadata {
2175 client_version: CLIENT_VERSION.to_string(),
2176 chain_id: self.backend.chain_id().to::<u64>(),
2177 latest_block_hash: self.backend.best_hash(),
2178 latest_block_number: self.backend.best_number(),
2179 instance_id: *self.instance_id.read(),
2180 forked_network: fork_config.map(|cfg| ForkedNetwork {
2181 chain_id: cfg.chain_id(),
2182 fork_block_number: cfg.block_number(),
2183 fork_block_hash: cfg.block_hash(),
2184 }),
2185 snapshots: self.backend.list_state_snapshots(),
2186 })
2187 }
2188
2189 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
2190 node_info!("anvil_removePoolTransactions");
2191 self.pool.remove_transactions_by_address(address);
2192 Ok(())
2193 }
2194
2195 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2209 node_info!("anvil_reorg");
2210 let depth = options.depth;
2211 let tx_block_pairs = options.tx_block_pairs;
2212
2213 let current_height = self.backend.best_number();
2215 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2216 RpcError::invalid_params(format!(
2217 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2218 )),
2219 ))?;
2220
2221 let common_block =
2223 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2224
2225 let block_pool_txs = if tx_block_pairs.is_empty() {
2228 HashMap::default()
2229 } else {
2230 let mut pairs = tx_block_pairs;
2231
2232 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2234 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2235 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2236 depth-1
2237 ))));
2238 }
2239
2240 pairs.sort_by_key(|a| a.1);
2242
2243 let mut nonces: HashMap<Address, u64> = HashMap::default();
2246
2247 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2248 for pair in pairs {
2249 let (tx_data, block_index) = pair;
2250
2251 let pending = match tx_data {
2252 TransactionData::Raw(bytes) => {
2253 let mut data = bytes.as_ref();
2254 let decoded = TypedTransaction::decode_2718(&mut data)
2255 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2256 PendingTransaction::new(decoded)?
2257 }
2258
2259 TransactionData::JSON(req) => {
2260 let mut tx_req = WithOtherFields::new(req);
2261 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2262 self.accounts()?
2263 .first()
2264 .copied()
2265 .ok_or(BlockchainError::NoSignerAvailable)
2266 })?;
2267
2268 let curr_nonce = nonces.entry(from).or_insert(
2270 self.get_transaction_count(
2271 from,
2272 Some(common_block.header.number.into()),
2273 )
2274 .await?,
2275 );
2276
2277 if tx_req.gas.is_none() {
2279 if let Ok(gas) = self
2280 .estimate_gas(tx_req.clone(), None, EvmOverrides::default())
2281 .await
2282 {
2283 tx_req.gas = Some(gas.to());
2284 }
2285 }
2286
2287 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2289
2290 *curr_nonce += 1;
2292
2293 if self.is_impersonated(from) {
2295 let bypass_signature = self.impersonated_signature(&typed);
2296 let transaction =
2297 sign::build_typed_transaction(typed, bypass_signature)?;
2298 self.ensure_typed_transaction_supported(&transaction)?;
2299 PendingTransaction::with_impersonated(transaction, from)
2300 } else {
2301 let transaction = self.sign_request(&from, typed)?;
2302 self.ensure_typed_transaction_supported(&transaction)?;
2303 PendingTransaction::new(transaction)?
2304 }
2305 }
2306 };
2307
2308 let pooled = PoolTransaction::new(pending);
2309 txs.entry(block_index).or_default().push(Arc::new(pooled));
2310 }
2311
2312 txs
2313 };
2314
2315 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2316 Ok(())
2317 }
2318
2319 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2330 node_info!("anvil_rollback");
2331 let depth = depth.unwrap_or(1);
2332
2333 let current_height = self.backend.best_number();
2335 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2336 RpcError::invalid_params(format!(
2337 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2338 )),
2339 ))?;
2340
2341 let common_block =
2343 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2344
2345 self.backend.rollback(common_block).await?;
2346 Ok(())
2347 }
2348
2349 pub async fn evm_snapshot(&self) -> Result<U256> {
2353 node_info!("evm_snapshot");
2354 Ok(self.backend.create_state_snapshot().await)
2355 }
2356
2357 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2362 node_info!("evm_revert");
2363 self.backend.revert_state_snapshot(id).await
2364 }
2365
2366 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2370 node_info!("evm_increaseTime");
2371 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2372 }
2373
2374 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2378 node_info!("evm_setNextBlockTimestamp");
2379 self.backend.time().set_next_block_timestamp(seconds)
2380 }
2381
2382 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2387 node_info!("evm_setTime");
2388 let now = self.backend.time().current_call_timestamp();
2389 self.backend.time().reset(timestamp);
2390
2391 let offset = timestamp.saturating_sub(now);
2393 Ok(Duration::from_millis(offset).as_secs())
2394 }
2395
2396 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2400 node_info!("evm_setBlockGasLimit");
2401 self.backend.set_gas_limit(gas_limit.to());
2402 Ok(true)
2403 }
2404
2405 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2409 node_info!("anvil_setBlockTimestampInterval");
2410 self.backend.time().set_block_timestamp_interval(seconds);
2411 Ok(())
2412 }
2413
2414 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2418 node_info!("anvil_removeBlockTimestampInterval");
2419 Ok(self.backend.time().remove_block_timestamp_interval())
2420 }
2421
2422 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2429 node_info!("evm_mine");
2430
2431 self.do_evm_mine(opts).await?;
2432
2433 Ok("0x0".to_string())
2434 }
2435
2436 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2446 node_info!("evm_mine_detailed");
2447
2448 let mined_blocks = self.do_evm_mine(opts).await?;
2449
2450 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2451
2452 let latest = self.backend.best_number();
2453 for offset in (0..mined_blocks).rev() {
2454 let block_num = latest - offset;
2455 if let Some(mut block) =
2456 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2457 {
2458 let block_txs = match block.transactions_mut() {
2459 BlockTransactions::Full(txs) => txs,
2460 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2461 };
2462 for tx in block_txs.iter_mut() {
2463 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash()) {
2464 if let Some(output) = receipt.out {
2465 if !receipt
2467 .inner
2468 .inner
2469 .as_receipt_with_bloom()
2470 .receipt
2471 .status
2472 .coerce_status()
2473 {
2474 if let Some(reason) =
2475 RevertDecoder::new().maybe_decode(&output, None)
2476 {
2477 tx.other.insert(
2478 "revertReason".to_string(),
2479 serde_json::to_value(reason).expect("Infallible"),
2480 );
2481 }
2482 }
2483 tx.other.insert(
2484 "output".to_string(),
2485 serde_json::to_value(output).expect("Infallible"),
2486 );
2487 }
2488 }
2489 }
2490 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2491 blocks.push(block);
2492 }
2493 }
2494
2495 Ok(blocks)
2496 }
2497
2498 pub fn anvil_set_block(&self, block_number: u64) -> Result<()> {
2502 node_info!("anvil_setBlock");
2503 self.backend.set_block_number(block_number);
2504 Ok(())
2505 }
2506
2507 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2511 node_info!("anvil_setRpcUrl");
2512 if let Some(fork) = self.backend.get_fork() {
2513 let mut config = fork.config.write();
2514 let new_provider = Arc::new(
2516 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2517 |_| {
2518 TransportErrorKind::custom_str(
2519 format!("Failed to parse invalid url {url}").as_str(),
2520 )
2521 },
2522 )?, );
2525 config.provider = new_provider;
2526 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2527 config.eth_rpc_url = url;
2528 }
2529 Ok(())
2530 }
2531
2532 pub async fn anvil_enable_traces(&self) -> Result<()> {
2537 node_info!("anvil_enableTraces");
2538 Err(BlockchainError::RpcUnimplemented)
2539 }
2540
2541 pub async fn eth_send_unsigned_transaction(
2545 &self,
2546 request: WithOtherFields<TransactionRequest>,
2547 ) -> Result<TxHash> {
2548 node_info!("eth_sendUnsignedTransaction");
2549 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2551
2552 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2553
2554 let request = self.build_typed_tx_request(request, nonce)?;
2555
2556 let bypass_signature = self.impersonated_signature(&request);
2557 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2558
2559 self.ensure_typed_transaction_supported(&transaction)?;
2560
2561 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2562
2563 self.backend.validate_pool_transaction(&pending_transaction).await?;
2565
2566 let requires = required_marker(nonce, on_chain_nonce, from);
2567 let provides = vec![to_marker(nonce, from)];
2568
2569 self.add_pending_transaction(pending_transaction, requires, provides)
2570 }
2571
2572 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2578 node_info!("txpool_status");
2579 Ok(self.pool.txpool_status())
2580 }
2581
2582 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2589 node_info!("txpool_inspect");
2590 let mut inspect = TxpoolInspect::default();
2591
2592 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2593 let tx = &tx.pending_transaction.transaction;
2594 let to = tx.to();
2595 let gas_price = tx.gas_price();
2596 let value = tx.value();
2597 let gas = tx.gas_limit();
2598 TxpoolInspectSummary { to, value, gas, gas_price }
2599 }
2600
2601 for pending in self.pool.ready_transactions() {
2608 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2609 let key = pending.pending_transaction.nonce().to_string();
2610 entry.insert(key, convert(pending));
2611 }
2612 for queued in self.pool.pending_transactions() {
2613 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2614 let key = queued.pending_transaction.nonce().to_string();
2615 entry.insert(key, convert(queued));
2616 }
2617 Ok(inspect)
2618 }
2619
2620 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2627 node_info!("txpool_content");
2628 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2629 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2630 let from = *tx.pending_transaction.sender();
2631 let tx = transaction_build(
2632 Some(tx.hash()),
2633 tx.pending_transaction.transaction.clone(),
2634 None,
2635 None,
2636 None,
2637 );
2638
2639 let WithOtherFields { inner: mut tx, other } = tx.0;
2640
2641 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2644
2645 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2646
2647 Ok(tx)
2648 }
2649
2650 for pending in self.pool.ready_transactions() {
2651 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2652 let key = pending.pending_transaction.nonce().to_string();
2653 entry.insert(key, convert(pending)?);
2654 }
2655 for queued in self.pool.pending_transactions() {
2656 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2657 let key = queued.pending_transaction.nonce().to_string();
2658 entry.insert(key, convert(queued)?);
2659 }
2660
2661 Ok(content)
2662 }
2663}
2664
2665impl EthApi {
2667 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2673 node_info!("wallet_getCapabilities");
2674 Ok(self.backend.get_capabilities())
2675 }
2676
2677 pub async fn wallet_send_transaction(
2678 &self,
2679 mut request: WithOtherFields<TransactionRequest>,
2680 ) -> Result<TxHash> {
2681 node_info!("wallet_sendTransaction");
2682
2683 if request.value.is_some_and(|val| val > U256::ZERO) {
2686 return Err(WalletError::ValueNotZero.into())
2687 }
2688
2689 if request.from.is_some() {
2691 return Err(WalletError::FromSet.into());
2692 }
2693
2694 if request.nonce.is_some() {
2696 return Err(WalletError::NonceSet.into());
2697 }
2698
2699 let capabilities = self.backend.get_capabilities();
2700 let valid_delegations: &[Address] = capabilities
2701 .get(self.chain_id())
2702 .map(|caps| caps.delegation.addresses.as_ref())
2703 .unwrap_or_default();
2704
2705 if let Some(authorizations) = &request.authorization_list {
2706 if authorizations.iter().any(|auth| !valid_delegations.contains(&auth.address)) {
2707 return Err(WalletError::InvalidAuthorization.into());
2708 }
2709 }
2710
2711 match (request.authorization_list.is_some(), request.to) {
2713 (false, Some(TxKind::Call(addr))) => {
2716 let acc = self.backend.get_account(addr).await?;
2717
2718 let delegated_address = acc
2719 .code
2720 .map(|code| match code {
2721 Bytecode::Eip7702(c) => c.address(),
2722 _ => Address::ZERO,
2723 })
2724 .unwrap_or_default();
2725
2726 if delegated_address == Address::ZERO ||
2728 !valid_delegations.contains(&delegated_address)
2729 {
2730 return Err(WalletError::IllegalDestination.into());
2731 }
2732 }
2733 (true, _) => (),
2735 _ => return Err(WalletError::IllegalDestination.into()),
2737 }
2738
2739 let wallet = self.backend.executor_wallet().ok_or(WalletError::InternalError)?;
2740
2741 let from = NetworkWallet::<Ethereum>::default_signer_address(&wallet);
2742
2743 let nonce = self.get_transaction_count(from, Some(BlockId::latest())).await?;
2744
2745 request.nonce = Some(nonce);
2746
2747 let chain_id = self.chain_id();
2748
2749 request.chain_id = Some(chain_id);
2750
2751 request.from = Some(from);
2752
2753 let gas_limit_fut =
2754 self.estimate_gas(request.clone(), Some(BlockId::latest()), EvmOverrides::default());
2755
2756 let fees_fut = self.fee_history(
2757 U256::from(EIP1559_FEE_ESTIMATION_PAST_BLOCKS),
2758 BlockNumber::Latest,
2759 vec![EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE],
2760 );
2761
2762 let (gas_limit, fees) = tokio::join!(gas_limit_fut, fees_fut);
2763
2764 let gas_limit = gas_limit?;
2765 let fees = fees?;
2766
2767 request.gas = Some(gas_limit.to());
2768
2769 let base_fee = fees.latest_block_base_fee().unwrap_or_default();
2770
2771 let estimation = eip1559_default_estimator(base_fee, &fees.reward.unwrap_or_default());
2772
2773 request.max_fee_per_gas = Some(estimation.max_fee_per_gas);
2774 request.max_priority_fee_per_gas = Some(estimation.max_priority_fee_per_gas);
2775 request.gas_price = None;
2776
2777 let envelope = request.build(&wallet).await.map_err(|_| WalletError::InternalError)?;
2778
2779 self.send_raw_transaction(envelope.encoded_2718().into()).await
2780 }
2781
2782 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2786 node_info!("anvil_addCapability");
2787 self.backend.add_capability(address);
2788 Ok(())
2789 }
2790
2791 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2792 node_info!("anvil_setExecutor");
2793 self.backend.set_executor(executor_pk)
2794 }
2795}
2796
2797impl EthApi {
2798 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2800 where
2801 C: FnOnce(Self) -> F,
2802 F: Future<Output = Result<R>> + Send + 'static,
2803 R: Send + 'static,
2804 {
2805 let (tx, rx) = oneshot::channel();
2806 let this = self.clone();
2807 let f = c(this);
2808 tokio::task::spawn_blocking(move || {
2809 tokio::runtime::Handle::current().block_on(async move {
2810 let res = f.await;
2811 let _ = tx.send(res);
2812 })
2813 });
2814 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2815 }
2816
2817 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2819 let mut blocks_to_mine = 1u64;
2820
2821 if let Some(opts) = opts {
2822 let timestamp = match opts {
2823 MineOptions::Timestamp(timestamp) => timestamp,
2824 MineOptions::Options { timestamp, blocks } => {
2825 if let Some(blocks) = blocks {
2826 blocks_to_mine = blocks;
2827 }
2828 timestamp
2829 }
2830 };
2831 if let Some(timestamp) = timestamp {
2832 self.evm_set_next_block_timestamp(timestamp)?;
2834 }
2835 }
2836
2837 self.on_blocking_task(|this| async move {
2840 for _ in 0..blocks_to_mine {
2842 this.mine_one().await;
2843 }
2844 Ok(())
2845 })
2846 .await?;
2847
2848 Ok(blocks_to_mine)
2849 }
2850
2851 async fn do_estimate_gas(
2852 &self,
2853 request: WithOtherFields<TransactionRequest>,
2854 block_number: Option<BlockId>,
2855 overrides: EvmOverrides,
2856 ) -> Result<u128> {
2857 let block_request = self.block_request(block_number).await?;
2858 if let BlockRequest::Number(number) = block_request {
2860 if let Some(fork) = self.get_fork() {
2861 if fork.predates_fork(number) {
2862 if overrides.has_state() || overrides.has_block() {
2863 return Err(BlockchainError::EvmOverrideError(
2864 "not available on past forked blocks".to_string(),
2865 ));
2866 }
2867 return Ok(fork.estimate_gas(&request, Some(number.into())).await?)
2868 }
2869 }
2870 }
2871
2872 self.on_blocking_task(|this| async move {
2875 this.backend
2876 .with_database_at(Some(block_request), |state, mut block| {
2877 let mut cache_db = CacheDB::new(state);
2878 if let Some(state_overrides) = overrides.state {
2879 state::apply_state_overrides(
2880 state_overrides.into_iter().collect(),
2881 &mut cache_db,
2882 )?;
2883 }
2884 if let Some(block_overrides) = overrides.block {
2885 state::apply_block_overrides(*block_overrides, &mut cache_db, &mut block);
2886 }
2887 this.do_estimate_gas_with_state(request, cache_db.as_dyn(), block)
2888 })
2889 .await?
2890 })
2891 .await
2892 }
2893
2894 fn do_estimate_gas_with_state(
2898 &self,
2899 mut request: WithOtherFields<TransactionRequest>,
2900 state: &dyn DatabaseRef<Error = DatabaseError>,
2901 block_env: BlockEnv,
2902 ) -> Result<u128> {
2903 let to = request.to.as_ref().and_then(TxKind::to);
2906
2907 let maybe_transfer = request.input.input().is_none() &&
2909 request.access_list.is_none() &&
2910 request.blob_versioned_hashes.is_none();
2911
2912 if maybe_transfer {
2913 if let Some(to) = to {
2914 if let Ok(target_code) = self.backend.get_code_with_state(&state, *to) {
2915 if target_code.as_ref().is_empty() {
2916 return Ok(MIN_TRANSACTION_GAS);
2917 }
2918 }
2919 }
2920 }
2921
2922 let fees = FeeDetails::new(
2923 request.gas_price,
2924 request.max_fee_per_gas,
2925 request.max_priority_fee_per_gas,
2926 request.max_fee_per_blob_gas,
2927 )?
2928 .or_zero_fees();
2929
2930 let mut highest_gas_limit = request.gas.map_or(block_env.gas_limit.into(), |g| g as u128);
2933
2934 let gas_price = fees.gas_price.unwrap_or_default();
2935 if gas_price > 0 {
2937 if let Some(from) = request.from {
2938 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
2939 if let Some(value) = request.value {
2940 if value > available_funds {
2941 return Err(InvalidTransactionError::InsufficientFunds.into());
2942 }
2943 available_funds -= value;
2945 }
2946 let allowance =
2948 available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
2949 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
2950 }
2951 }
2952
2953 let mut call_to_estimate = request.clone();
2954 call_to_estimate.gas = Some(highest_gas_limit as u64);
2955
2956 let ethres =
2958 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
2959
2960 let gas_used = match ethres.try_into()? {
2961 GasEstimationCallResult::Success(gas) => Ok(gas),
2962 GasEstimationCallResult::OutOfGas => {
2963 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
2964 }
2965 GasEstimationCallResult::Revert(output) => {
2966 Err(InvalidTransactionError::Revert(output).into())
2967 }
2968 GasEstimationCallResult::EvmError(err) => {
2969 warn!(target: "node", "estimation failed due to {:?}", err);
2970 Err(BlockchainError::EvmError(err))
2971 }
2972 }?;
2973
2974 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
2981
2982 let mut mid_gas_limit =
2984 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
2985
2986 while (highest_gas_limit - lowest_gas_limit) > 1 {
2988 request.gas = Some(mid_gas_limit as u64);
2989 let ethres = self.backend.call_with_state(
2990 &state,
2991 request.clone(),
2992 fees.clone(),
2993 block_env.clone(),
2994 );
2995
2996 match ethres.try_into()? {
2997 GasEstimationCallResult::Success(_) => {
2998 highest_gas_limit = mid_gas_limit;
3002 }
3003 GasEstimationCallResult::OutOfGas |
3004 GasEstimationCallResult::Revert(_) |
3005 GasEstimationCallResult::EvmError(_) => {
3006 lowest_gas_limit = mid_gas_limit;
3013 }
3014 };
3015 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
3017 }
3018
3019 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
3020
3021 Ok(highest_gas_limit)
3022 }
3023
3024 pub fn set_transaction_order(&self, order: TransactionOrder) {
3026 *self.transaction_order.write() = order;
3027 }
3028
3029 fn transaction_priority(&self, tx: &TypedTransaction) -> TransactionPriority {
3031 self.transaction_order.read().priority(tx)
3032 }
3033
3034 pub fn chain_id(&self) -> u64 {
3036 self.backend.chain_id().to::<u64>()
3037 }
3038
3039 pub fn get_fork(&self) -> Option<ClientFork> {
3041 self.backend.get_fork()
3042 }
3043
3044 pub fn instance_id(&self) -> B256 {
3046 *self.instance_id.read()
3047 }
3048
3049 pub fn reset_instance_id(&self) {
3051 *self.instance_id.write() = B256::random();
3052 }
3053
3054 #[expect(clippy::borrowed_box)]
3056 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
3057 self.signers.iter().find(|signer| signer.is_signer_for(address))
3058 }
3059
3060 pub fn new_block_notifications(&self) -> NewBlockNotifications {
3062 self.backend.new_block_notifications()
3063 }
3064
3065 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
3067 self.pool.add_ready_listener()
3068 }
3069
3070 pub fn full_pending_transactions(&self) -> UnboundedReceiver<AnyRpcTransaction> {
3072 let (tx, rx) = unbounded_channel();
3073 let mut hashes = self.new_ready_transactions();
3074
3075 let this = self.clone();
3076
3077 tokio::spawn(async move {
3078 while let Some(hash) = hashes.next().await {
3079 if let Ok(Some(txn)) = this.transaction_by_hash(hash).await {
3080 if tx.send(txn).is_err() {
3081 break;
3082 }
3083 }
3084 }
3085 });
3086
3087 rx
3088 }
3089
3090 pub fn storage_info(&self) -> StorageInfo {
3092 StorageInfo::new(Arc::clone(&self.backend))
3093 }
3094
3095 pub fn is_fork(&self) -> bool {
3097 self.backend.is_fork()
3098 }
3099
3100 pub async fn mine_one(&self) {
3102 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3103 let outcome = self.backend.mine_block(transactions).await;
3104
3105 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
3106 self.pool.on_mined_block(outcome);
3107 }
3108
3109 async fn pending_block(&self) -> AnyRpcBlock {
3111 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3112 let info = self.backend.pending_block(transactions).await;
3113 self.backend.convert_block(info.block)
3114 }
3115
3116 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
3118 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
3119 let BlockInfo { block, transactions, receipts: _ } =
3120 self.backend.pending_block(transactions).await;
3121
3122 let mut partial_block = self.backend.convert_block(block.clone());
3123
3124 let mut block_transactions = Vec::with_capacity(block.transactions.len());
3125 let base_fee = self.backend.base_fee();
3126
3127 for info in transactions {
3128 let tx = block.transactions.get(info.transaction_index as usize)?.clone();
3129
3130 let tx = transaction_build(
3131 Some(info.transaction_hash),
3132 tx,
3133 Some(&block),
3134 Some(info),
3135 Some(base_fee),
3136 );
3137 block_transactions.push(tx);
3138 }
3139
3140 partial_block.transactions = BlockTransactions::from(block_transactions);
3141
3142 Some(partial_block)
3143 }
3144
3145 fn build_typed_tx_request(
3146 &self,
3147 request: WithOtherFields<TransactionRequest>,
3148 nonce: u64,
3149 ) -> Result<TypedTransactionRequest> {
3150 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
3151 let max_fee_per_gas = request.max_fee_per_gas;
3152 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
3153 let gas_price = request.gas_price;
3154
3155 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
3156 let from = request.from;
3157
3158 let request = match transaction_request_to_typed(request) {
3159 Some(TypedTransactionRequest::Legacy(mut m)) => {
3160 m.nonce = nonce;
3161 m.chain_id = Some(chain_id);
3162 m.gas_limit = gas_limit;
3163 if gas_price.is_none() {
3164 m.gas_price = self.gas_price();
3165 }
3166 TypedTransactionRequest::Legacy(m)
3167 }
3168 Some(TypedTransactionRequest::EIP2930(mut m)) => {
3169 m.nonce = nonce;
3170 m.chain_id = chain_id;
3171 m.gas_limit = gas_limit;
3172 if gas_price.is_none() {
3173 m.gas_price = self.gas_price();
3174 }
3175 TypedTransactionRequest::EIP2930(m)
3176 }
3177 Some(TypedTransactionRequest::EIP1559(mut m)) => {
3178 m.nonce = nonce;
3179 m.chain_id = chain_id;
3180 m.gas_limit = gas_limit;
3181 if max_fee_per_gas.is_none() {
3182 m.max_fee_per_gas = self.gas_price();
3183 }
3184 TypedTransactionRequest::EIP1559(m)
3185 }
3186 Some(TypedTransactionRequest::EIP7702(mut m)) => {
3187 m.nonce = nonce;
3188 m.chain_id = chain_id;
3189 m.gas_limit = gas_limit;
3190 if max_fee_per_gas.is_none() {
3191 m.max_fee_per_gas = self.gas_price();
3192 }
3193 TypedTransactionRequest::EIP7702(m)
3194 }
3195 Some(TypedTransactionRequest::EIP4844(m)) => {
3196 TypedTransactionRequest::EIP4844(match m {
3197 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
3199 m.tx.nonce = nonce;
3200 m.tx.chain_id = chain_id;
3201 m.tx.gas_limit = gas_limit;
3202 if max_fee_per_gas.is_none() {
3203 m.tx.max_fee_per_gas = self.gas_price();
3204 }
3205 if max_fee_per_blob_gas.is_none() {
3206 m.tx.max_fee_per_blob_gas = self
3207 .excess_blob_gas_and_price()
3208 .unwrap_or_default()
3209 .map_or(0, |g| g.blob_gasprice)
3210 }
3211 TxEip4844Variant::TxEip4844WithSidecar(m)
3212 }
3213 TxEip4844Variant::TxEip4844(mut tx) => {
3214 if !self.backend.skip_blob_validation(from) {
3215 return Err(BlockchainError::FailedToDecodeTransaction)
3216 }
3217
3218 tx.nonce = nonce;
3220 tx.chain_id = chain_id;
3221 tx.gas_limit = gas_limit;
3222 if max_fee_per_gas.is_none() {
3223 tx.max_fee_per_gas = self.gas_price();
3224 }
3225 if max_fee_per_blob_gas.is_none() {
3226 tx.max_fee_per_blob_gas = self
3227 .excess_blob_gas_and_price()
3228 .unwrap_or_default()
3229 .map_or(0, |g| g.blob_gasprice)
3230 }
3231
3232 TxEip4844Variant::TxEip4844(tx)
3233 }
3234 })
3235 }
3236 Some(TypedTransactionRequest::Deposit(mut m)) => {
3237 m.gas_limit = gas_limit;
3238 TypedTransactionRequest::Deposit(m)
3239 }
3240 None => return Err(BlockchainError::FailedToDecodeTransaction),
3241 };
3242 Ok(request)
3243 }
3244
3245 pub fn is_impersonated(&self, addr: Address) -> bool {
3247 self.backend.cheats().is_impersonated(addr)
3248 }
3249
3250 fn impersonated_signature(&self, request: &TypedTransactionRequest) -> Signature {
3252 match request {
3253 TypedTransactionRequest::Legacy(_) => Signature::from_scalars_and_parity(
3256 B256::with_last_byte(1),
3257 B256::with_last_byte(1),
3258 false,
3259 ),
3260 TypedTransactionRequest::EIP2930(_) |
3261 TypedTransactionRequest::EIP1559(_) |
3262 TypedTransactionRequest::EIP7702(_) |
3263 TypedTransactionRequest::EIP4844(_) |
3264 TypedTransactionRequest::Deposit(_) => Signature::from_scalars_and_parity(
3265 B256::with_last_byte(1),
3266 B256::with_last_byte(1),
3267 false,
3268 ),
3269 }
3270 }
3271
3272 async fn get_transaction_count(
3274 &self,
3275 address: Address,
3276 block_number: Option<BlockId>,
3277 ) -> Result<u64> {
3278 let block_request = self.block_request(block_number).await?;
3279
3280 if let BlockRequest::Number(number) = block_request {
3281 if let Some(fork) = self.get_fork() {
3282 if fork.predates_fork(number) {
3283 return Ok(fork.get_nonce(address, number).await?)
3284 }
3285 }
3286 }
3287
3288 self.backend.get_nonce(address, block_request).await
3289 }
3290
3291 async fn request_nonce(
3299 &self,
3300 request: &TransactionRequest,
3301 from: Address,
3302 ) -> Result<(u64, u64)> {
3303 let highest_nonce =
3304 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3305 let nonce = request.nonce.unwrap_or(highest_nonce);
3306
3307 Ok((nonce, highest_nonce))
3308 }
3309
3310 fn add_pending_transaction(
3312 &self,
3313 pending_transaction: PendingTransaction,
3314 requires: Vec<TxMarker>,
3315 provides: Vec<TxMarker>,
3316 ) -> Result<TxHash> {
3317 let from = *pending_transaction.sender();
3318 let priority = self.transaction_priority(&pending_transaction.transaction);
3319 let pool_transaction =
3320 PoolTransaction { requires, provides, pending_transaction, priority };
3321 let tx = self.pool.add_transaction(pool_transaction)?;
3322 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3323 Ok(*tx.hash())
3324 }
3325
3326 pub async fn state_root(&self) -> Option<B256> {
3328 self.backend.get_db().read().await.maybe_state_root()
3329 }
3330
3331 fn ensure_typed_transaction_supported(&self, tx: &TypedTransaction) -> Result<()> {
3333 match &tx {
3334 TypedTransaction::EIP2930(_) => self.backend.ensure_eip2930_active(),
3335 TypedTransaction::EIP1559(_) => self.backend.ensure_eip1559_active(),
3336 TypedTransaction::EIP4844(_) => self.backend.ensure_eip4844_active(),
3337 TypedTransaction::EIP7702(_) => self.backend.ensure_eip7702_active(),
3338 TypedTransaction::Deposit(_) => self.backend.ensure_op_deposits_active(),
3339 TypedTransaction::Legacy(_) => Ok(()),
3340 }
3341 }
3342}
3343
3344fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3345 if provided_nonce == on_chain_nonce {
3346 return Vec::new();
3347 }
3348 let prev_nonce = provided_nonce.saturating_sub(1);
3349 if on_chain_nonce <= prev_nonce {
3350 vec![to_marker(prev_nonce, from)]
3351 } else {
3352 Vec::new()
3353 }
3354}
3355
3356fn convert_transact_out(out: &Option<Output>) -> Bytes {
3357 match out {
3358 None => Default::default(),
3359 Some(Output::Call(out)) => out.to_vec().into(),
3360 Some(Output::Create(out, _)) => out.to_vec().into(),
3361 }
3362}
3363
3364fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3366 let out = convert_transact_out(out);
3367 match exit {
3368 return_ok!() => Ok(out),
3369 return_revert!() => Err(InvalidTransactionError::Revert(Some(out.0.into())).into()),
3370 reason => Err(BlockchainError::EvmError(reason)),
3371 }
3372}
3373
3374fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3376 match transaction_request_to_typed(request.clone()) {
3377 Some(request) => match request {
3378 TypedTransactionRequest::Legacy(req) => match req.to {
3379 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3380 TxKind::Create => MIN_CREATE_GAS,
3381 },
3382 TypedTransactionRequest::EIP1559(req) => match req.to {
3383 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3384 TxKind::Create => MIN_CREATE_GAS,
3385 },
3386 TypedTransactionRequest::EIP7702(req) => {
3387 MIN_TRANSACTION_GAS +
3388 req.authorization_list.len() as u128 * PER_EMPTY_ACCOUNT_COST as u128
3389 }
3390 TypedTransactionRequest::EIP2930(req) => match req.to {
3391 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3392 TxKind::Create => MIN_CREATE_GAS,
3393 },
3394 TypedTransactionRequest::EIP4844(_) => MIN_TRANSACTION_GAS,
3395 TypedTransactionRequest::Deposit(req) => match req.to {
3396 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3397 TxKind::Create => MIN_CREATE_GAS,
3398 },
3399 },
3400 _ => MIN_CREATE_GAS,
3403 }
3404}
3405
3406enum GasEstimationCallResult {
3408 Success(u128),
3409 OutOfGas,
3410 Revert(Option<Bytes>),
3411 EvmError(InstructionResult),
3412}
3413
3414impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3416 type Error = BlockchainError;
3417
3418 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3419 match res {
3420 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3422 Ok(Self::OutOfGas)
3423 }
3424 Err(err) => Err(err),
3425 Ok((exit, output, gas, _)) => match exit {
3426 return_ok!() | InstructionResult::CallOrCreate => Ok(Self::Success(gas)),
3427
3428 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3429
3430 InstructionResult::OutOfGas |
3431 InstructionResult::MemoryOOG |
3432 InstructionResult::MemoryLimitOOG |
3433 InstructionResult::PrecompileOOG |
3434 InstructionResult::InvalidOperandOOG |
3435 InstructionResult::ReentrancySentryOOG => Ok(Self::OutOfGas),
3436
3437 InstructionResult::OpcodeNotFound |
3438 InstructionResult::CallNotAllowedInsideStatic |
3439 InstructionResult::StateChangeDuringStaticCall |
3440 InstructionResult::InvalidExtDelegateCallTarget |
3441 InstructionResult::InvalidEXTCALLTarget |
3442 InstructionResult::InvalidFEOpcode |
3443 InstructionResult::InvalidJump |
3444 InstructionResult::NotActivated |
3445 InstructionResult::StackUnderflow |
3446 InstructionResult::StackOverflow |
3447 InstructionResult::OutOfOffset |
3448 InstructionResult::CreateCollision |
3449 InstructionResult::OverflowPayment |
3450 InstructionResult::PrecompileError |
3451 InstructionResult::NonceOverflow |
3452 InstructionResult::CreateContractSizeLimit |
3453 InstructionResult::CreateContractStartingWithEF |
3454 InstructionResult::CreateInitCodeSizeLimit |
3455 InstructionResult::FatalExternalError |
3456 InstructionResult::OutOfFunds |
3457 InstructionResult::CallTooDeep => Ok(Self::EvmError(exit)),
3458
3459 InstructionResult::ReturnContractInNotInitEOF |
3461 InstructionResult::EOFOpcodeDisabledInLegacy |
3462 InstructionResult::SubRoutineStackOverflow |
3463 InstructionResult::CreateInitCodeStartingEF00 |
3464 InstructionResult::InvalidEOFInitCode |
3465 InstructionResult::EofAuxDataOverflow |
3466 InstructionResult::EofAuxDataTooSmall => Ok(Self::EvmError(exit)),
3467 },
3468 }
3469 }
3470}