miden_objects/account/storage/
header.rs1use alloc::vec::Vec;
2
3use vm_core::{
4 utils::{ByteReader, ByteWriter, Deserializable, Serializable},
5 ZERO,
6};
7use vm_processor::DeserializationError;
8
9use super::{AccountStorage, Felt, StorageSlot, StorageSlotType, Word};
10use crate::AccountError;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct StorageSlotHeader(StorageSlotType, Word);
22
23impl StorageSlotHeader {
24 pub fn new(value: &(StorageSlotType, Word)) -> Self {
26 Self(value.0, value.1)
27 }
28
29 pub fn as_elements(&self) -> [Felt; StorageSlot::NUM_ELEMENTS_PER_STORAGE_SLOT] {
36 let mut elements = [ZERO; StorageSlot::NUM_ELEMENTS_PER_STORAGE_SLOT];
37 elements[0..4].copy_from_slice(&self.1);
38 elements[4..8].copy_from_slice(&self.0.as_word());
39 elements
40 }
41}
42
43impl From<&StorageSlot> for StorageSlotHeader {
44 fn from(value: &StorageSlot) -> Self {
45 Self(value.slot_type(), value.value())
46 }
47}
48
49#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct AccountStorageHeader {
56 slots: Vec<(StorageSlotType, Word)>,
57}
58
59impl AccountStorageHeader {
60 pub fn new(slots: Vec<(StorageSlotType, Word)>) -> Self {
68 assert!(slots.len() <= AccountStorage::MAX_NUM_STORAGE_SLOTS);
69 Self { slots }
70 }
71
72 pub fn slots(&self) -> impl Iterator<Item = &(StorageSlotType, Word)> {
77 self.slots.iter()
78 }
79
80 pub fn num_slots(&self) -> usize {
82 self.slots.len()
83 }
84
85 pub fn slot(&self, index: usize) -> Result<&(StorageSlotType, Word), AccountError> {
90 self.slots.get(index).ok_or(AccountError::StorageIndexOutOfBounds {
91 slots_len: self.slots.len() as u8,
92 index: index as u8,
93 })
94 }
95
96 pub fn as_elements(&self) -> Vec<Felt> {
104 self.slots
105 .iter()
106 .flat_map(|slot| StorageSlotHeader::new(slot).as_elements())
107 .collect()
108 }
109}
110
111impl From<AccountStorage> for AccountStorageHeader {
112 fn from(value: AccountStorage) -> Self {
113 value.get_header()
114 }
115}
116
117impl Serializable for AccountStorageHeader {
121 fn write_into<W: ByteWriter>(&self, target: &mut W) {
122 let len = self.slots.len() as u8;
123 target.write_u8(len);
124 target.write_many(self.slots())
125 }
126}
127
128impl Deserializable for AccountStorageHeader {
129 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
130 let len = source.read_u8()?;
131 let slots = source.read_many(len as usize)?;
132 Ok(Self::new(slots))
134 }
135}
136
137#[cfg(test)]
141mod tests {
142 use vm_core::{
143 utils::{Deserializable, Serializable},
144 Felt,
145 };
146
147 use super::AccountStorageHeader;
148 use crate::account::{AccountStorage, StorageSlotType};
149
150 #[test]
151 fn test_from_account_storage() {
152 let slots = vec![
154 (StorageSlotType::Value, [Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)]),
155 (StorageSlotType::Value, [Felt::new(5), Felt::new(6), Felt::new(7), Felt::new(8)]),
156 (
157 StorageSlotType::Map,
158 [
159 Felt::new(12405212884040084310),
160 Felt::new(17614307840949763446),
161 Felt::new(6101527485586301500),
162 Felt::new(14442045877206841081),
163 ],
164 ),
165 ];
166
167 let expected_header = AccountStorageHeader { slots };
168 let account_storage = AccountStorage::mock();
169
170 assert_eq!(expected_header, AccountStorageHeader::from(account_storage))
171 }
172
173 #[test]
174 fn test_serde_account_storage_header() {
175 let storage = AccountStorage::mock();
177 let storage_header = AccountStorageHeader::from(storage);
178
179 let bytes = storage_header.to_bytes();
181 let deserialized = AccountStorageHeader::read_from_bytes(&bytes).unwrap();
182
183 assert_eq!(storage_header, deserialized);
185 }
186}