1use alloy_primitives::{B256, U256, keccak256};
4
5pub const L1_PRICING_SUBSPACE: &[u8] = &[0];
7pub const L2_PRICING_SUBSPACE: &[u8] = &[1];
8pub const RETRYABLES_SUBSPACE: &[u8] = &[2];
9pub const ADDRESS_TABLE_SUBSPACE: &[u8] = &[3];
10pub const CHAIN_OWNER_SUBSPACE: &[u8] = &[4];
11pub const SEND_MERKLE_SUBSPACE: &[u8] = &[5];
12pub const BLOCKHASHES_SUBSPACE: &[u8] = &[6];
13pub const CHAIN_CONFIG_SUBSPACE: &[u8] = &[7];
14pub const PROGRAMS_SUBSPACE: &[u8] = &[8];
15pub const FEATURES_SUBSPACE: &[u8] = &[9];
16pub const NATIVE_TOKEN_SUBSPACE: &[u8] = &[10];
17pub const TRANSACTION_FILTERER_SUBSPACE: &[u8] = &[11];
18
19pub const VERSION_OFFSET: u64 = 0;
21pub const UPGRADE_VERSION_OFFSET: u64 = 1;
22pub const UPGRADE_TIMESTAMP_OFFSET: u64 = 2;
23pub const NETWORK_FEE_ACCOUNT_OFFSET: u64 = 3;
24pub const CHAIN_ID_OFFSET: u64 = 4;
25pub const GENESIS_BLOCK_NUM_OFFSET: u64 = 5;
26pub const INFRA_FEE_ACCOUNT_OFFSET: u64 = 6;
27pub const BROTLI_COMPRESSION_LEVEL_OFFSET: u64 = 7;
28pub const NATIVE_TOKEN_ENABLED_FROM_TIME_OFFSET: u64 = 8;
29pub const TRANSACTION_FILTERING_ENABLED_FROM_TIME_OFFSET: u64 = 9;
30pub const FILTERED_FUNDS_RECIPIENT_OFFSET: u64 = 10;
31pub const COLLECT_TIPS_OFFSET: u64 = 11;
32
33pub mod programs {
35 pub const PARAMS_KEY: &[u8] = &[0];
36 pub const PROGRAM_DATA_KEY: &[u8] = &[1];
37 pub const MODULE_HASHES_KEY: &[u8] = &[2];
38 pub const DATA_PRICER_KEY: &[u8] = &[3];
39 pub const CACHE_MANAGERS_KEY: &[u8] = &[4];
40 pub const ACTIVATION_GAS_KEY: &[u8] = &[5];
41}
42
43pub const ROOT_STORAGE_KEY: &[u8] = &[];
44
45pub fn map_slot(storage_key: &[u8], offset: u64) -> U256 {
50 const BOUNDARY: usize = 31;
51
52 let mut key_bytes = [0u8; 32];
53 key_bytes[24..32].copy_from_slice(&offset.to_be_bytes());
54
55 let mut buf = [0u8; 64];
56 let sk_len = storage_key.len();
57 buf[..sk_len].copy_from_slice(storage_key);
58 buf[sk_len..sk_len + BOUNDARY].copy_from_slice(&key_bytes[..BOUNDARY]);
59 let h = keccak256(&buf[..sk_len + BOUNDARY]);
60
61 let mut mapped = [0u8; 32];
62 mapped[..BOUNDARY].copy_from_slice(&h.0[..BOUNDARY]);
63 mapped[BOUNDARY] = key_bytes[BOUNDARY];
64 U256::from_be_bytes(mapped)
65}
66
67pub fn map_slot_b256(storage_key: &[u8], key: &B256) -> U256 {
69 const BOUNDARY: usize = 31;
70
71 let mut buf = [0u8; 64];
72 let sk_len = storage_key.len();
73 buf[..sk_len].copy_from_slice(storage_key);
74 buf[sk_len..sk_len + BOUNDARY].copy_from_slice(&key.0[..BOUNDARY]);
75 let h = keccak256(&buf[..sk_len + BOUNDARY]);
76
77 let mut mapped = [0u8; 32];
78 mapped[..BOUNDARY].copy_from_slice(&h.0[..BOUNDARY]);
79 mapped[BOUNDARY] = key.0[BOUNDARY];
80 U256::from_be_bytes(mapped)
81}
82
83pub fn derive_subspace_key(parent_key: &[u8], sub_key: &[u8]) -> B256 {
87 let p_len = parent_key.len();
88 let s_len = sub_key.len();
89 if p_len + s_len <= 64 {
90 let mut buf = [0u8; 64];
91 buf[..p_len].copy_from_slice(parent_key);
92 buf[p_len..p_len + s_len].copy_from_slice(sub_key);
93 keccak256(&buf[..p_len + s_len])
94 } else {
95 let mut v = Vec::with_capacity(p_len + s_len);
96 v.extend_from_slice(parent_key);
97 v.extend_from_slice(sub_key);
98 keccak256(&v)
99 }
100}
101
102#[inline]
104pub fn root_slot(offset: u64) -> U256 {
105 map_slot(ROOT_STORAGE_KEY, offset)
106}
107
108pub fn subspace_slot(subspace_key: &[u8], offset: u64) -> U256 {
110 let sub_storage_key = derive_subspace_key(ROOT_STORAGE_KEY, subspace_key);
111 map_slot(sub_storage_key.as_slice(), offset)
112}
113
114fn l2_pricing_subspace() -> B256 {
115 derive_subspace_key(ROOT_STORAGE_KEY, L2_PRICING_SUBSPACE)
116}
117
118const GAS_CONSTRAINTS_SUBKEY: &[u8] = &[0];
119
120fn l2_vector_key(sub_key: &[u8]) -> B256 {
121 derive_subspace_key(l2_pricing_subspace().as_slice(), sub_key)
122}
123
124fn vector_element_key(vector_key: &B256, index: u64) -> B256 {
125 derive_subspace_key(vector_key.as_slice(), &index.to_be_bytes())
126}
127
128pub fn vector_element_field(vector_key: &B256, index: u64, offset: u64) -> U256 {
130 let elem = vector_element_key(vector_key, index);
131 map_slot(elem.as_slice(), offset)
132}
133
134pub fn gas_constraints_vec_key() -> B256 {
136 l2_vector_key(GAS_CONSTRAINTS_SUBKEY)
137}