miden_debug_engine/exec/
advice.rs1use std::sync::{Arc, Mutex};
5
6use miden_core::{
7 Felt, Word,
8 crypto::merkle::InnerNodeInfo,
9 precompile::PrecompileRequest,
10 serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
11};
12use miden_processor::advice::{AdviceMap, AdviceMutation};
13
14pub fn clone_advice_mutation(mutation: &AdviceMutation) -> AdviceMutation {
19 match mutation {
20 AdviceMutation::ExtendStack { values } => AdviceMutation::ExtendStack {
21 values: values.clone(),
22 },
23 AdviceMutation::ExtendMap { other } => AdviceMutation::ExtendMap {
24 other: other.clone(),
25 },
26 AdviceMutation::ExtendMerkleStore { infos } => AdviceMutation::ExtendMerkleStore {
27 infos: infos.clone(),
28 },
29 AdviceMutation::ExtendPrecompileRequests { data } => {
30 AdviceMutation::ExtendPrecompileRequests { data: data.clone() }
31 }
32 }
33}
34
35pub fn clone_advice_mutations(mutations: &[AdviceMutation]) -> Vec<AdviceMutation> {
37 mutations.iter().map(clone_advice_mutation).collect()
38}
39
40const TAG_EXTEND_STACK: u8 = 0;
46const TAG_EXTEND_MAP: u8 = 1;
47const TAG_EXTEND_MERKLE_STORE: u8 = 2;
48const TAG_EXTEND_PRECOMPILE_REQUESTS: u8 = 3;
49
50pub fn write_advice_mutation<W: ByteWriter>(mutation: &AdviceMutation, target: &mut W) {
52 match mutation {
53 AdviceMutation::ExtendStack { values } => {
54 target.write_u8(TAG_EXTEND_STACK);
55 values.write_into(target);
56 }
57 AdviceMutation::ExtendMap { other } => {
58 target.write_u8(TAG_EXTEND_MAP);
59 other.write_into(target);
60 }
61 AdviceMutation::ExtendMerkleStore { infos } => {
62 target.write_u8(TAG_EXTEND_MERKLE_STORE);
63 target.write_usize(infos.len());
64 for info in infos {
65 info.value.write_into(target);
66 info.left.write_into(target);
67 info.right.write_into(target);
68 }
69 }
70 AdviceMutation::ExtendPrecompileRequests { data } => {
71 target.write_u8(TAG_EXTEND_PRECOMPILE_REQUESTS);
72 data.write_into(target);
73 }
74 }
75}
76
77pub fn read_advice_mutation<R: ByteReader>(
79 source: &mut R,
80) -> Result<AdviceMutation, DeserializationError> {
81 match source.read_u8()? {
82 TAG_EXTEND_STACK => Ok(AdviceMutation::ExtendStack {
83 values: Vec::<Felt>::read_from(source)?,
84 }),
85 TAG_EXTEND_MAP => Ok(AdviceMutation::ExtendMap {
86 other: AdviceMap::read_from(source)?,
87 }),
88 TAG_EXTEND_MERKLE_STORE => {
89 let len = source.read_usize()?;
90 let mut infos = Vec::with_capacity(len);
91 for _ in 0..len {
92 let value = Word::read_from(source)?;
93 let left = Word::read_from(source)?;
94 let right = Word::read_from(source)?;
95 infos.push(InnerNodeInfo { value, left, right });
96 }
97 Ok(AdviceMutation::ExtendMerkleStore { infos })
98 }
99 TAG_EXTEND_PRECOMPILE_REQUESTS => Ok(AdviceMutation::ExtendPrecompileRequests {
100 data: Vec::<PrecompileRequest>::read_from(source)?,
101 }),
102 other => Err(DeserializationError::InvalidValue(format!(
103 "unknown AdviceMutation variant tag: {other}"
104 ))),
105 }
106}
107
108pub fn write_event_log<W: ByteWriter>(log: &[Vec<AdviceMutation>], target: &mut W) {
110 target.write_usize(log.len());
111 for batch in log {
112 target.write_usize(batch.len());
113 for mutation in batch {
114 write_advice_mutation(mutation, target);
115 }
116 }
117}
118
119pub fn read_event_log<R: ByteReader>(
121 source: &mut R,
122) -> Result<Vec<Vec<AdviceMutation>>, DeserializationError> {
123 let batches = source.read_usize()?;
124 let mut log = Vec::with_capacity(batches);
125 for _ in 0..batches {
126 let len = source.read_usize()?;
127 let mut batch = Vec::with_capacity(len);
128 for _ in 0..len {
129 batch.push(read_advice_mutation(source)?);
130 }
131 log.push(batch);
132 }
133 Ok(log)
134}
135
136#[derive(Clone, Default)]
149pub struct EventMutationRecorder {
150 log: Arc<Mutex<Vec<Vec<AdviceMutation>>>>,
151}
152
153impl core::fmt::Debug for EventMutationRecorder {
154 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
155 f.debug_struct("EventMutationRecorder").field("events", &self.len()).finish()
156 }
157}
158
159impl EventMutationRecorder {
160 pub fn new() -> Self {
162 Self::default()
163 }
164
165 pub fn take(&self) -> Vec<Vec<AdviceMutation>> {
167 core::mem::take(&mut *self.log.lock().expect("event mutation log poisoned"))
168 }
169
170 pub fn snapshot(&self) -> Vec<Vec<AdviceMutation>> {
172 self.log
173 .lock()
174 .expect("event mutation log poisoned")
175 .iter()
176 .map(|batch| clone_advice_mutations(batch))
177 .collect()
178 }
179
180 pub fn len(&self) -> usize {
182 self.log.lock().expect("event mutation log poisoned").len()
183 }
184
185 pub fn is_empty(&self) -> bool {
187 self.len() == 0
188 }
189
190 pub(crate) fn record(&self, mutations: Vec<AdviceMutation>) {
192 self.log.lock().expect("event mutation log poisoned").push(mutations);
193 }
194
195 pub(crate) fn clear(&self) {
197 self.log.lock().expect("event mutation log poisoned").clear();
198 }
199}