1use super::{
2 backend::mem::{state, BlockRequest, State},
3 sign::build_typed_transaction,
4};
5use crate::{
6 eth::{
7 backend::{
8 self,
9 db::SerializableState,
10 mem::{MIN_CREATE_GAS, MIN_TRANSACTION_GAS},
11 notifications::NewBlockNotifications,
12 validate::TransactionValidator,
13 },
14 error::{
15 BlockchainError, FeeHistoryError, InvalidTransactionError, Result, ToRpcResponseResult,
16 },
17 fees::{FeeDetails, FeeHistoryCache, MIN_SUGGESTED_PRIORITY_FEE},
18 macros::node_info,
19 miner::FixedBlockTimeMiner,
20 pool::{
21 transactions::{
22 to_marker, PoolTransaction, TransactionOrder, TransactionPriority, TxMarker,
23 },
24 Pool,
25 },
26 sign::{self, Signer},
27 },
28 filter::{EthFilter, Filters, LogsFilter},
29 mem::transaction_build,
30 revm::primitives::{BlobExcessGasAndPrice, Output},
31 ClientFork, LoggingManager, Miner, MiningMode, StorageInfo,
32};
33use alloy_consensus::{
34 transaction::{eip4844::TxEip4844Variant, Recovered},
35 Account,
36};
37use alloy_dyn_abi::TypedData;
38use alloy_eips::eip2718::Encodable2718;
39use alloy_network::{
40 eip2718::Decodable2718, AnyRpcBlock, AnyRpcTransaction, BlockResponse, Ethereum, NetworkWallet,
41 TransactionBuilder, TransactionResponse,
42};
43use alloy_primitives::{
44 map::{HashMap, HashSet},
45 Address, Bytes, PrimitiveSignature as Signature, TxHash, TxKind, B256, B64, U256, U64,
46};
47use alloy_provider::utils::{
48 eip1559_default_estimator, EIP1559_FEE_ESTIMATION_PAST_BLOCKS,
49 EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE,
50};
51use alloy_rpc_types::{
52 anvil::{
53 ForkedNetwork, Forking, Metadata, MineOptions, NodeEnvironment, NodeForkConfig, NodeInfo,
54 },
55 request::TransactionRequest,
56 simulate::{SimulatePayload, SimulatedBlock},
57 state::StateOverride,
58 trace::{
59 filter::TraceFilter,
60 geth::{GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace},
61 parity::LocalizedTransactionTrace,
62 },
63 txpool::{TxpoolContent, TxpoolInspect, TxpoolInspectSummary, TxpoolStatus},
64 AccessList, AccessListResult, BlockId, BlockNumberOrTag as BlockNumber, BlockTransactions,
65 EIP1186AccountProofResponse, FeeHistory, Filter, FilteredParams, Index, Log,
66};
67use alloy_serde::WithOtherFields;
68use alloy_transport::TransportErrorKind;
69use anvil_core::{
70 eth::{
71 block::BlockInfo,
72 transaction::{
73 transaction_request_to_typed, PendingTransaction, ReceiptResponse, TypedTransaction,
74 TypedTransactionRequest,
75 },
76 wallet::{WalletCapabilities, WalletError},
77 EthRequest,
78 },
79 types::{ReorgOptions, TransactionData, Work},
80};
81use anvil_rpc::{error::RpcError, response::ResponseResult};
82use foundry_common::provider::ProviderBuilder;
83use foundry_evm::{
84 backend::DatabaseError,
85 decode::RevertDecoder,
86 revm::{
87 db::DatabaseRef,
88 interpreter::{return_ok, return_revert, InstructionResult},
89 primitives::BlockEnv,
90 },
91};
92use futures::channel::{mpsc::Receiver, oneshot};
93use parking_lot::RwLock;
94use revm::primitives::Bytecode;
95use std::{future::Future, sync::Arc, time::Duration};
96
97pub const CLIENT_VERSION: &str = concat!("anvil/v", env!("CARGO_PKG_VERSION"));
99
100#[derive(Clone)]
104pub struct EthApi {
105 pool: Arc<Pool>,
107 pub backend: Arc<backend::mem::Backend>,
110 is_mining: bool,
112 signers: Arc<Vec<Box<dyn Signer>>>,
114 fee_history_cache: FeeHistoryCache,
116 fee_history_limit: u64,
118 miner: Miner,
123 logger: LoggingManager,
125 filters: Filters,
127 transaction_order: Arc<RwLock<TransactionOrder>>,
129 net_listening: bool,
131 instance_id: Arc<RwLock<B256>>,
133}
134
135impl EthApi {
136 #[expect(clippy::too_many_arguments)]
138 pub fn new(
139 pool: Arc<Pool>,
140 backend: Arc<backend::mem::Backend>,
141 signers: Arc<Vec<Box<dyn Signer>>>,
142 fee_history_cache: FeeHistoryCache,
143 fee_history_limit: u64,
144 miner: Miner,
145 logger: LoggingManager,
146 filters: Filters,
147 transactions_order: TransactionOrder,
148 ) -> Self {
149 Self {
150 pool,
151 backend,
152 is_mining: true,
153 signers,
154 fee_history_cache,
155 fee_history_limit,
156 miner,
157 logger,
158 filters,
159 net_listening: true,
160 transaction_order: Arc::new(RwLock::new(transactions_order)),
161 instance_id: Arc::new(RwLock::new(B256::random())),
162 }
163 }
164
165 pub async fn execute(&self, request: EthRequest) -> ResponseResult {
167 trace!(target: "rpc::api", "executing eth request");
168 let response = match request.clone() {
169 EthRequest::Web3ClientVersion(()) => self.client_version().to_rpc_result(),
170 EthRequest::Web3Sha3(content) => self.sha3(content).to_rpc_result(),
171 EthRequest::EthGetAccount(addr, block) => {
172 self.get_account(addr, block).await.to_rpc_result()
173 }
174 EthRequest::EthGetBalance(addr, block) => {
175 self.balance(addr, block).await.to_rpc_result()
176 }
177 EthRequest::EthGetTransactionByHash(hash) => {
178 self.transaction_by_hash(hash).await.to_rpc_result()
179 }
180 EthRequest::EthSendTransaction(request) => {
181 self.send_transaction(*request).await.to_rpc_result()
182 }
183 EthRequest::EthChainId(_) => self.eth_chain_id().to_rpc_result(),
184 EthRequest::EthNetworkId(_) => self.network_id().to_rpc_result(),
185 EthRequest::NetListening(_) => self.net_listening().to_rpc_result(),
186 EthRequest::EthGasPrice(_) => self.eth_gas_price().to_rpc_result(),
187 EthRequest::EthMaxPriorityFeePerGas(_) => {
188 self.gas_max_priority_fee_per_gas().to_rpc_result()
189 }
190 EthRequest::EthBlobBaseFee(_) => self.blob_base_fee().to_rpc_result(),
191 EthRequest::EthAccounts(_) => self.accounts().to_rpc_result(),
192 EthRequest::EthBlockNumber(_) => self.block_number().to_rpc_result(),
193 EthRequest::EthGetStorageAt(addr, slot, block) => {
194 self.storage_at(addr, slot, block).await.to_rpc_result()
195 }
196 EthRequest::EthGetBlockByHash(hash, full) => {
197 if full {
198 self.block_by_hash_full(hash).await.to_rpc_result()
199 } else {
200 self.block_by_hash(hash).await.to_rpc_result()
201 }
202 }
203 EthRequest::EthGetBlockByNumber(num, full) => {
204 if full {
205 self.block_by_number_full(num).await.to_rpc_result()
206 } else {
207 self.block_by_number(num).await.to_rpc_result()
208 }
209 }
210 EthRequest::EthGetTransactionCount(addr, block) => {
211 self.transaction_count(addr, block).await.to_rpc_result()
212 }
213 EthRequest::EthGetTransactionCountByHash(hash) => {
214 self.block_transaction_count_by_hash(hash).await.to_rpc_result()
215 }
216 EthRequest::EthGetTransactionCountByNumber(num) => {
217 self.block_transaction_count_by_number(num).await.to_rpc_result()
218 }
219 EthRequest::EthGetUnclesCountByHash(hash) => {
220 self.block_uncles_count_by_hash(hash).await.to_rpc_result()
221 }
222 EthRequest::EthGetUnclesCountByNumber(num) => {
223 self.block_uncles_count_by_number(num).await.to_rpc_result()
224 }
225 EthRequest::EthGetCodeAt(addr, block) => {
226 self.get_code(addr, block).await.to_rpc_result()
227 }
228 EthRequest::EthGetProof(addr, keys, block) => {
229 self.get_proof(addr, keys, block).await.to_rpc_result()
230 }
231 EthRequest::EthSign(addr, content) => self.sign(addr, content).await.to_rpc_result(),
232 EthRequest::PersonalSign(content, addr) => {
233 self.sign(addr, content).await.to_rpc_result()
234 }
235 EthRequest::EthSignTransaction(request) => {
236 self.sign_transaction(*request).await.to_rpc_result()
237 }
238 EthRequest::EthSignTypedData(addr, data) => {
239 self.sign_typed_data(addr, data).await.to_rpc_result()
240 }
241 EthRequest::EthSignTypedDataV3(addr, data) => {
242 self.sign_typed_data_v3(addr, data).await.to_rpc_result()
243 }
244 EthRequest::EthSignTypedDataV4(addr, data) => {
245 self.sign_typed_data_v4(addr, &data).await.to_rpc_result()
246 }
247 EthRequest::EthSendRawTransaction(tx) => {
248 self.send_raw_transaction(tx).await.to_rpc_result()
249 }
250 EthRequest::EthCall(call, block, overrides) => {
251 self.call(call, block, overrides).await.to_rpc_result()
252 }
253 EthRequest::EthSimulateV1(simulation, block) => {
254 self.simulate_v1(simulation, block).await.to_rpc_result()
255 }
256 EthRequest::EthCreateAccessList(call, block) => {
257 self.create_access_list(call, block).await.to_rpc_result()
258 }
259 EthRequest::EthEstimateGas(call, block, overrides) => {
260 self.estimate_gas(call, block, overrides).await.to_rpc_result()
261 }
262 EthRequest::EthGetRawTransactionByHash(hash) => {
263 self.raw_transaction(hash).await.to_rpc_result()
264 }
265 EthRequest::EthGetRawTransactionByBlockHashAndIndex(hash, index) => {
266 self.raw_transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
267 }
268 EthRequest::EthGetRawTransactionByBlockNumberAndIndex(num, index) => {
269 self.raw_transaction_by_block_number_and_index(num, index).await.to_rpc_result()
270 }
271 EthRequest::EthGetTransactionByBlockHashAndIndex(hash, index) => {
272 self.transaction_by_block_hash_and_index(hash, index).await.to_rpc_result()
273 }
274 EthRequest::EthGetTransactionByBlockNumberAndIndex(num, index) => {
275 self.transaction_by_block_number_and_index(num, index).await.to_rpc_result()
276 }
277 EthRequest::EthGetTransactionReceipt(tx) => {
278 self.transaction_receipt(tx).await.to_rpc_result()
279 }
280 EthRequest::EthGetBlockReceipts(number) => {
281 self.block_receipts(number).await.to_rpc_result()
282 }
283 EthRequest::EthGetUncleByBlockHashAndIndex(hash, index) => {
284 self.uncle_by_block_hash_and_index(hash, index).await.to_rpc_result()
285 }
286 EthRequest::EthGetUncleByBlockNumberAndIndex(num, index) => {
287 self.uncle_by_block_number_and_index(num, index).await.to_rpc_result()
288 }
289 EthRequest::EthGetLogs(filter) => self.logs(filter).await.to_rpc_result(),
290 EthRequest::EthGetWork(_) => self.work().to_rpc_result(),
291 EthRequest::EthSyncing(_) => self.syncing().to_rpc_result(),
292 EthRequest::EthSubmitWork(nonce, pow, digest) => {
293 self.submit_work(nonce, pow, digest).to_rpc_result()
294 }
295 EthRequest::EthSubmitHashRate(rate, id) => {
296 self.submit_hashrate(rate, id).to_rpc_result()
297 }
298 EthRequest::EthFeeHistory(count, newest, reward_percentiles) => {
299 self.fee_history(count, newest, reward_percentiles).await.to_rpc_result()
300 }
301 EthRequest::DebugGetRawTransaction(hash) => {
303 self.raw_transaction(hash).await.to_rpc_result()
304 }
305 EthRequest::DebugTraceTransaction(tx, opts) => {
307 self.debug_trace_transaction(tx, opts).await.to_rpc_result()
308 }
309 EthRequest::DebugTraceCall(tx, block, opts) => {
311 self.debug_trace_call(tx, block, opts).await.to_rpc_result()
312 }
313 EthRequest::TraceTransaction(tx) => self.trace_transaction(tx).await.to_rpc_result(),
314 EthRequest::TraceBlock(block) => self.trace_block(block).await.to_rpc_result(),
315 EthRequest::TraceFilter(filter) => self.trace_filter(filter).await.to_rpc_result(),
316 EthRequest::ImpersonateAccount(addr) => {
317 self.anvil_impersonate_account(addr).await.to_rpc_result()
318 }
319 EthRequest::StopImpersonatingAccount(addr) => {
320 self.anvil_stop_impersonating_account(addr).await.to_rpc_result()
321 }
322 EthRequest::AutoImpersonateAccount(enable) => {
323 self.anvil_auto_impersonate_account(enable).await.to_rpc_result()
324 }
325 EthRequest::GetAutoMine(()) => self.anvil_get_auto_mine().to_rpc_result(),
326 EthRequest::Mine(blocks, interval) => {
327 self.anvil_mine(blocks, interval).await.to_rpc_result()
328 }
329 EthRequest::SetAutomine(enabled) => {
330 self.anvil_set_auto_mine(enabled).await.to_rpc_result()
331 }
332 EthRequest::SetIntervalMining(interval) => {
333 self.anvil_set_interval_mining(interval).to_rpc_result()
334 }
335 EthRequest::GetIntervalMining(()) => self.anvil_get_interval_mining().to_rpc_result(),
336 EthRequest::DropTransaction(tx) => {
337 self.anvil_drop_transaction(tx).await.to_rpc_result()
338 }
339 EthRequest::DropAllTransactions() => {
340 self.anvil_drop_all_transactions().await.to_rpc_result()
341 }
342 EthRequest::Reset(fork) => {
343 self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result()
344 }
345 EthRequest::SetBalance(addr, val) => {
346 self.anvil_set_balance(addr, val).await.to_rpc_result()
347 }
348 EthRequest::SetCode(addr, code) => {
349 self.anvil_set_code(addr, code).await.to_rpc_result()
350 }
351 EthRequest::SetNonce(addr, nonce) => {
352 self.anvil_set_nonce(addr, nonce).await.to_rpc_result()
353 }
354 EthRequest::SetStorageAt(addr, slot, val) => {
355 self.anvil_set_storage_at(addr, slot, val).await.to_rpc_result()
356 }
357 EthRequest::SetCoinbase(addr) => self.anvil_set_coinbase(addr).await.to_rpc_result(),
358 EthRequest::SetChainId(id) => self.anvil_set_chain_id(id).await.to_rpc_result(),
359 EthRequest::SetLogging(log) => self.anvil_set_logging(log).await.to_rpc_result(),
360 EthRequest::SetMinGasPrice(gas) => {
361 self.anvil_set_min_gas_price(gas).await.to_rpc_result()
362 }
363 EthRequest::SetNextBlockBaseFeePerGas(gas) => {
364 self.anvil_set_next_block_base_fee_per_gas(gas).await.to_rpc_result()
365 }
366 EthRequest::DumpState(preserve_historical_states) => self
367 .anvil_dump_state(preserve_historical_states.and_then(|s| s.params))
368 .await
369 .to_rpc_result(),
370 EthRequest::LoadState(buf) => self.anvil_load_state(buf).await.to_rpc_result(),
371 EthRequest::NodeInfo(_) => self.anvil_node_info().await.to_rpc_result(),
372 EthRequest::AnvilMetadata(_) => self.anvil_metadata().await.to_rpc_result(),
373 EthRequest::EvmSnapshot(_) => self.evm_snapshot().await.to_rpc_result(),
374 EthRequest::EvmRevert(id) => self.evm_revert(id).await.to_rpc_result(),
375 EthRequest::EvmIncreaseTime(time) => self.evm_increase_time(time).await.to_rpc_result(),
376 EthRequest::EvmSetNextBlockTimeStamp(time) => {
377 if time >= U256::from(u64::MAX) {
378 return ResponseResult::Error(RpcError::invalid_params(
379 "The timestamp is too big",
380 ))
381 }
382 let time = time.to::<u64>();
383 self.evm_set_next_block_timestamp(time).to_rpc_result()
384 }
385 EthRequest::EvmSetTime(timestamp) => {
386 if timestamp >= U256::from(u64::MAX) {
387 return ResponseResult::Error(RpcError::invalid_params(
388 "The timestamp is too big",
389 ))
390 }
391 let time = timestamp.to::<u64>();
392 self.evm_set_time(time).to_rpc_result()
393 }
394 EthRequest::EvmSetBlockGasLimit(gas_limit) => {
395 self.evm_set_block_gas_limit(gas_limit).to_rpc_result()
396 }
397 EthRequest::EvmSetBlockTimeStampInterval(time) => {
398 self.evm_set_block_timestamp_interval(time).to_rpc_result()
399 }
400 EthRequest::EvmRemoveBlockTimeStampInterval(()) => {
401 self.evm_remove_block_timestamp_interval().to_rpc_result()
402 }
403 EthRequest::EvmMine(mine) => {
404 self.evm_mine(mine.and_then(|p| p.params)).await.to_rpc_result()
405 }
406 EthRequest::EvmMineDetailed(mine) => {
407 self.evm_mine_detailed(mine.and_then(|p| p.params)).await.to_rpc_result()
408 }
409 EthRequest::SetRpcUrl(url) => self.anvil_set_rpc_url(url).to_rpc_result(),
410 EthRequest::EthSendUnsignedTransaction(tx) => {
411 self.eth_send_unsigned_transaction(*tx).await.to_rpc_result()
412 }
413 EthRequest::EnableTraces(_) => self.anvil_enable_traces().await.to_rpc_result(),
414 EthRequest::EthNewFilter(filter) => self.new_filter(filter).await.to_rpc_result(),
415 EthRequest::EthGetFilterChanges(id) => self.get_filter_changes(&id).await,
416 EthRequest::EthNewBlockFilter(_) => self.new_block_filter().await.to_rpc_result(),
417 EthRequest::EthNewPendingTransactionFilter(_) => {
418 self.new_pending_transaction_filter().await.to_rpc_result()
419 }
420 EthRequest::EthGetFilterLogs(id) => self.get_filter_logs(&id).await.to_rpc_result(),
421 EthRequest::EthUninstallFilter(id) => self.uninstall_filter(&id).await.to_rpc_result(),
422 EthRequest::TxPoolStatus(_) => self.txpool_status().await.to_rpc_result(),
423 EthRequest::TxPoolInspect(_) => self.txpool_inspect().await.to_rpc_result(),
424 EthRequest::TxPoolContent(_) => self.txpool_content().await.to_rpc_result(),
425 EthRequest::ErigonGetHeaderByNumber(num) => {
426 self.erigon_get_header_by_number(num).await.to_rpc_result()
427 }
428 EthRequest::OtsGetApiLevel(_) => self.ots_get_api_level().await.to_rpc_result(),
429 EthRequest::OtsGetInternalOperations(hash) => {
430 self.ots_get_internal_operations(hash).await.to_rpc_result()
431 }
432 EthRequest::OtsHasCode(addr, num) => self.ots_has_code(addr, num).await.to_rpc_result(),
433 EthRequest::OtsTraceTransaction(hash) => {
434 self.ots_trace_transaction(hash).await.to_rpc_result()
435 }
436 EthRequest::OtsGetTransactionError(hash) => {
437 self.ots_get_transaction_error(hash).await.to_rpc_result()
438 }
439 EthRequest::OtsGetBlockDetails(num) => {
440 self.ots_get_block_details(num).await.to_rpc_result()
441 }
442 EthRequest::OtsGetBlockDetailsByHash(hash) => {
443 self.ots_get_block_details_by_hash(hash).await.to_rpc_result()
444 }
445 EthRequest::OtsGetBlockTransactions(num, page, page_size) => {
446 self.ots_get_block_transactions(num, page, page_size).await.to_rpc_result()
447 }
448 EthRequest::OtsSearchTransactionsBefore(address, num, page_size) => {
449 self.ots_search_transactions_before(address, num, page_size).await.to_rpc_result()
450 }
451 EthRequest::OtsSearchTransactionsAfter(address, num, page_size) => {
452 self.ots_search_transactions_after(address, num, page_size).await.to_rpc_result()
453 }
454 EthRequest::OtsGetTransactionBySenderAndNonce(address, nonce) => {
455 self.ots_get_transaction_by_sender_and_nonce(address, nonce).await.to_rpc_result()
456 }
457 EthRequest::OtsGetContractCreator(address) => {
458 self.ots_get_contract_creator(address).await.to_rpc_result()
459 }
460 EthRequest::RemovePoolTransactions(address) => {
461 self.anvil_remove_pool_transactions(address).await.to_rpc_result()
462 }
463 EthRequest::Reorg(reorg_options) => {
464 self.anvil_reorg(reorg_options).await.to_rpc_result()
465 }
466 EthRequest::Rollback(depth) => self.anvil_rollback(depth).await.to_rpc_result(),
467 EthRequest::WalletGetCapabilities(()) => self.get_capabilities().to_rpc_result(),
468 EthRequest::WalletSendTransaction(tx) => {
469 self.wallet_send_transaction(*tx).await.to_rpc_result()
470 }
471 EthRequest::AnvilAddCapability(addr) => self.anvil_add_capability(addr).to_rpc_result(),
472 EthRequest::AnvilSetExecutor(executor_pk) => {
473 self.anvil_set_executor(executor_pk).to_rpc_result()
474 }
475 };
476
477 if let ResponseResult::Error(err) = &response {
478 node_info!("\nRPC request failed:");
479 node_info!(" Request: {:?}", request);
480 node_info!(" Error: {}\n", err);
481 }
482
483 response
484 }
485
486 fn sign_request(
487 &self,
488 from: &Address,
489 request: TypedTransactionRequest,
490 ) -> Result<TypedTransaction> {
491 match request {
492 TypedTransactionRequest::Deposit(_) => {
493 let nil_signature = Signature::from_scalars_and_parity(
494 B256::with_last_byte(1),
495 B256::with_last_byte(1),
496 false,
497 );
498 return build_typed_transaction(request, nil_signature)
499 }
500 _ => {
501 for signer in self.signers.iter() {
502 if signer.accounts().contains(from) {
503 let signature = signer.sign_transaction(request.clone(), from)?;
504 return build_typed_transaction(request, signature)
505 }
506 }
507 }
508 }
509 Err(BlockchainError::NoSignerAvailable)
510 }
511
512 async fn block_request(&self, block_number: Option<BlockId>) -> Result<BlockRequest> {
513 let block_request = match block_number {
514 Some(BlockId::Number(BlockNumber::Pending)) => {
515 let pending_txs = self.pool.ready_transactions().collect();
516 BlockRequest::Pending(pending_txs)
517 }
518 _ => {
519 let number = self.backend.ensure_block_number(block_number).await?;
520 BlockRequest::Number(number)
521 }
522 };
523 Ok(block_request)
524 }
525
526 async fn inner_raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
527 match self.pool.get_transaction(hash) {
528 Some(tx) => Ok(Some(tx.transaction.encoded_2718().into())),
529 None => match self.backend.transaction_by_hash(hash).await? {
530 Some(tx) => Ok(Some(tx.inner.inner.encoded_2718().into())),
531 None => Ok(None),
532 },
533 }
534 }
535
536 pub fn client_version(&self) -> Result<String> {
540 node_info!("web3_clientVersion");
541 Ok(CLIENT_VERSION.to_string())
542 }
543
544 pub fn sha3(&self, bytes: Bytes) -> Result<String> {
548 node_info!("web3_sha3");
549 let hash = alloy_primitives::keccak256(bytes.as_ref());
550 Ok(alloy_primitives::hex::encode_prefixed(&hash[..]))
551 }
552
553 pub fn protocol_version(&self) -> Result<u64> {
557 node_info!("eth_protocolVersion");
558 Ok(1)
559 }
560
561 pub fn hashrate(&self) -> Result<U256> {
565 node_info!("eth_hashrate");
566 Ok(U256::ZERO)
567 }
568
569 pub fn author(&self) -> Result<Address> {
573 node_info!("eth_coinbase");
574 Ok(self.backend.coinbase())
575 }
576
577 pub fn is_mining(&self) -> Result<bool> {
581 node_info!("eth_mining");
582 Ok(self.is_mining)
583 }
584
585 pub fn eth_chain_id(&self) -> Result<Option<U64>> {
591 node_info!("eth_chainId");
592 Ok(Some(self.backend.chain_id().to::<U64>()))
593 }
594
595 pub fn network_id(&self) -> Result<Option<String>> {
599 node_info!("eth_networkId");
600 let chain_id = self.backend.chain_id().to::<u64>();
601 Ok(Some(format!("{chain_id}")))
602 }
603
604 pub fn net_listening(&self) -> Result<bool> {
608 node_info!("net_listening");
609 Ok(self.net_listening)
610 }
611
612 fn eth_gas_price(&self) -> Result<U256> {
614 node_info!("eth_gasPrice");
615 Ok(U256::from(self.gas_price()))
616 }
617
618 pub fn gas_price(&self) -> u128 {
620 if self.backend.is_eip1559() {
621 if self.backend.is_min_priority_fee_enforced() {
622 (self.backend.base_fee() as u128).saturating_add(self.lowest_suggestion_tip())
623 } else {
624 self.backend.base_fee() as u128
625 }
626 } else {
627 self.backend.fees().raw_gas_price()
628 }
629 }
630
631 pub fn excess_blob_gas_and_price(&self) -> Result<Option<BlobExcessGasAndPrice>> {
633 Ok(self.backend.excess_blob_gas_and_price())
634 }
635
636 pub fn gas_max_priority_fee_per_gas(&self) -> Result<U256> {
641 self.max_priority_fee_per_gas()
642 }
643
644 pub fn blob_base_fee(&self) -> Result<U256> {
648 Ok(U256::from(self.backend.fees().base_fee_per_blob_gas()))
649 }
650
651 pub fn gas_limit(&self) -> U256 {
653 U256::from(self.backend.gas_limit())
654 }
655
656 pub fn accounts(&self) -> Result<Vec<Address>> {
660 node_info!("eth_accounts");
661 let mut unique = HashSet::new();
662 let mut accounts: Vec<Address> = Vec::new();
663 for signer in self.signers.iter() {
664 accounts.extend(signer.accounts().into_iter().filter(|acc| unique.insert(*acc)));
665 }
666 accounts.extend(
667 self.backend
668 .cheats()
669 .impersonated_accounts()
670 .into_iter()
671 .filter(|acc| unique.insert(*acc)),
672 );
673 Ok(accounts.into_iter().collect())
674 }
675
676 pub fn block_number(&self) -> Result<U256> {
680 node_info!("eth_blockNumber");
681 Ok(U256::from(self.backend.best_number()))
682 }
683
684 pub async fn balance(&self, address: Address, block_number: Option<BlockId>) -> Result<U256> {
688 node_info!("eth_getBalance");
689 let block_request = self.block_request(block_number).await?;
690
691 if let BlockRequest::Number(number) = block_request {
693 if let Some(fork) = self.get_fork() {
694 if fork.predates_fork(number) {
695 return Ok(fork.get_balance(address, number).await?)
696 }
697 }
698 }
699
700 self.backend.get_balance(address, Some(block_request)).await
701 }
702
703 pub async fn get_account(
707 &self,
708 address: Address,
709 block_number: Option<BlockId>,
710 ) -> Result<Account> {
711 node_info!("eth_getAccount");
712 let block_request = self.block_request(block_number).await?;
713
714 if let BlockRequest::Number(number) = block_request {
716 if let Some(fork) = self.get_fork() {
717 if fork.predates_fork(number) {
718 return Ok(fork.get_account(address, number).await?)
719 }
720 }
721 }
722
723 self.backend.get_account_at_block(address, Some(block_request)).await
724 }
725
726 pub async fn storage_at(
730 &self,
731 address: Address,
732 index: U256,
733 block_number: Option<BlockId>,
734 ) -> Result<B256> {
735 node_info!("eth_getStorageAt");
736 let block_request = self.block_request(block_number).await?;
737
738 if let BlockRequest::Number(number) = block_request {
740 if let Some(fork) = self.get_fork() {
741 if fork.predates_fork(number) {
742 return Ok(B256::from(
743 fork.storage_at(address, index, Some(BlockNumber::Number(number))).await?,
744 ));
745 }
746 }
747 }
748
749 self.backend.storage_at(address, index, Some(block_request)).await
750 }
751
752 pub async fn block_by_hash(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
756 node_info!("eth_getBlockByHash");
757 self.backend.block_by_hash(hash).await
758 }
759
760 pub async fn block_by_hash_full(&self, hash: B256) -> Result<Option<AnyRpcBlock>> {
764 node_info!("eth_getBlockByHash");
765 self.backend.block_by_hash_full(hash).await
766 }
767
768 pub async fn block_by_number(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
772 node_info!("eth_getBlockByNumber");
773 if number == BlockNumber::Pending {
774 return Ok(Some(self.pending_block().await));
775 }
776
777 self.backend.block_by_number(number).await
778 }
779
780 pub async fn block_by_number_full(&self, number: BlockNumber) -> Result<Option<AnyRpcBlock>> {
784 node_info!("eth_getBlockByNumber");
785 if number == BlockNumber::Pending {
786 return Ok(self.pending_block_full().await);
787 }
788 self.backend.block_by_number_full(number).await
789 }
790
791 pub async fn transaction_count(
798 &self,
799 address: Address,
800 block_number: Option<BlockId>,
801 ) -> Result<U256> {
802 node_info!("eth_getTransactionCount");
803 self.get_transaction_count(address, block_number).await.map(U256::from)
804 }
805
806 pub async fn block_transaction_count_by_hash(&self, hash: B256) -> Result<Option<U256>> {
810 node_info!("eth_getBlockTransactionCountByHash");
811 let block = self.backend.block_by_hash(hash).await?;
812 let txs = block.map(|b| match b.transactions() {
813 BlockTransactions::Full(txs) => U256::from(txs.len()),
814 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
815 BlockTransactions::Uncle => U256::from(0),
816 });
817 Ok(txs)
818 }
819
820 pub async fn block_transaction_count_by_number(
824 &self,
825 block_number: BlockNumber,
826 ) -> Result<Option<U256>> {
827 node_info!("eth_getBlockTransactionCountByNumber");
828 let block_request = self.block_request(Some(block_number.into())).await?;
829 if let BlockRequest::Pending(txs) = block_request {
830 let block = self.backend.pending_block(txs).await;
831 return Ok(Some(U256::from(block.transactions.len())));
832 }
833 let block = self.backend.block_by_number(block_number).await?;
834 let txs = block.map(|b| match b.transactions() {
835 BlockTransactions::Full(txs) => U256::from(txs.len()),
836 BlockTransactions::Hashes(txs) => U256::from(txs.len()),
837 BlockTransactions::Uncle => U256::from(0),
838 });
839 Ok(txs)
840 }
841
842 pub async fn block_uncles_count_by_hash(&self, hash: B256) -> Result<U256> {
846 node_info!("eth_getUncleCountByBlockHash");
847 let block =
848 self.backend.block_by_hash(hash).await?.ok_or(BlockchainError::BlockNotFound)?;
849 Ok(U256::from(block.uncles.len()))
850 }
851
852 pub async fn block_uncles_count_by_number(&self, block_number: BlockNumber) -> Result<U256> {
856 node_info!("eth_getUncleCountByBlockNumber");
857 let block = self
858 .backend
859 .block_by_number(block_number)
860 .await?
861 .ok_or(BlockchainError::BlockNotFound)?;
862 Ok(U256::from(block.uncles.len()))
863 }
864
865 pub async fn get_code(&self, address: Address, block_number: Option<BlockId>) -> Result<Bytes> {
869 node_info!("eth_getCode");
870 let block_request = self.block_request(block_number).await?;
871 if let BlockRequest::Number(number) = block_request {
873 if let Some(fork) = self.get_fork() {
874 if fork.predates_fork(number) {
875 return Ok(fork.get_code(address, number).await?)
876 }
877 }
878 }
879 self.backend.get_code(address, Some(block_request)).await
880 }
881
882 pub async fn get_proof(
887 &self,
888 address: Address,
889 keys: Vec<B256>,
890 block_number: Option<BlockId>,
891 ) -> Result<EIP1186AccountProofResponse> {
892 node_info!("eth_getProof");
893 let block_request = self.block_request(block_number).await?;
894
895 if let BlockRequest::Number(number) = block_request {
898 if let Some(fork) = self.get_fork() {
899 if fork.predates_fork_inclusive(number) {
900 return Ok(fork.get_proof(address, keys, Some(number.into())).await?)
901 }
902 }
903 }
904
905 let proof = self.backend.prove_account_at(address, keys, Some(block_request)).await?;
906 Ok(proof)
907 }
908
909 pub async fn sign_typed_data(
913 &self,
914 _address: Address,
915 _data: serde_json::Value,
916 ) -> Result<String> {
917 node_info!("eth_signTypedData");
918 Err(BlockchainError::RpcUnimplemented)
919 }
920
921 pub async fn sign_typed_data_v3(
925 &self,
926 _address: Address,
927 _data: serde_json::Value,
928 ) -> Result<String> {
929 node_info!("eth_signTypedData_v3");
930 Err(BlockchainError::RpcUnimplemented)
931 }
932
933 pub async fn sign_typed_data_v4(&self, address: Address, data: &TypedData) -> Result<String> {
937 node_info!("eth_signTypedData_v4");
938 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
939 let signature = signer.sign_typed_data(address, data).await?;
940 let signature = alloy_primitives::hex::encode(signature.as_bytes());
941 Ok(format!("0x{signature}"))
942 }
943
944 pub async fn sign(&self, address: Address, content: impl AsRef<[u8]>) -> Result<String> {
948 node_info!("eth_sign");
949 let signer = self.get_signer(address).ok_or(BlockchainError::NoSignerAvailable)?;
950 let signature =
951 alloy_primitives::hex::encode(signer.sign(address, content.as_ref()).await?.as_bytes());
952 Ok(format!("0x{signature}"))
953 }
954
955 pub async fn sign_transaction(
959 &self,
960 mut request: WithOtherFields<TransactionRequest>,
961 ) -> Result<String> {
962 node_info!("eth_signTransaction");
963
964 let from = request.from.map(Ok).unwrap_or_else(|| {
965 self.accounts()?.first().cloned().ok_or(BlockchainError::NoSignerAvailable)
966 })?;
967
968 let (nonce, _) = self.request_nonce(&request, from).await?;
969
970 if request.gas.is_none() {
971 if let Ok(gas) = self.estimate_gas(request.clone(), None, None).await {
973 request.gas = Some(gas.to());
974 }
975 }
976
977 let request = self.build_typed_tx_request(request, nonce)?;
978
979 let signed_transaction = self.sign_request(&from, request)?.encoded_2718();
980 Ok(alloy_primitives::hex::encode_prefixed(signed_transaction))
981 }
982
983 pub async fn send_transaction(
987 &self,
988 mut request: WithOtherFields<TransactionRequest>,
989 ) -> Result<TxHash> {
990 node_info!("eth_sendTransaction");
991
992 let from = request.from.map(Ok).unwrap_or_else(|| {
993 self.accounts()?.first().cloned().ok_or(BlockchainError::NoSignerAvailable)
994 })?;
995 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
996
997 if request.gas.is_none() {
998 if let Ok(gas) = self.estimate_gas(request.clone(), None, None).await {
1000 request.gas = Some(gas.to());
1001 }
1002 }
1003
1004 let request = self.build_typed_tx_request(request, nonce)?;
1005
1006 let pending_transaction = if self.is_impersonated(from) {
1008 let bypass_signature = self.impersonated_signature(&request);
1009 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
1010 self.ensure_typed_transaction_supported(&transaction)?;
1011 trace!(target : "node", ?from, "eth_sendTransaction: impersonating");
1012 PendingTransaction::with_impersonated(transaction, from)
1013 } else {
1014 let transaction = self.sign_request(&from, request)?;
1015 self.ensure_typed_transaction_supported(&transaction)?;
1016 PendingTransaction::new(transaction)?
1017 };
1018 self.backend.validate_pool_transaction(&pending_transaction).await?;
1020
1021 let requires = required_marker(nonce, on_chain_nonce, from);
1022 let provides = vec![to_marker(nonce, from)];
1023 debug_assert!(requires != provides);
1024
1025 self.add_pending_transaction(pending_transaction, requires, provides)
1026 }
1027
1028 pub async fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash> {
1032 node_info!("eth_sendRawTransaction");
1033 let mut data = tx.as_ref();
1034 if data.is_empty() {
1035 return Err(BlockchainError::EmptyRawTransactionData);
1036 }
1037
1038 let transaction = TypedTransaction::decode_2718(&mut data)
1039 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
1040
1041 self.ensure_typed_transaction_supported(&transaction)?;
1042
1043 let pending_transaction = PendingTransaction::new(transaction)?;
1044
1045 self.backend.validate_pool_transaction(&pending_transaction).await?;
1047
1048 let on_chain_nonce = self.backend.current_nonce(*pending_transaction.sender()).await?;
1049 let from = *pending_transaction.sender();
1050 let nonce = pending_transaction.transaction.nonce();
1051 let requires = required_marker(nonce, on_chain_nonce, from);
1052
1053 let priority = self.transaction_priority(&pending_transaction.transaction);
1054 let pool_transaction = PoolTransaction {
1055 requires,
1056 provides: vec![to_marker(nonce, *pending_transaction.sender())],
1057 pending_transaction,
1058 priority,
1059 };
1060
1061 let tx = self.pool.add_transaction(pool_transaction)?;
1062 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
1063 Ok(*tx.hash())
1064 }
1065
1066 pub async fn call(
1070 &self,
1071 request: WithOtherFields<TransactionRequest>,
1072 block_number: Option<BlockId>,
1073 overrides: Option<StateOverride>,
1074 ) -> Result<Bytes> {
1075 node_info!("eth_call");
1076 let block_request = self.block_request(block_number).await?;
1077 if let BlockRequest::Number(number) = block_request {
1079 if let Some(fork) = self.get_fork() {
1080 if fork.predates_fork(number) {
1081 if overrides.is_some() {
1082 return Err(BlockchainError::StateOverrideError(
1083 "not available on past forked blocks".to_string(),
1084 ));
1085 }
1086 return Ok(fork.call(&request, Some(number.into())).await?)
1087 }
1088 }
1089 }
1090
1091 let fees = FeeDetails::new(
1092 request.gas_price,
1093 request.max_fee_per_gas,
1094 request.max_priority_fee_per_gas,
1095 request.max_fee_per_blob_gas,
1096 )?
1097 .or_zero_fees();
1098 self.on_blocking_task(|this| async move {
1101 let (exit, out, gas, _) =
1102 this.backend.call(request, fees, Some(block_request), overrides).await?;
1103 trace!(target : "node", "Call status {:?}, gas {}", exit, gas);
1104
1105 ensure_return_ok(exit, &out)
1106 })
1107 .await
1108 }
1109
1110 pub async fn simulate_v1(
1111 &self,
1112 request: SimulatePayload,
1113 block_number: Option<BlockId>,
1114 ) -> Result<Vec<SimulatedBlock<AnyRpcBlock>>> {
1115 node_info!("eth_simulateV1");
1116 let block_request = self.block_request(block_number).await?;
1117 if let BlockRequest::Number(number) = block_request {
1119 if let Some(fork) = self.get_fork() {
1120 if fork.predates_fork(number) {
1121 return Ok(fork.simulate_v1(&request, Some(number.into())).await?)
1122 }
1123 }
1124 }
1125
1126 self.on_blocking_task(|this| async move {
1129 let simulated_blocks = this.backend.simulate(request, Some(block_request)).await?;
1130 trace!(target : "node", "Simulate status {:?}", simulated_blocks);
1131
1132 Ok(simulated_blocks)
1133 })
1134 .await
1135 }
1136
1137 pub async fn create_access_list(
1151 &self,
1152 mut request: WithOtherFields<TransactionRequest>,
1153 block_number: Option<BlockId>,
1154 ) -> Result<AccessListResult> {
1155 node_info!("eth_createAccessList");
1156 let block_request = self.block_request(block_number).await?;
1157 if let BlockRequest::Number(number) = block_request {
1159 if let Some(fork) = self.get_fork() {
1160 if fork.predates_fork(number) {
1161 return Ok(fork.create_access_list(&request, Some(number.into())).await?)
1162 }
1163 }
1164 }
1165
1166 self.backend
1167 .with_database_at(Some(block_request), |state, block_env| {
1168 let (exit, out, _, access_list) = self.backend.build_access_list_with_state(
1169 &state,
1170 request.clone(),
1171 FeeDetails::zero(),
1172 block_env.clone(),
1173 )?;
1174 ensure_return_ok(exit, &out)?;
1175
1176 request.access_list = Some(access_list.clone());
1178
1179 let (exit, out, gas_used, _) = self.backend.call_with_state(
1180 &state,
1181 request.clone(),
1182 FeeDetails::zero(),
1183 block_env,
1184 )?;
1185 ensure_return_ok(exit, &out)?;
1186
1187 Ok(AccessListResult {
1188 access_list: AccessList(access_list.0),
1189 gas_used: U256::from(gas_used),
1190 error: None,
1191 })
1192 })
1193 .await?
1194 }
1195
1196 pub async fn estimate_gas(
1201 &self,
1202 request: WithOtherFields<TransactionRequest>,
1203 block_number: Option<BlockId>,
1204 overrides: Option<StateOverride>,
1205 ) -> Result<U256> {
1206 node_info!("eth_estimateGas");
1207 self.do_estimate_gas(
1208 request,
1209 block_number.or_else(|| Some(BlockNumber::Pending.into())),
1210 overrides,
1211 )
1212 .await
1213 .map(U256::from)
1214 }
1215
1216 pub async fn transaction_by_hash(&self, hash: B256) -> Result<Option<AnyRpcTransaction>> {
1223 node_info!("eth_getTransactionByHash");
1224 let mut tx = self.pool.get_transaction(hash).map(|pending| {
1225 let from = *pending.sender();
1226 let tx = transaction_build(
1227 Some(*pending.hash()),
1228 pending.transaction,
1229 None,
1230 None,
1231 Some(self.backend.base_fee()),
1232 );
1233
1234 let WithOtherFields { inner: mut tx, other } = tx.0;
1235 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
1238
1239 AnyRpcTransaction(WithOtherFields { inner: tx, other })
1240 });
1241 if tx.is_none() {
1242 tx = self.backend.transaction_by_hash(hash).await?
1243 }
1244
1245 Ok(tx)
1246 }
1247
1248 pub async fn transaction_by_block_hash_and_index(
1252 &self,
1253 hash: B256,
1254 index: Index,
1255 ) -> Result<Option<AnyRpcTransaction>> {
1256 node_info!("eth_getTransactionByBlockHashAndIndex");
1257 self.backend.transaction_by_block_hash_and_index(hash, index).await
1258 }
1259
1260 pub async fn transaction_by_block_number_and_index(
1264 &self,
1265 block: BlockNumber,
1266 idx: Index,
1267 ) -> Result<Option<AnyRpcTransaction>> {
1268 node_info!("eth_getTransactionByBlockNumberAndIndex");
1269 self.backend.transaction_by_block_number_and_index(block, idx).await
1270 }
1271
1272 pub async fn transaction_receipt(&self, hash: B256) -> Result<Option<ReceiptResponse>> {
1276 node_info!("eth_getTransactionReceipt");
1277 let tx = self.pool.get_transaction(hash);
1278 if tx.is_some() {
1279 return Ok(None);
1280 }
1281 self.backend.transaction_receipt(hash).await
1282 }
1283
1284 pub async fn block_receipts(&self, number: BlockId) -> Result<Option<Vec<ReceiptResponse>>> {
1288 node_info!("eth_getBlockReceipts");
1289 self.backend.block_receipts(number).await
1290 }
1291
1292 pub async fn uncle_by_block_hash_and_index(
1296 &self,
1297 block_hash: B256,
1298 idx: Index,
1299 ) -> Result<Option<AnyRpcBlock>> {
1300 node_info!("eth_getUncleByBlockHashAndIndex");
1301 let number =
1302 self.backend.ensure_block_number(Some(BlockId::Hash(block_hash.into()))).await?;
1303 if let Some(fork) = self.get_fork() {
1304 if fork.predates_fork_inclusive(number) {
1305 return Ok(fork.uncle_by_block_hash_and_index(block_hash, idx.into()).await?)
1306 }
1307 }
1308 Ok(None)
1310 }
1311
1312 pub async fn uncle_by_block_number_and_index(
1316 &self,
1317 block_number: BlockNumber,
1318 idx: Index,
1319 ) -> Result<Option<AnyRpcBlock>> {
1320 node_info!("eth_getUncleByBlockNumberAndIndex");
1321 let number = self.backend.ensure_block_number(Some(BlockId::Number(block_number))).await?;
1322 if let Some(fork) = self.get_fork() {
1323 if fork.predates_fork_inclusive(number) {
1324 return Ok(fork.uncle_by_block_number_and_index(number, idx.into()).await?)
1325 }
1326 }
1327 Ok(None)
1329 }
1330
1331 pub async fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
1335 node_info!("eth_getLogs");
1336 self.backend.logs(filter).await
1337 }
1338
1339 pub fn work(&self) -> Result<Work> {
1343 node_info!("eth_getWork");
1344 Err(BlockchainError::RpcUnimplemented)
1345 }
1346
1347 pub fn syncing(&self) -> Result<bool> {
1351 node_info!("eth_syncing");
1352 Ok(false)
1353 }
1354
1355 pub fn submit_work(&self, _: B64, _: B256, _: B256) -> Result<bool> {
1359 node_info!("eth_submitWork");
1360 Err(BlockchainError::RpcUnimplemented)
1361 }
1362
1363 pub fn submit_hashrate(&self, _: U256, _: B256) -> Result<bool> {
1367 node_info!("eth_submitHashrate");
1368 Err(BlockchainError::RpcUnimplemented)
1369 }
1370
1371 pub async fn fee_history(
1375 &self,
1376 block_count: U256,
1377 newest_block: BlockNumber,
1378 reward_percentiles: Vec<f64>,
1379 ) -> Result<FeeHistory> {
1380 node_info!("eth_feeHistory");
1381 let current = self.backend.best_number();
1384 let slots_in_an_epoch = 32u64;
1385
1386 let number = match newest_block {
1387 BlockNumber::Latest | BlockNumber::Pending => current,
1388 BlockNumber::Earliest => 0,
1389 BlockNumber::Number(n) => n,
1390 BlockNumber::Safe => current.saturating_sub(slots_in_an_epoch),
1391 BlockNumber::Finalized => current.saturating_sub(slots_in_an_epoch * 2),
1392 };
1393
1394 if let Some(fork) = self.get_fork() {
1396 if fork.predates_fork_inclusive(number) {
1399 return fork
1400 .fee_history(block_count.to(), BlockNumber::Number(number), &reward_percentiles)
1401 .await
1402 .map_err(BlockchainError::AlloyForkProvider);
1403 }
1404 }
1405
1406 const MAX_BLOCK_COUNT: u64 = 1024u64;
1407 let block_count = block_count.to::<u64>().min(MAX_BLOCK_COUNT);
1408
1409 let highest = number;
1411 let lowest = highest.saturating_sub(block_count.saturating_sub(1));
1412
1413 if lowest < self.backend.best_number().saturating_sub(self.fee_history_limit) {
1415 return Err(FeeHistoryError::InvalidBlockRange.into());
1416 }
1417
1418 let mut response = FeeHistory {
1419 oldest_block: lowest,
1420 base_fee_per_gas: Vec::new(),
1421 gas_used_ratio: Vec::new(),
1422 reward: Some(Default::default()),
1423 base_fee_per_blob_gas: Default::default(),
1424 blob_gas_used_ratio: Default::default(),
1425 };
1426 let mut rewards = Vec::new();
1427
1428 {
1429 let fee_history = self.fee_history_cache.lock();
1430
1431 for n in lowest..=highest {
1433 if let Some(block) = fee_history.get(&n) {
1435 response.base_fee_per_gas.push(block.base_fee);
1436 response.base_fee_per_blob_gas.push(block.base_fee_per_blob_gas.unwrap_or(0));
1437 response.blob_gas_used_ratio.push(block.blob_gas_used_ratio);
1438 response.gas_used_ratio.push(block.gas_used_ratio);
1439
1440 if !reward_percentiles.is_empty() {
1442 let mut block_rewards = Vec::new();
1443 let resolution_per_percentile: f64 = 2.0;
1444 for p in &reward_percentiles {
1445 let p = p.clamp(0.0, 100.0);
1446 let index = ((p.round() / 2f64) * 2f64) * resolution_per_percentile;
1447 let reward = block.rewards.get(index as usize).map_or(0, |r| *r);
1448 block_rewards.push(reward);
1449 }
1450 rewards.push(block_rewards);
1451 }
1452 }
1453 }
1454 }
1455
1456 response.reward = Some(rewards);
1457
1458 response.base_fee_per_gas.push(self.backend.fees().base_fee() as u128);
1463
1464 response.base_fee_per_blob_gas.push(self.backend.fees().base_fee_per_blob_gas());
1468
1469 Ok(response)
1470 }
1471
1472 pub fn max_priority_fee_per_gas(&self) -> Result<U256> {
1479 node_info!("eth_maxPriorityFeePerGas");
1480 Ok(U256::from(self.lowest_suggestion_tip()))
1481 }
1482
1483 fn lowest_suggestion_tip(&self) -> u128 {
1487 let block_number = self.backend.best_number();
1488 let latest_cached_block = self.fee_history_cache.lock().get(&block_number).cloned();
1489
1490 match latest_cached_block {
1491 Some(block) => block.rewards.iter().copied().min(),
1492 None => self.fee_history_cache.lock().values().flat_map(|b| b.rewards.clone()).min(),
1493 }
1494 .map(|fee| fee.max(MIN_SUGGESTED_PRIORITY_FEE))
1495 .unwrap_or(MIN_SUGGESTED_PRIORITY_FEE)
1496 }
1497
1498 pub async fn new_filter(&self, filter: Filter) -> Result<String> {
1502 node_info!("eth_newFilter");
1503 let historic = if filter.block_option.get_from_block().is_some() {
1506 self.backend.logs(filter.clone()).await?
1507 } else {
1508 vec![]
1509 };
1510 let filter = EthFilter::Logs(Box::new(LogsFilter {
1511 blocks: self.new_block_notifications(),
1512 storage: self.storage_info(),
1513 filter: FilteredParams::new(Some(filter)),
1514 historic: Some(historic),
1515 }));
1516 Ok(self.filters.add_filter(filter).await)
1517 }
1518
1519 pub async fn new_block_filter(&self) -> Result<String> {
1523 node_info!("eth_newBlockFilter");
1524 let filter = EthFilter::Blocks(self.new_block_notifications());
1525 Ok(self.filters.add_filter(filter).await)
1526 }
1527
1528 pub async fn new_pending_transaction_filter(&self) -> Result<String> {
1532 node_info!("eth_newPendingTransactionFilter");
1533 let filter = EthFilter::PendingTransactions(self.new_ready_transactions());
1534 Ok(self.filters.add_filter(filter).await)
1535 }
1536
1537 pub async fn get_filter_changes(&self, id: &str) -> ResponseResult {
1541 node_info!("eth_getFilterChanges");
1542 self.filters.get_filter_changes(id).await
1543 }
1544
1545 pub async fn get_filter_logs(&self, id: &str) -> Result<Vec<Log>> {
1549 node_info!("eth_getFilterLogs");
1550 if let Some(filter) = self.filters.get_log_filter(id).await {
1551 self.backend.logs(filter).await
1552 } else {
1553 Ok(Vec::new())
1554 }
1555 }
1556
1557 pub async fn uninstall_filter(&self, id: &str) -> Result<bool> {
1559 node_info!("eth_uninstallFilter");
1560 Ok(self.filters.uninstall_filter(id).await.is_some())
1561 }
1562
1563 pub async fn raw_transaction(&self, hash: B256) -> Result<Option<Bytes>> {
1567 node_info!("debug_getRawTransaction");
1568 self.inner_raw_transaction(hash).await
1569 }
1570
1571 pub async fn raw_transaction_by_block_hash_and_index(
1575 &self,
1576 block_hash: B256,
1577 index: Index,
1578 ) -> Result<Option<Bytes>> {
1579 node_info!("eth_getRawTransactionByBlockHashAndIndex");
1580 match self.backend.transaction_by_block_hash_and_index(block_hash, index).await? {
1581 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1582 None => Ok(None),
1583 }
1584 }
1585
1586 pub async fn raw_transaction_by_block_number_and_index(
1590 &self,
1591 block_number: BlockNumber,
1592 index: Index,
1593 ) -> Result<Option<Bytes>> {
1594 node_info!("eth_getRawTransactionByBlockNumberAndIndex");
1595 match self.backend.transaction_by_block_number_and_index(block_number, index).await? {
1596 Some(tx) => self.inner_raw_transaction(tx.tx_hash()).await,
1597 None => Ok(None),
1598 }
1599 }
1600
1601 pub async fn debug_trace_transaction(
1605 &self,
1606 tx_hash: B256,
1607 opts: GethDebugTracingOptions,
1608 ) -> Result<GethTrace> {
1609 node_info!("debug_traceTransaction");
1610 self.backend.debug_trace_transaction(tx_hash, opts).await
1611 }
1612
1613 pub async fn debug_trace_call(
1617 &self,
1618 request: WithOtherFields<TransactionRequest>,
1619 block_number: Option<BlockId>,
1620 opts: GethDebugTracingCallOptions,
1621 ) -> Result<GethTrace> {
1622 node_info!("debug_traceCall");
1623 let block_request = self.block_request(block_number).await?;
1624 let fees = FeeDetails::new(
1625 request.gas_price,
1626 request.max_fee_per_gas,
1627 request.max_priority_fee_per_gas,
1628 request.max_fee_per_blob_gas,
1629 )?
1630 .or_zero_fees();
1631
1632 let result: std::result::Result<GethTrace, BlockchainError> =
1633 self.backend.call_with_tracing(request, fees, Some(block_request), opts).await;
1634 result
1635 }
1636
1637 pub async fn trace_transaction(&self, tx_hash: B256) -> Result<Vec<LocalizedTransactionTrace>> {
1641 node_info!("trace_transaction");
1642 self.backend.trace_transaction(tx_hash).await
1643 }
1644
1645 pub async fn trace_block(&self, block: BlockNumber) -> Result<Vec<LocalizedTransactionTrace>> {
1649 node_info!("trace_block");
1650 self.backend.trace_block(block).await
1651 }
1652
1653 pub async fn trace_filter(
1657 &self,
1658 filter: TraceFilter,
1659 ) -> Result<Vec<LocalizedTransactionTrace>> {
1660 node_info!("trace_filter");
1661 self.backend.trace_filter(filter).await
1662 }
1663}
1664
1665impl EthApi {
1668 pub async fn anvil_impersonate_account(&self, address: Address) -> Result<()> {
1672 node_info!("anvil_impersonateAccount");
1673 self.backend.impersonate(address);
1674 Ok(())
1675 }
1676
1677 pub async fn anvil_stop_impersonating_account(&self, address: Address) -> Result<()> {
1681 node_info!("anvil_stopImpersonatingAccount");
1682 self.backend.stop_impersonating(address);
1683 Ok(())
1684 }
1685
1686 pub async fn anvil_auto_impersonate_account(&self, enabled: bool) -> Result<()> {
1690 node_info!("anvil_autoImpersonateAccount");
1691 self.backend.auto_impersonate_account(enabled);
1692 Ok(())
1693 }
1694
1695 pub fn anvil_get_auto_mine(&self) -> Result<bool> {
1699 node_info!("anvil_getAutomine");
1700 Ok(self.miner.is_auto_mine())
1701 }
1702
1703 pub fn anvil_get_interval_mining(&self) -> Result<Option<u64>> {
1707 node_info!("anvil_getIntervalMining");
1708 Ok(self.miner.get_interval())
1709 }
1710
1711 pub async fn anvil_set_auto_mine(&self, enable_automine: bool) -> Result<()> {
1716 node_info!("evm_setAutomine");
1717 if self.miner.is_auto_mine() {
1718 if enable_automine {
1719 return Ok(());
1720 }
1721 self.miner.set_mining_mode(MiningMode::None);
1722 } else if enable_automine {
1723 let listener = self.pool.add_ready_listener();
1724 let mode = MiningMode::instant(1_000, listener);
1725 self.miner.set_mining_mode(mode);
1726 }
1727 Ok(())
1728 }
1729
1730 pub async fn anvil_mine(&self, num_blocks: Option<U256>, interval: Option<U256>) -> Result<()> {
1734 node_info!("anvil_mine");
1735 let interval = interval.map(|i| i.to::<u64>());
1736 let blocks = num_blocks.unwrap_or(U256::from(1));
1737 if blocks.is_zero() {
1738 return Ok(());
1739 }
1740
1741 for _ in 0..blocks.to::<u64>() {
1743 if let Some(interval) = interval {
1745 self.backend.time().increase_time(interval);
1746 }
1747
1748 self.mine_one().await;
1749 }
1750
1751 Ok(())
1752 }
1753
1754 pub fn anvil_set_interval_mining(&self, secs: u64) -> Result<()> {
1758 node_info!("evm_setIntervalMining");
1759 let mining_mode = if secs == 0 {
1760 MiningMode::None
1761 } else {
1762 let block_time = Duration::from_secs(secs);
1763
1764 self.backend.update_interval_mine_block_time(block_time);
1766
1767 MiningMode::FixedBlockTime(FixedBlockTimeMiner::new(block_time))
1768 };
1769 self.miner.set_mining_mode(mining_mode);
1770 Ok(())
1771 }
1772
1773 pub async fn anvil_drop_transaction(&self, tx_hash: B256) -> Result<Option<B256>> {
1777 node_info!("anvil_dropTransaction");
1778 Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash()))
1779 }
1780
1781 pub async fn anvil_drop_all_transactions(&self) -> Result<()> {
1785 node_info!("anvil_dropAllTransactions");
1786 self.pool.clear();
1787 Ok(())
1788 }
1789
1790 pub async fn anvil_reset(&self, forking: Option<Forking>) -> Result<()> {
1796 node_info!("anvil_reset");
1797 if let Some(forking) = forking {
1798 self.reset_instance_id();
1800 self.backend.reset_fork(forking).await
1801 } else {
1802 Err(BlockchainError::RpcUnimplemented)
1803 }
1804 }
1805
1806 pub async fn anvil_set_chain_id(&self, chain_id: u64) -> Result<()> {
1807 node_info!("anvil_setChainId");
1808 self.backend.set_chain_id(chain_id);
1809 Ok(())
1810 }
1811
1812 pub async fn anvil_set_balance(&self, address: Address, balance: U256) -> Result<()> {
1816 node_info!("anvil_setBalance");
1817 self.backend.set_balance(address, balance).await?;
1818 Ok(())
1819 }
1820
1821 pub async fn anvil_set_code(&self, address: Address, code: Bytes) -> Result<()> {
1825 node_info!("anvil_setCode");
1826 self.backend.set_code(address, code).await?;
1827 Ok(())
1828 }
1829
1830 pub async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> Result<()> {
1834 node_info!("anvil_setNonce");
1835 self.backend.set_nonce(address, nonce).await?;
1836 Ok(())
1837 }
1838
1839 pub async fn anvil_set_storage_at(
1843 &self,
1844 address: Address,
1845 slot: U256,
1846 val: B256,
1847 ) -> Result<bool> {
1848 node_info!("anvil_setStorageAt");
1849 self.backend.set_storage_at(address, slot, val).await?;
1850 Ok(true)
1851 }
1852
1853 pub async fn anvil_set_logging(&self, enable: bool) -> Result<()> {
1857 node_info!("anvil_setLoggingEnabled");
1858 self.logger.set_enabled(enable);
1859 Ok(())
1860 }
1861
1862 pub async fn anvil_set_min_gas_price(&self, gas: U256) -> Result<()> {
1866 node_info!("anvil_setMinGasPrice");
1867 if self.backend.is_eip1559() {
1868 return Err(RpcError::invalid_params(
1869 "anvil_setMinGasPrice is not supported when EIP-1559 is active",
1870 )
1871 .into());
1872 }
1873 self.backend.set_gas_price(gas.to());
1874 Ok(())
1875 }
1876
1877 pub async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: U256) -> Result<()> {
1881 node_info!("anvil_setNextBlockBaseFeePerGas");
1882 if !self.backend.is_eip1559() {
1883 return Err(RpcError::invalid_params(
1884 "anvil_setNextBlockBaseFeePerGas is only supported when EIP-1559 is active",
1885 )
1886 .into());
1887 }
1888 self.backend.set_base_fee(basefee.to());
1889 Ok(())
1890 }
1891
1892 pub async fn anvil_set_coinbase(&self, address: Address) -> Result<()> {
1896 node_info!("anvil_setCoinbase");
1897 self.backend.set_coinbase(address);
1898 Ok(())
1899 }
1900
1901 pub async fn anvil_dump_state(
1906 &self,
1907 preserve_historical_states: Option<bool>,
1908 ) -> Result<Bytes> {
1909 node_info!("anvil_dumpState");
1910 self.backend.dump_state(preserve_historical_states.unwrap_or(false)).await
1911 }
1912
1913 pub async fn serialized_state(
1915 &self,
1916 preserve_historical_states: bool,
1917 ) -> Result<SerializableState> {
1918 self.backend.serialized_state(preserve_historical_states).await
1919 }
1920
1921 pub async fn anvil_load_state(&self, buf: Bytes) -> Result<bool> {
1926 node_info!("anvil_loadState");
1927 self.backend.load_state_bytes(buf).await
1928 }
1929
1930 pub async fn anvil_node_info(&self) -> Result<NodeInfo> {
1934 node_info!("anvil_nodeInfo");
1935
1936 let env = self.backend.env().read();
1937 let fork_config = self.backend.get_fork();
1938 let tx_order = self.transaction_order.read();
1939 let hard_fork: &str = env.handler_cfg.spec_id.into();
1940
1941 Ok(NodeInfo {
1942 current_block_number: self.backend.best_number(),
1943 current_block_timestamp: env.block.timestamp.try_into().unwrap_or(u64::MAX),
1944 current_block_hash: self.backend.best_hash(),
1945 hard_fork: hard_fork.to_string(),
1946 transaction_order: match *tx_order {
1947 TransactionOrder::Fifo => "fifo".to_string(),
1948 TransactionOrder::Fees => "fees".to_string(),
1949 },
1950 environment: NodeEnvironment {
1951 base_fee: self.backend.base_fee() as u128,
1952 chain_id: self.backend.chain_id().to::<u64>(),
1953 gas_limit: self.backend.gas_limit(),
1954 gas_price: self.gas_price(),
1955 },
1956 fork_config: fork_config
1957 .map(|fork| {
1958 let config = fork.config.read();
1959
1960 NodeForkConfig {
1961 fork_url: Some(config.eth_rpc_url.clone()),
1962 fork_block_number: Some(config.block_number),
1963 fork_retry_backoff: Some(config.backoff.as_millis()),
1964 }
1965 })
1966 .unwrap_or_default(),
1967 })
1968 }
1969
1970 pub async fn anvil_metadata(&self) -> Result<Metadata> {
1974 node_info!("anvil_metadata");
1975 let fork_config = self.backend.get_fork();
1976
1977 Ok(Metadata {
1978 client_version: CLIENT_VERSION.to_string(),
1979 chain_id: self.backend.chain_id().to::<u64>(),
1980 latest_block_hash: self.backend.best_hash(),
1981 latest_block_number: self.backend.best_number(),
1982 instance_id: *self.instance_id.read(),
1983 forked_network: fork_config.map(|cfg| ForkedNetwork {
1984 chain_id: cfg.chain_id(),
1985 fork_block_number: cfg.block_number(),
1986 fork_block_hash: cfg.block_hash(),
1987 }),
1988 snapshots: self.backend.list_state_snapshots(),
1989 })
1990 }
1991
1992 pub async fn anvil_remove_pool_transactions(&self, address: Address) -> Result<()> {
1993 node_info!("anvil_removePoolTransactions");
1994 self.pool.remove_transactions_by_address(address);
1995 Ok(())
1996 }
1997
1998 pub async fn anvil_reorg(&self, options: ReorgOptions) -> Result<()> {
2012 node_info!("anvil_reorg");
2013 let depth = options.depth;
2014 let tx_block_pairs = options.tx_block_pairs;
2015
2016 let current_height = self.backend.best_number();
2018 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2019 RpcError::invalid_params(format!(
2020 "Reorg depth must not exceed current chain height: current height {current_height}, depth {depth}"
2021 )),
2022 ))?;
2023
2024 let common_block =
2026 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2027
2028 let block_pool_txs = if tx_block_pairs.is_empty() {
2031 HashMap::default()
2032 } else {
2033 let mut pairs = tx_block_pairs;
2034
2035 if let Some((_, num)) = pairs.iter().find(|(_, num)| *num >= depth) {
2037 return Err(BlockchainError::RpcError(RpcError::invalid_params(format!(
2038 "Block number for reorg tx will exceed the reorged chain height. Block number {num} must not exceed (depth-1) {}",
2039 depth-1
2040 ))));
2041 }
2042
2043 pairs.sort_by_key(|a| a.1);
2045
2046 let mut nonces: HashMap<Address, u64> = HashMap::default();
2049
2050 let mut txs: HashMap<u64, Vec<Arc<PoolTransaction>>> = HashMap::default();
2051 for pair in pairs {
2052 let (tx_data, block_index) = pair;
2053
2054 let mut tx_req = match tx_data {
2055 TransactionData::JSON(req) => WithOtherFields::new(req),
2056 TransactionData::Raw(bytes) => {
2057 let mut data = bytes.as_ref();
2058 let decoded = TypedTransaction::decode_2718(&mut data)
2059 .map_err(|_| BlockchainError::FailedToDecodeSignedTransaction)?;
2060 let request =
2061 TransactionRequest::try_from(decoded.clone()).map_err(|_| {
2062 BlockchainError::RpcError(RpcError::invalid_params(
2063 "Failed to convert raw transaction",
2064 ))
2065 })?;
2066 WithOtherFields::new(request)
2067 }
2068 };
2069
2070 let from = tx_req.from.map(Ok).unwrap_or_else(|| {
2071 self.accounts()?.first().cloned().ok_or(BlockchainError::NoSignerAvailable)
2072 })?;
2073
2074 let curr_nonce = nonces.entry(from).or_insert(
2076 self.get_transaction_count(from, Some(common_block.header.number.into()))
2077 .await?,
2078 );
2079
2080 if tx_req.gas.is_none() {
2082 if let Ok(gas) = self.estimate_gas(tx_req.clone(), None, None).await {
2083 tx_req.gas = Some(gas.to());
2084 }
2085 }
2086
2087 let typed = self.build_typed_tx_request(tx_req, *curr_nonce)?;
2089
2090 *curr_nonce += 1;
2092
2093 let pending = if self.is_impersonated(from) {
2095 let bypass_signature = self.impersonated_signature(&typed);
2096 let transaction = sign::build_typed_transaction(typed, bypass_signature)?;
2097 self.ensure_typed_transaction_supported(&transaction)?;
2098 PendingTransaction::with_impersonated(transaction, from)
2099 } else {
2100 let transaction = self.sign_request(&from, typed)?;
2101 self.ensure_typed_transaction_supported(&transaction)?;
2102 PendingTransaction::new(transaction)?
2103 };
2104
2105 let pooled = PoolTransaction::new(pending);
2106 txs.entry(block_index).or_default().push(Arc::new(pooled));
2107 }
2108
2109 txs
2110 };
2111
2112 self.backend.reorg(depth, block_pool_txs, common_block).await?;
2113 Ok(())
2114 }
2115
2116 pub async fn anvil_rollback(&self, depth: Option<u64>) -> Result<()> {
2127 node_info!("anvil_rollback");
2128 let depth = depth.unwrap_or(1);
2129
2130 let current_height = self.backend.best_number();
2132 let common_height = current_height.checked_sub(depth).ok_or(BlockchainError::RpcError(
2133 RpcError::invalid_params(format!(
2134 "Rollback depth must not exceed current chain height: current height {current_height}, depth {depth}"
2135 )),
2136 ))?;
2137
2138 let common_block =
2140 self.backend.get_block(common_height).ok_or(BlockchainError::BlockNotFound)?;
2141
2142 self.backend.rollback(common_block).await?;
2143 Ok(())
2144 }
2145
2146 pub async fn evm_snapshot(&self) -> Result<U256> {
2150 node_info!("evm_snapshot");
2151 Ok(self.backend.create_state_snapshot().await)
2152 }
2153
2154 pub async fn evm_revert(&self, id: U256) -> Result<bool> {
2159 node_info!("evm_revert");
2160 self.backend.revert_state_snapshot(id).await
2161 }
2162
2163 pub async fn evm_increase_time(&self, seconds: U256) -> Result<i64> {
2167 node_info!("evm_increaseTime");
2168 Ok(self.backend.time().increase_time(seconds.try_into().unwrap_or(u64::MAX)) as i64)
2169 }
2170
2171 pub fn evm_set_next_block_timestamp(&self, seconds: u64) -> Result<()> {
2175 node_info!("evm_setNextBlockTimestamp");
2176 self.backend.time().set_next_block_timestamp(seconds)
2177 }
2178
2179 pub fn evm_set_time(&self, timestamp: u64) -> Result<u64> {
2184 node_info!("evm_setTime");
2185 let now = self.backend.time().current_call_timestamp();
2186 self.backend.time().reset(timestamp);
2187
2188 let offset = timestamp.saturating_sub(now);
2190 Ok(Duration::from_millis(offset).as_secs())
2191 }
2192
2193 pub fn evm_set_block_gas_limit(&self, gas_limit: U256) -> Result<bool> {
2197 node_info!("evm_setBlockGasLimit");
2198 self.backend.set_gas_limit(gas_limit.to());
2199 Ok(true)
2200 }
2201
2202 pub fn evm_set_block_timestamp_interval(&self, seconds: u64) -> Result<()> {
2206 node_info!("anvil_setBlockTimestampInterval");
2207 self.backend.time().set_block_timestamp_interval(seconds);
2208 Ok(())
2209 }
2210
2211 pub fn evm_remove_block_timestamp_interval(&self) -> Result<bool> {
2215 node_info!("anvil_removeBlockTimestampInterval");
2216 Ok(self.backend.time().remove_block_timestamp_interval())
2217 }
2218
2219 pub async fn evm_mine(&self, opts: Option<MineOptions>) -> Result<String> {
2226 node_info!("evm_mine");
2227
2228 self.do_evm_mine(opts).await?;
2229
2230 Ok("0x0".to_string())
2231 }
2232
2233 pub async fn evm_mine_detailed(&self, opts: Option<MineOptions>) -> Result<Vec<AnyRpcBlock>> {
2243 node_info!("evm_mine_detailed");
2244
2245 let mined_blocks = self.do_evm_mine(opts).await?;
2246
2247 let mut blocks = Vec::with_capacity(mined_blocks as usize);
2248
2249 let latest = self.backend.best_number();
2250 for offset in (0..mined_blocks).rev() {
2251 let block_num = latest - offset;
2252 if let Some(mut block) =
2253 self.backend.block_by_number_full(BlockNumber::Number(block_num)).await?
2254 {
2255 let block_txs = match block.transactions_mut() {
2256 BlockTransactions::Full(txs) => txs,
2257 BlockTransactions::Hashes(_) | BlockTransactions::Uncle => unreachable!(),
2258 };
2259 for tx in block_txs.iter_mut() {
2260 if let Some(receipt) = self.backend.mined_transaction_receipt(tx.tx_hash()) {
2261 if let Some(output) = receipt.out {
2262 if !receipt
2264 .inner
2265 .inner
2266 .as_receipt_with_bloom()
2267 .receipt
2268 .status
2269 .coerce_status()
2270 {
2271 if let Some(reason) =
2272 RevertDecoder::new().maybe_decode(&output, None)
2273 {
2274 tx.other.insert(
2275 "revertReason".to_string(),
2276 serde_json::to_value(reason).expect("Infallible"),
2277 );
2278 }
2279 }
2280 tx.other.insert(
2281 "output".to_string(),
2282 serde_json::to_value(output).expect("Infallible"),
2283 );
2284 }
2285 }
2286 }
2287 block.transactions = BlockTransactions::Full(block_txs.to_vec());
2288 blocks.push(block);
2289 }
2290 }
2291
2292 Ok(blocks)
2293 }
2294
2295 pub fn anvil_set_block(&self, block_number: U256) -> Result<()> {
2299 node_info!("anvil_setBlock");
2300 self.backend.set_block_number(block_number);
2301 Ok(())
2302 }
2303
2304 pub fn anvil_set_rpc_url(&self, url: String) -> Result<()> {
2308 node_info!("anvil_setRpcUrl");
2309 if let Some(fork) = self.backend.get_fork() {
2310 let mut config = fork.config.write();
2311 let new_provider = Arc::new(
2313 ProviderBuilder::new(&url).max_retry(10).initial_backoff(1000).build().map_err(
2314 |_| {
2315 TransportErrorKind::custom_str(
2316 format!("Failed to parse invalid url {url}").as_str(),
2317 )
2318 },
2319 )?, );
2322 config.provider = new_provider;
2323 trace!(target: "backend", "Updated fork rpc from \"{}\" to \"{}\"", config.eth_rpc_url, url);
2324 config.eth_rpc_url = url;
2325 }
2326 Ok(())
2327 }
2328
2329 pub async fn anvil_enable_traces(&self) -> Result<()> {
2334 node_info!("anvil_enableTraces");
2335 Err(BlockchainError::RpcUnimplemented)
2336 }
2337
2338 pub async fn eth_send_unsigned_transaction(
2342 &self,
2343 request: WithOtherFields<TransactionRequest>,
2344 ) -> Result<TxHash> {
2345 node_info!("eth_sendUnsignedTransaction");
2346 let from = request.from.ok_or(BlockchainError::NoSignerAvailable)?;
2348
2349 let (nonce, on_chain_nonce) = self.request_nonce(&request, from).await?;
2350
2351 let request = self.build_typed_tx_request(request, nonce)?;
2352
2353 let bypass_signature = self.impersonated_signature(&request);
2354 let transaction = sign::build_typed_transaction(request, bypass_signature)?;
2355
2356 self.ensure_typed_transaction_supported(&transaction)?;
2357
2358 let pending_transaction = PendingTransaction::with_impersonated(transaction, from);
2359
2360 self.backend.validate_pool_transaction(&pending_transaction).await?;
2362
2363 let requires = required_marker(nonce, on_chain_nonce, from);
2364 let provides = vec![to_marker(nonce, from)];
2365
2366 self.add_pending_transaction(pending_transaction, requires, provides)
2367 }
2368
2369 pub async fn txpool_status(&self) -> Result<TxpoolStatus> {
2375 node_info!("txpool_status");
2376 Ok(self.pool.txpool_status())
2377 }
2378
2379 pub async fn txpool_inspect(&self) -> Result<TxpoolInspect> {
2386 node_info!("txpool_inspect");
2387 let mut inspect = TxpoolInspect::default();
2388
2389 fn convert(tx: Arc<PoolTransaction>) -> TxpoolInspectSummary {
2390 let tx = &tx.pending_transaction.transaction;
2391 let to = tx.to();
2392 let gas_price = tx.gas_price();
2393 let value = tx.value();
2394 let gas = tx.gas_limit();
2395 TxpoolInspectSummary { to, value, gas, gas_price }
2396 }
2397
2398 for pending in self.pool.ready_transactions() {
2405 let entry = inspect.pending.entry(*pending.pending_transaction.sender()).or_default();
2406 let key = pending.pending_transaction.nonce().to_string();
2407 entry.insert(key, convert(pending));
2408 }
2409 for queued in self.pool.pending_transactions() {
2410 let entry = inspect.pending.entry(*queued.pending_transaction.sender()).or_default();
2411 let key = queued.pending_transaction.nonce().to_string();
2412 entry.insert(key, convert(queued));
2413 }
2414 Ok(inspect)
2415 }
2416
2417 pub async fn txpool_content(&self) -> Result<TxpoolContent<AnyRpcTransaction>> {
2424 node_info!("txpool_content");
2425 let mut content = TxpoolContent::<AnyRpcTransaction>::default();
2426 fn convert(tx: Arc<PoolTransaction>) -> Result<AnyRpcTransaction> {
2427 let from = *tx.pending_transaction.sender();
2428 let tx = transaction_build(
2429 Some(tx.hash()),
2430 tx.pending_transaction.transaction.clone(),
2431 None,
2432 None,
2433 None,
2434 );
2435
2436 let WithOtherFields { inner: mut tx, other } = tx.0;
2437
2438 tx.inner = Recovered::new_unchecked(tx.inner.into_inner(), from);
2441
2442 let tx = AnyRpcTransaction(WithOtherFields { inner: tx, other });
2443
2444 Ok(tx)
2445 }
2446
2447 for pending in self.pool.ready_transactions() {
2448 let entry = content.pending.entry(*pending.pending_transaction.sender()).or_default();
2449 let key = pending.pending_transaction.nonce().to_string();
2450 entry.insert(key, convert(pending)?);
2451 }
2452 for queued in self.pool.pending_transactions() {
2453 let entry = content.pending.entry(*queued.pending_transaction.sender()).or_default();
2454 let key = queued.pending_transaction.nonce().to_string();
2455 entry.insert(key, convert(queued)?);
2456 }
2457
2458 Ok(content)
2459 }
2460}
2461
2462impl EthApi {
2464 pub fn get_capabilities(&self) -> Result<WalletCapabilities> {
2470 node_info!("wallet_getCapabilities");
2471 Ok(self.backend.get_capabilities())
2472 }
2473
2474 pub async fn wallet_send_transaction(
2475 &self,
2476 mut request: WithOtherFields<TransactionRequest>,
2477 ) -> Result<TxHash> {
2478 node_info!("wallet_sendTransaction");
2479
2480 if request.value.is_some_and(|val| val > U256::ZERO) {
2483 return Err(WalletError::ValueNotZero.into())
2484 }
2485
2486 if request.from.is_some() {
2488 return Err(WalletError::FromSet.into());
2489 }
2490
2491 if request.nonce.is_some() {
2493 return Err(WalletError::NonceSet.into());
2494 }
2495
2496 let capabilities = self.backend.get_capabilities();
2497 let valid_delegations: &[Address] = capabilities
2498 .get(self.chain_id())
2499 .map(|caps| caps.delegation.addresses.as_ref())
2500 .unwrap_or_default();
2501
2502 if let Some(authorizations) = &request.authorization_list {
2503 if authorizations.iter().any(|auth| !valid_delegations.contains(&auth.address)) {
2504 return Err(WalletError::InvalidAuthorization.into());
2505 }
2506 }
2507
2508 match (request.authorization_list.is_some(), request.to) {
2510 (false, Some(TxKind::Call(addr))) => {
2513 let acc = self.backend.get_account(addr).await?;
2514
2515 let delegated_address = acc
2516 .code
2517 .map(|code| match code {
2518 Bytecode::Eip7702(c) => c.address(),
2519 _ => Address::ZERO,
2520 })
2521 .unwrap_or_default();
2522
2523 if delegated_address == Address::ZERO ||
2525 !valid_delegations.contains(&delegated_address)
2526 {
2527 return Err(WalletError::IllegalDestination.into());
2528 }
2529 }
2530 (true, _) => (),
2532 _ => return Err(WalletError::IllegalDestination.into()),
2534 }
2535
2536 let wallet = self.backend.executor_wallet().ok_or(WalletError::InternalError)?;
2537
2538 let from = NetworkWallet::<Ethereum>::default_signer_address(&wallet);
2539
2540 let nonce = self.get_transaction_count(from, Some(BlockId::latest())).await?;
2541
2542 request.nonce = Some(nonce);
2543
2544 let chain_id = self.chain_id();
2545
2546 request.chain_id = Some(chain_id);
2547
2548 request.from = Some(from);
2549
2550 let gas_limit_fut = self.estimate_gas(request.clone(), Some(BlockId::latest()), None);
2551
2552 let fees_fut = self.fee_history(
2553 U256::from(EIP1559_FEE_ESTIMATION_PAST_BLOCKS),
2554 BlockNumber::Latest,
2555 vec![EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE],
2556 );
2557
2558 let (gas_limit, fees) = tokio::join!(gas_limit_fut, fees_fut);
2559
2560 let gas_limit = gas_limit?;
2561 let fees = fees?;
2562
2563 request.gas = Some(gas_limit.to());
2564
2565 let base_fee = fees.latest_block_base_fee().unwrap_or_default();
2566
2567 let estimation = eip1559_default_estimator(base_fee, &fees.reward.unwrap_or_default());
2568
2569 request.max_fee_per_gas = Some(estimation.max_fee_per_gas);
2570 request.max_priority_fee_per_gas = Some(estimation.max_priority_fee_per_gas);
2571 request.gas_price = None;
2572
2573 let envelope = request.build(&wallet).await.map_err(|_| WalletError::InternalError)?;
2574
2575 self.send_raw_transaction(envelope.encoded_2718().into()).await
2576 }
2577
2578 pub fn anvil_add_capability(&self, address: Address) -> Result<()> {
2582 node_info!("anvil_addCapability");
2583 self.backend.add_capability(address);
2584 Ok(())
2585 }
2586
2587 pub fn anvil_set_executor(&self, executor_pk: String) -> Result<Address> {
2588 node_info!("anvil_setExecutor");
2589 self.backend.set_executor(executor_pk)
2590 }
2591}
2592
2593impl EthApi {
2594 async fn on_blocking_task<C, F, R>(&self, c: C) -> Result<R>
2596 where
2597 C: FnOnce(Self) -> F,
2598 F: Future<Output = Result<R>> + Send + 'static,
2599 R: Send + 'static,
2600 {
2601 let (tx, rx) = oneshot::channel();
2602 let this = self.clone();
2603 let f = c(this);
2604 tokio::task::spawn_blocking(move || {
2605 tokio::runtime::Handle::current().block_on(async move {
2606 let res = f.await;
2607 let _ = tx.send(res);
2608 })
2609 });
2610 rx.await.map_err(|_| BlockchainError::Internal("blocking task panicked".to_string()))?
2611 }
2612
2613 async fn do_evm_mine(&self, opts: Option<MineOptions>) -> Result<u64> {
2615 let mut blocks_to_mine = 1u64;
2616
2617 if let Some(opts) = opts {
2618 let timestamp = match opts {
2619 MineOptions::Timestamp(timestamp) => timestamp,
2620 MineOptions::Options { timestamp, blocks } => {
2621 if let Some(blocks) = blocks {
2622 blocks_to_mine = blocks;
2623 }
2624 timestamp
2625 }
2626 };
2627 if let Some(timestamp) = timestamp {
2628 self.evm_set_next_block_timestamp(timestamp)?;
2630 }
2631 }
2632
2633 for _ in 0..blocks_to_mine {
2635 self.mine_one().await;
2636 }
2637
2638 Ok(blocks_to_mine)
2639 }
2640
2641 async fn do_estimate_gas(
2642 &self,
2643 request: WithOtherFields<TransactionRequest>,
2644 block_number: Option<BlockId>,
2645 overrides: Option<StateOverride>,
2646 ) -> Result<u128> {
2647 let block_request = self.block_request(block_number).await?;
2648 if let BlockRequest::Number(number) = block_request {
2650 if let Some(fork) = self.get_fork() {
2651 if fork.predates_fork(number) {
2652 if overrides.is_some() {
2653 return Err(BlockchainError::StateOverrideError(
2654 "not available on past forked blocks".to_string(),
2655 ));
2656 }
2657 return Ok(fork.estimate_gas(&request, Some(number.into())).await?)
2658 }
2659 }
2660 }
2661
2662 self.backend
2663 .with_database_at(Some(block_request), |mut state, block| {
2664 if let Some(overrides) = overrides {
2665 state = Box::new(state::apply_state_override(
2666 overrides.into_iter().collect(),
2667 state,
2668 )?);
2669 }
2670 self.do_estimate_gas_with_state(request, &state, block)
2671 })
2672 .await?
2673 }
2674
2675 fn do_estimate_gas_with_state(
2679 &self,
2680 mut request: WithOtherFields<TransactionRequest>,
2681 state: &dyn DatabaseRef<Error = DatabaseError>,
2682 block_env: BlockEnv,
2683 ) -> Result<u128> {
2684 let to = request.to.as_ref().and_then(TxKind::to);
2687
2688 let maybe_transfer = request.input.input().is_none() &&
2690 request.access_list.is_none() &&
2691 request.blob_versioned_hashes.is_none();
2692
2693 if maybe_transfer {
2694 if let Some(to) = to {
2695 if let Ok(target_code) = self.backend.get_code_with_state(&state, *to) {
2696 if target_code.as_ref().is_empty() {
2697 return Ok(MIN_TRANSACTION_GAS);
2698 }
2699 }
2700 }
2701 }
2702
2703 let fees = FeeDetails::new(
2704 request.gas_price,
2705 request.max_fee_per_gas,
2706 request.max_priority_fee_per_gas,
2707 request.max_fee_per_blob_gas,
2708 )?
2709 .or_zero_fees();
2710
2711 let mut highest_gas_limit =
2714 request.gas.map_or(block_env.gas_limit.to::<u128>(), |g| g as u128);
2715
2716 let gas_price = fees.gas_price.unwrap_or_default();
2717 if gas_price > 0 {
2719 if let Some(from) = request.from {
2720 let mut available_funds = self.backend.get_balance_with_state(state, from)?;
2721 if let Some(value) = request.value {
2722 if value > available_funds {
2723 return Err(InvalidTransactionError::InsufficientFunds.into());
2724 }
2725 available_funds -= value;
2727 }
2728 let allowance =
2730 available_funds.checked_div(U256::from(gas_price)).unwrap_or_default();
2731 highest_gas_limit = std::cmp::min(highest_gas_limit, allowance.saturating_to());
2732 }
2733 }
2734
2735 let mut call_to_estimate = request.clone();
2736 call_to_estimate.gas = Some(highest_gas_limit as u64);
2737
2738 let ethres =
2740 self.backend.call_with_state(&state, call_to_estimate, fees.clone(), block_env.clone());
2741
2742 let gas_used = match ethres.try_into()? {
2743 GasEstimationCallResult::Success(gas) => Ok(gas),
2744 GasEstimationCallResult::OutOfGas => {
2745 Err(InvalidTransactionError::BasicOutOfGas(highest_gas_limit).into())
2746 }
2747 GasEstimationCallResult::Revert(output) => {
2748 Err(InvalidTransactionError::Revert(output).into())
2749 }
2750 GasEstimationCallResult::EvmError(err) => {
2751 warn!(target: "node", "estimation failed due to {:?}", err);
2752 Err(BlockchainError::EvmError(err))
2753 }
2754 }?;
2755
2756 let mut lowest_gas_limit = determine_base_gas_by_kind(&request);
2763
2764 let mut mid_gas_limit =
2766 std::cmp::min(gas_used * 3, (highest_gas_limit + lowest_gas_limit) / 2);
2767
2768 while (highest_gas_limit - lowest_gas_limit) > 1 {
2770 request.gas = Some(mid_gas_limit as u64);
2771 let ethres = self.backend.call_with_state(
2772 &state,
2773 request.clone(),
2774 fees.clone(),
2775 block_env.clone(),
2776 );
2777
2778 match ethres.try_into()? {
2779 GasEstimationCallResult::Success(_) => {
2780 highest_gas_limit = mid_gas_limit;
2784 }
2785 GasEstimationCallResult::OutOfGas |
2786 GasEstimationCallResult::Revert(_) |
2787 GasEstimationCallResult::EvmError(_) => {
2788 lowest_gas_limit = mid_gas_limit;
2795 }
2796 };
2797 mid_gas_limit = (highest_gas_limit + lowest_gas_limit) / 2;
2799 }
2800
2801 trace!(target : "node", "Estimated Gas for call {:?}", highest_gas_limit);
2802
2803 Ok(highest_gas_limit)
2804 }
2805
2806 pub fn set_transaction_order(&self, order: TransactionOrder) {
2808 *self.transaction_order.write() = order;
2809 }
2810
2811 fn transaction_priority(&self, tx: &TypedTransaction) -> TransactionPriority {
2813 self.transaction_order.read().priority(tx)
2814 }
2815
2816 pub fn chain_id(&self) -> u64 {
2818 self.backend.chain_id().to::<u64>()
2819 }
2820
2821 pub fn get_fork(&self) -> Option<ClientFork> {
2823 self.backend.get_fork()
2824 }
2825
2826 pub fn instance_id(&self) -> B256 {
2828 *self.instance_id.read()
2829 }
2830
2831 pub fn reset_instance_id(&self) {
2833 *self.instance_id.write() = B256::random();
2834 }
2835
2836 #[expect(clippy::borrowed_box)]
2838 pub fn get_signer(&self, address: Address) -> Option<&Box<dyn Signer>> {
2839 self.signers.iter().find(|signer| signer.is_signer_for(address))
2840 }
2841
2842 pub fn new_block_notifications(&self) -> NewBlockNotifications {
2844 self.backend.new_block_notifications()
2845 }
2846
2847 pub fn new_ready_transactions(&self) -> Receiver<TxHash> {
2849 self.pool.add_ready_listener()
2850 }
2851
2852 pub fn storage_info(&self) -> StorageInfo {
2854 StorageInfo::new(Arc::clone(&self.backend))
2855 }
2856
2857 pub fn is_fork(&self) -> bool {
2859 self.backend.is_fork()
2860 }
2861
2862 pub async fn mine_one(&self) {
2864 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
2865 let outcome = self.backend.mine_block(transactions).await;
2866
2867 trace!(target: "node", blocknumber = ?outcome.block_number, "mined block");
2868 self.pool.on_mined_block(outcome);
2869 }
2870
2871 async fn pending_block(&self) -> AnyRpcBlock {
2873 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
2874 let info = self.backend.pending_block(transactions).await;
2875 self.backend.convert_block(info.block)
2876 }
2877
2878 async fn pending_block_full(&self) -> Option<AnyRpcBlock> {
2880 let transactions = self.pool.ready_transactions().collect::<Vec<_>>();
2881 let BlockInfo { block, transactions, receipts: _ } =
2882 self.backend.pending_block(transactions).await;
2883
2884 let mut partial_block = self.backend.convert_block(block.clone());
2885
2886 let mut block_transactions = Vec::with_capacity(block.transactions.len());
2887 let base_fee = self.backend.base_fee();
2888
2889 for info in transactions {
2890 let tx = block.transactions.get(info.transaction_index as usize)?.clone();
2891
2892 let tx = transaction_build(
2893 Some(info.transaction_hash),
2894 tx,
2895 Some(&block),
2896 Some(info),
2897 Some(base_fee),
2898 );
2899 block_transactions.push(tx);
2900 }
2901
2902 partial_block.transactions = BlockTransactions::from(block_transactions);
2903
2904 Some(partial_block)
2905 }
2906
2907 fn build_typed_tx_request(
2908 &self,
2909 request: WithOtherFields<TransactionRequest>,
2910 nonce: u64,
2911 ) -> Result<TypedTransactionRequest> {
2912 let chain_id = request.chain_id.unwrap_or_else(|| self.chain_id());
2913 let max_fee_per_gas = request.max_fee_per_gas;
2914 let max_fee_per_blob_gas = request.max_fee_per_blob_gas;
2915 let gas_price = request.gas_price;
2916
2917 let gas_limit = request.gas.unwrap_or_else(|| self.backend.gas_limit());
2918 let from = request.from;
2919
2920 let request = match transaction_request_to_typed(request) {
2921 Some(TypedTransactionRequest::Legacy(mut m)) => {
2922 m.nonce = nonce;
2923 m.chain_id = Some(chain_id);
2924 m.gas_limit = gas_limit;
2925 if gas_price.is_none() {
2926 m.gas_price = self.gas_price();
2927 }
2928 TypedTransactionRequest::Legacy(m)
2929 }
2930 Some(TypedTransactionRequest::EIP2930(mut m)) => {
2931 m.nonce = nonce;
2932 m.chain_id = chain_id;
2933 m.gas_limit = gas_limit;
2934 if gas_price.is_none() {
2935 m.gas_price = self.gas_price();
2936 }
2937 TypedTransactionRequest::EIP2930(m)
2938 }
2939 Some(TypedTransactionRequest::EIP1559(mut m)) => {
2940 m.nonce = nonce;
2941 m.chain_id = chain_id;
2942 m.gas_limit = gas_limit;
2943 if max_fee_per_gas.is_none() {
2944 m.max_fee_per_gas = self.gas_price();
2945 }
2946 TypedTransactionRequest::EIP1559(m)
2947 }
2948 Some(TypedTransactionRequest::EIP4844(m)) => {
2949 TypedTransactionRequest::EIP4844(match m {
2950 TxEip4844Variant::TxEip4844WithSidecar(mut m) => {
2952 m.tx.nonce = nonce;
2953 m.tx.chain_id = chain_id;
2954 m.tx.gas_limit = gas_limit;
2955 if max_fee_per_gas.is_none() {
2956 m.tx.max_fee_per_gas = self.gas_price();
2957 }
2958 if max_fee_per_blob_gas.is_none() {
2959 m.tx.max_fee_per_blob_gas = self
2960 .excess_blob_gas_and_price()
2961 .unwrap_or_default()
2962 .map_or(0, |g| g.blob_gasprice)
2963 }
2964 TxEip4844Variant::TxEip4844WithSidecar(m)
2965 }
2966 TxEip4844Variant::TxEip4844(mut tx) => {
2967 if !self.backend.skip_blob_validation(from) {
2968 return Err(BlockchainError::FailedToDecodeTransaction)
2969 }
2970
2971 tx.nonce = nonce;
2973 tx.chain_id = chain_id;
2974 tx.gas_limit = gas_limit;
2975 if max_fee_per_gas.is_none() {
2976 tx.max_fee_per_gas = self.gas_price();
2977 }
2978 if max_fee_per_blob_gas.is_none() {
2979 tx.max_fee_per_blob_gas = self
2980 .excess_blob_gas_and_price()
2981 .unwrap_or_default()
2982 .map_or(0, |g| g.blob_gasprice)
2983 }
2984
2985 TxEip4844Variant::TxEip4844(tx)
2986 }
2987 })
2988 }
2989 Some(TypedTransactionRequest::Deposit(mut m)) => {
2990 m.gas_limit = gas_limit;
2991 TypedTransactionRequest::Deposit(m)
2992 }
2993 None => return Err(BlockchainError::FailedToDecodeTransaction),
2994 };
2995 Ok(request)
2996 }
2997
2998 pub fn is_impersonated(&self, addr: Address) -> bool {
3000 self.backend.cheats().is_impersonated(addr)
3001 }
3002
3003 fn impersonated_signature(&self, request: &TypedTransactionRequest) -> Signature {
3005 match request {
3006 TypedTransactionRequest::Legacy(_) => Signature::from_scalars_and_parity(
3009 B256::with_last_byte(1),
3010 B256::with_last_byte(1),
3011 false,
3012 ),
3013 TypedTransactionRequest::EIP2930(_) |
3014 TypedTransactionRequest::EIP1559(_) |
3015 TypedTransactionRequest::EIP4844(_) |
3016 TypedTransactionRequest::Deposit(_) => Signature::from_scalars_and_parity(
3017 B256::with_last_byte(1),
3018 B256::with_last_byte(1),
3019 false,
3020 ),
3021 }
3022 }
3023
3024 async fn get_transaction_count(
3026 &self,
3027 address: Address,
3028 block_number: Option<BlockId>,
3029 ) -> Result<u64> {
3030 let block_request = self.block_request(block_number).await?;
3031
3032 if let BlockRequest::Number(number) = block_request {
3033 if let Some(fork) = self.get_fork() {
3034 if fork.predates_fork(number) {
3035 return Ok(fork.get_nonce(address, number).await?)
3036 }
3037 }
3038 }
3039
3040 self.backend.get_nonce(address, block_request).await
3041 }
3042
3043 async fn request_nonce(
3051 &self,
3052 request: &TransactionRequest,
3053 from: Address,
3054 ) -> Result<(u64, u64)> {
3055 let highest_nonce =
3056 self.get_transaction_count(from, Some(BlockId::Number(BlockNumber::Pending))).await?;
3057 let nonce = request.nonce.unwrap_or(highest_nonce);
3058
3059 Ok((nonce, highest_nonce))
3060 }
3061
3062 fn add_pending_transaction(
3064 &self,
3065 pending_transaction: PendingTransaction,
3066 requires: Vec<TxMarker>,
3067 provides: Vec<TxMarker>,
3068 ) -> Result<TxHash> {
3069 let from = *pending_transaction.sender();
3070 let priority = self.transaction_priority(&pending_transaction.transaction);
3071 let pool_transaction =
3072 PoolTransaction { requires, provides, pending_transaction, priority };
3073 let tx = self.pool.add_transaction(pool_transaction)?;
3074 trace!(target: "node", "Added transaction: [{:?}] sender={:?}", tx.hash(), from);
3075 Ok(*tx.hash())
3076 }
3077
3078 pub async fn state_root(&self) -> Option<B256> {
3080 self.backend.get_db().read().await.maybe_state_root()
3081 }
3082
3083 fn ensure_typed_transaction_supported(&self, tx: &TypedTransaction) -> Result<()> {
3085 match &tx {
3086 TypedTransaction::EIP2930(_) => self.backend.ensure_eip2930_active(),
3087 TypedTransaction::EIP1559(_) => self.backend.ensure_eip1559_active(),
3088 TypedTransaction::EIP4844(_) => self.backend.ensure_eip4844_active(),
3089 TypedTransaction::EIP7702(_) => self.backend.ensure_eip7702_active(),
3090 TypedTransaction::Deposit(_) => self.backend.ensure_op_deposits_active(),
3091 TypedTransaction::Legacy(_) => Ok(()),
3092 }
3093 }
3094}
3095
3096fn required_marker(provided_nonce: u64, on_chain_nonce: u64, from: Address) -> Vec<TxMarker> {
3097 if provided_nonce == on_chain_nonce {
3098 return Vec::new();
3099 }
3100 let prev_nonce = provided_nonce.saturating_sub(1);
3101 if on_chain_nonce <= prev_nonce {
3102 vec![to_marker(prev_nonce, from)]
3103 } else {
3104 Vec::new()
3105 }
3106}
3107
3108fn convert_transact_out(out: &Option<Output>) -> Bytes {
3109 match out {
3110 None => Default::default(),
3111 Some(Output::Call(out)) => out.to_vec().into(),
3112 Some(Output::Create(out, _)) => out.to_vec().into(),
3113 }
3114}
3115
3116fn ensure_return_ok(exit: InstructionResult, out: &Option<Output>) -> Result<Bytes> {
3118 let out = convert_transact_out(out);
3119 match exit {
3120 return_ok!() => Ok(out),
3121 return_revert!() => Err(InvalidTransactionError::Revert(Some(out.0.into())).into()),
3122 reason => Err(BlockchainError::EvmError(reason)),
3123 }
3124}
3125
3126fn determine_base_gas_by_kind(request: &WithOtherFields<TransactionRequest>) -> u128 {
3128 match transaction_request_to_typed(request.clone()) {
3129 Some(request) => match request {
3130 TypedTransactionRequest::Legacy(req) => match req.to {
3131 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3132 TxKind::Create => MIN_CREATE_GAS,
3133 },
3134 TypedTransactionRequest::EIP1559(req) => match req.to {
3135 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3136 TxKind::Create => MIN_CREATE_GAS,
3137 },
3138 TypedTransactionRequest::EIP2930(req) => match req.to {
3139 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3140 TxKind::Create => MIN_CREATE_GAS,
3141 },
3142 TypedTransactionRequest::EIP4844(_) => MIN_TRANSACTION_GAS,
3143 TypedTransactionRequest::Deposit(req) => match req.to {
3144 TxKind::Call(_) => MIN_TRANSACTION_GAS,
3145 TxKind::Create => MIN_CREATE_GAS,
3146 },
3147 },
3148 _ => MIN_CREATE_GAS,
3151 }
3152}
3153
3154enum GasEstimationCallResult {
3156 Success(u128),
3157 OutOfGas,
3158 Revert(Option<Bytes>),
3159 EvmError(InstructionResult),
3160}
3161
3162impl TryFrom<Result<(InstructionResult, Option<Output>, u128, State)>> for GasEstimationCallResult {
3164 type Error = BlockchainError;
3165
3166 fn try_from(res: Result<(InstructionResult, Option<Output>, u128, State)>) -> Result<Self> {
3167 match res {
3168 Err(BlockchainError::InvalidTransaction(InvalidTransactionError::GasTooHigh(_))) => {
3170 Ok(Self::OutOfGas)
3171 }
3172 Err(err) => Err(err),
3173 Ok((exit, output, gas, _)) => match exit {
3174 return_ok!() | InstructionResult::CallOrCreate => Ok(Self::Success(gas)),
3175
3176 InstructionResult::Revert => Ok(Self::Revert(output.map(|o| o.into_data()))),
3177
3178 InstructionResult::OutOfGas |
3179 InstructionResult::MemoryOOG |
3180 InstructionResult::MemoryLimitOOG |
3181 InstructionResult::PrecompileOOG |
3182 InstructionResult::InvalidOperandOOG => Ok(Self::OutOfGas),
3183
3184 InstructionResult::OpcodeNotFound |
3185 InstructionResult::CallNotAllowedInsideStatic |
3186 InstructionResult::StateChangeDuringStaticCall |
3187 InstructionResult::InvalidExtDelegateCallTarget |
3188 InstructionResult::InvalidEXTCALLTarget |
3189 InstructionResult::InvalidFEOpcode |
3190 InstructionResult::InvalidJump |
3191 InstructionResult::NotActivated |
3192 InstructionResult::StackUnderflow |
3193 InstructionResult::StackOverflow |
3194 InstructionResult::OutOfOffset |
3195 InstructionResult::CreateCollision |
3196 InstructionResult::OverflowPayment |
3197 InstructionResult::PrecompileError |
3198 InstructionResult::NonceOverflow |
3199 InstructionResult::CreateContractSizeLimit |
3200 InstructionResult::CreateContractStartingWithEF |
3201 InstructionResult::CreateInitCodeSizeLimit |
3202 InstructionResult::FatalExternalError |
3203 InstructionResult::OutOfFunds |
3204 InstructionResult::CallTooDeep => Ok(Self::EvmError(exit)),
3205
3206 InstructionResult::ReturnContractInNotInitEOF |
3208 InstructionResult::EOFOpcodeDisabledInLegacy |
3209 InstructionResult::EOFFunctionStackOverflow |
3210 InstructionResult::CreateInitCodeStartingEF00 |
3211 InstructionResult::InvalidEOFInitCode |
3212 InstructionResult::EofAuxDataOverflow |
3213 InstructionResult::EofAuxDataTooSmall => Ok(Self::EvmError(exit)),
3214 },
3215 }
3216 }
3217}