tasm_lib/verifier/vm_proof_iter/
drop.rs1use triton_vm::prelude::*;
2
3use crate::prelude::*;
4use crate::verifier::vm_proof_iter::shared::vm_proof_iter_type;
5
6#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
11pub struct Drop;
12
13impl BasicSnippet for Drop {
14 fn inputs(&self) -> Vec<(DataType, String)> {
15 vec![(
16 DataType::StructRef(vm_proof_iter_type()),
17 "vm_proof_iter".to_owned(),
18 )]
19 }
20
21 fn outputs(&self) -> Vec<(DataType, String)> {
22 vec![]
23 }
24
25 fn entrypoint(&self) -> String {
26 "tasmlib_verifier_vm_proof_iter_drop".to_owned()
27 }
28
29 fn code(&self, _library: &mut Library) -> Vec<LabelledInstruction> {
30 let entrypoint = self.entrypoint();
31
32 triton_asm!(
33 {entrypoint}:
34 addi 4
38 read_mem 5
39 pop 1
40
41 place 2
44 add
47 addi 1
48 eq
49 assert error_id 50
52 eq
55 assert error_id 60
56 return
59 )
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use arbitrary::Arbitrary;
66 use arbitrary::Unstructured;
67 use triton_vm::proof_item::ProofItemVariant;
68 use triton_vm::proof_stream::ProofStream;
69
70 use super::*;
71 use crate::test_prelude::*;
72 use crate::verifier::vm_proof_iter::dequeue_next_as::DequeueNextAs;
73 use crate::verifier::vm_proof_iter::shared::vm_proof_iter_struct::VmProofIter;
74
75 #[test]
76 fn rust_shadow() {
77 ShadowedAccessor::new(Drop).test();
78 }
79
80 #[test]
81 fn negative_test_proof_len_mismatch() {
82 let proof_ptr = bfe!(450);
83 let proof_len = 10_000u32;
84 let correct_proof_end = proof_ptr + bfe!(proof_len);
85 let bad_proof_length = VmProofIter {
86 current_item_count: 12,
87 total_item_count: 12,
88 proof_start_pointer: proof_ptr,
89 proof_length: proof_len,
90 current_item_pointer: correct_proof_end + bfe!(4),
91 };
92
93 test_assertion_failure(
94 &ShadowedAccessor::new(Drop),
95 Drop.init_state(bad_proof_length).into(),
96 &[50],
97 );
98 }
99
100 #[test]
101 fn negative_test_proof_item_count_mismatch() {
102 let proof_ptr = bfe!(450);
103 let proof_len = 10_000u32;
104 let correct_proof_end = proof_ptr + bfe!(proof_len);
105 let bad_proof_length = VmProofIter {
106 current_item_count: 16,
107 total_item_count: 12,
108 proof_start_pointer: proof_ptr,
109 proof_length: proof_len,
110 current_item_pointer: correct_proof_end,
111 };
112
113 test_assertion_failure(
114 &ShadowedAccessor::new(Drop),
115 Drop.init_state(bad_proof_length).into(),
116 &[50],
117 );
118 }
119
120 impl Drop {
121 fn init_state(&self, vm_proof_iter: VmProofIter) -> AccessorInitialState {
122 let mut memory = HashMap::default();
123 let vm_iter_ptr = bfe!(1u64 << 32);
124 encode_to_memory(&mut memory, vm_iter_ptr, &vm_proof_iter);
125
126 let stack = [self.init_stack_for_isolated_run(), vec![vm_iter_ptr]].concat();
127 AccessorInitialState { stack, memory }
128 }
129 }
130
131 impl Accessor for Drop {
132 fn rust_shadow(
133 &self,
134 stack: &mut Vec<BFieldElement>,
135 memory: &HashMap<BFieldElement, BFieldElement>,
136 ) {
137 let vm_proof_iter_ptr = stack.pop().unwrap();
138 let vm_proof_iter =
139 *VmProofIter::decode_from_memory(memory, vm_proof_iter_ptr).unwrap();
140 assert_eq!(
141 vm_proof_iter.current_item_count,
142 vm_proof_iter.total_item_count
143 );
144
145 assert_eq!(
146 vm_proof_iter.proof_start_pointer + bfe!(vm_proof_iter.proof_length + 1),
147 vm_proof_iter.current_item_pointer,
148 "{} + {} and {} must match",
149 vm_proof_iter.proof_start_pointer,
150 vm_proof_iter.proof_length,
151 vm_proof_iter.current_item_pointer
152 );
153 }
154
155 fn pseudorandom_initial_state(
156 &self,
157 seed: [u8; 32],
158 bench_case: Option<BenchmarkCase>,
159 ) -> AccessorInitialState {
160 let mut rng = StdRng::from_seed(seed);
161
162 let fake_proof_stream = match bench_case {
163 Some(BenchmarkCase::CommonCase) => {
164 let proof_item_variants = vec![ProofItemVariant::MerkleRoot; 20];
165 DequeueNextAs::pseudorandom_proof_stream(proof_item_variants, seed)
166 }
167 Some(BenchmarkCase::WorstCase) => {
168 let proof_item_variants = vec![ProofItemVariant::MerkleRoot; 40];
169 DequeueNextAs::pseudorandom_proof_stream(proof_item_variants, seed)
170 }
171 None => {
172 let bigger_seed: Vec<u8> = (0..1_000_000).map(|_| rng.random()).collect();
173 let unstructured = Unstructured::new(bigger_seed.as_ref());
174 ProofStream::arbitrary_take_rest(unstructured).unwrap()
175 }
176 };
177
178 let proof_ptr = bfe!(rng.random_range(0..20u32));
179 let fake_proof = fake_proof_stream.clone().into();
180
181 let mut vm_proof_iter = VmProofIter::new(proof_ptr, &fake_proof);
183 vm_proof_iter.current_item_count = fake_proof_stream.items.len().try_into().unwrap();
184 vm_proof_iter.current_item_pointer = proof_ptr + bfe!(fake_proof.0.len() as u64 + 2);
185
186 self.init_state(vm_proof_iter)
187 }
188 }
189}
190
191#[cfg(test)]
192mod benches {
193 use super::*;
194 use crate::test_prelude::*;
195
196 #[test]
197 fn benchmark() {
198 ShadowedAccessor::new(Drop).bench();
199 }
200}