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::InvalidParams("too many blocks.".to_string()).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 mut evm_env = this
131 .evm_config()
132 .next_evm_env(&parent, &this.next_env_attributes(&parent)?)
133 .map_err(RethError::other)
134 .map_err(Self::Error::from_eth_err)?;
135
136 evm_env.cfg_env.disable_eip3607 = true;
138
139 if !validation {
140 evm_env.cfg_env.disable_nonce_check = true;
142 evm_env.cfg_env.disable_base_fee = true;
143 evm_env.cfg_env.tx_gas_limit_cap = Some(u64::MAX);
144 evm_env.block_env.inner_mut().basefee = 0;
145 }
146
147 let SimBlock { block_overrides, state_overrides, calls } = block;
148
149 evm_env.block_env.inner_mut().prevrandao = Some(B256::ZERO);
153
154 if let Some(block_overrides) = block_overrides {
155 if let Some(gas_limit_override) = block_overrides.gas_limit &&
157 gas_limit_override > evm_env.block_env.gas_limit() &&
158 gas_limit_override > this.call_gas_limit()
159 {
160 return Err(EthApiError::other(EthSimulateError::GasLimitReached).into())
161 }
162 apply_block_overrides(
163 block_overrides,
164 &mut db,
165 evm_env.block_env.inner_mut(),
166 );
167 }
168 if let Some(ref state_overrides) = state_overrides {
169 apply_state_overrides(state_overrides.clone(), &mut db)
170 .map_err(Self::Error::from_eth_err)?;
171 }
172
173 let block_gas_limit = evm_env.block_env.gas_limit();
174 let chain_id = evm_env.cfg_env.chain_id;
175
176 let default_gas_limit = {
177 let total_specified_gas =
178 calls.iter().filter_map(|tx| tx.as_ref().gas_limit()).sum::<u64>();
179 let txs_without_gas_limit =
180 calls.iter().filter(|tx| tx.as_ref().gas_limit().is_none()).count();
181
182 if total_specified_gas > block_gas_limit {
183 return Err(EthApiError::Other(Box::new(
184 EthSimulateError::BlockGasLimitExceeded,
185 ))
186 .into())
187 }
188
189 if txs_without_gas_limit > 0 {
190 let gas_per_tx = (block_gas_limit - total_specified_gas) /
193 txs_without_gas_limit as u64;
194 let call_gas_limit = this.call_gas_limit();
196 if call_gas_limit > 0 {
197 gas_per_tx.min(call_gas_limit)
198 } else {
199 gas_per_tx
200 }
201 } else {
202 0
203 }
204 };
205
206 let ctx = this
207 .evm_config()
208 .context_for_next_block(&parent, this.next_env_attributes(&parent)?)
209 .map_err(RethError::other)
210 .map_err(Self::Error::from_eth_err)?;
211 let map_err = |e: EthApiError| -> Self::Error {
212 match e.as_simulate_error() {
213 Some(sim_err) => Self::Error::from_eth_err(EthApiError::other(sim_err)),
214 None => Self::Error::from_eth_err(e),
215 }
216 };
217
218 let (result, results) = if trace_transfers {
219 let inspector = TransferInspector::new(false).with_logs(true);
222 let evm = this
223 .evm_config()
224 .evm_with_env_and_inspector(&mut db, evm_env, inspector);
225 let mut builder = this.evm_config().create_block_builder(evm, &parent, ctx);
226
227 if let Some(ref state_overrides) = state_overrides {
228 simulate::apply_precompile_overrides(
229 state_overrides,
230 builder.evm_mut().precompiles_mut(),
231 )
232 .map_err(|e| Self::Error::from_eth_err(EthApiError::other(e)))?;
233 }
234
235 simulate::execute_transactions(
236 builder,
237 calls,
238 default_gas_limit,
239 chain_id,
240 this.converter(),
241 )
242 .map_err(map_err)?
243 } else {
244 let evm = this.evm_config().evm_with_env(&mut db, evm_env);
245 let mut builder = this.evm_config().create_block_builder(evm, &parent, ctx);
246
247 if let Some(ref state_overrides) = state_overrides {
248 simulate::apply_precompile_overrides(
249 state_overrides,
250 builder.evm_mut().precompiles_mut(),
251 )
252 .map_err(|e| Self::Error::from_eth_err(EthApiError::other(e)))?;
253 }
254
255 simulate::execute_transactions(
256 builder,
257 calls,
258 default_gas_limit,
259 chain_id,
260 this.converter(),
261 )
262 .map_err(map_err)?
263 };
264
265 parent = result.block.clone_sealed_header();
266
267 prev_block_number = parent.number();
269 prev_timestamp = parent.timestamp();
270
271 let block = simulate::build_simulated_block::<Self::Error, _>(
272 result.block,
273 results,
274 return_full_transactions.into(),
275 this.converter(),
276 )?;
277
278 blocks.push(block);
279 }
280
281 Ok(blocks)
282 })
283 .await
284 }
285 }
286
287 fn call(
289 &self,
290 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
291 block_number: Option<BlockId>,
292 overrides: EvmOverrides,
293 ) -> impl Future<Output = Result<Bytes, Self::Error>> + Send {
294 async move {
295 let _permit = self.acquire_owned_blocking_io().await;
296 let res =
297 self.transact_call_at(request, block_number.unwrap_or_default(), overrides).await?;
298
299 Self::Error::ensure_success(res.result)
300 }
301 }
302
303 fn call_many(
306 &self,
307 bundles: Vec<Bundle<RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>>>,
308 state_context: Option<StateContext>,
309 mut state_override: Option<StateOverride>,
310 ) -> impl Future<Output = Result<Vec<Vec<EthCallResponse>>, Self::Error>> + Send {
311 async move {
312 if bundles.is_empty() {
314 return Err(EthApiError::InvalidParams(String::from("bundles are empty.")).into());
315 }
316
317 let StateContext { transaction_index, block_number } =
318 state_context.unwrap_or_default();
319 let transaction_index = transaction_index.unwrap_or_default();
320
321 let mut target_block = block_number.unwrap_or_default();
322 let is_block_target_pending = target_block.is_pending();
323
324 if !is_block_target_pending {
327 let Some(block_hash) = self
328 .provider()
329 .block_hash_for_id(target_block)
330 .map_err(Self::Error::from_eth_err::<ProviderError>)?
331 else {
332 return Err(EthApiError::HeaderNotFound(target_block).into())
333 };
334 target_block = block_hash.into();
335 }
336
337 let block = self
338 .recovered_block(target_block)
339 .await?
340 .ok_or(EthApiError::HeaderNotFound(target_block))?;
341 let evm_env = self.evm_env_for_header(block.sealed_block().sealed_header())?;
342
343 let mut at = block.parent_hash();
347 let mut replay_block_txs = true;
348
349 let num_txs =
350 transaction_index.index().unwrap_or_else(|| block.body().transactions().len());
351 if !is_block_target_pending && num_txs == block.body().transactions().len() {
355 at = block.hash();
356 replay_block_txs = false;
357 }
358
359 self.spawn_with_state_at_block(at, move |this, mut db| {
360 let mut all_results = Vec::with_capacity(bundles.len());
361
362 if replay_block_txs {
363 let mut executor = RpcNodeCore::evm_config(&this)
364 .executor_for_block(&mut db, block.sealed_block())
365 .map_err(RethError::other)
366 .map_err(Self::Error::from_eth_err)?;
367 executor.apply_pre_execution_changes().map_err(Self::Error::from_eth_err)?;
368 for tx in block.transactions_recovered().take(num_txs) {
369 executor.execute_transaction(tx).map_err(Self::Error::from_eth_err)?;
370 }
371 }
372
373 for (bundle_index, bundle) in bundles.into_iter().enumerate() {
375 let Bundle { transactions, block_override } = bundle;
376 if transactions.is_empty() {
377 continue;
379 }
380
381 let mut bundle_results = Vec::with_capacity(transactions.len());
382 let block_overrides = block_override.map(Box::new);
383
384 for (tx_index, tx) in transactions.into_iter().enumerate() {
386 let overrides =
389 EvmOverrides::new(state_override.take(), block_overrides.clone());
390
391 let (current_evm_env, prepared_tx) = this
392 .prepare_call_env(evm_env.clone(), tx, &mut db, overrides)
393 .map_err(|err| {
394 Self::Error::from_eth_err(EthApiError::call_many_error(
395 bundle_index,
396 tx_index,
397 err.into(),
398 ))
399 })?;
400 let res = this.transact(&mut db, current_evm_env, prepared_tx).map_err(
401 |err| {
402 Self::Error::from_eth_err(EthApiError::call_many_error(
403 bundle_index,
404 tx_index,
405 err.into(),
406 ))
407 },
408 )?;
409
410 match Self::Error::ensure_success(res.result) {
411 Ok(output) => {
412 bundle_results
413 .push(EthCallResponse { value: Some(output), error: None });
414 }
415 Err(err) => {
416 bundle_results.push(EthCallResponse {
417 value: None,
418 error: Some(err.to_string()),
419 });
420 }
421 }
422
423 db.commit(res.state);
426 }
427
428 all_results.push(bundle_results);
429 }
430
431 Ok(all_results)
432 })
433 .await
434 }
435 }
436
437 fn create_access_list_at(
440 &self,
441 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
442 block_number: Option<BlockId>,
443 state_override: Option<StateOverride>,
444 ) -> impl Future<Output = Result<AccessListResult, Self::Error>> + Send
445 where
446 Self: Trace,
447 {
448 async move {
449 let block_id = block_number.unwrap_or_default();
450 let (evm_env, at) = self.evm_env_at(block_id).await?;
451
452 self.spawn_blocking_io_fut(async move |this| {
453 this.create_access_list_with(evm_env, at, request, state_override).await
454 })
455 .await
456 }
457 }
458
459 fn create_access_list_with(
462 &self,
463 mut evm_env: EvmEnvFor<Self::Evm>,
464 at: BlockId,
465 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
466 state_override: Option<StateOverride>,
467 ) -> impl Future<Output = Result<AccessListResult, Self::Error>> + Send
468 where
469 Self: Trace,
470 {
471 self.spawn_blocking_io_fut(async move |this| {
472 let state = this.state_at_block_id(at).await?;
473 let mut db = State::builder().with_database(StateProviderDatabase::new(state)).build();
474
475 if let Some(state_overrides) = state_override {
476 apply_state_overrides(state_overrides, &mut db)
477 .map_err(Self::Error::from_eth_err)?;
478 }
479
480 let mut tx_env = this.create_txn_env(&evm_env, request.clone(), &mut db)?;
481
482 evm_env.cfg_env.disable_block_gas_limit = true;
485
486 evm_env.cfg_env.disable_base_fee = true;
490
491 evm_env.cfg_env.disable_eip3607 = true;
493
494 if request.as_ref().gas_limit().is_none() && tx_env.gas_price() > 0 {
495 let cap = this.caller_gas_allowance(&mut db, &evm_env, &tx_env)?;
496 tx_env.set_gas_limit(cap.min(evm_env.block_env.gas_limit()));
499 }
500
501 let initial = request.as_ref().access_list().cloned().unwrap_or_default();
503
504 let mut inspector = AccessListInspector::new(initial);
505
506 let result = this.inspect(&mut db, evm_env.clone(), tx_env.clone(), &mut inspector)?;
507 let access_list = inspector.into_access_list();
508 let gas_used = result.result.gas_used();
509 tx_env.set_access_list(access_list.clone());
510 if let Err(err) = Self::Error::ensure_success(result.result) {
511 return Ok(AccessListResult {
512 access_list,
513 gas_used: U256::from(gas_used),
514 error: Some(err.to_string()),
515 });
516 }
517
518 let result = this.transact(&mut db, evm_env, tx_env)?;
520 let gas_used = result.result.gas_used();
521 let error = Self::Error::ensure_success(result.result).err().map(|e| e.to_string());
522
523 Ok(AccessListResult { access_list, gas_used: U256::from(gas_used), error })
524 })
525 }
526}
527
528pub trait Call:
530 LoadState<
531 RpcConvert: RpcConvert<Evm = Self::Evm>,
532 Error: FromEvmError<Self::Evm>
533 + From<<Self::RpcConvert as RpcConvert>::Error>
534 + From<ProviderError>,
535 > + SpawnBlocking
536{
537 fn call_gas_limit(&self) -> u64;
541
542 fn max_simulate_blocks(&self) -> u64;
544
545 fn evm_memory_limit(&self) -> u64;
547
548 fn caller_gas_allowance(
550 &self,
551 mut db: impl Database<Error: Into<EthApiError>>,
552 _evm_env: &EvmEnvFor<Self::Evm>,
553 tx_env: &TxEnvFor<Self::Evm>,
554 ) -> Result<u64, Self::Error> {
555 alloy_evm::call::caller_gas_allowance(&mut db, tx_env).map_err(Self::Error::from_eth_err)
556 }
557
558 fn with_state_at_block<F, R>(
560 &self,
561 at: BlockId,
562 f: F,
563 ) -> impl Future<Output = Result<R, Self::Error>> + Send
564 where
565 R: Send + 'static,
566 F: FnOnce(Self, StateProviderBox) -> Result<R, Self::Error> + Send + 'static,
567 {
568 self.spawn_blocking_io_fut(async move |this| {
569 let state = this.state_at_block_id(at).await?;
570 f(this, state)
571 })
572 }
573
574 fn transact<DB>(
577 &self,
578 db: DB,
579 evm_env: EvmEnvFor<Self::Evm>,
580 tx_env: TxEnvFor<Self::Evm>,
581 ) -> Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>
582 where
583 DB: Database<Error = EvmDatabaseError<ProviderError>> + fmt::Debug,
584 {
585 let mut evm = self.evm_config().evm_with_env(db, evm_env);
586 let res = evm.transact(tx_env).map_err(Self::Error::from_evm_err)?;
587
588 Ok(res)
589 }
590
591 fn transact_with_inspector<DB, I>(
594 &self,
595 db: DB,
596 evm_env: EvmEnvFor<Self::Evm>,
597 tx_env: TxEnvFor<Self::Evm>,
598 inspector: I,
599 ) -> Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>
600 where
601 DB: Database<Error = EvmDatabaseError<ProviderError>> + fmt::Debug,
602 I: InspectorFor<Self::Evm, DB>,
603 {
604 let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env, inspector);
605 let res = evm.transact(tx_env).map_err(Self::Error::from_evm_err)?;
606
607 Ok(res)
608 }
609
610 fn transact_call_at(
617 &self,
618 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
619 at: BlockId,
620 overrides: EvmOverrides,
621 ) -> impl Future<Output = Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>> + Send
622 where
623 Self: LoadPendingBlock,
624 {
625 async move {
626 let guard = CancelOnDrop::default();
627 let cancel = guard.clone();
628 let this = self.clone();
629
630 let res = self
631 .spawn_with_call_at(request, at, overrides, move |db, evm_env, tx_env| {
632 if cancel.is_cancelled() {
633 return Err(EthApiError::InternalEthError.into())
635 }
636 this.transact(db, evm_env, tx_env)
637 })
638 .await;
639 drop(guard);
640 res
641 }
642 }
643
644 fn spawn_with_state_at_block<F, R>(
646 &self,
647 at: impl Into<BlockId>,
648 f: F,
649 ) -> impl Future<Output = Result<R, Self::Error>> + Send
650 where
651 F: FnOnce(Self, StateCacheDb) -> Result<R, Self::Error> + Send + 'static,
652 R: Send + 'static,
653 {
654 let at = at.into();
655 self.spawn_blocking_io_fut(async move |this| {
656 let state = this.state_at_block_id(at).await?;
657 let db = State::builder()
658 .with_database(StateProviderDatabase::new(StateProviderTraitObjWrapper(state)))
659 .build();
660 f(this, db)
661 })
662 }
663
664 fn spawn_with_call_at<F, R>(
680 &self,
681 request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
682 at: BlockId,
683 overrides: EvmOverrides,
684 f: F,
685 ) -> impl Future<Output = Result<R, Self::Error>> + Send
686 where
687 Self: LoadPendingBlock,
688 F: FnOnce(
689 &mut StateCacheDb,
690 EvmEnvFor<Self::Evm>,
691 TxEnvFor<Self::Evm>,
692 ) -> Result<R, Self::Error>
693 + Send
694 + 'static,
695 R: Send + 'static,
696 {
697 async move {
698 let (evm_env, at) = self.evm_env_at(at).await?;
699 self.spawn_with_state_at_block(at, move |this, mut db| {
700 let (evm_env, tx_env) =
701 this.prepare_call_env(evm_env, request, &mut db, overrides)?;
702
703 f(&mut db, evm_env, tx_env)
704 })
705 .await
706 }
707 }
708
709 fn spawn_replay_transaction<F, R>(
719 &self,
720 hash: B256,
721 f: F,
722 ) -> impl Future<Output = Result<Option<R>, Self::Error>> + Send
723 where
724 Self: LoadBlock + LoadTransaction,
725 F: FnOnce(
726 TransactionInfo,
727 ResultAndState<HaltReasonFor<Self::Evm>>,
728 StateCacheDb,
729 ) -> Result<R, Self::Error>
730 + Send
731 + 'static,
732 R: Send + 'static,
733 {
734 async move {
735 let (transaction, block) = match self.transaction_and_block(hash).await? {
736 None => return Ok(None),
737 Some(res) => res,
738 };
739 let (tx, tx_info) = transaction.split();
740
741 let parent_block = block.parent_hash();
744
745 self.spawn_with_state_at_block(parent_block, move |this, mut db| {
746 let block_txs = block.transactions_recovered();
747
748 let mut executor = RpcNodeCore::evm_config(&this)
749 .executor_for_block(&mut db, block.sealed_block())
750 .map_err(RethError::other)
751 .map_err(Self::Error::from_eth_err)?;
752 executor.apply_pre_execution_changes().map_err(Self::Error::from_eth_err)?;
753
754 for block_tx in block_txs {
756 if block_tx.tx_hash() == tx.tx_hash() {
757 break;
758 }
759 executor.execute_transaction(block_tx).map_err(Self::Error::from_eth_err)?;
760 }
761
762 let tx_env = RpcNodeCore::evm_config(&this).tx_env(tx);
763
764 let res = executor.evm_mut().transact(tx_env).map_err(Self::Error::from_evm_err)?;
765 drop(executor);
766 f(tx_info, res, db)
767 })
768 .await
769 .map(Some)
770 }
771 }
772
773 fn replay_transactions_until<'a, DB, I>(
781 &self,
782 db: &mut DB,
783 evm_env: EvmEnvFor<Self::Evm>,
784 transactions: I,
785 target_tx_hash: B256,
786 ) -> Result<usize, Self::Error>
787 where
788 DB: Database<Error = EvmDatabaseError<ProviderError>> + DatabaseCommit + core::fmt::Debug,
789 I: IntoIterator<Item = Recovered<&'a ProviderTx<Self::Provider>>>,
790 {
791 let mut evm = self.evm_config().evm_with_env(db, evm_env);
792 let mut index = 0;
793 for tx in transactions {
794 if *tx.tx_hash() == target_tx_hash {
795 break
797 }
798
799 let tx_env = self.evm_config().tx_env(tx);
800 evm.transact_commit(tx_env).map_err(Self::Error::from_evm_err)?;
801 index += 1;
802 }
803 Ok(index)
804 }
805
806 fn create_txn_env(
810 &self,
811 evm_env: &EvmEnvFor<Self::Evm>,
812 mut request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
813 mut db: impl Database<Error: Into<EthApiError>>,
814 ) -> Result<TxEnvFor<Self::Evm>, Self::Error> {
815 if request.as_ref().nonce().is_none() {
816 let nonce = db
817 .basic(request.as_ref().from().unwrap_or_default())
818 .map_err(Into::into)?
819 .map(|acc| acc.nonce)
820 .unwrap_or_default();
821 request.as_mut().set_nonce(nonce);
822 }
823
824 Ok(self.converter().tx_env(request, evm_env)?)
825 }
826
827 #[expect(clippy::type_complexity)]
841 fn prepare_call_env<DB>(
842 &self,
843 mut evm_env: EvmEnvFor<Self::Evm>,
844 mut request: RpcTxReq<<Self::RpcConvert as RpcConvert>::Network>,
845 db: &mut DB,
846 overrides: EvmOverrides,
847 ) -> Result<(EvmEnvFor<Self::Evm>, TxEnvFor<Self::Evm>), Self::Error>
848 where
849 DB: Database + DatabaseCommit + OverrideBlockHashes,
850 EthApiError: From<<DB as Database>::Error>,
851 {
852 let request_has_gas_limit = request.as_ref().gas_limit().is_some();
854
855 if let Some(requested_gas) = request.as_ref().gas_limit() {
856 let global_gas_cap = self.call_gas_limit();
857 if global_gas_cap != 0 && global_gas_cap < requested_gas {
858 warn!(target: "rpc::eth::call", ?request, ?global_gas_cap, "Capping gas limit to global gas cap");
859 request.as_mut().set_gas_limit(global_gas_cap);
860 }
861 } else {
862 request.as_mut().set_gas_limit(self.call_gas_limit());
864 }
865
866 evm_env.cfg_env.disable_block_gas_limit = true;
869
870 evm_env.cfg_env.disable_eip3607 = true;
873
874 evm_env.cfg_env.disable_base_fee = true;
878
879 evm_env.cfg_env.tx_gas_limit_cap = Some(u64::MAX);
881
882 evm_env.cfg_env.disable_fee_charge = true;
886
887 evm_env.cfg_env.memory_limit = self.evm_memory_limit();
888
889 request.as_mut().take_nonce();
891
892 if let Some(block_overrides) = overrides.block {
893 apply_block_overrides(*block_overrides, db, evm_env.block_env.inner_mut());
894 }
895 if let Some(state_overrides) = overrides.state {
896 apply_state_overrides(state_overrides, db)
897 .map_err(EthApiError::from_state_overrides_err)?;
898 }
899
900 let mut tx_env = self.create_txn_env(&evm_env, request, &mut *db)?;
901
902 if tx_env.gas_price() == 0 {
904 evm_env.block_env.inner_mut().basefee = 0;
905 }
906
907 if !request_has_gas_limit {
908 if tx_env.gas_price() > 0 {
910 trace!(target: "rpc::eth::call", ?tx_env, "Applying gas limit cap with caller allowance");
912 let cap = self.caller_gas_allowance(db, &evm_env, &tx_env)?;
913 tx_env.set_gas_limit(cap.min(evm_env.block_env.gas_limit()));
915 }
916 }
917
918 Ok((evm_env, tx_env))
919 }
920}