foundry_evm/executors/
builder.rs1use crate::{executors::Executor, inspectors::InspectorStackBuilder};
2use foundry_evm_core::{Env, backend::Backend};
3use revm::primitives::hardfork::SpecId;
4
5use super::ExecutorStrategy;
6
7#[derive(Clone, Debug)]
15#[must_use = "builders do nothing unless you call `build` on them"]
16pub struct ExecutorBuilder {
17 stack: InspectorStackBuilder,
19 gas_limit: Option<u64>,
21 spec_id: SpecId,
23 legacy_assertions: bool,
24}
25
26impl Default for ExecutorBuilder {
27 #[inline]
28 fn default() -> Self {
29 Self {
30 stack: InspectorStackBuilder::new(),
31 gas_limit: None,
32 spec_id: SpecId::default(),
33 legacy_assertions: false,
34 }
35 }
36}
37
38impl ExecutorBuilder {
39 #[inline]
41 pub fn new() -> Self {
42 Self::default()
43 }
44
45 #[inline]
47 pub fn inspectors(
48 mut self,
49 f: impl FnOnce(InspectorStackBuilder) -> InspectorStackBuilder,
50 ) -> Self {
51 self.stack = f(self.stack);
52 self
53 }
54
55 #[inline]
57 pub fn spec_id(mut self, spec: SpecId) -> Self {
58 self.spec_id = spec;
59 self
60 }
61
62 #[inline]
64 pub fn gas_limit(mut self, gas_limit: u64) -> Self {
65 self.gas_limit = Some(gas_limit);
66 self
67 }
68
69 #[inline]
71 pub fn legacy_assertions(mut self, legacy_assertions: bool) -> Self {
72 self.legacy_assertions = legacy_assertions;
73 self
74 }
75
76 #[inline]
78 pub fn build(self, env: Env, db: Backend, strategy: ExecutorStrategy) -> Executor {
79 let Self { mut stack, gas_limit, spec_id, legacy_assertions } = self;
80 if stack.block.is_none() {
81 stack.block = Some(env.evm_env.block_env.clone());
82 }
83 if stack.gas_price.is_none() {
84 stack.gas_price = Some(env.tx.gas_price);
85 }
86 let gas_limit = gas_limit.unwrap_or(env.evm_env.block_env.gas_limit);
87 let env = Env::new_with_spec_id(
88 env.evm_env.cfg_env.clone(),
89 env.evm_env.block_env.clone(),
90 env.tx,
91 spec_id,
92 );
93 Executor::new(db, env, stack.build(), gas_limit, legacy_assertions, strategy)
94 }
95}