Skip to main content

revm_context/
cfg.rs

1//! This module contains [`CfgEnv`] and implements [`Cfg`] trait for it.
2pub use context_interface::Cfg;
3
4use context_interface::cfg::GasParams;
5use primitives::{eip170, eip3860, eip7825, eip7954, hardfork::SpecId};
6
7/// EVM configuration
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[derive(Clone, Debug, Eq, PartialEq)]
10#[non_exhaustive]
11pub struct CfgEnv<SPEC = SpecId> {
12    /// Specification for EVM represent the hardfork
13    ///
14    /// [`CfgEnv::new_with_spec`] is going to set both gas params and spec.
15    ///
16    /// As GasParams is spec dependent, it is recommended to use one of following function to set both of them.
17    /// [`CfgEnv::set_spec_and_mainnet_gas_params`], [`CfgEnv::with_mainnet_gas_params`], [`CfgEnv::with_mainnet_gas_params`]
18    pub spec: SPEC,
19
20    /// Gas params for the EVM. Use [`CfgEnv::set_gas_params`] to set the gas params.
21    /// If gas_params was not set it will be set to the default gas params for the spec.
22    pub gas_params: GasParams,
23
24    /// Chain ID of the EVM. Used in CHAINID opcode and transaction's chain ID check.
25    ///
26    /// Chain ID is introduced EIP-155.
27    pub chain_id: u64,
28
29    /// Whether to check the transaction's chain ID.
30    ///
31    /// If set to `false`, the transaction's chain ID check will be skipped.
32    pub tx_chain_id_check: bool,
33
34    /// Contract code size limit override.
35    ///
36    /// If None, the limit will be determined by the SpecId (EIP-170 or EIP-7954) at runtime.
37    /// If Some, this specific limit will be used regardless of SpecId.
38    ///
39    /// Useful to increase this because of tests.
40    pub limit_contract_code_size: Option<usize>,
41    /// Contract initcode size limit override.
42    ///
43    /// If None, the limit will check if `limit_contract_code_size` is set.
44    /// If it is set, it will double it for a limit.
45    /// If it is not set, the limit will be determined by the SpecId (EIP-170 or EIP-7954) at runtime.
46    ///
47    /// Useful to increase this because of tests.
48    pub limit_contract_initcode_size: Option<usize>,
49    /// Skips the nonce validation against the account's nonce
50    pub disable_nonce_check: bool,
51    /// Blob max count. EIP-7840 Add blob schedule to EL config files.
52    ///
53    /// If this config is not set, the check for max blobs will be skipped.
54    pub max_blobs_per_tx: Option<u64>,
55    /// Blob base fee update fraction. EIP-4844 Blob base fee update fraction.
56    ///
57    /// If this config is not set, the blob base fee update fraction will be set to the default value.
58    /// See also [CfgEnv::blob_base_fee_update_fraction].
59    ///
60    /// Default values for Cancun is [`primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN`]
61    /// and for Prague is [`primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE`].
62    pub blob_base_fee_update_fraction: Option<u64>,
63    /// Configures the gas limit cap for the transaction.
64    ///
65    /// If `None`, default value defined by spec will be used.
66    ///
67    /// Introduced in Osaka in [EIP-7825: Transaction Gas Limit Cap](https://eips.ethereum.org/EIPS/eip-7825)
68    /// with initials cap of 30M.
69    pub tx_gas_limit_cap: Option<u64>,
70    /// A hard memory limit in bytes beyond which
71    /// [OutOfGasError::Memory][context_interface::result::OutOfGasError::Memory] cannot be resized.
72    ///
73    /// In cases where the gas limit may be extraordinarily high, it is recommended to set this to
74    /// a sane value to prevent memory allocation panics.
75    ///
76    /// Defaults to `2^32 - 1` bytes per EIP-1985.
77    #[cfg(feature = "memory_limit")]
78    pub memory_limit: u64,
79    /// Skip balance checks if `true`
80    ///
81    /// Adds transaction cost to balance to ensure execution doesn't fail.
82    ///
83    /// By default, it is set to `false`.
84    #[cfg(feature = "optional_balance_check")]
85    pub disable_balance_check: bool,
86    /// There are use cases where it's allowed to provide a gas limit that's higher than a block's gas limit.
87    ///
88    /// To that end, you can disable the block gas limit validation.
89    ///
90    /// By default, it is set to `false`.
91    #[cfg(feature = "optional_block_gas_limit")]
92    pub disable_block_gas_limit: bool,
93    /// EIP-3541 rejects the creation of contracts that starts with 0xEF
94    ///
95    /// This is useful for chains that do not implement EIP-3541.
96    ///
97    /// By default, it is set to `false`.
98    #[cfg(feature = "optional_eip3541")]
99    pub disable_eip3541: bool,
100    /// EIP-3607 rejects transactions from senders with deployed code
101    ///
102    /// In development, it can be desirable to simulate calls from contracts, which this setting allows.
103    ///
104    /// By default, it is set to `false`.
105    #[cfg(feature = "optional_eip3607")]
106    pub disable_eip3607: bool,
107    /// EIP-7623 increases calldata cost.
108    ///
109    /// This EIP can be considered irrelevant in the context of an EVM-compatible L2 rollup,
110    /// if it does not make use of blobs.
111    ///
112    /// By default, it is set to `false`.
113    #[cfg(feature = "optional_eip7623")]
114    pub disable_eip7623: bool,
115    /// Disables base fee checks for EIP-1559 transactions
116    ///
117    /// This is useful for testing method calls with zero gas price.
118    ///
119    /// By default, it is set to `false`.
120    #[cfg(feature = "optional_no_base_fee")]
121    pub disable_base_fee: bool,
122    /// Disables "max fee must be less than or equal to max priority fee" check for EIP-1559 transactions.
123    /// This is useful because some chains (e.g. Arbitrum) do not enforce this check.
124    /// By default, it is set to `false`.
125    #[cfg(feature = "optional_priority_fee_check")]
126    pub disable_priority_fee_check: bool,
127    /// Disables fee charging for transactions.
128    /// This is useful when executing `eth_call` for example, on OP-chains where setting the base fee
129    /// to 0 isn't sufficient.
130    /// By default, it is set to `false`.
131    #[cfg(feature = "optional_fee_charge")]
132    pub disable_fee_charge: bool,
133    /// Enables EIP-8037 (Amsterdam) state creation gas cost increase.
134    ///
135    /// EIP-8037 introduces dual gas limits: regular gas for execution and state gas
136    /// for storage creation. State gas is tracked via a reservoir model.
137    /// It specifies concrete gas values based on `cost_per_state_byte` and adds
138    /// a hash cost for deployed bytecode.
139    ///
140    /// By default, it is set to `false`.
141    pub enable_amsterdam_eip8037: bool,
142    /// Enables EIP-8024 (Amsterdam) DUPN, SWAPN, and EXCHANGE instructions.
143    ///
144    /// Enabled by default for Amsterdam and later. Can be enabled independently
145    /// on earlier forks without changing their other rules or gas parameters.
146    pub enable_amsterdam_eip8024: bool,
147    /// Enables EIP-2780 (Amsterdam) reduced intrinsic transaction gas.
148    ///
149    /// Replaces the legacy 21,000 base with the decomposed
150    /// `TX_BASE_COST + to-based + value-based` model and adds top-level
151    /// execution charges for empty recipients with value (state gas) and
152    /// EIP-7702-delegated recipients (extra cold access).
153    ///
154    /// By default, it is set to `false`.
155    pub enable_amsterdam_eip2780: bool,
156    /// Disables EIP-7708 (ETH transfers emit logs).
157    ///
158    /// By default, it is set to `false`.
159    pub amsterdam_eip7708_disabled: bool,
160    /// Disables the EIP-8246 delayed clearing of self-destructed accounts.
161    ///
162    /// When enabled, revm tracks all self-destructed addresses and, at the end of the
163    /// transaction, clears the code, storage and nonce of any that still have a remaining
164    /// balance while preserving the balance ([EIP-8246]). This can be disabled for performance
165    /// reasons as it requires storing and iterating over all self-destructed accounts. When
166    /// disabled, this clearing can be done outside of revm when applying accounts to database
167    /// state.
168    ///
169    /// By default, it is set to `false`.
170    ///
171    /// [EIP-8246]: https://eips.ethereum.org/EIPS/eip-8246
172    pub amsterdam_eip8246_delayed_clear_disabled: bool,
173}
174
175impl CfgEnv {
176    /// Creates new `CfgEnv` with default values.
177    pub fn new() -> Self {
178        Self::default()
179    }
180}
181
182impl<SPEC> CfgEnv<SPEC> {
183    /// Returns the spec for the `CfgEnv`.
184    #[inline]
185    pub const fn spec(&self) -> &SPEC {
186        &self.spec
187    }
188
189    /// Consumes `self` and returns a new `CfgEnv` with the specified chain ID.
190    pub const fn with_chain_id(mut self, chain_id: u64) -> Self {
191        self.chain_id = chain_id;
192        self
193    }
194
195    /// Sets the gas params for the `CfgEnv`.
196    #[inline]
197    pub fn with_gas_params(mut self, gas_params: GasParams) -> Self {
198        self.set_gas_params(gas_params);
199        self
200    }
201
202    /// Sets the spec for the `CfgEnv`.
203    #[inline]
204    #[deprecated(note = "Use [`CfgEnv::set_spec_and_mainnet_gas_params`] instead")]
205    pub fn set_spec(&mut self, spec: SPEC) {
206        self.spec = spec;
207    }
208
209    /// Sets the gas params for the `CfgEnv`.
210    #[inline]
211    pub fn set_gas_params(&mut self, gas_params: GasParams) {
212        self.gas_params = gas_params;
213    }
214
215    /// Enables the transaction's chain ID check.
216    pub const fn enable_tx_chain_id_check(mut self) -> Self {
217        self.tx_chain_id_check = true;
218        self
219    }
220
221    /// Disables the transaction's chain ID check.
222    pub const fn disable_tx_chain_id_check(mut self) -> Self {
223        self.tx_chain_id_check = false;
224        self
225    }
226
227    /// Sets the spec for the `CfgEnv`.
228    #[inline]
229    #[deprecated(note = "Use [`CfgEnv::with_spec_and_mainnet_gas_params`] instead")]
230    pub fn with_spec(mut self, spec: SPEC) -> Self {
231        self.spec = spec;
232        self
233    }
234
235    /// Sets the spec for the `CfgEnv` and the gas params to the mainnet gas params.
236    ///
237    /// Automatically enables EIP-8037, EIP-8024, and EIP-2780 for AMSTERDAM and later.
238    pub fn with_spec_and_mainnet_gas_params<OSPEC: Into<SpecId> + Clone>(
239        self,
240        spec: OSPEC,
241    ) -> CfgEnv<OSPEC> {
242        let is_amsterdam = spec.clone().into().is_enabled_in(SpecId::AMSTERDAM);
243        let enable_amsterdam_eip8037 = self.enable_amsterdam_eip8037 || is_amsterdam;
244        let enable_amsterdam_eip2780 = self.enable_amsterdam_eip2780 || is_amsterdam;
245        let enable_amsterdam_eip8024 = self.enable_amsterdam_eip8024 || is_amsterdam;
246        let mut cfg = self.with_spec_and_gas_params(spec.clone(), GasParams::new_spec(spec.into()));
247        cfg.enable_amsterdam_eip8037 = enable_amsterdam_eip8037;
248        cfg.enable_amsterdam_eip2780 = enable_amsterdam_eip2780;
249        cfg.enable_amsterdam_eip8024 = enable_amsterdam_eip8024;
250        cfg
251    }
252
253    /// Consumes `self` and returns a new `CfgEnv` with the specified spec.
254    ///
255    /// Resets the gas params override function as it is generic over SPEC.
256    pub fn with_spec_and_gas_params<OSPEC: Into<SpecId> + Clone>(
257        self,
258        spec: OSPEC,
259        gas_params: GasParams,
260    ) -> CfgEnv<OSPEC> {
261        CfgEnv {
262            chain_id: self.chain_id,
263            tx_chain_id_check: self.tx_chain_id_check,
264            limit_contract_code_size: self.limit_contract_code_size,
265            limit_contract_initcode_size: self.limit_contract_initcode_size,
266            spec,
267            disable_nonce_check: self.disable_nonce_check,
268            tx_gas_limit_cap: self.tx_gas_limit_cap,
269            max_blobs_per_tx: self.max_blobs_per_tx,
270            blob_base_fee_update_fraction: self.blob_base_fee_update_fraction,
271            gas_params,
272            #[cfg(feature = "memory_limit")]
273            memory_limit: self.memory_limit,
274            #[cfg(feature = "optional_balance_check")]
275            disable_balance_check: self.disable_balance_check,
276            #[cfg(feature = "optional_block_gas_limit")]
277            disable_block_gas_limit: self.disable_block_gas_limit,
278            #[cfg(feature = "optional_eip3541")]
279            disable_eip3541: self.disable_eip3541,
280            #[cfg(feature = "optional_eip3607")]
281            disable_eip3607: self.disable_eip3607,
282            #[cfg(feature = "optional_eip7623")]
283            disable_eip7623: self.disable_eip7623,
284            #[cfg(feature = "optional_no_base_fee")]
285            disable_base_fee: self.disable_base_fee,
286            #[cfg(feature = "optional_priority_fee_check")]
287            disable_priority_fee_check: self.disable_priority_fee_check,
288            #[cfg(feature = "optional_fee_charge")]
289            disable_fee_charge: self.disable_fee_charge,
290            enable_amsterdam_eip8037: self.enable_amsterdam_eip8037,
291            enable_amsterdam_eip2780: self.enable_amsterdam_eip2780,
292            enable_amsterdam_eip8024: self.enable_amsterdam_eip8024,
293            amsterdam_eip7708_disabled: self.amsterdam_eip7708_disabled,
294            amsterdam_eip8246_delayed_clear_disabled: self.amsterdam_eip8246_delayed_clear_disabled,
295        }
296    }
297
298    /// Sets the blob target
299    pub const fn with_max_blobs_per_tx(mut self, max_blobs_per_tx: u64) -> Self {
300        self.set_max_blobs_per_tx(max_blobs_per_tx);
301        self
302    }
303
304    /// Sets the blob target
305    pub const fn set_max_blobs_per_tx(&mut self, max_blobs_per_tx: u64) {
306        self.max_blobs_per_tx = Some(max_blobs_per_tx);
307    }
308
309    /// Clears the blob target and max count over hardforks.
310    pub const fn clear_max_blobs_per_tx(&mut self) {
311        self.max_blobs_per_tx = None;
312    }
313
314    /// Sets the disable priority fee check flag.
315    #[cfg(feature = "optional_priority_fee_check")]
316    pub const fn with_disable_priority_fee_check(mut self, disable: bool) -> Self {
317        self.disable_priority_fee_check = disable;
318        self
319    }
320
321    /// Sets the disable fee charge flag.
322    #[cfg(feature = "optional_fee_charge")]
323    pub const fn with_disable_fee_charge(mut self, disable: bool) -> Self {
324        self.disable_fee_charge = disable;
325        self
326    }
327
328    /// Sets the disable eip7623 flag.
329    #[cfg(feature = "optional_eip7623")]
330    pub const fn with_disable_eip7623(mut self, disable: bool) -> Self {
331        self.disable_eip7623 = disable;
332        self
333    }
334
335    /// Sets the enable EIP-8037 (Amsterdam) state creation gas cost flag.
336    pub const fn with_enable_amsterdam_eip8037(mut self, enable: bool) -> Self {
337        self.enable_amsterdam_eip8037 = enable;
338        self
339    }
340
341    /// Sets the enable EIP-8024 (Amsterdam) stack instructions flag.
342    pub const fn with_enable_amsterdam_eip8024(mut self, enable: bool) -> Self {
343        self.enable_amsterdam_eip8024 = enable;
344        self
345    }
346
347    /// Sets the enable EIP-2780 (Amsterdam) reduced intrinsic transaction
348    /// gas flag.
349    pub const fn with_enable_amsterdam_eip2780(mut self, enable: bool) -> Self {
350        self.enable_amsterdam_eip2780 = enable;
351        self
352    }
353}
354
355impl<SPEC: Into<SpecId> + Clone> CfgEnv<SPEC> {
356    /// Create new `CfgEnv` with default values and specified spec.
357    pub fn new_with_spec_and_gas_params(spec: SPEC, gas_params: GasParams) -> Self {
358        let is_amsterdam = spec.clone().into().is_enabled_in(SpecId::AMSTERDAM);
359        Self {
360            chain_id: 1,
361            tx_chain_id_check: true,
362            limit_contract_code_size: None,
363            limit_contract_initcode_size: None,
364            spec,
365            disable_nonce_check: false,
366            max_blobs_per_tx: None,
367            tx_gas_limit_cap: None,
368            blob_base_fee_update_fraction: None,
369            gas_params,
370            #[cfg(feature = "memory_limit")]
371            memory_limit: (1 << 32) - 1,
372            #[cfg(feature = "optional_balance_check")]
373            disable_balance_check: false,
374            #[cfg(feature = "optional_block_gas_limit")]
375            disable_block_gas_limit: false,
376            #[cfg(feature = "optional_eip3541")]
377            disable_eip3541: false,
378            #[cfg(feature = "optional_eip3607")]
379            disable_eip3607: false,
380            #[cfg(feature = "optional_eip7623")]
381            disable_eip7623: false,
382            #[cfg(feature = "optional_no_base_fee")]
383            disable_base_fee: false,
384            #[cfg(feature = "optional_priority_fee_check")]
385            disable_priority_fee_check: false,
386            #[cfg(feature = "optional_fee_charge")]
387            disable_fee_charge: false,
388            enable_amsterdam_eip8037: is_amsterdam,
389            enable_amsterdam_eip2780: is_amsterdam,
390            enable_amsterdam_eip8024: is_amsterdam,
391            amsterdam_eip7708_disabled: false,
392            amsterdam_eip8246_delayed_clear_disabled: false,
393        }
394    }
395
396    /// Returns the blob base fee update fraction from [CfgEnv::blob_base_fee_update_fraction].
397    ///
398    /// If this field is not set, return the default value for the spec.
399    ///
400    /// Default values for Cancun is [`primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN`]
401    /// and for Prague is [`primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE`].
402    pub fn blob_base_fee_update_fraction(&self) -> u64 {
403        self.blob_base_fee_update_fraction.unwrap_or_else(|| {
404            let spec: SpecId = self.spec.clone().into();
405            if spec.is_enabled_in(SpecId::PRAGUE) {
406                primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE
407            } else {
408                primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN
409            }
410        })
411    }
412
413    /// Create new `CfgEnv` with default values and specified spec.
414    /// It will create a new gas params based on mainnet spec.
415    ///
416    /// Internally it will call [`CfgEnv::new_with_spec_and_gas_params`] with the mainnet gas params.
417    pub fn new_with_spec(spec: SPEC) -> Self {
418        Self::new_with_spec_and_gas_params(spec.clone(), GasParams::new_spec(spec.into()))
419    }
420
421    /// Sets the gas params for the `CfgEnv` to the mainnet gas params.
422    ///
423    /// If spec gets changed, calling this function would use this spec to set the mainnetF gas params.
424    pub fn with_mainnet_gas_params(mut self) -> Self {
425        self.set_gas_params(GasParams::new_spec(self.spec.clone().into()));
426        self
427    }
428
429    /// Sets the spec for the `CfgEnv` and the gas params to the mainnet gas params.
430    ///
431    /// Automatically enables EIP-8037, EIP-8024, and EIP-2780 for AMSTERDAM and later.
432    #[inline]
433    pub fn set_spec_and_mainnet_gas_params(&mut self, spec: SPEC) {
434        self.spec = spec.clone();
435        self.set_gas_params(GasParams::new_spec(spec.clone().into()));
436        // EIP-8037/EIP-8024/EIP-2780: Enable for AMSTERDAM and later
437        if spec.into().is_enabled_in(SpecId::AMSTERDAM) {
438            self.enable_amsterdam_eip8037 = true;
439            self.enable_amsterdam_eip2780 = true;
440            self.enable_amsterdam_eip8024 = true;
441        }
442    }
443}
444
445impl<SPEC: Into<SpecId> + Clone> Cfg for CfgEnv<SPEC> {
446    type Spec = SPEC;
447
448    #[inline]
449    fn chain_id(&self) -> u64 {
450        self.chain_id
451    }
452
453    #[inline]
454    fn spec(&self) -> Self::Spec {
455        self.spec.clone()
456    }
457
458    #[inline]
459    fn tx_chain_id_check(&self) -> bool {
460        self.tx_chain_id_check
461    }
462
463    #[inline]
464    fn tx_gas_limit_cap(&self) -> u64 {
465        self.tx_gas_limit_cap
466            .unwrap_or(if self.spec.clone().into().is_enabled_in(SpecId::OSAKA) {
467                eip7825::TX_GAS_LIMIT_CAP
468            } else {
469                u64::MAX
470            })
471    }
472
473    #[inline]
474    fn max_blobs_per_tx(&self) -> Option<u64> {
475        self.max_blobs_per_tx
476    }
477
478    fn max_code_size(&self) -> usize {
479        self.limit_contract_code_size.unwrap_or(
480            if self.spec.clone().into().is_enabled_in(SpecId::AMSTERDAM) {
481                eip7954::MAX_CODE_SIZE
482            } else {
483                eip170::MAX_CODE_SIZE
484            },
485        )
486    }
487
488    fn max_initcode_size(&self) -> usize {
489        self.limit_contract_initcode_size
490            .or_else(|| {
491                self.limit_contract_code_size
492                    .map(|size| size.saturating_mul(2))
493            })
494            .unwrap_or(
495                if self.spec.clone().into().is_enabled_in(SpecId::AMSTERDAM) {
496                    eip7954::MAX_INITCODE_SIZE
497                } else {
498                    eip3860::MAX_INITCODE_SIZE
499                },
500            )
501    }
502
503    fn is_eip3541_disabled(&self) -> bool {
504        cfg_if::cfg_if! {
505            if #[cfg(feature = "optional_eip3541")] {
506                self.disable_eip3541
507            } else {
508                false
509            }
510        }
511    }
512
513    fn is_eip3607_disabled(&self) -> bool {
514        cfg_if::cfg_if! {
515            if #[cfg(feature = "optional_eip3607")] {
516                self.disable_eip3607
517            } else {
518                false
519            }
520        }
521    }
522
523    fn is_eip7623_disabled(&self) -> bool {
524        cfg_if::cfg_if! {
525            if #[cfg(feature = "optional_eip7623")] {
526                self.disable_eip7623
527            } else {
528                false
529            }
530        }
531    }
532
533    fn is_balance_check_disabled(&self) -> bool {
534        cfg_if::cfg_if! {
535            if #[cfg(feature = "optional_balance_check")] {
536                self.disable_balance_check
537            } else {
538                false
539            }
540        }
541    }
542
543    /// Returns `true` if the block gas limit is disabled.
544    fn is_block_gas_limit_disabled(&self) -> bool {
545        cfg_if::cfg_if! {
546            if #[cfg(feature = "optional_block_gas_limit")] {
547                self.disable_block_gas_limit
548            } else {
549                false
550            }
551        }
552    }
553
554    fn is_nonce_check_disabled(&self) -> bool {
555        self.disable_nonce_check
556    }
557
558    fn is_base_fee_check_disabled(&self) -> bool {
559        cfg_if::cfg_if! {
560            if #[cfg(feature = "optional_no_base_fee")] {
561                self.disable_base_fee
562            } else {
563                false
564            }
565        }
566    }
567
568    fn is_priority_fee_check_disabled(&self) -> bool {
569        cfg_if::cfg_if! {
570            if #[cfg(feature = "optional_priority_fee_check")] {
571                self.disable_priority_fee_check
572            } else {
573                false
574            }
575        }
576    }
577
578    fn is_fee_charge_disabled(&self) -> bool {
579        cfg_if::cfg_if! {
580            if #[cfg(feature = "optional_fee_charge")] {
581                self.disable_fee_charge
582            } else {
583                false
584            }
585        }
586    }
587
588    fn is_eip7708_disabled(&self) -> bool {
589        self.amsterdam_eip7708_disabled
590    }
591
592    fn is_eip8246_delayed_clear_disabled(&self) -> bool {
593        self.amsterdam_eip8246_delayed_clear_disabled
594    }
595
596    fn memory_limit(&self) -> u64 {
597        cfg_if::cfg_if! {
598            if #[cfg(feature = "memory_limit")] {
599                self.memory_limit
600            } else {
601                u64::MAX
602            }
603        }
604    }
605
606    #[inline]
607    fn gas_params(&self) -> &GasParams {
608        &self.gas_params
609    }
610
611    fn is_amsterdam_eip8037_enabled(&self) -> bool {
612        self.enable_amsterdam_eip8037
613    }
614
615    fn is_amsterdam_eip2780_enabled(&self) -> bool {
616        self.enable_amsterdam_eip2780
617    }
618
619    fn is_amsterdam_eip8024_enabled(&self) -> bool {
620        self.enable_amsterdam_eip8024
621    }
622}
623
624impl<SPEC: Default + Into<SpecId> + Clone> Default for CfgEnv<SPEC> {
625    fn default() -> Self {
626        Self::new_with_spec_and_gas_params(
627            SPEC::default(),
628            GasParams::new_spec(SPEC::default().into()),
629        )
630    }
631}
632
633#[cfg(test)]
634mod test {
635    use super::*;
636
637    #[test]
638    fn eip8024_defaults_and_overrides() {
639        let osaka = CfgEnv::new_with_spec(SpecId::OSAKA);
640        assert!(!osaka.is_amsterdam_eip8024_enabled());
641        let enabled = osaka.clone().with_enable_amsterdam_eip8024(true);
642        assert!(enabled.is_amsterdam_eip8024_enabled());
643        assert_eq!(enabled.gas_params, osaka.gas_params);
644        assert!(!enabled.is_amsterdam_eip8037_enabled());
645        assert!(!enabled.is_amsterdam_eip2780_enabled());
646
647        let amsterdam = CfgEnv::new_with_spec(SpecId::AMSTERDAM);
648        assert!(amsterdam.is_amsterdam_eip8024_enabled());
649        assert!(!amsterdam
650            .with_enable_amsterdam_eip8024(false)
651            .is_amsterdam_eip8024_enabled());
652    }
653
654    #[test]
655    fn eip8024_survives_config_conversion() {
656        let cfg = CfgEnv::new_with_spec(SpecId::OSAKA).with_enable_amsterdam_eip8024(true);
657        let cfg = cfg.with_spec_and_gas_params(SpecId::PRAGUE, GasParams::new_spec(SpecId::PRAGUE));
658        assert!(cfg.is_amsterdam_eip8024_enabled());
659        let cfg = cfg.with_spec_and_mainnet_gas_params(SpecId::OSAKA);
660        assert!(cfg.is_amsterdam_eip8024_enabled());
661
662        let cfg = CfgEnv::new_with_spec(SpecId::AMSTERDAM)
663            .with_enable_amsterdam_eip8024(false)
664            .with_spec_and_gas_params(SpecId::AMSTERDAM, GasParams::new_spec(SpecId::AMSTERDAM));
665        assert!(!cfg.is_amsterdam_eip8024_enabled());
666    }
667
668    #[test]
669    fn eip8024_enabled_by_mainnet_spec_setters() {
670        let mut cfg = CfgEnv::new_with_spec(SpecId::OSAKA);
671        cfg.set_spec_and_mainnet_gas_params(SpecId::AMSTERDAM);
672        assert!(cfg.is_amsterdam_eip8024_enabled());
673        let cfg = CfgEnv::new_with_spec(SpecId::OSAKA)
674            .with_spec_and_mainnet_gas_params(SpecId::AMSTERDAM);
675        assert!(cfg.is_amsterdam_eip8024_enabled());
676    }
677
678    #[test]
679    fn blob_max_and_target_count() {
680        let cfg: CfgEnv = Default::default();
681        assert_eq!(cfg.max_blobs_per_tx(), None);
682    }
683}