stratus/eth/primitives/
slot_index.rs1use std::fmt::Display;
2use std::io::Read;
3
4use alloy_primitives::FixedBytes;
5use alloy_primitives::U256;
6use alloy_primitives::keccak256;
7use display_json::DebugAsJson;
8use fake::Dummy;
9use fake::Faker;
10
11#[derive(DebugAsJson, Clone, Copy, Default, Hash, Eq, PartialEq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
12pub struct SlotIndex(pub U256);
13
14impl SlotIndex {
15 pub const ZERO: SlotIndex = SlotIndex(U256::ZERO);
16 pub const ONE: SlotIndex = SlotIndex(U256::ONE);
17
18 pub fn to_mapping_index(&self, key: Vec<u8>) -> SlotIndex {
20 let slot_index_bytes: [u8; 32] = self.0.to_be_bytes();
22
23 let mut key_bytes = [0u8; 32];
25 let _ = key.take(32).read(&mut key_bytes[32usize.saturating_sub(key.len())..32]);
26
27 let mut mapping_index_bytes = [0u8; 64];
29 mapping_index_bytes[0..32].copy_from_slice(&key_bytes);
30 mapping_index_bytes[32..64].copy_from_slice(&slot_index_bytes);
31
32 let hashed_bytes = keccak256(mapping_index_bytes);
33 Self::from(hashed_bytes)
34 }
35}
36
37impl Dummy<Faker> for SlotIndex {
38 fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &Faker, rng: &mut R) -> Self {
39 Self(U256::random_with(rng))
40 }
41}
42
43impl Display for SlotIndex {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 write!(f, "{:#x}", self.0)
46 }
47}
48
49impl From<U256> for SlotIndex {
54 fn from(value: U256) -> Self {
55 Self(value)
56 }
57}
58
59impl From<[u8; 32]> for SlotIndex {
60 fn from(value: [u8; 32]) -> Self {
61 Self(U256::from_be_bytes(value))
62 }
63}
64
65impl From<[u64; 4]> for SlotIndex {
66 fn from(value: [u64; 4]) -> Self {
67 Self(U256::from_limbs(value))
68 }
69}
70
71impl From<FixedBytes<32>> for SlotIndex {
72 fn from(value: FixedBytes<32>) -> Self {
73 Self::from(value.0)
74 }
75}
76
77#[cfg(test)]
82mod tests {
83 use hex_literal::hex;
84
85 use crate::eth::primitives::SlotIndex;
86
87 #[test]
88 fn slot_index_to_mapping_index() {
89 let address = hex!("3c44cdddb6a900fa2b585dd299e03d12fa4293bc").to_vec();
90 let hashed = SlotIndex::ZERO.to_mapping_index(address);
91 assert_eq!(hashed.to_string(), "0x215be5d23550ceb1beff54fb579a765903ba2ccc85b6f79bcf9bda4e8cb86034");
92 }
93}