miden_objects/account/storage/
header.rs1use alloc::vec::Vec;
2
3use super::{AccountStorage, Felt, StorageSlot, StorageSlotType, Word};
4use crate::{
5 AccountError, ZERO,
6 utils::serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
7};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct StorageSlotHeader(StorageSlotType, Word);
19
20impl StorageSlotHeader {
21 pub fn new(value: &(StorageSlotType, Word)) -> Self {
23 Self(value.0, value.1)
24 }
25
26 pub fn as_elements(&self) -> [Felt; StorageSlot::NUM_ELEMENTS_PER_STORAGE_SLOT] {
33 let mut elements = [ZERO; StorageSlot::NUM_ELEMENTS_PER_STORAGE_SLOT];
34 elements[0..4].copy_from_slice(&self.1);
35 elements[4..8].copy_from_slice(&self.0.as_word());
36 elements
37 }
38}
39
40impl From<&StorageSlot> for StorageSlotHeader {
41 fn from(value: &StorageSlot) -> Self {
42 Self(value.slot_type(), value.value())
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct AccountStorageHeader {
53 slots: Vec<(StorageSlotType, Word)>,
54}
55
56impl AccountStorageHeader {
57 pub fn new(slots: Vec<(StorageSlotType, Word)>) -> Self {
65 assert!(slots.len() <= AccountStorage::MAX_NUM_STORAGE_SLOTS);
66 Self { slots }
67 }
68
69 pub fn slots(&self) -> impl Iterator<Item = &(StorageSlotType, Word)> {
74 self.slots.iter()
75 }
76
77 pub fn num_slots(&self) -> usize {
79 self.slots.len()
80 }
81
82 pub fn slot(&self, index: usize) -> Result<&(StorageSlotType, Word), AccountError> {
87 self.slots.get(index).ok_or(AccountError::StorageIndexOutOfBounds {
88 slots_len: self.slots.len() as u8,
89 index: index as u8,
90 })
91 }
92
93 pub fn as_elements(&self) -> Vec<Felt> {
101 self.slots
102 .iter()
103 .flat_map(|slot| StorageSlotHeader::new(slot).as_elements())
104 .collect()
105 }
106}
107
108impl From<AccountStorage> for AccountStorageHeader {
109 fn from(value: AccountStorage) -> Self {
110 value.get_header()
111 }
112}
113
114impl Serializable for AccountStorageHeader {
118 fn write_into<W: ByteWriter>(&self, target: &mut W) {
119 let len = self.slots.len() as u8;
120 target.write_u8(len);
121 target.write_many(self.slots())
122 }
123}
124
125impl Deserializable for AccountStorageHeader {
126 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
127 let len = source.read_u8()?;
128 let slots = source.read_many(len as usize)?;
129 Ok(Self::new(slots))
131 }
132}
133
134#[cfg(test)]
138mod tests {
139 use vm_core::{
140 Felt,
141 utils::{Deserializable, Serializable},
142 };
143
144 use super::AccountStorageHeader;
145 use crate::account::{AccountStorage, StorageSlotType};
146
147 #[test]
148 fn test_from_account_storage() {
149 let slots = vec![
151 (StorageSlotType::Value, [Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)]),
152 (StorageSlotType::Value, [Felt::new(5), Felt::new(6), Felt::new(7), Felt::new(8)]),
153 (
154 StorageSlotType::Map,
155 [
156 Felt::new(12405212884040084310),
157 Felt::new(17614307840949763446),
158 Felt::new(6101527485586301500),
159 Felt::new(14442045877206841081),
160 ],
161 ),
162 ];
163
164 let expected_header = AccountStorageHeader { slots };
165 let account_storage = AccountStorage::mock();
166
167 assert_eq!(expected_header, AccountStorageHeader::from(account_storage))
168 }
169
170 #[test]
171 fn test_serde_account_storage_header() {
172 let storage = AccountStorage::mock();
174 let storage_header = AccountStorageHeader::from(storage);
175
176 let bytes = storage_header.to_bytes();
178 let deserialized = AccountStorageHeader::read_from_bytes(&bytes).unwrap();
179
180 assert_eq!(storage_header, deserialized);
182 }
183}