miden_core/mast/serialization/
view.rs1use alloc::{borrow::Cow, collections::BTreeMap, vec::Vec};
2use core::mem::size_of;
3
4use super::{
5 MastNodeEntry, MastNodeInfo,
6 layout::{OffsetTrackingReader, TrackingReader},
7};
8use crate::{
9 Felt, Word,
10 advice::AdviceMap,
11 mast::MastNodeId,
12 serde::{ByteReader, Deserializable, DeserializationError, SliceReader},
13};
14
15const FELT_SERIALIZED_SIZE: usize = size_of::<u64>();
16
17#[derive(Debug)]
19pub struct AdviceValueView<'a> {
20 inner: Cow<'a, [Felt]>,
21}
22
23impl<'a> AdviceValueView<'a> {
24 pub(crate) fn borrowed(values: &'a [Felt]) -> Self {
25 Self { inner: Cow::Borrowed(values) }
26 }
27
28 fn owned(values: Vec<Felt>) -> Self {
29 Self { inner: Cow::Owned(values) }
30 }
31
32 pub fn as_slice(&self) -> &[Felt] {
34 self.inner.as_ref()
35 }
36
37 pub fn len(&self) -> usize {
39 self.as_slice().len()
40 }
41
42 pub fn is_empty(&self) -> bool {
44 self.as_slice().is_empty()
45 }
46}
47
48impl AsRef<[Felt]> for AdviceValueView<'_> {
49 fn as_ref(&self) -> &[Felt] {
50 self.as_slice()
51 }
52}
53
54#[derive(Debug)]
56pub struct AdviceMapView<'a> {
57 inner: AdviceMapViewInner<'a>,
58}
59
60#[derive(Debug)]
61enum AdviceMapViewInner<'a> {
62 Materialized(&'a AdviceMap),
63 Wire(&'a WireAdviceMapView<'a>),
64}
65
66impl<'a> AdviceMapView<'a> {
67 pub(crate) fn materialized(advice_map: &'a AdviceMap) -> Self {
68 Self {
69 inner: AdviceMapViewInner::Materialized(advice_map),
70 }
71 }
72
73 pub(crate) fn wire(advice_map: &'a WireAdviceMapView<'a>) -> Self {
74 Self {
75 inner: AdviceMapViewInner::Wire(advice_map),
76 }
77 }
78
79 pub fn len(&self) -> usize {
81 match self.inner {
82 AdviceMapViewInner::Materialized(advice_map) => advice_map.len(),
83 AdviceMapViewInner::Wire(advice_map) => advice_map.len(),
84 }
85 }
86
87 pub fn is_empty(&self) -> bool {
89 self.len() == 0
90 }
91
92 pub fn contains_key(&self, key: &Word) -> bool {
94 match self.inner {
95 AdviceMapViewInner::Materialized(advice_map) => advice_map.contains_key(key),
96 AdviceMapViewInner::Wire(advice_map) => advice_map.contains_key(key),
97 }
98 }
99
100 pub fn get(&self, key: &Word) -> Result<Option<AdviceValueView<'a>>, DeserializationError> {
102 match self.inner {
103 AdviceMapViewInner::Materialized(advice_map) => {
104 Ok(advice_map.get(key).map(|values| AdviceValueView::borrowed(values.as_ref())))
105 },
106 AdviceMapViewInner::Wire(advice_map) => advice_map.get(key),
107 }
108 }
109}
110
111#[derive(Debug)]
112pub(crate) struct WireAdviceMapView<'a> {
113 bytes: &'a [u8],
114 entries: BTreeMap<Word, AdviceValueRange>,
115 end_offset: usize,
116}
117
118#[derive(Debug, Clone, Copy)]
119struct AdviceValueRange {
120 offset: usize,
121 len: usize,
122}
123
124impl<'a> WireAdviceMapView<'a> {
125 pub(crate) fn new(bytes: &'a [u8], offset: usize) -> Result<Self, DeserializationError> {
126 let slice = bytes.get(offset..).ok_or(DeserializationError::UnexpectedEOF)?;
127 let mut reader = SliceReader::new(slice);
128 let mut reader = TrackingReader::new(&mut reader);
129 let entry_count = reader.read_usize()?;
130 let mut entries = BTreeMap::new();
131
132 for _ in 0..entry_count {
133 let key = Word::read_from(&mut reader)?;
134 let len = reader.read_usize()?;
135 let value_offset = offset.checked_add(reader.offset()).ok_or_else(|| {
136 DeserializationError::InvalidValue("advice value offset overflow".into())
137 })?;
138 let value_byte_len = len.checked_mul(FELT_SERIALIZED_SIZE).ok_or_else(|| {
139 DeserializationError::InvalidValue("advice value length overflow".into())
140 })?;
141 reader.read_slice(value_byte_len)?;
142
143 if entries.insert(key, AdviceValueRange { offset: value_offset, len }).is_some() {
144 return Err(DeserializationError::InvalidValue(
145 "duplicate advice key in wire payload".into(),
146 ));
147 }
148 }
149
150 let end_offset = offset.checked_add(reader.offset()).ok_or_else(|| {
151 DeserializationError::InvalidValue("advice map offset overflow".into())
152 })?;
153
154 Ok(Self { bytes, entries, end_offset })
155 }
156
157 pub(crate) fn end_offset(&self) -> usize {
158 self.end_offset
159 }
160
161 fn len(&self) -> usize {
162 self.entries.len()
163 }
164
165 fn contains_key(&self, key: &Word) -> bool {
166 self.entries.contains_key(key)
167 }
168
169 fn get(&self, key: &Word) -> Result<Option<AdviceValueView<'a>>, DeserializationError> {
170 let Some(range) = self.entries.get(key) else {
171 return Ok(None);
172 };
173
174 let byte_len = range.len.checked_mul(FELT_SERIALIZED_SIZE).ok_or_else(|| {
175 DeserializationError::InvalidValue("advice value length overflow".into())
176 })?;
177 let end = range.offset.checked_add(byte_len).ok_or_else(|| {
178 DeserializationError::InvalidValue("advice value offset overflow".into())
179 })?;
180 let bytes = self.bytes.get(range.offset..end).ok_or(DeserializationError::UnexpectedEOF)?;
181 let mut reader = SliceReader::new(bytes);
182 let mut values = Vec::with_capacity(range.len);
183
184 for _ in 0..range.len {
185 values.push(Felt::read_from(&mut reader)?);
186 }
187
188 Ok(Some(AdviceValueView::owned(values)))
189 }
190}
191
192pub trait MastForestView {
198 fn node_count(&self) -> usize;
200
201 fn node_entry_at(&self, index: usize) -> Result<MastNodeEntry, DeserializationError>;
205
206 fn node_digest_at(&self, index: usize) -> Result<Word, DeserializationError>;
210
211 fn node_info_at(&self, index: usize) -> Result<MastNodeInfo, DeserializationError> {
215 Ok(MastNodeInfo::from_entry(
216 self.node_entry_at(index)?,
217 self.node_digest_at(index)?,
218 ))
219 }
220
221 fn procedure_root_count(&self) -> usize;
223
224 fn procedure_root_at(&self, index: usize) -> Result<MastNodeId, DeserializationError>;
228
229 fn advice_map(&self) -> AdviceMapView<'_>;
231
232 fn is_empty(&self) -> bool {
234 self.node_count() == 0
235 }
236
237 fn has_node(&self, index: usize) -> bool {
239 index < self.node_count()
240 }
241
242 fn all_node_infos(&self) -> Result<Vec<MastNodeInfo>, DeserializationError> {
244 (0..self.node_count()).map(|index| self.node_info_at(index)).collect()
245 }
246
247 fn procedure_roots(&self) -> Result<Vec<MastNodeId>, DeserializationError> {
249 (0..self.procedure_root_count())
250 .map(|index| self.procedure_root_at(index))
251 .collect()
252 }
253}