1use core::fmt;
5
6use super::{LoadBlock, LoadPendingBlock, LoadState, LoadTransaction, SpawnBlocking, Trace};
7use crate::{
8 helpers::estimate::EstimateCall, FromEvmError, FullEthApiTypes, RpcBlock, RpcNodeCore,
9};
10use alloy_consensus::{transaction::TxHashRef, BlockHeader};
11use alloy_eips::eip2930::AccessListResult;
12use alloy_evm::overrides::{apply_block_overrides, apply_state_overrides, OverrideBlockHashes};
13use alloy_network::TransactionBuilder;
14use alloy_primitives::{Bytes, B256, U256};
15use alloy_rpc_types_eth::{
16 simulate::{SimBlock, SimulatePayload, SimulatedBlock},
17 state::{EvmOverrides, StateOverride},
18 BlockId, Bundle, EthCallResponse, StateContext, TransactionInfo,
19};
20use futures::Future;
21use reth_errors::{ProviderError, RethError};
22use reth_evm::{
23 block::BlockExecutor, env::BlockEnvironment, execute::BlockBuilder, ConfigureEvm, Evm,
24 EvmEnvFor, HaltReasonFor, InspectorFor, TransactionEnv, TxEnvFor,
25};
26use reth_node_api::BlockBody;
27use reth_primitives_traits::Recovered;
28use reth_revm::{
29 cancelled::CancelOnDrop,
30 database::StateProviderDatabase,
31 db::{bal::EvmDatabaseError, State},
32};
33use reth_rpc_convert::{RpcConvert, RpcTxReq};
34use reth_rpc_eth_types::{
35 cache::db::StateProviderTraitObjWrapper,
36 error::{AsEthApiError, FromEthApiError},
37 simulate::{self, EthSimulateError},
38 EthApiError, StateCacheDb,
39};
40use reth_storage_api::{BlockIdReader, ProviderTx, StateProviderBox};
41use revm::{
42 context::Block,
43 context_interface::{result::ResultAndState, Transaction},
44 Database, DatabaseCommit,
45};
46use revm_inspectors::{access_list::AccessListInspector, transfer::TransferInspector};
47use tracing::{trace, warn};
48
49pub type SimulatedBlocksResult<N, E> = Result<Vec<SimulatedBlock<RpcBlock<N>>>, E>;
51
52pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthApiTypes {
55 fn estimate_gas_at(
57 &self,
58 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
59 at: BlockId,
60 state_override: Option<StateOverride>,
61 ) -> impl Future<Output = Result<U256, Self::Error>> + Send {
62 EstimateCall::estimate_gas_at(self, request, at, state_override)
63 }
64
65 fn simulate_v1(
70 &self,
71 payload: SimulatePayload<RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>>,
72 block: Option<BlockId>,
73 ) -> impl Future<Output = SimulatedBlocksResult<Self::NetworkTypes, Self::Error>> + Send {
74 async move {
75 if payload.block_state_calls.len() > self.max_simulate_blocks() as usize {
76 return Err(EthApiError::other(EthSimulateError::TooManyBlocks).into())
77 }
78
79 let block = block.unwrap_or_default();
80
81 let SimulatePayload {
82 block_state_calls,
83 trace_transfers,
84 validation,
85 return_full_transactions,
86 } = payload;
87
88 if block_state_calls.is_empty() {
89 return Err(EthApiError::InvalidParams(String::from("calls are empty.")).into())
90 }
91
92 let base_block =
93 self.recovered_block(block).await?.ok_or(EthApiError::HeaderNotFound(block))?;
94 let mut parent = base_block.sealed_header().clone();
95
96 self.spawn_with_state_at_block(block, move |this, mut db| {
97 let mut blocks: Vec<SimulatedBlock<RpcBlock<Self::NetworkTypes>>> =
98 Vec::with_capacity(block_state_calls.len());
99
100 let mut prev_block_number = parent.number();
102 let mut prev_timestamp = parent.timestamp();
103
104 for block in block_state_calls {
105 if let Some(number) = block.block_overrides.as_ref().and_then(|o| o.number) {
107 let number: u64 = number.try_into().unwrap_or(u64::MAX);
108 if number <= prev_block_number {
109 return Err(EthApiError::other(EthSimulateError::BlockNumberInvalid {
110 got: number,
111 parent: prev_block_number,
112 })
113 .into());
114 }
115 }
116 if let Some(time) = block
118 .block_overrides
119 .as_ref()
120 .and_then(|o| o.time)
121 .filter(|&t| t <= prev_timestamp)
122 {
123 return Err(EthApiError::other(EthSimulateError::BlockTimestampInvalid {
124 got: time,
125 parent: prev_timestamp,
126 })
127 .into());
128 }
129
130 let attributes = this.next_env_attributes(&parent)?;
131
132 let mut evm_env = this
133 .evm_config()
134 .next_evm_env(&parent, &attributes)
135 .map_err(RethError::other)
136 .map_err(Self::Error::from_eth_err)?;
137
138 evm_env.cfg_env.disable_eip3607 = true;
140
141 if !validation {
142 evm_env.cfg_env.disable_nonce_check = true;
144 evm_env.cfg_env.disable_base_fee = true;
145 evm_env.cfg_env.tx_gas_limit_cap = Some(u64::MAX);
146 evm_env.block_env.inner_mut().basefee = 0;
147 }
148
149 let SimBlock { block_overrides, state_overrides, calls } = block;
150
151 evm_env.block_env.inner_mut().prevrandao = Some(B256::ZERO);
155
156 if let Some(block_overrides) = block_overrides {
157 if let Some(gas_limit_override) = block_overrides.gas_limit &&
159 gas_limit_override > evm_env.block_env.gas_limit() &&
160 gas_limit_override > this.call_gas_limit()
161 {
162 return Err(EthApiError::other(EthSimulateError::GasLimitReached).into())
163 }
164 apply_block_overrides(
165 block_overrides,
166 &mut db,
167 evm_env.block_env.inner_mut(),
168 );
169 }
170 if let Some(ref state_overrides) = state_overrides {
171 apply_state_overrides(state_overrides.clone(), &mut db)
172 .map_err(Self::Error::from_eth_err)?;
173 }
174
175 let block_gas_limit = evm_env.block_env.gas_limit();
176 let chain_id = evm_env.cfg_env.chain_id;
177
178 let default_gas_limit = {
179 let total_specified_gas =
180 calls.iter().filter_map(|tx| tx.as_ref().gas_limit()).sum::<u64>();
181 let txs_without_gas_limit =
182 calls.iter().filter(|tx| tx.as_ref().gas_limit().is_none()).count();
183
184 if total_specified_gas > block_gas_limit {
185 return Err(EthApiError::Other(Box::new(
186 EthSimulateError::BlockGasLimitExceeded,
187 ))
188 .into())
189 }
190
191 if txs_without_gas_limit > 0 {
192 let gas_per_tx = (block_gas_limit - total_specified_gas) /
195 txs_without_gas_limit as u64;
196 let call_gas_limit = this.call_gas_limit();
198 if call_gas_limit > 0 {
199 gas_per_tx.min(call_gas_limit)
200 } else {
201 gas_per_tx
202 }
203 } else {
204 0
205 }
206 };
207
208 let ctx = this
209 .evm_config()
210 .context_for_next_block(&parent, attributes)
211 .map_err(RethError::other)
212 .map_err(Self::Error::from_eth_err)?;
213 let map_err = |e: EthApiError| -> Self::Error {
214 match e.as_simulate_error() {
215 Some(sim_err) => Self::Error::from_eth_err(EthApiError::other(sim_err)),
216 None => Self::Error::from_eth_err(e),
217 }
218 };
219
220 let (result, results) = if trace_transfers {
221 let inspector = TransferInspector::new(false).with_logs(true);
224 let evm = this
225 .evm_config()
226 .evm_with_env_and_inspector(&mut db, evm_env, inspector);
227 let mut builder = this.evm_config().create_block_builder(evm, &parent, ctx);
228
229 if let Some(ref state_overrides) = state_overrides {
230 simulate::apply_precompile_overrides(
231 state_overrides,
232 builder.evm_mut().precompiles_mut(),
233 )
234 .map_err(|e| Self::Error::from_eth_err(EthApiError::other(e)))?;
235 }
236
237 simulate::execute_transactions(
238 builder,
239 calls,
240 default_gas_limit,
241 chain_id,
242 this.converter(),
243 )
244 .map_err(map_err)?
245 } else {
246 let evm = this.evm_config().evm_with_env(&mut db, evm_env);
247 let mut builder = this.evm_config().create_block_builder(evm, &parent, ctx);
248
249 if let Some(ref state_overrides) = state_overrides {
250 simulate::apply_precompile_overrides(
251 state_overrides,
252 builder.evm_mut().precompiles_mut(),
253 )
254 .map_err(|e| Self::Error::from_eth_err(EthApiError::other(e)))?;
255 }
256
257 simulate::execute_transactions(
258 builder,
259 calls,
260 default_gas_limit,
261 chain_id,
262 this.converter(),
263 )
264 .map_err(map_err)?
265 };
266
267 parent = result.block.clone_sealed_header();
268
269 prev_block_number = parent.number();
271 prev_timestamp = parent.timestamp();
272
273 let block = simulate::build_simulated_block::<Self::Error, _>(
274 result.block,
275 results,
276 return_full_transactions.into(),
277 this.converter(),
278 )?;
279
280 blocks.push(block);
281 }
282
283 Ok(blocks)
284 })
285 .await
286 }
287 }
288
289 fn call(
291 &self,
292 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
293 block_number: Option<BlockId>,
294 overrides: EvmOverrides,
295 ) -> impl Future<Output = Result<Bytes, Self::Error>> + Send {
296 async move {
297 let _permit = self.acquire_owned_blocking_io().await;
298 let res =
299 self.transact_call_at(request, block_number.unwrap_or_default(), overrides).await?;
300
301 Self::Error::ensure_success(res.result)
302 }
303 }
304
305 fn call_many(
308 &self,
309 bundles: Vec<Bundle<RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>>>,
310 state_context: Option<StateContext>,
311 mut state_override: Option<StateOverride>,
312 ) -> impl Future<Output = Result<Vec<Vec<EthCallResponse>>, Self::Error>> + Send {
313 async move {
314 if bundles.is_empty() {
316 return Err(EthApiError::InvalidParams(String::from("bundles are empty.")).into());
317 }
318
319 let StateContext { transaction_index, block_number } =
320 state_context.unwrap_or_default();
321 let transaction_index = transaction_index.unwrap_or_default();
322
323 let mut target_block = block_number.unwrap_or_default();
324 let is_block_target_pending = target_block.is_pending();
325
326 if !is_block_target_pending {
329 let Some(block_hash) = self
330 .provider()
331 .block_hash_for_id(target_block)
332 .map_err(Self::Error::from_eth_err::<ProviderError>)?
333 else {
334 return Err(EthApiError::HeaderNotFound(target_block).into())
335 };
336 target_block = block_hash.into();
337 }
338
339 let block = self
340 .recovered_block(target_block)
341 .await?
342 .ok_or(EthApiError::HeaderNotFound(target_block))?;
343 let evm_env = self.evm_env_for_header(block.sealed_block().sealed_header())?;
344
345 let mut at = block.parent_hash();
349 let mut replay_block_txs = true;
350
351 let num_txs =
352 transaction_index.index().unwrap_or_else(|| block.body().transactions().len());
353 if !is_block_target_pending && num_txs == block.body().transactions().len() {
357 at = block.hash();
358 replay_block_txs = false;
359 }
360
361 self.spawn_with_state_at_block(at, move |this, mut db| {
362 let mut all_results = Vec::with_capacity(bundles.len());
363
364 if replay_block_txs {
365 let mut executor = RpcNodeCore::evm_config(&this)
366 .executor_for_block(&mut db, block.sealed_block())
367 .map_err(RethError::other)
368 .map_err(Self::Error::from_eth_err)?;
369 executor.apply_pre_execution_changes().map_err(Self::Error::from_eth_err)?;
370 for tx in block.transactions_recovered().take(num_txs) {
371 executor.execute_transaction(tx).map_err(Self::Error::from_eth_err)?;
372 }
373 }
374
375 for (bundle_index, bundle) in bundles.into_iter().enumerate() {
377 let Bundle { transactions, block_override } = bundle;
378 if transactions.is_empty() {
379 continue;
381 }
382
383 let mut bundle_results = Vec::with_capacity(transactions.len());
384 let block_overrides = block_override.map(Box::new);
385
386 for (tx_index, tx) in transactions.into_iter().enumerate() {
388 let overrides =
391 EvmOverrides::new(state_override.take(), block_overrides.clone());
392
393 let (current_evm_env, prepared_tx) = this
394 .prepare_call_env(evm_env.clone(), tx, &mut db, overrides)
395 .map_err(|err| {
396 Self::Error::from_eth_err(EthApiError::call_many_error(
397 bundle_index,
398 tx_index,
399 err.into(),
400 ))
401 })?;
402 let res = this.transact(&mut db, current_evm_env, prepared_tx).map_err(
403 |err| {
404 Self::Error::from_eth_err(EthApiError::call_many_error(
405 bundle_index,
406 tx_index,
407 err.into(),
408 ))
409 },
410 )?;
411
412 match Self::Error::ensure_success(res.result) {
413 Ok(output) => {
414 bundle_results
415 .push(EthCallResponse { value: Some(output), error: None });
416 }
417 Err(err) => {
418 bundle_results.push(EthCallResponse {
419 value: None,
420 error: Some(err.to_string()),
421 });
422 }
423 }
424
425 db.commit(res.state);
428 }
429
430 all_results.push(bundle_results);
431 }
432
433 Ok(all_results)
434 })
435 .await
436 }
437 }
438
439 fn create_access_list_at(
442 &self,
443 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
444 block_number: Option<BlockId>,
445 state_override: Option<StateOverride>,
446 ) -> impl Future<Output = Result<AccessListResult, Self::Error>> + Send
447 where
448 Self: Trace,
449 {
450 async move {
451 let block_id = block_number.unwrap_or_default();
452 let (evm_env, at) = self.evm_env_at(block_id).await?;
453
454 self.spawn_blocking_io_fut(async move |this| {
455 this.create_access_list_with(evm_env, at, request, state_override).await
456 })
457 .await
458 }
459 }
460
461 fn create_access_list_with(
464 &self,
465 mut evm_env: EvmEnvFor<Self::Evm>,
466 at: BlockId,
467 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
468 state_override: Option<StateOverride>,
469 ) -> impl Future<Output = Result<AccessListResult, Self::Error>> + Send
470 where
471 Self: Trace,
472 {
473 self.spawn_blocking_io_fut(async move |this| {
474 let state = this.state_at_block_id(at).await?;
475 let mut db = State::builder().with_database(StateProviderDatabase::new(state)).build();
476
477 if let Some(state_overrides) = state_override {
478 apply_state_overrides(state_overrides, &mut db)
479 .map_err(Self::Error::from_eth_err)?;
480 }
481
482 let request_has_gas_limit = request.as_ref().gas_limit().is_some();
484 let initial = request.as_ref().access_list().cloned().unwrap_or_default();
485
486 let mut tx_env = this.create_txn_env(&evm_env, request, &mut db)?;
487
488 evm_env.cfg_env.disable_block_gas_limit = true;
491
492 evm_env.cfg_env.disable_base_fee = true;
496
497 evm_env.cfg_env.disable_eip3607 = true;
499
500 evm_env.cfg_env.disable_fee_charge = true;
503
504 evm_env.cfg_env.tx_gas_limit_cap = Some(u64::MAX);
508
509 if !request_has_gas_limit && tx_env.gas_price() > 0 {
510 let cap = this.caller_gas_allowance(&mut db, &evm_env, &tx_env)?;
511 tx_env.set_gas_limit(cap.min(evm_env.block_env.gas_limit()));
514 }
515
516 let mut inspector = AccessListInspector::new(initial);
517
518 let result = this.inspect(&mut db, evm_env.clone(), tx_env.clone(), &mut inspector)?;
519 let access_list = inspector.into_access_list();
520 let gas_used = result.result.gas_used();
521 tx_env.set_access_list(access_list.clone());
522 if let Err(err) = Self::Error::ensure_success(result.result) {
523 return Ok(AccessListResult {
524 access_list,
525 gas_used: U256::from(gas_used),
526 error: Some(err.to_string()),
527 });
528 }
529
530 let result = this.transact(&mut db, evm_env, tx_env)?;
532 let gas_used = result.result.gas_used();
533 let error = Self::Error::ensure_success(result.result).err().map(|e| e.to_string());
534
535 Ok(AccessListResult { access_list, gas_used: U256::from(gas_used), error })
536 })
537 }
538}
539
540pub trait Call:
542 LoadState<
543 RpcConvert: RpcConvert<Evm = Self::Evm>,
544 Error: FromEvmError<Self::Evm>
545 + From<<Self::RpcConvert as RpcConvert>::Error>
546 + From<ProviderError>,
547 > + SpawnBlocking
548{
549 fn call_gas_limit(&self) -> u64;
553
554 fn max_simulate_blocks(&self) -> u64;
556
557 fn evm_memory_limit(&self) -> u64;
559
560 fn caller_gas_allowance(
562 &self,
563 mut db: impl Database<Error: Into<EthApiError>>,
564 _evm_env: &EvmEnvFor<Self::Evm>,
565 tx_env: &TxEnvFor<Self::Evm>,
566 ) -> Result<u64, Self::Error> {
567 alloy_evm::call::caller_gas_allowance(&mut db, tx_env).map_err(Self::Error::from_eth_err)
568 }
569
570 fn with_state_at_block<F, R>(
572 &self,
573 at: BlockId,
574 f: F,
575 ) -> impl Future<Output = Result<R, Self::Error>> + Send
576 where
577 R: Send + 'static,
578 F: FnOnce(Self, StateProviderBox) -> Result<R, Self::Error> + Send + 'static,
579 {
580 self.spawn_blocking_io_fut(async move |this| {
581 let state = this.state_at_block_id(at).await?;
582 f(this, state)
583 })
584 }
585
586 fn transact<DB>(
589 &self,
590 db: DB,
591 evm_env: EvmEnvFor<Self::Evm>,
592 tx_env: TxEnvFor<Self::Evm>,
593 ) -> Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>
594 where
595 DB: Database<Error = EvmDatabaseError<ProviderError>> + fmt::Debug,
596 {
597 let mut evm = self.evm_config().evm_with_env(db, evm_env);
598 let res = evm.transact(tx_env).map_err(Self::Error::from_evm_err)?;
599
600 Ok(res)
601 }
602
603 fn transact_with_inspector<DB, I>(
606 &self,
607 db: DB,
608 evm_env: EvmEnvFor<Self::Evm>,
609 tx_env: TxEnvFor<Self::Evm>,
610 inspector: I,
611 ) -> Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>
612 where
613 DB: Database<Error = EvmDatabaseError<ProviderError>> + fmt::Debug,
614 I: InspectorFor<Self::Evm, DB>,
615 {
616 let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env, inspector);
617 let res = evm.transact(tx_env).map_err(Self::Error::from_evm_err)?;
618
619 Ok(res)
620 }
621
622 fn transact_call_at(
629 &self,
630 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
631 at: BlockId,
632 overrides: EvmOverrides,
633 ) -> impl Future<Output = Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>> + Send
634 where
635 Self: LoadPendingBlock,
636 {
637 async move {
638 let guard = CancelOnDrop::default();
639 let cancel = guard.clone();
640 let this = self.clone();
641
642 let res = self
643 .spawn_with_call_at(request, at, overrides, move |db, evm_env, tx_env| {
644 if cancel.is_cancelled() {
645 return Err(EthApiError::InternalEthError.into())
647 }
648 this.transact(db, evm_env, tx_env)
649 })
650 .await;
651 drop(guard);
652 res
653 }
654 }
655
656 fn spawn_with_state_at_block<F, R>(
658 &self,
659 at: impl Into<BlockId>,
660 f: F,
661 ) -> impl Future<Output = Result<R, Self::Error>> + Send
662 where
663 F: FnOnce(Self, StateCacheDb) -> Result<R, Self::Error> + Send + 'static,
664 R: Send + 'static,
665 {
666 let at = at.into();
667 self.spawn_blocking_io_fut(async move |this| {
668 let state = this.state_at_block_id(at).await?;
669 let db = State::builder()
670 .with_database(StateProviderDatabase::new(StateProviderTraitObjWrapper(state)))
671 .build();
672 f(this, db)
673 })
674 }
675
676 fn spawn_with_call_at<F, R>(
692 &self,
693 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
694 at: BlockId,
695 overrides: EvmOverrides,
696 f: F,
697 ) -> impl Future<Output = Result<R, Self::Error>> + Send
698 where
699 Self: LoadPendingBlock,
700 F: FnOnce(
701 &mut StateCacheDb,
702 EvmEnvFor<Self::Evm>,
703 TxEnvFor<Self::Evm>,
704 ) -> Result<R, Self::Error>
705 + Send
706 + 'static,
707 R: Send + 'static,
708 {
709 async move {
710 let (evm_env, at) = self.evm_env_at(at).await?;
711 self.spawn_with_state_at_block(at, move |this, mut db| {
712 let (evm_env, tx_env) =
713 this.prepare_call_env(evm_env, request, &mut db, overrides)?;
714
715 f(&mut db, evm_env, tx_env)
716 })
717 .await
718 }
719 }
720
721 fn spawn_replay_transaction<F, R>(
731 &self,
732 hash: B256,
733 f: F,
734 ) -> impl Future<Output = Result<Option<R>, Self::Error>> + Send
735 where
736 Self: LoadBlock + LoadTransaction,
737 F: FnOnce(
738 TransactionInfo,
739 ResultAndState<HaltReasonFor<Self::Evm>>,
740 StateCacheDb,
741 ) -> Result<R, Self::Error>
742 + Send
743 + 'static,
744 R: Send + 'static,
745 {
746 async move {
747 let (transaction, block) = match self.transaction_and_block(hash).await? {
748 None => return Ok(None),
749 Some(res) => res,
750 };
751 let (tx, tx_info) = transaction.split();
752
753 let parent_block = block.parent_hash();
756
757 self.spawn_with_state_at_block(parent_block, move |this, mut db| {
758 let block_txs = block.transactions_recovered();
759
760 let mut executor = RpcNodeCore::evm_config(&this)
761 .executor_for_block(&mut db, block.sealed_block())
762 .map_err(RethError::other)
763 .map_err(Self::Error::from_eth_err)?;
764 executor.apply_pre_execution_changes().map_err(Self::Error::from_eth_err)?;
765
766 for block_tx in block_txs {
768 if block_tx.tx_hash() == tx.tx_hash() {
769 break;
770 }
771 executor.execute_transaction(block_tx).map_err(Self::Error::from_eth_err)?;
772 }
773
774 let tx_env = RpcNodeCore::evm_config(&this).tx_env(tx);
775
776 let res = executor.evm_mut().transact(tx_env).map_err(Self::Error::from_evm_err)?;
777 drop(executor);
778 f(tx_info, res, db)
779 })
780 .await
781 .map(Some)
782 }
783 }
784
785 fn replay_transactions_until<'a, DB, I>(
793 &self,
794 db: &mut DB,
795 evm_env: EvmEnvFor<Self::Evm>,
796 transactions: I,
797 target_tx_hash: B256,
798 ) -> Result<usize, Self::Error>
799 where
800 DB: Database<Error = EvmDatabaseError<ProviderError>> + DatabaseCommit + core::fmt::Debug,
801 I: IntoIterator<Item = Recovered<&'a ProviderTx<Self::Provider>>>,
802 {
803 let mut evm = self.evm_config().evm_with_env(db, evm_env);
804 let mut index = 0;
805 for tx in transactions {
806 if *tx.tx_hash() == target_tx_hash {
807 break
809 }
810
811 let tx_env = self.evm_config().tx_env(tx);
812 evm.transact_commit(tx_env).map_err(Self::Error::from_evm_err)?;
813 index += 1;
814 }
815 Ok(index)
816 }
817
818 fn create_txn_env(
822 &self,
823 evm_env: &EvmEnvFor<Self::Evm>,
824 mut request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
825 mut db: impl Database<Error: Into<EthApiError>>,
826 ) -> Result<TxEnvFor<Self::Evm>, Self::Error> {
827 if request.as_ref().nonce().is_none() {
828 let nonce = db
829 .basic(request.as_ref().from().unwrap_or_default())
830 .map_err(Into::into)?
831 .map(|acc| acc.nonce)
832 .unwrap_or_default();
833 request.as_mut().set_nonce(nonce);
834 }
835
836 Ok(self.converter().tx_env(request, evm_env)?)
837 }
838
839 #[expect(clippy::type_complexity)]
853 fn prepare_call_env<DB>(
854 &self,
855 mut evm_env: EvmEnvFor<Self::Evm>,
856 mut request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
857 db: &mut DB,
858 overrides: EvmOverrides,
859 ) -> Result<(EvmEnvFor<Self::Evm>, TxEnvFor<Self::Evm>), Self::Error>
860 where
861 DB: Database + DatabaseCommit + OverrideBlockHashes,
862 EthApiError: From<<DB as Database>::Error>,
863 {
864 let request_has_gas_limit = request.as_ref().gas_limit().is_some();
866
867 if let Some(requested_gas) = request.as_ref().gas_limit() {
868 let global_gas_cap = self.call_gas_limit();
869 if global_gas_cap != 0 && global_gas_cap < requested_gas {
870 warn!(target: "rpc::eth::call", ?request, ?global_gas_cap, "Capping gas limit to global gas cap");
871 request.as_mut().set_gas_limit(global_gas_cap);
872 }
873 } else {
874 request.as_mut().set_gas_limit(self.call_gas_limit());
876 }
877
878 evm_env.cfg_env.disable_block_gas_limit = true;
881
882 evm_env.cfg_env.disable_eip3607 = true;
885
886 evm_env.cfg_env.disable_base_fee = true;
890
891 evm_env.cfg_env.tx_gas_limit_cap = Some(u64::MAX);
893
894 evm_env.cfg_env.disable_fee_charge = true;
898
899 evm_env.cfg_env.memory_limit = self.evm_memory_limit();
900
901 request.as_mut().take_nonce();
903
904 if let Some(block_overrides) = overrides.block {
905 apply_block_overrides(*block_overrides, db, evm_env.block_env.inner_mut());
906 }
907 if let Some(state_overrides) = overrides.state {
908 apply_state_overrides(state_overrides, db)
909 .map_err(EthApiError::from_state_overrides_err)?;
910 }
911
912 let mut tx_env = self.create_txn_env(&evm_env, request, &mut *db)?;
913
914 if tx_env.gas_price() == 0 {
916 evm_env.block_env.inner_mut().basefee = 0;
917 }
918
919 if !request_has_gas_limit {
920 if tx_env.gas_price() > 0 {
922 trace!(target: "rpc::eth::call", ?tx_env, "Applying gas limit cap with caller allowance");
924 let cap = self.caller_gas_allowance(db, &evm_env, &tx_env)?;
925 tx_env.set_gas_limit(cap.min(evm_env.block_env.gas_limit()));
927 }
928 }
929
930 Ok((evm_env, tx_env))
931 }
932}