sp1_recursion_executor/
public_values.rs1use crate::DIGEST_SIZE;
2use core::fmt::Debug;
3use serde::{Deserialize, Serialize};
4use slop_algebra::PrimeField32;
5use sp1_derive::AlignedBorrow;
6use sp1_hypercube::{
7 air::{timestamp_from_limbs, ShardRange, POSEIDON_NUM_WORDS, PROOF_NONCE_NUM_WORDS},
8 indices_arr,
9 septic_digest::SepticDigest,
10 PROOF_MAX_NUM_PVS,
11};
12use static_assertions::const_assert_eq;
13use std::{
14 borrow::BorrowMut,
15 mem::{size_of, transmute, MaybeUninit},
16};
17
18pub const PV_DIGEST_NUM_WORDS: usize = 8;
19
20pub const RECURSIVE_PROOF_NUM_PV_ELTS: usize = size_of::<RecursionPublicValues<u8>>();
21
22const fn make_col_map() -> RecursionPublicValues<usize> {
23 let indices_arr = indices_arr::<RECURSIVE_PROOF_NUM_PV_ELTS>();
24 unsafe {
25 transmute::<[usize; RECURSIVE_PROOF_NUM_PV_ELTS], RecursionPublicValues<usize>>(indices_arr)
26 }
27}
28
29pub const RECURSION_PUBLIC_VALUES_COL_MAP: RecursionPublicValues<usize> = make_col_map();
30
31pub const NUM_PV_ELMS_TO_HASH: usize = RECURSION_PUBLIC_VALUES_COL_MAP.digest[0];
33
34const_assert_eq!(RECURSIVE_PROOF_NUM_PV_ELTS, PROOF_MAX_NUM_PVS);
37
38#[derive(AlignedBorrow, Serialize, Deserialize, Clone, Copy, Default, Debug)]
40#[repr(C)]
41pub struct RecursionPublicValues<T> {
42 pub prev_committed_value_digest: [[T; 4]; PV_DIGEST_NUM_WORDS],
44
45 pub committed_value_digest: [[T; 4]; PV_DIGEST_NUM_WORDS],
47
48 pub prev_deferred_proofs_digest: [T; POSEIDON_NUM_WORDS],
50
51 pub deferred_proofs_digest: [T; POSEIDON_NUM_WORDS],
53
54 pub prev_deferred_proof: T,
56
57 pub deferred_proof: T,
59
60 pub pc_start: [T; 3],
62
63 pub next_pc: [T; 3],
65
66 pub initial_timestamp: [T; 4],
68
69 pub last_timestamp: [T; 4],
71
72 pub previous_init_addr: [T; 3],
74
75 pub last_init_addr: [T; 3],
77
78 pub previous_finalize_addr: [T; 3],
80
81 pub last_finalize_addr: [T; 3],
83
84 pub previous_init_page_idx: [T; 3],
86
87 pub last_init_page_idx: [T; 3],
89
90 pub previous_finalize_page_idx: [T; 3],
92
93 pub last_finalize_page_idx: [T; 3],
95
96 pub start_reconstruct_deferred_digest: [T; POSEIDON_NUM_WORDS],
98
99 pub end_reconstruct_deferred_digest: [T; POSEIDON_NUM_WORDS],
101
102 pub sp1_vk_digest: [T; DIGEST_SIZE],
104
105 pub vk_root: [T; DIGEST_SIZE],
107
108 pub global_cumulative_sum: SepticDigest<T>,
111
112 pub contains_first_shard: T,
114
115 pub num_included_shard: T,
117
118 pub is_complete: T,
120
121 pub prev_exit_code: T,
123
124 pub exit_code: T,
126
127 pub prev_commit_syscall: T,
129
130 pub commit_syscall: T,
132
133 pub prev_commit_deferred_syscall: T,
135
136 pub commit_deferred_syscall: T,
138
139 pub digest: [T; DIGEST_SIZE],
141
142 pub proof_nonce: [T; PROOF_NONCE_NUM_WORDS],
144}
145
146impl<F: Copy> RecursionPublicValues<F> {
148 pub fn as_array(&self) -> [F; RECURSIVE_PROOF_NUM_PV_ELTS] {
149 unsafe {
150 let mut ret = [MaybeUninit::<F>::zeroed().assume_init(); RECURSIVE_PROOF_NUM_PV_ELTS];
151 let pv: &mut RecursionPublicValues<F> = ret.as_mut_slice().borrow_mut();
152 *pv = *self;
153 ret
154 }
155 }
156
157 pub fn range(&self) -> ShardRange
158 where
159 F: PrimeField32,
160 {
161 let initial_timestamp = timestamp_from_limbs(&self.initial_timestamp);
162 let last_timestamp = timestamp_from_limbs(&self.last_timestamp);
163 let previous_init_addr = self
164 .previous_init_addr
165 .iter()
166 .rev()
167 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64);
168 let last_init_addr = self
169 .last_init_addr
170 .iter()
171 .rev()
172 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64);
173 let previous_finalize_addr = self
174 .previous_finalize_addr
175 .iter()
176 .rev()
177 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64);
178 let last_finalize_addr = self
179 .last_finalize_addr
180 .iter()
181 .rev()
182 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64);
183 let previous_init_page_idx = self
184 .previous_init_page_idx
185 .iter()
186 .rev()
187 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64);
188 let last_init_page_idx = self
189 .last_init_page_idx
190 .iter()
191 .rev()
192 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64);
193 let previous_finalize_page_idx = self
194 .previous_finalize_page_idx
195 .iter()
196 .rev()
197 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64);
198 let last_finalize_page_idx = self
199 .last_finalize_page_idx
200 .iter()
201 .rev()
202 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64);
203
204 let prev_deferred_proof = self.prev_deferred_proof.as_canonical_u64();
205 let deferred_proof = self.deferred_proof.as_canonical_u64();
206
207 ShardRange {
208 timestamp_range: (initial_timestamp, last_timestamp),
209 initialized_address_range: (previous_init_addr, last_init_addr),
210 finalized_address_range: (previous_finalize_addr, last_finalize_addr),
211 initialized_page_index_range: (previous_init_page_idx, last_init_page_idx),
212 finalized_page_index_range: (previous_finalize_page_idx, last_finalize_page_idx),
213 deferred_proof_range: (prev_deferred_proof, deferred_proof),
214 }
215 }
216}
217
218impl<T: Copy> IntoIterator for RecursionPublicValues<T> {
219 type Item = T;
220 type IntoIter = std::array::IntoIter<T, RECURSIVE_PROOF_NUM_PV_ELTS>;
221
222 fn into_iter(self) -> Self::IntoIter {
223 self.as_array().into_iter()
224 }
225}