foundry_evm/executors/
builder.rs1use crate::{executors::Executor, inspectors::InspectorStackBuilder};
2use foundry_evm_core::{EvmEnv, backend::Backend};
3use revm::{context::TxEnv, primitives::hardfork::SpecId};
4
5#[derive(Debug, Clone)]
13#[must_use = "builders do nothing unless you call `build` on them"]
14pub struct ExecutorBuilder {
15 stack: InspectorStackBuilder,
17 gas_limit: Option<u64>,
19 spec_id: SpecId,
21 legacy_assertions: bool,
22}
23
24impl Default for ExecutorBuilder {
25 #[inline]
26 fn default() -> Self {
27 Self {
28 stack: InspectorStackBuilder::new(),
29 gas_limit: None,
30 spec_id: SpecId::default(),
31 legacy_assertions: false,
32 }
33 }
34}
35
36impl ExecutorBuilder {
37 #[inline]
39 pub fn new() -> Self {
40 Self::default()
41 }
42
43 #[inline]
45 pub fn inspectors(
46 mut self,
47 f: impl FnOnce(InspectorStackBuilder) -> InspectorStackBuilder,
48 ) -> Self {
49 self.stack = f(self.stack);
50 self
51 }
52
53 #[inline]
55 pub fn spec_id(mut self, spec: SpecId) -> Self {
56 self.spec_id = spec;
57 self
58 }
59
60 #[inline]
62 pub fn gas_limit(mut self, gas_limit: u64) -> Self {
63 self.gas_limit = Some(gas_limit);
64 self
65 }
66
67 #[inline]
69 pub fn legacy_assertions(mut self, legacy_assertions: bool) -> Self {
70 self.legacy_assertions = legacy_assertions;
71 self
72 }
73
74 #[inline]
76 pub fn build(self, mut evm_env: EvmEnv, tx_env: TxEnv, db: Backend) -> Executor {
77 let Self { mut stack, gas_limit, spec_id, legacy_assertions } = self;
78 if stack.block.is_none() {
79 stack.block = Some(evm_env.block_env.clone());
80 }
81 if stack.gas_price.is_none() {
82 stack.gas_price = Some(tx_env.gas_price);
83 }
84 let gas_limit = gas_limit.unwrap_or(evm_env.block_env.gas_limit);
85 evm_env.cfg_env.set_spec(spec_id);
86 Executor::new(db, evm_env, tx_env, stack.build(), gas_limit, legacy_assertions)
87 }
88}