Skip to main content

miden_node_store/state/
apply_proof.rs

1use anyhow::{Context, ensure};
2use miden_node_utils::tracing::miden_instrument;
3use miden_protocol::block::{BlockNumber, BlockProof};
4use miden_protocol::utils::serde::Deserializable;
5
6use crate::COMPONENT;
7use crate::state::{Finality, ProofNotification, State};
8
9impl State {
10    /// Saves a block proof, advances the proven-in-sequence tip, and notifies replica subscribers.
11    ///
12    /// # Errors
13    ///
14    /// - If proofs are not applied in strict ascending order (exactly one block past the proven tip)
15    /// - If the proof's corresponding block was not already committed
16    #[miden_instrument(
17        target = COMPONENT,
18        skip_all,
19        err,
20        fields(
21            block.number = block_num.as_u32(),
22        ),
23    )]
24    pub async fn apply_proof(
25        &self,
26        block_num: BlockNumber,
27        proof_bytes: Vec<u8>,
28    ) -> anyhow::Result<()> {
29        let expected = self.proven_tip.read().child();
30        ensure!(
31            block_num == expected,
32            "out-of-sequence proof: expected block {expected}, got {block_num}",
33        );
34
35        let committed_tip = self.chain_tip(Finality::Committed).await;
36        ensure!(
37            block_num <= committed_tip,
38            "proof for uncommitted block {block_num} exceeds committed tip {committed_tip}",
39        );
40
41        verify_block_proof(block_num, &proof_bytes)?;
42
43        self.block_store.commit_proof(block_num, &proof_bytes).await?;
44        self.proof_cache
45            .push(block_num, ProofNotification::new(block_num, proof_bytes))
46            .expect("proof cache receives sequential block numbers");
47        self.proven_tip.advance(block_num);
48        Ok(())
49    }
50}
51
52/// Verifies that `proof_bytes` is a valid [`BlockProof`] for the block at `block_num`.
53fn verify_block_proof(_block_num: BlockNumber, proof_bytes: &[u8]) -> anyhow::Result<()> {
54    let _proof =
55        BlockProof::read_from_bytes(proof_bytes).context("failed to deserialize block proof")?;
56
57    // TODO: perform verification.
58    Ok(())
59}