risc0_binfmt/
sys_state.rs1extern crate alloc;
16
17use alloc::{collections::VecDeque, vec::Vec};
18use core::fmt;
19
20use borsh::{BorshDeserialize, BorshSerialize};
21use risc0_zkp::core::{digest::Digest, hash::sha::Sha256};
22use serde::{Deserialize, Serialize};
23
24use crate::{tagged_struct, Digestible};
25
26#[derive(Clone, Serialize, Deserialize, PartialEq, BorshSerialize, BorshDeserialize)]
29pub struct SystemState {
30 pub pc: u32,
32
33 pub merkle_root: Digest,
36}
37
38impl SystemState {
39 pub fn decode(flat: &mut VecDeque<u32>) -> Result<Self, DecodeError> {
43 Ok(Self {
44 pc: read_u32_bytes(flat)?,
45 merkle_root: read_sha_halfs(flat)?,
46 })
47 }
48
49 pub fn encode(&self, flat: &mut Vec<u32>) {
53 write_u32_bytes(flat, self.pc);
54 write_sha_halfs(flat, &self.merkle_root);
55 }
56}
57
58impl fmt::Debug for SystemState {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 f.debug_struct("SystemState")
61 .field("pc", &format_args!("0x{:08x}", self.pc))
62 .field("merkle_root", &self.merkle_root)
63 .finish()
64 }
65}
66
67impl Eq for SystemState {}
68
69impl Digestible for SystemState {
70 fn digest<S: Sha256>(&self) -> Digest {
72 tagged_struct::<S>("risc0.SystemState", &[self.merkle_root], &[self.pc])
73 }
74}
75
76pub fn read_sha_halfs(flat: &mut VecDeque<u32>) -> Result<Digest, DecodeError> {
78 let mut bytes = Vec::<u8>::new();
79 if flat.len() < 16 {
80 return Err(DecodeError::EndOfStream);
81 }
82 for half in flat.drain(0..16) {
83 bytes.push((half & 0xff).try_into().unwrap());
84 bytes.push(
85 (half >> 8)
86 .try_into()
87 .map_err(|_| DecodeError::OutOfRange)?,
88 );
89 }
90 Ok(bytes.try_into().unwrap())
91}
92
93fn read_u32_bytes(flat: &mut VecDeque<u32>) -> Result<u32, DecodeError> {
94 if flat.len() < 4 {
95 return Err(DecodeError::EndOfStream);
96 }
97 Ok(u32::from_le_bytes(
98 flat.drain(0..4)
99 .map(|x| x as u8)
100 .collect::<Vec<u8>>()
101 .try_into()
102 .unwrap(),
103 ))
104}
105
106pub fn write_sha_halfs(flat: &mut Vec<u32>, digest: &Digest) {
108 for x in digest.as_words() {
109 flat.push(*x & 0xffff);
110 flat.push(*x >> 16);
111 }
112}
113
114fn write_u32_bytes(flat: &mut Vec<u32>, word: u32) {
115 for x in word.to_le_bytes() {
116 flat.push(x as u32);
117 }
118}
119
120#[derive(Debug, Copy, Clone)]
122pub enum DecodeError {
123 EndOfStream,
125 OutOfRange,
127}
128
129impl fmt::Display for DecodeError {
130 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 match self {
132 Self::EndOfStream => write!(f, "end of stream reached when more data was expected"),
133 Self::OutOfRange => write!(f, "value outside of expected range"),
134 }
135 }
136}
137
138#[cfg(feature = "std")]
139impl std::error::Error for DecodeError {}