1use core::{fmt::Debug, mem::size_of};
2use std::{
3 borrow::{Borrow, BorrowMut},
4 ops::Range,
5};
6
7use deepsize2::DeepSizeOf;
8use itertools::Itertools;
9use serde::{Deserialize, Serialize};
10use slop_algebra::{AbstractField, PrimeField32};
11use sp1_primitives::consts::split_page_idx;
12
13use crate::{septic_curve::SepticCurve, septic_digest::SepticDigest, PROOF_MAX_NUM_PVS};
14
15pub const SP1_PROOF_NUM_PV_ELTS: usize = size_of::<PublicValues<[u8; 4], [u8; 3], [u8; 4], u8>>();
17
18pub const PV_DIGEST_NUM_WORDS: usize = 8;
20
21pub const POSEIDON_NUM_WORDS: usize = 8;
23
24pub const PROOF_NONCE_NUM_WORDS: usize = 4;
26
27#[derive(Serialize, Deserialize, Clone, Copy, Default, Debug, PartialEq, Eq, DeepSizeOf)]
29#[repr(C)]
30pub struct PublicValues<W1, W2, W3, T> {
31 pub prev_committed_value_digest: [W1; PV_DIGEST_NUM_WORDS],
33
34 pub committed_value_digest: [W1; PV_DIGEST_NUM_WORDS],
36
37 pub prev_deferred_proofs_digest: [T; POSEIDON_NUM_WORDS],
39
40 pub deferred_proofs_digest: [T; POSEIDON_NUM_WORDS],
44
45 pub pc_start: W2,
47
48 pub next_pc: W2,
50
51 pub prev_exit_code: T,
53
54 pub exit_code: T,
57
58 pub is_execution_shard: T,
60
61 pub previous_init_addr: W2,
63
64 pub last_init_addr: W2,
66
67 pub previous_finalize_addr: W2,
69
70 pub last_finalize_addr: W2,
72
73 pub previous_init_page_idx: W2,
75
76 pub last_init_page_idx: W2,
78
79 pub previous_finalize_page_idx: W2,
81
82 pub last_finalize_page_idx: W2,
84
85 pub initial_timestamp: W3,
87
88 pub last_timestamp: W3,
90
91 pub is_timestamp_high_eq: T,
93
94 pub inv_timestamp_high: T,
96
97 pub is_timestamp_low_eq: T,
99
100 pub inv_timestamp_low: T,
102
103 pub global_init_count: T,
105
106 pub global_finalize_count: T,
108
109 pub global_page_prot_init_count: T,
111
112 pub global_page_prot_finalize_count: T,
114
115 pub global_count: T,
117
118 pub global_cumulative_sum: SepticDigest<T>,
120
121 pub prev_commit_syscall: T,
123
124 pub commit_syscall: T,
126
127 pub prev_commit_deferred_syscall: T,
129
130 pub commit_deferred_syscall: T,
132
133 pub initial_timestamp_inv: T,
135
136 pub last_timestamp_inv: T,
138
139 pub is_first_execution_shard: T,
141
142 pub is_untrusted_programs_enabled: T,
145
146 pub proof_nonce: [T; PROOF_NONCE_NUM_WORDS],
148
149 pub empty: [T; 4],
151}
152
153impl PublicValues<u32, u64, u64, u32> {
154 #[must_use]
157 pub fn to_vec<F: AbstractField>(&self) -> Vec<F> {
158 let mut ret = vec![F::zero(); PROOF_MAX_NUM_PVS];
159
160 let field_values = PublicValues::<[F; 4], [F; 3], [F; 4], F>::from(*self);
161 let ret_ref_mut: &mut PublicValues<[F; 4], [F; 3], [F; 4], F> =
162 ret.as_mut_slice().borrow_mut();
163 *ret_ref_mut = field_values;
164 ret
165 }
166
167 #[must_use]
171 pub fn range(&self) -> ShardRange {
172 ShardRange {
173 timestamp_range: (self.initial_timestamp, self.last_timestamp),
174 initialized_address_range: (self.previous_init_addr, self.last_init_addr),
175 finalized_address_range: (self.previous_finalize_addr, self.last_finalize_addr),
176 initialized_page_index_range: (self.previous_init_page_idx, self.last_init_page_idx),
177 finalized_page_index_range: (
178 self.previous_finalize_page_idx,
179 self.last_finalize_page_idx,
180 ),
181 deferred_proof_range: (0, 0),
182 }
183 }
184
185 #[must_use]
187 pub fn reset(&self) -> Self {
188 let mut copy = *self;
189 copy.pc_start = 0;
190 copy.next_pc = 0;
191 copy.previous_init_addr = 0;
192 copy.last_init_addr = 0;
193 copy.previous_finalize_addr = 0;
194 copy.last_finalize_addr = 0;
195 copy.previous_init_page_idx = 0;
196 copy.last_init_page_idx = 0;
197 copy.previous_finalize_page_idx = 0;
198 copy.last_finalize_page_idx = 0;
199 copy
200 }
201
202 #[must_use]
205 pub fn initialize(&self, pc_start_abs: u64, enable_untrusted_programs: bool) -> Self {
206 let mut state = *self;
207 state.pc_start = pc_start_abs;
208 state.next_pc = pc_start_abs;
209 state.initial_timestamp = 1;
210 state.last_timestamp = 1;
211 state.is_timestamp_high_eq = 1;
212 state.is_timestamp_low_eq = 1;
213 state.is_first_execution_shard = 0;
214 state.is_execution_shard = 0;
215 state.initial_timestamp_inv = 0;
216 state.last_timestamp_inv = 0;
217 state.is_untrusted_programs_enabled = enable_untrusted_programs as u32;
218 state
219 }
220
221 pub fn update_state(&mut self, state: &PublicValues<u32, u64, u64, u32>) {
223 self.pc_start = state.pc_start;
224 self.next_pc = state.next_pc;
225 self.exit_code = state.exit_code;
226 self.initial_timestamp = state.initial_timestamp;
227 self.last_timestamp = state.last_timestamp;
228 self.is_timestamp_high_eq = state.is_timestamp_high_eq;
229 self.is_timestamp_low_eq = state.is_timestamp_low_eq;
230 self.last_timestamp_inv = state.last_timestamp_inv;
231 self.initial_timestamp_inv = state.initial_timestamp_inv;
232 self.is_first_execution_shard = state.is_first_execution_shard;
233 self.is_execution_shard = state.is_execution_shard;
234 self.is_untrusted_programs_enabled = state.is_untrusted_programs_enabled;
235 }
236
237 pub fn update_initialized_state(&mut self, pc_start_abs: u64, enable_untrusted_programs: bool) {
240 self.pc_start = pc_start_abs;
241 self.next_pc = pc_start_abs;
242 self.exit_code = 0;
243 self.initial_timestamp = 1;
244 self.last_timestamp = 1;
245 self.is_timestamp_high_eq = 1;
246 self.is_timestamp_low_eq = 1;
247 self.is_first_execution_shard = 0;
248 self.is_execution_shard = 0;
249 self.initial_timestamp_inv = 0;
250 self.last_timestamp_inv = 0;
251 self.is_untrusted_programs_enabled = enable_untrusted_programs as u32;
252 }
253
254 #[allow(clippy::too_many_arguments)]
257 pub fn update_finalized_state(
258 &mut self,
259 timestamp: u64,
260 pc: u64,
261 exit_code: u32,
262 is_untrusted_programs_enabled: u32,
263 committed_value_digest: [u32; PV_DIGEST_NUM_WORDS],
264 deferred_proofs_digest: [u32; POSEIDON_NUM_WORDS],
265 nonce: [u32; PROOF_NONCE_NUM_WORDS],
266 ) {
267 self.pc_start = pc;
268 self.next_pc = pc;
269 self.exit_code = exit_code;
270 self.initial_timestamp = timestamp;
271 self.last_timestamp = timestamp;
272 self.is_timestamp_high_eq = 1;
273 self.is_timestamp_low_eq = 1;
274 self.is_first_execution_shard = 0;
275 self.is_execution_shard = 0;
276 self.initial_timestamp_inv = 0;
277 self.last_timestamp_inv = 0;
278 self.prev_committed_value_digest = committed_value_digest;
279 self.committed_value_digest = committed_value_digest;
280 self.prev_deferred_proofs_digest = deferred_proofs_digest;
281 self.deferred_proofs_digest = deferred_proofs_digest;
282 self.is_untrusted_programs_enabled = is_untrusted_programs_enabled;
283 self.prev_exit_code = exit_code;
284 self.prev_commit_syscall = 1;
285 self.commit_syscall = 1;
286 self.prev_commit_deferred_syscall = 1;
287 self.commit_deferred_syscall = 1;
288 self.proof_nonce = nonce;
289 }
290
291 pub fn update_finalized_state_from_public_values(
294 &mut self,
295 public_values: &PublicValues<u32, u64, u64, u32>,
296 ) {
297 self.update_finalized_state(
298 public_values.last_timestamp,
299 public_values.next_pc,
300 public_values.exit_code,
301 public_values.is_untrusted_programs_enabled,
302 public_values.committed_value_digest,
303 public_values.deferred_proofs_digest,
304 public_values.proof_nonce,
305 );
306 }
307}
308
309#[inline]
314pub fn timestamp_from_limbs<F: PrimeField32>(limbs: &[F; 4]) -> u64 {
315 let mut timestamp = (limbs[0].as_canonical_u32() as u64) << 32;
316 timestamp += (limbs[1].as_canonical_u32() as u64) << 24;
317 timestamp += (limbs[2].as_canonical_u32() as u64) << 16;
318 timestamp += limbs[3].as_canonical_u32() as u64;
319 timestamp
320}
321
322pub type SP1CorePublicValues<F> = PublicValues<[F; 4], [F; 3], [F; 4], F>;
324
325impl<F: PrimeField32> PublicValues<[F; 4], [F; 3], [F; 4], F> {
326 pub fn commit_digest_bytes(&self) -> Vec<u8> {
328 self.committed_value_digest
329 .iter()
330 .flat_map(|w| w.iter().map(|f| f.as_canonical_u32() as u8))
331 .collect_vec()
332 }
333
334 pub fn initial_timestamp(&self) -> u64 {
336 timestamp_from_limbs(&self.initial_timestamp)
337 }
338
339 pub fn last_timestamp(&self) -> u64 {
341 timestamp_from_limbs(&self.last_timestamp)
342 }
343
344 pub fn previous_init_addr(&self) -> u64 {
346 self.previous_init_addr
347 .iter()
348 .rev()
349 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64)
350 }
351
352 pub fn last_init_addr(&self) -> u64 {
354 self.last_init_addr
355 .iter()
356 .rev()
357 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64)
358 }
359
360 pub fn previous_finalize_addr(&self) -> u64 {
362 self.previous_finalize_addr
363 .iter()
364 .rev()
365 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64)
366 }
367
368 pub fn last_finalize_addr(&self) -> u64 {
370 self.last_finalize_addr
371 .iter()
372 .rev()
373 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64)
374 }
375
376 pub fn previous_init_page_idx(&self) -> u64 {
378 self.previous_init_page_idx
379 .iter()
380 .rev()
381 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64)
382 }
383
384 pub fn last_init_page_idx(&self) -> u64 {
386 self.last_init_page_idx
387 .iter()
388 .rev()
389 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64)
390 }
391
392 pub fn previous_finalize_page_idx(&self) -> u64 {
394 self.previous_finalize_page_idx
395 .iter()
396 .rev()
397 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64)
398 }
399
400 pub fn last_finalize_page_idx(&self) -> u64 {
402 self.last_finalize_page_idx
403 .iter()
404 .rev()
405 .fold(0, |acc, x| acc * (1 << 16) + x.as_canonical_u32() as u64)
406 }
407
408 #[must_use]
410 pub fn range(&self) -> ShardRange {
411 let timestamp_range = (self.initial_timestamp(), self.last_timestamp());
412 let initialized_address_range = (self.previous_init_addr(), self.last_init_addr());
413 let finalized_address_range = (self.previous_finalize_addr(), self.last_finalize_addr());
414 let initialized_page_index_range =
415 (self.previous_init_page_idx(), self.last_init_page_idx());
416 let finalized_page_index_range =
417 (self.previous_finalize_page_idx(), self.last_finalize_page_idx());
418 let deferred_proof_range = (0, 0);
419
420 ShardRange {
421 timestamp_range,
422 initialized_address_range,
423 finalized_address_range,
424 initialized_page_index_range,
425 finalized_page_index_range,
426 deferred_proof_range,
427 }
428 }
429}
430
431impl<T: Clone> Borrow<PublicValues<[T; 4], [T; 3], [T; 4], T>> for [T] {
432 fn borrow(&self) -> &PublicValues<[T; 4], [T; 3], [T; 4], T> {
433 let size = std::mem::size_of::<PublicValues<[u8; 4], [u8; 3], [u8; 4], u8>>();
434 debug_assert!(self.len() >= size);
435 let slice = &self[0..size];
436 let (prefix, shorts, _suffix) =
437 unsafe { slice.align_to::<PublicValues<[T; 4], [T; 3], [T; 4], T>>() };
438 debug_assert!(prefix.is_empty(), "Alignment should match");
439 debug_assert_eq!(shorts.len(), 1);
440 &shorts[0]
441 }
442}
443
444impl<T: Clone> BorrowMut<PublicValues<[T; 4], [T; 3], [T; 4], T>> for [T] {
445 fn borrow_mut(&mut self) -> &mut PublicValues<[T; 4], [T; 3], [T; 4], T> {
446 let size = std::mem::size_of::<PublicValues<[u8; 4], [u8; 3], [u8; 4], u8>>();
447 debug_assert!(self.len() >= size);
448 let slice = &mut self[0..size];
449 let (prefix, shorts, _suffix) =
450 unsafe { slice.align_to_mut::<PublicValues<[T; 4], [T; 3], [T; 4], T>>() };
451 debug_assert!(prefix.is_empty(), "Alignment should match");
452 debug_assert_eq!(shorts.len(), 1);
453 &mut shorts[0]
454 }
455}
456
457impl<F: AbstractField> From<PublicValues<u32, u64, u64, u32>>
458 for PublicValues<[F; 4], [F; 3], [F; 4], F>
459{
460 #[allow(clippy::too_many_lines)]
461 fn from(value: PublicValues<u32, u64, u64, u32>) -> Self {
462 let PublicValues {
463 prev_committed_value_digest,
464 committed_value_digest,
465 prev_deferred_proofs_digest,
466 deferred_proofs_digest,
467 pc_start,
468 next_pc,
469 prev_exit_code,
470 exit_code,
471 is_execution_shard,
472 previous_init_addr,
473 last_init_addr,
474 previous_finalize_addr,
475 last_finalize_addr,
476 previous_init_page_idx,
477 last_init_page_idx,
478 previous_finalize_page_idx,
479 last_finalize_page_idx,
480 initial_timestamp,
481 last_timestamp,
482 is_timestamp_high_eq,
483 inv_timestamp_high,
484 is_timestamp_low_eq,
485 inv_timestamp_low,
486 global_init_count,
487 global_finalize_count,
488 global_page_prot_init_count,
489 global_page_prot_finalize_count,
490 global_count,
491 global_cumulative_sum,
492 prev_commit_syscall,
493 commit_syscall,
494 prev_commit_deferred_syscall,
495 commit_deferred_syscall,
496 is_untrusted_programs_enabled,
497 proof_nonce,
498 initial_timestamp_inv,
499 last_timestamp_inv,
500 is_first_execution_shard,
501 ..
502 } = value;
503
504 let prev_committed_value_digest: [_; PV_DIGEST_NUM_WORDS] = core::array::from_fn(|i| {
505 [
506 F::from_canonical_u32(prev_committed_value_digest[i] & 0xFF),
507 F::from_canonical_u32((prev_committed_value_digest[i] >> 8) & 0xFF),
508 F::from_canonical_u32((prev_committed_value_digest[i] >> 16) & 0xFF),
509 F::from_canonical_u32((prev_committed_value_digest[i] >> 24) & 0xFF),
510 ]
511 });
512
513 let committed_value_digest: [_; PV_DIGEST_NUM_WORDS] = core::array::from_fn(|i| {
514 [
515 F::from_canonical_u32(committed_value_digest[i] & 0xFF),
516 F::from_canonical_u32((committed_value_digest[i] >> 8) & 0xFF),
517 F::from_canonical_u32((committed_value_digest[i] >> 16) & 0xFF),
518 F::from_canonical_u32((committed_value_digest[i] >> 24) & 0xFF),
519 ]
520 });
521
522 let prev_deferred_proofs_digest: [_; POSEIDON_NUM_WORDS] =
523 core::array::from_fn(|i| F::from_canonical_u32(prev_deferred_proofs_digest[i]));
524
525 let deferred_proofs_digest: [_; POSEIDON_NUM_WORDS] =
526 core::array::from_fn(|i| F::from_canonical_u32(deferred_proofs_digest[i]));
527
528 let pc_start = [
529 F::from_canonical_u16((pc_start & 0xFFFF) as u16),
530 F::from_canonical_u16(((pc_start >> 16) & 0xFFFF) as u16),
531 F::from_canonical_u16(((pc_start >> 32) & 0xFFFF) as u16),
532 ];
533 let next_pc = [
534 F::from_canonical_u16((next_pc & 0xFFFF) as u16),
535 F::from_canonical_u16(((next_pc >> 16) & 0xFFFF) as u16),
536 F::from_canonical_u16(((next_pc >> 32) & 0xFFFF) as u16),
537 ];
538 let exit_code = F::from_canonical_u32(exit_code);
539 let prev_exit_code = F::from_canonical_u32(prev_exit_code);
540 let is_execution_shard = F::from_canonical_u32(is_execution_shard);
541 let previous_init_addr = [
542 F::from_canonical_u16((previous_init_addr & 0xFFFF) as u16),
543 F::from_canonical_u16(((previous_init_addr >> 16) & 0xFFFF) as u16),
544 F::from_canonical_u16(((previous_init_addr >> 32) & 0xFFFF) as u16),
545 ];
546 let last_init_addr = [
547 F::from_canonical_u16((last_init_addr & 0xFFFF) as u16),
548 F::from_canonical_u16(((last_init_addr >> 16) & 0xFFFF) as u16),
549 F::from_canonical_u16(((last_init_addr >> 32) & 0xFFFF) as u16),
550 ];
551 let previous_finalize_addr = [
552 F::from_canonical_u16((previous_finalize_addr & 0xFFFF) as u16),
553 F::from_canonical_u16(((previous_finalize_addr >> 16) & 0xFFFF) as u16),
554 F::from_canonical_u16(((previous_finalize_addr >> 32) & 0xFFFF) as u16),
555 ];
556 let last_finalize_addr = [
557 F::from_canonical_u16((last_finalize_addr & 0xFFFF) as u16),
558 F::from_canonical_u16(((last_finalize_addr >> 16) & 0xFFFF) as u16),
559 F::from_canonical_u16(((last_finalize_addr >> 32) & 0xFFFF) as u16),
560 ];
561 let previous_init_page_idx: [F; 3] = core::array::from_fn(|i| {
562 F::from_canonical_u16(split_page_idx(previous_init_page_idx)[i])
563 });
564 let last_init_page_idx: [F; 3] =
565 core::array::from_fn(|i| F::from_canonical_u16(split_page_idx(last_init_page_idx)[i]));
566 let previous_finalize_page_idx: [F; 3] = core::array::from_fn(|i| {
567 F::from_canonical_u16(split_page_idx(previous_finalize_page_idx)[i])
568 });
569 let last_finalize_page_idx: [F; 3] = core::array::from_fn(|i| {
570 F::from_canonical_u16(split_page_idx(last_finalize_page_idx)[i])
571 });
572 let initial_timestamp = [
573 F::from_canonical_u16((initial_timestamp >> 32) as u16),
574 F::from_canonical_u8(((initial_timestamp >> 24) & 0xFF) as u8),
575 F::from_canonical_u8(((initial_timestamp >> 16) & 0xFF) as u8),
576 F::from_canonical_u16((initial_timestamp & 0xFFFF) as u16),
577 ];
578 let last_timestamp = [
579 F::from_canonical_u16((last_timestamp >> 32) as u16),
580 F::from_canonical_u8(((last_timestamp >> 24) & 0xFF) as u8),
581 F::from_canonical_u8(((last_timestamp >> 16) & 0xFF) as u8),
582 F::from_canonical_u16((last_timestamp & 0xFFFF) as u16),
583 ];
584
585 let is_timestamp_high_eq = F::from_canonical_u32(is_timestamp_high_eq);
586 let inv_timestamp_high = F::from_canonical_u32(inv_timestamp_high);
587 let is_timestamp_low_eq = F::from_canonical_u32(is_timestamp_low_eq);
588 let inv_timestamp_low = F::from_canonical_u32(inv_timestamp_low);
589
590 let global_init_count = F::from_canonical_u32(global_init_count);
591 let global_finalize_count = F::from_canonical_u32(global_finalize_count);
592 let global_page_prot_init_count = F::from_canonical_u32(global_page_prot_init_count);
593 let global_page_prot_finalize_count =
594 F::from_canonical_u32(global_page_prot_finalize_count);
595 let global_count = F::from_canonical_u32(global_count);
596 let global_cumulative_sum =
597 SepticDigest(SepticCurve::convert(global_cumulative_sum.0, F::from_canonical_u32));
598
599 let prev_commit_syscall = F::from_canonical_u32(prev_commit_syscall);
600 let commit_syscall = F::from_canonical_u32(commit_syscall);
601 let prev_commit_deferred_syscall = F::from_canonical_u32(prev_commit_deferred_syscall);
602 let commit_deferred_syscall = F::from_canonical_u32(commit_deferred_syscall);
603
604 let initial_timestamp_inv = F::from_canonical_u32(initial_timestamp_inv);
605 let last_timestamp_inv = F::from_canonical_u32(last_timestamp_inv);
606 let is_first_execution_shard = F::from_canonical_u32(is_first_execution_shard);
607 let is_untrusted_programs_enabled = F::from_canonical_u32(is_untrusted_programs_enabled);
608
609 let proof_nonce: [_; PROOF_NONCE_NUM_WORDS] =
610 core::array::from_fn(|i| F::from_canonical_u32(proof_nonce[i]));
611
612 Self {
613 prev_committed_value_digest,
614 committed_value_digest,
615 prev_deferred_proofs_digest,
616 deferred_proofs_digest,
617 pc_start,
618 next_pc,
619 prev_exit_code,
620 exit_code,
621 is_execution_shard,
622 previous_init_addr,
623 last_init_addr,
624 previous_finalize_addr,
625 last_finalize_addr,
626 previous_init_page_idx,
627 last_init_page_idx,
628 previous_finalize_page_idx,
629 last_finalize_page_idx,
630 initial_timestamp,
631 last_timestamp,
632 is_timestamp_high_eq,
633 inv_timestamp_high,
634 is_timestamp_low_eq,
635 inv_timestamp_low,
636 global_init_count,
637 global_finalize_count,
638 global_page_prot_init_count,
639 global_page_prot_finalize_count,
640 global_count,
641 global_cumulative_sum,
642 prev_commit_syscall,
643 commit_syscall,
644 prev_commit_deferred_syscall,
645 commit_deferred_syscall,
646 is_untrusted_programs_enabled,
647 initial_timestamp_inv,
648 last_timestamp_inv,
649 is_first_execution_shard,
650 proof_nonce,
651 empty: core::array::from_fn(|_| F::zero()),
652 }
653 }
654}
655
656#[derive(
658 Serialize, Deserialize, Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
659)]
660#[repr(C)]
661pub struct ShardBoundary {
662 pub timestamp: u64,
664 pub initialized_address: u64,
666 pub finalized_address: u64,
668 pub initialized_page_index: u64,
670 pub finalized_page_index: u64,
672 pub deferred_proof: u64,
674}
675
676impl ShardBoundary {
677 #[inline]
681 #[must_use]
682 pub fn initial() -> Self {
683 Self {
684 timestamp: 1,
685 initialized_address: 0,
686 finalized_address: 0,
687 initialized_page_index: 0,
688 finalized_page_index: 0,
689 deferred_proof: 0,
690 }
691 }
692}
693
694#[derive(
696 Serialize, Deserialize, Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
697)]
698#[repr(C)]
699pub struct ShardRange {
700 pub timestamp_range: (u64, u64),
702 pub initialized_address_range: (u64, u64),
704 pub finalized_address_range: (u64, u64),
706 pub initialized_page_index_range: (u64, u64),
708 pub finalized_page_index_range: (u64, u64),
710 pub deferred_proof_range: (u64, u64),
712}
713
714impl From<Range<ShardBoundary>> for ShardRange {
715 fn from(value: Range<ShardBoundary>) -> Self {
716 Self {
717 timestamp_range: (value.start.timestamp, value.end.timestamp),
718 initialized_address_range: (
719 value.start.initialized_address,
720 value.end.initialized_address,
721 ),
722 finalized_address_range: (value.start.finalized_address, value.end.finalized_address),
723 initialized_page_index_range: (
724 value.start.initialized_page_index,
725 value.end.initialized_page_index,
726 ),
727 finalized_page_index_range: (
728 value.start.finalized_page_index,
729 value.end.finalized_page_index,
730 ),
731 deferred_proof_range: (value.start.deferred_proof, value.end.deferred_proof),
732 }
733 }
734}
735
736impl ShardRange {
737 #[must_use]
739 #[inline]
740 pub fn start(&self) -> ShardBoundary {
741 ShardBoundary {
742 timestamp: self.timestamp_range.0,
743 initialized_address: self.initialized_address_range.0,
744 finalized_address: self.finalized_address_range.0,
745 initialized_page_index: self.initialized_page_index_range.0,
746 finalized_page_index: self.finalized_page_index_range.0,
747 deferred_proof: self.deferred_proof_range.0,
748 }
749 }
750
751 #[must_use]
753 #[inline]
754 pub fn end(&self) -> ShardBoundary {
755 ShardBoundary {
756 timestamp: self.timestamp_range.1,
757 initialized_address: self.initialized_address_range.1,
758 finalized_address: self.finalized_address_range.1,
759 initialized_page_index: self.initialized_page_index_range.1,
760 finalized_page_index: self.finalized_page_index_range.1,
761 deferred_proof: self.deferred_proof_range.1,
762 }
763 }
764
765 #[must_use]
770 #[inline]
771 pub fn precompile() -> Self {
772 Self {
773 timestamp_range: (1, 1),
774 initialized_address_range: (0, 0),
775 finalized_address_range: (0, 0),
776 initialized_page_index_range: (0, 0),
777 finalized_page_index_range: (0, 0),
778 deferred_proof_range: (0, 0),
779 }
780 }
781
782 #[must_use]
786 #[inline]
787 pub fn deferred(prev_deferred_proof: u64, deferred_proof: u64) -> Self {
788 ShardRange {
789 timestamp_range: (1, 1),
790 initialized_address_range: (0, 0),
791 finalized_address_range: (0, 0),
792 initialized_page_index_range: (0, 0),
793 finalized_page_index_range: (0, 0),
794 deferred_proof_range: (prev_deferred_proof, deferred_proof),
795 }
796 }
797}
798
799impl core::fmt::Display for ShardRange {
800 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
801 write!(f, "ShardRange:")?;
802 write!(f, "timestamp_range: {}..{}", self.timestamp_range.0, self.timestamp_range.1)?;
803 write!(
804 f,
805 "initialized_address_range: {}..{}",
806 self.initialized_address_range.0, self.initialized_address_range.1
807 )?;
808 write!(
809 f,
810 "finalized_address_range: {}..{}",
811 self.finalized_address_range.0, self.finalized_address_range.1
812 )?;
813 write!(
814 f,
815 "initialized_page_index_range: {}..{}",
816 self.initialized_page_index_range.0, self.initialized_page_index_range.1
817 )?;
818 write!(
819 f,
820 "finalized_page_index_range: {}..{}",
821 self.finalized_page_index_range.0, self.finalized_page_index_range.1
822 )?;
823 Ok(())
824 }
825}
826
827#[cfg(test)]
828mod tests {
829 use crate::air::public_values;
830
831 #[test]
833 fn test_public_values_digest_num_words_consistency_zkvm() {
834 assert_eq!(public_values::PV_DIGEST_NUM_WORDS, sp1_zkvm::PV_DIGEST_NUM_WORDS);
835 }
836}