1pub use context_interface::Cfg;
3
4use context_interface::cfg::GasParams;
5use primitives::{eip170, eip3860, eip7825, eip7954, hardfork::SpecId};
6
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[derive(Clone, Debug, Eq, PartialEq)]
10#[non_exhaustive]
11pub struct CfgEnv<SPEC = SpecId> {
12 pub spec: SPEC,
19
20 pub gas_params: GasParams,
23
24 pub chain_id: u64,
28
29 pub tx_chain_id_check: bool,
33
34 pub limit_contract_code_size: Option<usize>,
41 pub limit_contract_initcode_size: Option<usize>,
49 pub disable_nonce_check: bool,
51 pub max_blobs_per_tx: Option<u64>,
55 pub blob_base_fee_update_fraction: Option<u64>,
63 pub tx_gas_limit_cap: Option<u64>,
70 #[cfg(feature = "memory_limit")]
78 pub memory_limit: u64,
79 #[cfg(feature = "optional_balance_check")]
85 pub disable_balance_check: bool,
86 #[cfg(feature = "optional_block_gas_limit")]
92 pub disable_block_gas_limit: bool,
93 #[cfg(feature = "optional_eip3541")]
99 pub disable_eip3541: bool,
100 #[cfg(feature = "optional_eip3607")]
106 pub disable_eip3607: bool,
107 #[cfg(feature = "optional_eip7623")]
114 pub disable_eip7623: bool,
115 #[cfg(feature = "optional_no_base_fee")]
121 pub disable_base_fee: bool,
122 #[cfg(feature = "optional_priority_fee_check")]
126 pub disable_priority_fee_check: bool,
127 #[cfg(feature = "optional_fee_charge")]
132 pub disable_fee_charge: bool,
133 pub enable_amsterdam_eip8037: bool,
142 pub enable_amsterdam_eip2780: bool,
151 pub amsterdam_eip7708_disabled: bool,
155 pub amsterdam_eip8246_delayed_clear_disabled: bool,
168}
169
170impl CfgEnv {
171 pub fn new() -> Self {
173 Self::default()
174 }
175}
176
177impl<SPEC> CfgEnv<SPEC> {
178 #[inline]
180 pub const fn spec(&self) -> &SPEC {
181 &self.spec
182 }
183
184 pub const fn with_chain_id(mut self, chain_id: u64) -> Self {
186 self.chain_id = chain_id;
187 self
188 }
189
190 #[inline]
192 pub fn with_gas_params(mut self, gas_params: GasParams) -> Self {
193 self.set_gas_params(gas_params);
194 self
195 }
196
197 #[inline]
199 #[deprecated(note = "Use [`CfgEnv::set_spec_and_mainnet_gas_params`] instead")]
200 pub fn set_spec(&mut self, spec: SPEC) {
201 self.spec = spec;
202 }
203
204 #[inline]
206 pub fn set_gas_params(&mut self, gas_params: GasParams) {
207 self.gas_params = gas_params;
208 }
209
210 pub const fn enable_tx_chain_id_check(mut self) -> Self {
212 self.tx_chain_id_check = true;
213 self
214 }
215
216 pub const fn disable_tx_chain_id_check(mut self) -> Self {
218 self.tx_chain_id_check = false;
219 self
220 }
221
222 #[inline]
224 #[deprecated(note = "Use [`CfgEnv::with_spec_and_mainnet_gas_params`] instead")]
225 pub fn with_spec(mut self, spec: SPEC) -> Self {
226 self.spec = spec;
227 self
228 }
229
230 pub fn with_spec_and_mainnet_gas_params<OSPEC: Into<SpecId> + Clone>(
234 self,
235 spec: OSPEC,
236 ) -> CfgEnv<OSPEC> {
237 let is_amsterdam = spec.clone().into().is_enabled_in(SpecId::AMSTERDAM);
238 let enable_amsterdam_eip8037 = self.enable_amsterdam_eip8037 || is_amsterdam;
239 let enable_amsterdam_eip2780 = self.enable_amsterdam_eip2780 || is_amsterdam;
240 let mut cfg = self.with_spec_and_gas_params(spec.clone(), GasParams::new_spec(spec.into()));
241 cfg.enable_amsterdam_eip8037 = enable_amsterdam_eip8037;
242 cfg.enable_amsterdam_eip2780 = enable_amsterdam_eip2780;
243 cfg
244 }
245
246 pub fn with_spec_and_gas_params<OSPEC: Into<SpecId> + Clone>(
250 self,
251 spec: OSPEC,
252 gas_params: GasParams,
253 ) -> CfgEnv<OSPEC> {
254 CfgEnv {
255 chain_id: self.chain_id,
256 tx_chain_id_check: self.tx_chain_id_check,
257 limit_contract_code_size: self.limit_contract_code_size,
258 limit_contract_initcode_size: self.limit_contract_initcode_size,
259 spec,
260 disable_nonce_check: self.disable_nonce_check,
261 tx_gas_limit_cap: self.tx_gas_limit_cap,
262 max_blobs_per_tx: self.max_blobs_per_tx,
263 blob_base_fee_update_fraction: self.blob_base_fee_update_fraction,
264 gas_params,
265 #[cfg(feature = "memory_limit")]
266 memory_limit: self.memory_limit,
267 #[cfg(feature = "optional_balance_check")]
268 disable_balance_check: self.disable_balance_check,
269 #[cfg(feature = "optional_block_gas_limit")]
270 disable_block_gas_limit: self.disable_block_gas_limit,
271 #[cfg(feature = "optional_eip3541")]
272 disable_eip3541: self.disable_eip3541,
273 #[cfg(feature = "optional_eip3607")]
274 disable_eip3607: self.disable_eip3607,
275 #[cfg(feature = "optional_eip7623")]
276 disable_eip7623: self.disable_eip7623,
277 #[cfg(feature = "optional_no_base_fee")]
278 disable_base_fee: self.disable_base_fee,
279 #[cfg(feature = "optional_priority_fee_check")]
280 disable_priority_fee_check: self.disable_priority_fee_check,
281 #[cfg(feature = "optional_fee_charge")]
282 disable_fee_charge: self.disable_fee_charge,
283 enable_amsterdam_eip8037: self.enable_amsterdam_eip8037,
284 enable_amsterdam_eip2780: self.enable_amsterdam_eip2780,
285 amsterdam_eip7708_disabled: self.amsterdam_eip7708_disabled,
286 amsterdam_eip8246_delayed_clear_disabled: self.amsterdam_eip8246_delayed_clear_disabled,
287 }
288 }
289
290 pub const fn with_max_blobs_per_tx(mut self, max_blobs_per_tx: u64) -> Self {
292 self.set_max_blobs_per_tx(max_blobs_per_tx);
293 self
294 }
295
296 pub const fn set_max_blobs_per_tx(&mut self, max_blobs_per_tx: u64) {
298 self.max_blobs_per_tx = Some(max_blobs_per_tx);
299 }
300
301 pub const fn clear_max_blobs_per_tx(&mut self) {
303 self.max_blobs_per_tx = None;
304 }
305
306 #[cfg(feature = "optional_priority_fee_check")]
308 pub const fn with_disable_priority_fee_check(mut self, disable: bool) -> Self {
309 self.disable_priority_fee_check = disable;
310 self
311 }
312
313 #[cfg(feature = "optional_fee_charge")]
315 pub const fn with_disable_fee_charge(mut self, disable: bool) -> Self {
316 self.disable_fee_charge = disable;
317 self
318 }
319
320 #[cfg(feature = "optional_eip7623")]
322 pub const fn with_disable_eip7623(mut self, disable: bool) -> Self {
323 self.disable_eip7623 = disable;
324 self
325 }
326
327 pub const fn with_enable_amsterdam_eip8037(mut self, enable: bool) -> Self {
329 self.enable_amsterdam_eip8037 = enable;
330 self
331 }
332
333 pub const fn with_enable_amsterdam_eip2780(mut self, enable: bool) -> Self {
336 self.enable_amsterdam_eip2780 = enable;
337 self
338 }
339}
340
341impl<SPEC: Into<SpecId> + Clone> CfgEnv<SPEC> {
342 pub fn new_with_spec_and_gas_params(spec: SPEC, gas_params: GasParams) -> Self {
344 let is_amsterdam = spec.clone().into().is_enabled_in(SpecId::AMSTERDAM);
345 Self {
346 chain_id: 1,
347 tx_chain_id_check: true,
348 limit_contract_code_size: None,
349 limit_contract_initcode_size: None,
350 spec,
351 disable_nonce_check: false,
352 max_blobs_per_tx: None,
353 tx_gas_limit_cap: None,
354 blob_base_fee_update_fraction: None,
355 gas_params,
356 #[cfg(feature = "memory_limit")]
357 memory_limit: (1 << 32) - 1,
358 #[cfg(feature = "optional_balance_check")]
359 disable_balance_check: false,
360 #[cfg(feature = "optional_block_gas_limit")]
361 disable_block_gas_limit: false,
362 #[cfg(feature = "optional_eip3541")]
363 disable_eip3541: false,
364 #[cfg(feature = "optional_eip3607")]
365 disable_eip3607: false,
366 #[cfg(feature = "optional_eip7623")]
367 disable_eip7623: false,
368 #[cfg(feature = "optional_no_base_fee")]
369 disable_base_fee: false,
370 #[cfg(feature = "optional_priority_fee_check")]
371 disable_priority_fee_check: false,
372 #[cfg(feature = "optional_fee_charge")]
373 disable_fee_charge: false,
374 enable_amsterdam_eip8037: is_amsterdam,
375 enable_amsterdam_eip2780: is_amsterdam,
376 amsterdam_eip7708_disabled: false,
377 amsterdam_eip8246_delayed_clear_disabled: false,
378 }
379 }
380
381 pub fn blob_base_fee_update_fraction(&self) -> u64 {
388 self.blob_base_fee_update_fraction.unwrap_or_else(|| {
389 let spec: SpecId = self.spec.clone().into();
390 if spec.is_enabled_in(SpecId::PRAGUE) {
391 primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE
392 } else {
393 primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN
394 }
395 })
396 }
397
398 pub fn new_with_spec(spec: SPEC) -> Self {
403 Self::new_with_spec_and_gas_params(spec.clone(), GasParams::new_spec(spec.into()))
404 }
405
406 pub fn with_mainnet_gas_params(mut self) -> Self {
410 self.set_gas_params(GasParams::new_spec(self.spec.clone().into()));
411 self
412 }
413
414 #[inline]
418 pub fn set_spec_and_mainnet_gas_params(&mut self, spec: SPEC) {
419 self.spec = spec.clone();
420 self.set_gas_params(GasParams::new_spec(spec.clone().into()));
421 if spec.into().is_enabled_in(SpecId::AMSTERDAM) {
423 self.enable_amsterdam_eip8037 = true;
424 self.enable_amsterdam_eip2780 = true;
425 }
426 }
427}
428
429impl<SPEC: Into<SpecId> + Clone> Cfg for CfgEnv<SPEC> {
430 type Spec = SPEC;
431
432 #[inline]
433 fn chain_id(&self) -> u64 {
434 self.chain_id
435 }
436
437 #[inline]
438 fn spec(&self) -> Self::Spec {
439 self.spec.clone()
440 }
441
442 #[inline]
443 fn tx_chain_id_check(&self) -> bool {
444 self.tx_chain_id_check
445 }
446
447 #[inline]
448 fn tx_gas_limit_cap(&self) -> u64 {
449 self.tx_gas_limit_cap
450 .unwrap_or(if self.spec.clone().into().is_enabled_in(SpecId::OSAKA) {
451 eip7825::TX_GAS_LIMIT_CAP
452 } else {
453 u64::MAX
454 })
455 }
456
457 #[inline]
458 fn max_blobs_per_tx(&self) -> Option<u64> {
459 self.max_blobs_per_tx
460 }
461
462 fn max_code_size(&self) -> usize {
463 self.limit_contract_code_size.unwrap_or(
464 if self.spec.clone().into().is_enabled_in(SpecId::AMSTERDAM) {
465 eip7954::MAX_CODE_SIZE
466 } else {
467 eip170::MAX_CODE_SIZE
468 },
469 )
470 }
471
472 fn max_initcode_size(&self) -> usize {
473 self.limit_contract_initcode_size
474 .or_else(|| {
475 self.limit_contract_code_size
476 .map(|size| size.saturating_mul(2))
477 })
478 .unwrap_or(
479 if self.spec.clone().into().is_enabled_in(SpecId::AMSTERDAM) {
480 eip7954::MAX_INITCODE_SIZE
481 } else {
482 eip3860::MAX_INITCODE_SIZE
483 },
484 )
485 }
486
487 fn is_eip3541_disabled(&self) -> bool {
488 cfg_if::cfg_if! {
489 if #[cfg(feature = "optional_eip3541")] {
490 self.disable_eip3541
491 } else {
492 false
493 }
494 }
495 }
496
497 fn is_eip3607_disabled(&self) -> bool {
498 cfg_if::cfg_if! {
499 if #[cfg(feature = "optional_eip3607")] {
500 self.disable_eip3607
501 } else {
502 false
503 }
504 }
505 }
506
507 fn is_eip7623_disabled(&self) -> bool {
508 cfg_if::cfg_if! {
509 if #[cfg(feature = "optional_eip7623")] {
510 self.disable_eip7623
511 } else {
512 false
513 }
514 }
515 }
516
517 fn is_balance_check_disabled(&self) -> bool {
518 cfg_if::cfg_if! {
519 if #[cfg(feature = "optional_balance_check")] {
520 self.disable_balance_check
521 } else {
522 false
523 }
524 }
525 }
526
527 fn is_block_gas_limit_disabled(&self) -> bool {
529 cfg_if::cfg_if! {
530 if #[cfg(feature = "optional_block_gas_limit")] {
531 self.disable_block_gas_limit
532 } else {
533 false
534 }
535 }
536 }
537
538 fn is_nonce_check_disabled(&self) -> bool {
539 self.disable_nonce_check
540 }
541
542 fn is_base_fee_check_disabled(&self) -> bool {
543 cfg_if::cfg_if! {
544 if #[cfg(feature = "optional_no_base_fee")] {
545 self.disable_base_fee
546 } else {
547 false
548 }
549 }
550 }
551
552 fn is_priority_fee_check_disabled(&self) -> bool {
553 cfg_if::cfg_if! {
554 if #[cfg(feature = "optional_priority_fee_check")] {
555 self.disable_priority_fee_check
556 } else {
557 false
558 }
559 }
560 }
561
562 fn is_fee_charge_disabled(&self) -> bool {
563 cfg_if::cfg_if! {
564 if #[cfg(feature = "optional_fee_charge")] {
565 self.disable_fee_charge
566 } else {
567 false
568 }
569 }
570 }
571
572 fn is_eip7708_disabled(&self) -> bool {
573 self.amsterdam_eip7708_disabled
574 }
575
576 fn is_eip8246_delayed_clear_disabled(&self) -> bool {
577 self.amsterdam_eip8246_delayed_clear_disabled
578 }
579
580 fn memory_limit(&self) -> u64 {
581 cfg_if::cfg_if! {
582 if #[cfg(feature = "memory_limit")] {
583 self.memory_limit
584 } else {
585 u64::MAX
586 }
587 }
588 }
589
590 #[inline]
591 fn gas_params(&self) -> &GasParams {
592 &self.gas_params
593 }
594
595 fn is_amsterdam_eip8037_enabled(&self) -> bool {
596 self.enable_amsterdam_eip8037
597 }
598
599 fn is_amsterdam_eip2780_enabled(&self) -> bool {
600 self.enable_amsterdam_eip2780
601 }
602}
603
604impl<SPEC: Default + Into<SpecId> + Clone> Default for CfgEnv<SPEC> {
605 fn default() -> Self {
606 Self::new_with_spec_and_gas_params(
607 SPEC::default(),
608 GasParams::new_spec(SPEC::default().into()),
609 )
610 }
611}
612
613#[cfg(test)]
614mod test {
615 use super::*;
616
617 #[test]
618 fn blob_max_and_target_count() {
619 let cfg: CfgEnv = Default::default();
620 assert_eq!(cfg.max_blobs_per_tx(), None);
621 }
622}