1use std::marker::PhantomData;
2
3use alloy_primitives::U256;
4use arb_storage::{StorageBackedBigUint, StorageBackend, SystemStateBackend};
5
6mod error;
7pub use error::FeaturesError;
8
9const INCREASED_CALLDATA: usize = 0;
10
11pub struct Features<'a, D> {
13 features: StorageBackedBigUint,
14 _phantom: PhantomData<&'a mut revm::database::State<D>>,
15}
16
17pub fn open_features<'a, D>(base_key: alloy_primitives::B256, offset: u64) -> Features<'a, D> {
18 Features {
19 features: StorageBackedBigUint::new(base_key, offset),
20 _phantom: PhantomData,
21 }
22}
23
24impl<D> Features<'_, D> {
25 pub fn set_calldata_price_increase<B: StorageBackend>(
28 &self,
29 backend: &mut B,
30 enabled: bool,
31 ) -> Result<U256, FeaturesError> {
32 self.set_bit(backend, INCREASED_CALLDATA, enabled)
33 }
34
35 pub fn is_increased_calldata_price_enabled<B: SystemStateBackend>(
36 &self,
37 backend: &mut B,
38 ) -> Result<bool, FeaturesError> {
39 self.is_set(backend, INCREASED_CALLDATA)
40 }
41
42 fn set_bit<B: StorageBackend>(
43 &self,
44 backend: &mut B,
45 index: usize,
46 enabled: bool,
47 ) -> Result<U256, FeaturesError> {
48 let mut val = self.features.get(backend)?;
49 if enabled {
50 val |= U256::from(1) << index;
51 } else {
52 val &= !(U256::from(1) << index);
53 }
54 self.features.set(backend, val)?;
55 Ok(val)
56 }
57
58 fn is_set<B: SystemStateBackend>(
59 &self,
60 backend: &mut B,
61 index: usize,
62 ) -> Result<bool, FeaturesError> {
63 let val = self.features.get(backend)?;
64 Ok((val >> index) & U256::from(1) != U256::ZERO)
65 }
66}