1pub use context_interface::Cfg;
3
4use primitives::{eip170::MAX_CODE_SIZE, hardfork::SpecId};
5
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[derive(Clone, Debug, Eq, PartialEq)]
9#[non_exhaustive]
10pub struct CfgEnv<SPEC = SpecId> {
11 pub chain_id: u64,
15
16 pub tx_chain_id_check: bool,
20
21 pub spec: SPEC,
23 pub limit_contract_code_size: Option<usize>,
29 pub disable_nonce_check: bool,
31 pub blob_max_count: Option<u64>,
35 pub blob_base_fee_update_fraction: Option<u64>,
43 #[cfg(feature = "memory_limit")]
51 pub memory_limit: u64,
52 #[cfg(feature = "optional_balance_check")]
58 pub disable_balance_check: bool,
59 #[cfg(feature = "optional_block_gas_limit")]
65 pub disable_block_gas_limit: bool,
66 #[cfg(feature = "optional_eip3607")]
72 pub disable_eip3607: bool,
73 #[cfg(feature = "optional_no_base_fee")]
79 pub disable_base_fee: bool,
80}
81
82impl CfgEnv {
83 pub fn new() -> Self {
85 Self::default()
86 }
87}
88
89impl<SPEC: Into<SpecId> + Copy> CfgEnv<SPEC> {
90 pub fn blob_base_fee_update_fraction(&mut self) -> u64 {
97 self.blob_base_fee_update_fraction.unwrap_or_else(|| {
98 let spec: SpecId = self.spec.into();
99 if spec.is_enabled_in(SpecId::PRAGUE) {
100 primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE
101 } else {
102 primitives::eip4844::BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN
103 }
104 })
105 }
106}
107
108impl<SPEC> CfgEnv<SPEC> {
109 pub fn new_with_spec(spec: SPEC) -> Self {
111 Self {
112 chain_id: 1,
113 tx_chain_id_check: false,
114 limit_contract_code_size: None,
115 spec,
116 disable_nonce_check: false,
117 blob_max_count: None,
118 blob_base_fee_update_fraction: None,
119 #[cfg(feature = "memory_limit")]
120 memory_limit: (1 << 32) - 1,
121 #[cfg(feature = "optional_balance_check")]
122 disable_balance_check: false,
123 #[cfg(feature = "optional_block_gas_limit")]
124 disable_block_gas_limit: false,
125 #[cfg(feature = "optional_eip3607")]
126 disable_eip3607: false,
127 #[cfg(feature = "optional_no_base_fee")]
128 disable_base_fee: false,
129 }
130 }
131
132 pub fn with_chain_id(mut self, chain_id: u64) -> Self {
134 self.chain_id = chain_id;
135 self
136 }
137
138 pub fn enable_tx_chain_id_check(mut self) -> Self {
140 self.tx_chain_id_check = true;
141 self
142 }
143
144 pub fn disable_tx_chain_id_check(mut self) -> Self {
146 self.tx_chain_id_check = false;
147 self
148 }
149
150 pub fn with_spec<OSPEC: Into<SpecId>>(self, spec: OSPEC) -> CfgEnv<OSPEC> {
152 CfgEnv {
153 chain_id: self.chain_id,
154 tx_chain_id_check: self.tx_chain_id_check,
155 limit_contract_code_size: self.limit_contract_code_size,
156 spec,
157 disable_nonce_check: self.disable_nonce_check,
158 blob_max_count: self.blob_max_count,
159 blob_base_fee_update_fraction: self.blob_base_fee_update_fraction,
160 #[cfg(feature = "memory_limit")]
161 memory_limit: self.memory_limit,
162 #[cfg(feature = "optional_balance_check")]
163 disable_balance_check: self.disable_balance_check,
164 #[cfg(feature = "optional_block_gas_limit")]
165 disable_block_gas_limit: self.disable_block_gas_limit,
166 #[cfg(feature = "optional_eip3607")]
167 disable_eip3607: self.disable_eip3607,
168 #[cfg(feature = "optional_no_base_fee")]
169 disable_base_fee: self.disable_base_fee,
170 }
171 }
172
173 pub fn with_blob_max_count(mut self, blob_max_count: u64) -> Self {
175 self.set_blob_max_count(blob_max_count);
176 self
177 }
178
179 pub fn set_blob_max_count(&mut self, blob_max_count: u64) {
181 self.blob_max_count = Some(blob_max_count);
182 }
183
184 pub fn clear_blob_max_count(&mut self) {
186 self.blob_max_count = None;
187 }
188}
189
190impl<SPEC: Into<SpecId> + Copy> Cfg for CfgEnv<SPEC> {
191 type Spec = SPEC;
192
193 fn chain_id(&self) -> u64 {
194 self.chain_id
195 }
196
197 fn spec(&self) -> Self::Spec {
198 self.spec
199 }
200
201 fn tx_chain_id_check(&self) -> bool {
202 self.tx_chain_id_check
203 }
204
205 #[inline]
206 fn blob_max_count(&self) -> Option<u64> {
207 self.blob_max_count
208 }
209
210 fn max_code_size(&self) -> usize {
211 self.limit_contract_code_size.unwrap_or(MAX_CODE_SIZE)
212 }
213
214 fn is_eip3607_disabled(&self) -> bool {
215 cfg_if::cfg_if! {
216 if #[cfg(feature = "optional_eip3607")] {
217 self.disable_eip3607
218 } else {
219 false
220 }
221 }
222 }
223
224 fn is_balance_check_disabled(&self) -> bool {
225 cfg_if::cfg_if! {
226 if #[cfg(feature = "optional_balance_check")] {
227 self.disable_balance_check
228 } else {
229 false
230 }
231 }
232 }
233
234 fn is_block_gas_limit_disabled(&self) -> bool {
236 cfg_if::cfg_if! {
237 if #[cfg(feature = "optional_block_gas_limit")] {
238 self.disable_block_gas_limit
239 } else {
240 false
241 }
242 }
243 }
244
245 fn is_nonce_check_disabled(&self) -> bool {
246 self.disable_nonce_check
247 }
248
249 fn is_base_fee_check_disabled(&self) -> bool {
250 cfg_if::cfg_if! {
251 if #[cfg(feature = "optional_no_base_fee")] {
252 self.disable_base_fee
253 } else {
254 false
255 }
256 }
257 }
258}
259
260impl<SPEC: Default> Default for CfgEnv<SPEC> {
261 fn default() -> Self {
262 Self::new_with_spec(SPEC::default())
263 }
264}
265
266#[cfg(test)]
267mod test {
268 use super::*;
269
270 #[test]
271 fn blob_max_and_target_count() {
272 let cfg: CfgEnv = Default::default();
273 assert_eq!(cfg.blob_max_count(), None);
274 }
275}