miden_protocol/account/storage/slot/
slot_id.rs1use core::cmp::Ordering;
2use core::fmt::Display;
3use core::hash::Hash;
4
5use miden_core::utils::hash_string_to_word;
6
7use crate::Felt;
8use crate::utils::serde::{
9 ByteReader,
10 ByteWriter,
11 Deserializable,
12 DeserializationError,
13 Serializable,
14};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub struct StorageSlotId {
25 suffix: Felt,
26 prefix: Felt,
27}
28
29impl StorageSlotId {
30 pub fn new(suffix: Felt, prefix: Felt) -> Self {
35 Self { suffix, prefix }
36 }
37
38 pub(super) fn from_str(name: &str) -> StorageSlotId {
42 let hashed_word = hash_string_to_word(name);
43 let suffix = hashed_word[0];
44 let prefix = hashed_word[1];
45 StorageSlotId::new(suffix, prefix)
46 }
47
48 pub fn suffix(&self) -> Felt {
53 self.suffix
54 }
55
56 pub fn prefix(&self) -> Felt {
58 self.prefix
59 }
60
61 fn as_u128(&self) -> u128 {
63 let mut le_bytes = [0_u8; 16];
64 le_bytes[..8].copy_from_slice(&self.suffix().as_int().to_le_bytes());
65 le_bytes[8..].copy_from_slice(&self.prefix().as_int().to_le_bytes());
66 u128::from_le_bytes(le_bytes)
67 }
68}
69
70impl Ord for StorageSlotId {
71 fn cmp(&self, other: &Self) -> Ordering {
72 match self.prefix.as_int().cmp(&other.prefix.as_int()) {
73 ord @ Ordering::Less | ord @ Ordering::Greater => ord,
74 Ordering::Equal => self.suffix.as_int().cmp(&other.suffix.as_int()),
75 }
76 }
77}
78
79impl PartialOrd for StorageSlotId {
80 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
81 Some(self.cmp(other))
82 }
83}
84
85impl Hash for StorageSlotId {
86 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
87 self.suffix.inner().hash(state);
88 self.prefix.inner().hash(state);
89 }
90}
91
92impl Display for StorageSlotId {
93 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
97 f.write_fmt(format_args!("0x{:032x}", self.as_u128()))
98 }
99}
100
101impl Serializable for StorageSlotId {
102 fn write_into<W: ByteWriter>(&self, target: &mut W) {
103 self.suffix.write_into(target);
104 self.prefix.write_into(target);
105 }
106}
107
108impl Deserializable for StorageSlotId {
109 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
110 let suffix = Felt::read_from(source)?;
111 let prefix = Felt::read_from(source)?;
112 Ok(StorageSlotId::new(suffix, prefix))
113 }
114}
115
116#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn test_slot_id_as_u128() {
125 let suffix = 5;
126 let prefix = 3;
127 let slot_id = StorageSlotId::new(Felt::from(suffix as u32), Felt::from(prefix as u32));
128 assert_eq!(slot_id.as_u128(), (prefix << 64) + suffix);
129 assert_eq!(format!("{slot_id}"), "0x00000000000000030000000000000005");
130 }
131}