1pub use context_interface::Cfg;
3
4use context_interface::cfg::GasParams;
5use primitives::{eip170, eip3860, eip7825, 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 amsterdam_eip7708_disabled: bool,
137 pub amsterdam_eip7708_delayed_burn_disabled: bool,
147}
148
149impl CfgEnv {
150 pub fn new() -> Self {
152 Self::default()
153 }
154}
155
156impl<SPEC> CfgEnv<SPEC> {
157 pub fn new_with_spec_and_gas_params(spec: SPEC, gas_params: GasParams) -> Self {
159 Self {
160 chain_id: 1,
161 tx_chain_id_check: true,
162 limit_contract_code_size: None,
163 limit_contract_initcode_size: None,
164 spec,
165 disable_nonce_check: false,
166 max_blobs_per_tx: None,
167 tx_gas_limit_cap: None,
168 blob_base_fee_update_fraction: None,
169 gas_params,
170 #[cfg(feature = "memory_limit")]
171 memory_limit: (1 << 32) - 1,
172 #[cfg(feature = "optional_balance_check")]
173 disable_balance_check: false,
174 #[cfg(feature = "optional_block_gas_limit")]
175 disable_block_gas_limit: false,
176 #[cfg(feature = "optional_eip3541")]
177 disable_eip3541: false,
178 #[cfg(feature = "optional_eip3607")]
179 disable_eip3607: false,
180 #[cfg(feature = "optional_eip7623")]
181 disable_eip7623: false,
182 #[cfg(feature = "optional_no_base_fee")]
183 disable_base_fee: false,
184 #[cfg(feature = "optional_priority_fee_check")]
185 disable_priority_fee_check: false,
186 #[cfg(feature = "optional_fee_charge")]
187 disable_fee_charge: false,
188 amsterdam_eip7708_disabled: false,
189 amsterdam_eip7708_delayed_burn_disabled: false,
190 }
191 }
192
193 #[inline]
195 pub fn spec(&self) -> &SPEC {
196 &self.spec
197 }
198
199 pub fn with_chain_id(mut self, chain_id: u64) -> Self {
201 self.chain_id = chain_id;
202 self
203 }
204
205 #[inline]
207 pub fn with_gas_params(mut self, gas_params: GasParams) -> Self {
208 self.set_gas_params(gas_params);
209 self
210 }
211
212 #[inline]
214 pub fn set_spec(&mut self, spec: SPEC) {
215 self.spec = spec;
216 }
217
218 #[inline]
220 pub fn set_gas_params(&mut self, gas_params: GasParams) {
221 self.gas_params = gas_params;
222 }
223
224 pub fn enable_tx_chain_id_check(mut self) -> Self {
226 self.tx_chain_id_check = true;
227 self
228 }
229
230 pub fn disable_tx_chain_id_check(mut self) -> Self {
232 self.tx_chain_id_check = false;
233 self
234 }
235
236 #[inline]
238 #[deprecated(
239 since = "0.1.0",
240 note = "Use [`CfgEnv::with_spec_and_mainnet_gas_params`] instead"
241 )]
242 pub fn with_spec(mut self, spec: SPEC) -> Self {
243 self.spec = spec;
244 self
245 }
246
247 pub fn with_spec_and_mainnet_gas_params<OSPEC: Into<SpecId> + Clone>(
249 self,
250 spec: OSPEC,
251 ) -> CfgEnv<OSPEC> {
252 self.with_spec_and_gas_params(spec.clone(), GasParams::new_spec(spec.into()))
253 }
254
255 pub fn with_spec_and_gas_params<OSPEC: Into<SpecId> + Clone>(
259 self,
260 spec: OSPEC,
261 gas_params: GasParams,
262 ) -> CfgEnv<OSPEC> {
263 CfgEnv {
264 chain_id: self.chain_id,
265 tx_chain_id_check: self.tx_chain_id_check,
266 limit_contract_code_size: self.limit_contract_code_size,
267 limit_contract_initcode_size: self.limit_contract_initcode_size,
268 spec,
269 disable_nonce_check: self.disable_nonce_check,
270 tx_gas_limit_cap: self.tx_gas_limit_cap,
271 max_blobs_per_tx: self.max_blobs_per_tx,
272 blob_base_fee_update_fraction: self.blob_base_fee_update_fraction,
273 gas_params,
274 #[cfg(feature = "memory_limit")]
275 memory_limit: self.memory_limit,
276 #[cfg(feature = "optional_balance_check")]
277 disable_balance_check: self.disable_balance_check,
278 #[cfg(feature = "optional_block_gas_limit")]
279 disable_block_gas_limit: self.disable_block_gas_limit,
280 #[cfg(feature = "optional_eip3541")]
281 disable_eip3541: self.disable_eip3541,
282 #[cfg(feature = "optional_eip3607")]
283 disable_eip3607: self.disable_eip3607,
284 #[cfg(feature = "optional_eip7623")]
285 disable_eip7623: self.disable_eip7623,
286 #[cfg(feature = "optional_no_base_fee")]
287 disable_base_fee: self.disable_base_fee,
288 #[cfg(feature = "optional_priority_fee_check")]
289 disable_priority_fee_check: self.disable_priority_fee_check,
290 #[cfg(feature = "optional_fee_charge")]
291 disable_fee_charge: self.disable_fee_charge,
292 amsterdam_eip7708_disabled: self.amsterdam_eip7708_disabled,
293 amsterdam_eip7708_delayed_burn_disabled: self.amsterdam_eip7708_delayed_burn_disabled,
294 }
295 }
296
297 pub fn with_max_blobs_per_tx(mut self, max_blobs_per_tx: u64) -> Self {
299 self.set_max_blobs_per_tx(max_blobs_per_tx);
300 self
301 }
302
303 pub fn set_max_blobs_per_tx(&mut self, max_blobs_per_tx: u64) {
305 self.max_blobs_per_tx = Some(max_blobs_per_tx);
306 }
307
308 pub fn clear_max_blobs_per_tx(&mut self) {
310 self.max_blobs_per_tx = None;
311 }
312
313 #[cfg(feature = "optional_priority_fee_check")]
315 pub fn with_disable_priority_fee_check(mut self, disable: bool) -> Self {
316 self.disable_priority_fee_check = disable;
317 self
318 }
319
320 #[cfg(feature = "optional_fee_charge")]
322 pub fn with_disable_fee_charge(mut self, disable: bool) -> Self {
323 self.disable_fee_charge = disable;
324 self
325 }
326
327 #[cfg(feature = "optional_eip7623")]
329 pub fn with_disable_eip7623(mut self, disable: bool) -> Self {
330 self.disable_eip7623 = disable;
331 self
332 }
333}
334
335impl<SPEC: Into<SpecId> + Clone> CfgEnv<SPEC> {
336 pub fn blob_base_fee_update_fraction(&mut self) -> u64 {
343 self.blob_base_fee_update_fraction.unwrap_or_else(|| {
344 let spec: SpecId = self.spec.clone().into();
345 if spec.is_enabled_in(SpecId::PRAGUE) {
346 primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE
347 } else {
348 primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN
349 }
350 })
351 }
352
353 pub fn new_with_spec(spec: SPEC) -> Self {
358 Self::new_with_spec_and_gas_params(spec.clone(), GasParams::new_spec(spec.into()))
359 }
360
361 pub fn with_mainnet_gas_params(mut self) -> Self {
365 self.set_gas_params(GasParams::new_spec(self.spec.clone().into()));
366 self
367 }
368
369 #[inline]
371 pub fn set_spec_and_mainnet_gas_params(&mut self, spec: SPEC) {
372 self.set_spec(spec.clone());
373 self.set_gas_params(GasParams::new_spec(spec.into()));
374 }
375}
376
377impl<SPEC: Into<SpecId> + Clone> Cfg for CfgEnv<SPEC> {
378 type Spec = SPEC;
379
380 #[inline]
381 fn chain_id(&self) -> u64 {
382 self.chain_id
383 }
384
385 #[inline]
386 fn spec(&self) -> Self::Spec {
387 self.spec.clone()
388 }
389
390 #[inline]
391 fn tx_chain_id_check(&self) -> bool {
392 self.tx_chain_id_check
393 }
394
395 #[inline]
396 fn tx_gas_limit_cap(&self) -> u64 {
397 self.tx_gas_limit_cap
398 .unwrap_or(if self.spec.clone().into().is_enabled_in(SpecId::OSAKA) {
399 eip7825::TX_GAS_LIMIT_CAP
400 } else {
401 u64::MAX
402 })
403 }
404
405 #[inline]
406 fn max_blobs_per_tx(&self) -> Option<u64> {
407 self.max_blobs_per_tx
408 }
409
410 fn max_code_size(&self) -> usize {
411 self.limit_contract_code_size
412 .unwrap_or(eip170::MAX_CODE_SIZE)
413 }
414
415 fn max_initcode_size(&self) -> usize {
416 self.limit_contract_initcode_size
417 .or_else(|| {
418 self.limit_contract_code_size
419 .map(|size| size.saturating_mul(2))
420 })
421 .unwrap_or(eip3860::MAX_INITCODE_SIZE)
422 }
423
424 fn is_eip3541_disabled(&self) -> bool {
425 cfg_if::cfg_if! {
426 if #[cfg(feature = "optional_eip3541")] {
427 self.disable_eip3541
428 } else {
429 false
430 }
431 }
432 }
433
434 fn is_eip3607_disabled(&self) -> bool {
435 cfg_if::cfg_if! {
436 if #[cfg(feature = "optional_eip3607")] {
437 self.disable_eip3607
438 } else {
439 false
440 }
441 }
442 }
443
444 fn is_eip7623_disabled(&self) -> bool {
445 cfg_if::cfg_if! {
446 if #[cfg(feature = "optional_eip7623")] {
447 self.disable_eip7623
448 } else {
449 false
450 }
451 }
452 }
453
454 fn is_balance_check_disabled(&self) -> bool {
455 cfg_if::cfg_if! {
456 if #[cfg(feature = "optional_balance_check")] {
457 self.disable_balance_check
458 } else {
459 false
460 }
461 }
462 }
463
464 fn is_block_gas_limit_disabled(&self) -> bool {
466 cfg_if::cfg_if! {
467 if #[cfg(feature = "optional_block_gas_limit")] {
468 self.disable_block_gas_limit
469 } else {
470 false
471 }
472 }
473 }
474
475 fn is_nonce_check_disabled(&self) -> bool {
476 self.disable_nonce_check
477 }
478
479 fn is_base_fee_check_disabled(&self) -> bool {
480 cfg_if::cfg_if! {
481 if #[cfg(feature = "optional_no_base_fee")] {
482 self.disable_base_fee
483 } else {
484 false
485 }
486 }
487 }
488
489 fn is_priority_fee_check_disabled(&self) -> bool {
490 cfg_if::cfg_if! {
491 if #[cfg(feature = "optional_priority_fee_check")] {
492 self.disable_priority_fee_check
493 } else {
494 false
495 }
496 }
497 }
498
499 fn is_fee_charge_disabled(&self) -> bool {
500 cfg_if::cfg_if! {
501 if #[cfg(feature = "optional_fee_charge")] {
502 self.disable_fee_charge
503 } else {
504 false
505 }
506 }
507 }
508
509 fn is_eip7708_disabled(&self) -> bool {
510 self.amsterdam_eip7708_disabled
511 }
512
513 fn is_eip7708_delayed_burn_disabled(&self) -> bool {
514 self.amsterdam_eip7708_delayed_burn_disabled
515 }
516
517 fn memory_limit(&self) -> u64 {
518 cfg_if::cfg_if! {
519 if #[cfg(feature = "memory_limit")] {
520 self.memory_limit
521 } else {
522 u64::MAX
523 }
524 }
525 }
526
527 #[inline]
528 fn gas_params(&self) -> &GasParams {
529 &self.gas_params
530 }
531}
532
533impl<SPEC: Default + Into<SpecId>> Default for CfgEnv<SPEC> {
534 fn default() -> Self {
535 Self::new_with_spec_and_gas_params(
536 SPEC::default(),
537 GasParams::new_spec(SPEC::default().into()),
538 )
539 }
540}
541
542#[cfg(test)]
543mod test {
544 use super::*;
545
546 #[test]
547 fn blob_max_and_target_count() {
548 let cfg: CfgEnv = Default::default();
549 assert_eq!(cfg.max_blobs_per_tx(), None);
550 }
551}