miden_objects/decoded/
blockchain.rs1use miden_protobuf::unwrap_infallible;
3
4use crate::decoded::VerificationError;
5use crate::{Verify, proto};
6
7#[cfg(test)]
8mod tests;
9
10#[cfg(test)]
11pub(crate) mod test_utils;
12
13pub use proto::blockchain::DecodedBlockNumber as BlockNumber;
14
15impl Verify for BlockNumber {
16 type Verified = miden_protocol::block::BlockNumber;
17 type Error = core::convert::Infallible;
18 fn verify(self) -> Result<Self::Verified, Self::Error> {
19 Ok(self.block_num.into())
20 }
21}
22
23pub use proto::blockchain::DecodedFeeParameters as FeeParameters;
24
25impl Verify for FeeParameters {
26 type Verified = miden_protocol::block::FeeParameters;
27 type Error = core::convert::Infallible;
28 fn verify(self) -> Result<Self::Verified, Self::Error> {
29 Ok(Self::Verified::new(self.verification_base_fee))
30 }
31}
32
33pub use proto::blockchain::DecodedNextProtocolConfig as NextProtocolConfig;
34
35impl Verify for NextProtocolConfig {
36 type Verified = miden_protocol::protocol_config::NextProtocolConfig;
37 type Error = miden_protocol::errors::ProtocolConfigError;
38 fn verify(self) -> Result<Self::Verified, Self::Error> {
39 let effective_from = unwrap_infallible(self.effective_from.verify());
40 Self::Verified::new(effective_from, self.protocol_config)
41 }
42}
43
44pub use proto::blockchain::DecodedValidatorConfig as ValidatorConfig;
45
46impl Verify for ValidatorConfig {
47 type Verified = miden_protocol::block::ValidatorConfig;
48 type Error = VerificationError;
49 fn verify(self) -> Result<Self::Verified, Self::Error> {
50 let keys = self.keys.verify_infallible();
51 Ok(Self::Verified::new(keys, self.quorum.try_into()?)?)
52 }
53}
54
55pub use proto::blockchain::DecodedBlockHeader as BlockHeader;
56
57impl crate::BuildUnchecked for BlockHeader {
59 type Output = miden_protocol::block::BlockHeader;
60 type Error = VerificationError;
61 fn build_unchecked(self) -> Result<Self::Output, Self::Error> {
62 if self.version != proto::blockchain::BlockVersion::V1 {
63 return Err(BlockHeaderError::UnspecifiedVersion.into());
64 }
65 Ok(Self::Output::new(
66 self.prev_block_commitment,
67 unwrap_infallible(self.block_num.verify()),
68 self.chain_commitment,
69 self.account_root,
70 self.nullifier_root,
71 self.note_root,
72 self.tx_commitment,
73 self.validator_config.verify()?,
74 unwrap_infallible(self.fee_parameters.verify()),
75 self.protocol_config_commitment,
76 self.next_protocol_config.verify()?,
77 self.timestamp,
78 ))
79 }
80}
81
82#[derive(Debug, thiserror::Error)]
83pub enum BlockHeaderError {
84 #[error("block header version is unspecified")]
85 UnspecifiedVersion,
86}
87
88pub use proto::blockchain::DecodedPartialBlockchain as PartialBlockchain;
89
90impl crate::BuildUnchecked for PartialBlockchain {
93 type Output = miden_protocol::transaction::PartialBlockchain;
94 type Error = VerificationError;
95 fn build_unchecked(self) -> Result<Self::Output, Self::Error> {
96 let mmr = self.mmr.verify()?;
97 let mut previous = None;
98 let mut headers = alloc::vec::Vec::new();
99 for header in self.block_headers.into_inner() {
100 let header = header.build_unchecked()?;
101 if previous.is_some_and(|previous| header.block_num() <= previous) {
102 return Err(PartialBlockchainError::HeaderOrder.into());
103 }
104 previous = Some(header.block_num());
105 headers.push(header);
106 }
107 Ok(Self::Output::new(mmr, headers)?)
108 }
109}
110
111#[derive(Debug, thiserror::Error)]
112pub enum PartialBlockchainError {
113 #[error("block headers must be unique and ordered by ascending block number")]
114 HeaderOrder,
115}
116
117pub use proto::blockchain::DecodedBlockAccountUpdate as BlockAccountUpdate;
118
119impl Verify for BlockAccountUpdate {
120 type Verified = miden_protocol::block::BlockAccountUpdate;
121 type Error = VerificationError;
122 fn verify(self) -> Result<Self::Verified, Self::Error> {
123 Ok(Self::Verified::new(
124 self.account_id.verify()?,
125 self.final_state_commitment,
126 self.details.verify()?,
127 )?)
128 }
129}
130
131pub use proto::blockchain::DecodedIndexedOutputNote as IndexedOutputNote;
132
133impl Verify for IndexedOutputNote {
134 type Verified = (usize, miden_protocol::transaction::OutputNote);
135 type Error = VerificationError;
136 fn verify(self) -> Result<Self::Verified, Self::Error> {
137 Ok((self.note_index_in_batch.try_into()?, self.note.verify()?))
138 }
139}
140
141pub use proto::blockchain::DecodedOutputNoteBatch as OutputNoteBatch;
142
143impl Verify for OutputNoteBatch {
144 type Verified = miden_protocol::block::OutputNoteBatch;
145 type Error = VerificationError;
146 fn verify(self) -> Result<Self::Verified, Self::Error> {
147 Ok(self.notes.verify()?)
148 }
149}
150
151pub use proto::blockchain::DecodedBlockBody as BlockBody;
152
153impl crate::BuildUnchecked for BlockBody {
155 type Output = miden_protocol::block::BlockBody;
156 type Error = VerificationError;
157 fn build_unchecked(self) -> Result<Self::Output, Self::Error> {
158 let updates = self.updated_accounts.verify()?;
159 let notes = self.output_note_batches.verify()?;
160 let nullifiers = self.created_nullifiers.map(miden_protocol::note::Nullifier::from_raw);
161 let transactions = self.transactions.build_unchecked()?;
162 Ok(Self::Output::new(
163 updates,
164 notes,
165 nullifiers,
166 miden_protocol::transaction::OrderedTransactionHeaders::new_unchecked(transactions),
167 )?)
168 }
169}
170
171pub use proto::blockchain::DecodedSignedBlock as SignedBlock;
172
173impl crate::BuildUnchecked for SignedBlock {
175 type Output = miden_protocol::block::SignedBlock;
176 type Error = VerificationError;
177 fn build_unchecked(self) -> Result<Self::Output, Self::Error> {
178 self.build(None)
179 }
180}
181
182impl SignedBlock {
183 fn build(
184 self,
185 parent: Option<&miden_protocol::block::BlockHeader>,
186 ) -> Result<miden_protocol::block::SignedBlock, VerificationError> {
187 use crate::BuildUnchecked;
188
189 let header = self.header.build_unchecked()?;
190 let body = self.body.build_unchecked()?;
191 let signatures = self.signatures.verify_infallible();
192 let signatures = miden_protocol::block::BlockSignatures::new(signatures)
193 .map_err(VerificationError::new)?;
194 let block = miden_protocol::block::SignedBlock::new_unchecked(header, body, signatures);
195 block.validate(parent)?;
196 Ok(block)
197 }
198}
199
200impl crate::VerifyWith<&miden_protocol::block::BlockHeader> for SignedBlock {
203 type Verified = miden_protocol::block::SignedBlock;
204 type Error = VerificationError;
205 fn verify_with(
206 self,
207 parent: &miden_protocol::block::BlockHeader,
208 ) -> Result<Self::Verified, Self::Error> {
209 self.build(Some(parent))
210 }
211}