alloy_evm/
env.rs

1//! Configuration types for EVM environment.
2
3use core::fmt::Debug;
4
5use alloy_primitives::U256;
6use revm::{
7    context::{BlockEnv, CfgEnv},
8    primitives::hardfork::SpecId,
9};
10
11/// Container type that holds both the configuration and block environment for EVM execution.
12#[derive(Debug, Clone, Default, PartialEq, Eq)]
13pub struct EvmEnv<Spec = SpecId, BlockEnv = revm::context::BlockEnv> {
14    /// The configuration environment with handler settings
15    pub cfg_env: CfgEnv<Spec>,
16    /// The block environment containing block-specific data
17    pub block_env: BlockEnv,
18}
19
20impl<Spec, BlockEnv> EvmEnv<Spec, BlockEnv> {
21    /// Create a new `EvmEnv` from its components.
22    ///
23    /// # Arguments
24    ///
25    /// * `cfg_env_with_handler_cfg` - The configuration environment with handler settings
26    /// * `block` - The block environment containing block-specific data
27    pub const fn new(cfg_env: CfgEnv<Spec>, block_env: BlockEnv) -> Self {
28        Self { cfg_env, block_env }
29    }
30}
31
32impl<Spec, BlockEnv: BlockEnvironment> EvmEnv<Spec, BlockEnv> {
33    /// Sets an extension on the environment.
34    pub fn map_block_env<NewBlockEnv>(
35        self,
36        f: impl FnOnce(BlockEnv) -> NewBlockEnv,
37    ) -> EvmEnv<Spec, NewBlockEnv> {
38        let Self { cfg_env, block_env } = self;
39        EvmEnv { cfg_env, block_env: f(block_env) }
40    }
41
42    /// Returns a reference to the block environment.
43    pub const fn block_env(&self) -> &BlockEnv {
44        &self.block_env
45    }
46
47    /// Returns a reference to the configuration environment.
48    pub const fn cfg_env(&self) -> &CfgEnv<Spec> {
49        &self.cfg_env
50    }
51
52    /// Returns the chain ID of the environment.
53    pub const fn chainid(&self) -> u64 {
54        self.cfg_env.chain_id
55    }
56
57    /// Returns the spec id of the chain
58    pub const fn spec_id(&self) -> &Spec {
59        &self.cfg_env.spec
60    }
61
62    /// Overrides the configured block number
63    pub fn with_block_number(mut self, number: U256) -> Self {
64        self.block_env.inner_mut().number = number;
65        self
66    }
67
68    /// Convenience function that overrides the configured block number with the given
69    /// `Some(number)`.
70    ///
71    /// This is intended for block overrides.
72    pub fn with_block_number_opt(mut self, number: Option<U256>) -> Self {
73        if let Some(number) = number {
74            self.block_env.inner_mut().number = number;
75        }
76        self
77    }
78
79    /// Sets the block number if provided.
80    pub fn set_block_number_opt(&mut self, number: Option<U256>) -> &mut Self {
81        if let Some(number) = number {
82            self.block_env.inner_mut().number = number;
83        }
84        self
85    }
86
87    /// Overrides the configured block timestamp.
88    pub fn with_timestamp(mut self, timestamp: U256) -> Self {
89        self.block_env.inner_mut().timestamp = timestamp;
90        self
91    }
92
93    /// Convenience function that overrides the configured block timestamp with the given
94    /// `Some(timestamp)`.
95    ///
96    /// This is intended for block overrides.
97    pub fn with_timestamp_opt(mut self, timestamp: Option<U256>) -> Self {
98        if let Some(timestamp) = timestamp {
99            self.block_env.inner_mut().timestamp = timestamp;
100        }
101        self
102    }
103
104    /// Sets the block timestamp if provided.
105    pub fn set_timestamp_opt(&mut self, timestamp: Option<U256>) -> &mut Self {
106        if let Some(timestamp) = timestamp {
107            self.block_env.inner_mut().timestamp = timestamp;
108        }
109        self
110    }
111
112    /// Overrides the configured block base fee.
113    pub fn with_base_fee(mut self, base_fee: u64) -> Self {
114        self.block_env.inner_mut().basefee = base_fee;
115        self
116    }
117
118    /// Convenience function that overrides the configured block base fee with the given
119    /// `Some(base_fee)`.
120    ///
121    /// This is intended for block overrides.
122    pub fn with_base_fee_opt(mut self, base_fee: Option<u64>) -> Self {
123        if let Some(base_fee) = base_fee {
124            self.block_env.inner_mut().basefee = base_fee;
125        }
126        self
127    }
128
129    /// Sets the block base fee if provided.
130    pub fn set_base_fee_opt(&mut self, base_fee: Option<u64>) -> &mut Self {
131        if let Some(base_fee) = base_fee {
132            self.block_env.inner_mut().basefee = base_fee;
133        }
134        self
135    }
136}
137
138impl<Spec, BlockEnv> From<(CfgEnv<Spec>, BlockEnv)> for EvmEnv<Spec, BlockEnv> {
139    fn from((cfg_env, block_env): (CfgEnv<Spec>, BlockEnv)) -> Self {
140        Self { cfg_env, block_env }
141    }
142}
143
144/// Trait for types that can be used as a block environment.
145///
146/// Assumes that the type wraps an inner [`revm::context::BlockEnv`].
147pub trait BlockEnvironment: revm::context::Block + Clone + Debug + Send + Sync + 'static {
148    /// Returns a mutable reference to the inner [`revm::context::BlockEnv`].
149    fn inner_mut(&mut self) -> &mut revm::context::BlockEnv;
150}
151
152impl BlockEnvironment for BlockEnv {
153    fn inner_mut(&mut self) -> &mut revm::context::BlockEnv {
154        self
155    }
156}