foundry_evm/executors/
builder.rs1use crate::{executors::Executor, inspectors::InspectorStackBuilder};
2use foundry_evm_core::{
3 backend::Backend,
4 evm::{BlockEnvFor, EvmEnvFor, FoundryEvmNetwork, SpecFor, TxEnvFor},
5};
6use foundry_evm_networks::NetworkConfigs;
7use revm::context::{Block, Transaction};
8
9#[derive(Debug, Clone)]
17#[must_use = "builders do nothing unless you call `build` on them"]
18pub struct ExecutorBuilder<FEN: FoundryEvmNetwork> {
19 stack: InspectorStackBuilder<BlockEnvFor<FEN>>,
21 gas_limit: Option<u64>,
23 spec: Option<SpecFor<FEN>>,
25 legacy_assertions: bool,
26}
27
28impl<FEN: FoundryEvmNetwork> Default for ExecutorBuilder<FEN> {
29 #[inline]
30 fn default() -> Self {
31 Self {
32 stack: InspectorStackBuilder::new(),
33 gas_limit: None,
34 spec: None,
35 legacy_assertions: false,
36 }
37 }
38}
39
40impl<FEN: FoundryEvmNetwork> ExecutorBuilder<FEN> {
41 #[inline]
43 pub fn inspectors(
44 mut self,
45 f: impl FnOnce(
46 InspectorStackBuilder<BlockEnvFor<FEN>>,
47 ) -> InspectorStackBuilder<BlockEnvFor<FEN>>,
48 ) -> Self {
49 self.stack = f(self.stack);
50 self
51 }
52
53 #[inline]
55 pub const fn spec_id(mut self, spec: SpecFor<FEN>) -> Self {
56 self.spec = Some(spec);
57 self
58 }
59
60 #[inline]
62 pub const fn spec_id_opt(self, spec: Option<SpecFor<FEN>>) -> Self {
63 if let Some(spec) = spec { self.spec_id(spec) } else { self }
64 }
65
66 #[inline]
68 pub const fn gas_limit(mut self, gas_limit: u64) -> Self {
69 self.gas_limit = Some(gas_limit);
70 self
71 }
72
73 #[inline]
75 pub const fn legacy_assertions(mut self, legacy_assertions: bool) -> Self {
76 self.legacy_assertions = legacy_assertions;
77 self
78 }
79
80 #[inline]
82 pub fn build(
83 self,
84 mut evm_env: EvmEnvFor<FEN>,
85 tx_env: TxEnvFor<FEN>,
86 db: Backend<FEN>,
87 networks: NetworkConfigs,
88 ) -> Executor<FEN> {
89 let Self { mut stack, gas_limit, spec, legacy_assertions, .. } = self;
90 stack.networks = networks;
91 if stack.block.is_none() {
92 stack.block = Some(evm_env.block_env.clone());
93 }
94 if stack.gas_price.is_none() {
95 stack.gas_price = Some(tx_env.gas_price());
96 }
97 let gas_limit = gas_limit.unwrap_or(evm_env.block_env.gas_limit());
98 if let Some(spec) = spec {
99 evm_env.cfg_env.set_spec_and_mainnet_gas_params(spec);
100 }
101 Executor::new(db, evm_env, tx_env, stack.build(), networks, gas_limit, legacy_assertions)
102 }
103}