sp_subspace_mmr/
lib.rs

1//! Primitives for Subspace MMR.
2
3#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(feature = "std")]
6pub mod host_functions;
7mod runtime_interface;
8#[cfg(feature = "std")]
9pub use runtime_interface::domain_mmr_runtime_interface::HostFunctions as DomainHostFunctions;
10#[cfg(feature = "std")]
11pub use runtime_interface::subspace_mmr_runtime_interface::HostFunctions;
12pub use runtime_interface::{domain_mmr_runtime_interface, subspace_mmr_runtime_interface};
13
14#[cfg(not(feature = "std"))]
15extern crate alloc;
16
17use parity_scale_codec::{Decode, Encode};
18use scale_info::TypeInfo;
19use sp_mmr_primitives::{EncodableOpaqueLeaf, LeafProof as MmrProof};
20
21/// MMR leaf structure
22#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
23pub enum MmrLeaf<BlockNumber, Hash> {
24    /// V0 version of leaf data
25    V0(LeafDataV0<BlockNumber, Hash>),
26}
27
28impl<BlockNumber: Clone, Hash: Clone> MmrLeaf<BlockNumber, Hash> {
29    pub fn state_root(&self) -> Hash {
30        match self {
31            MmrLeaf::V0(leaf) => leaf.state_root.clone(),
32        }
33    }
34
35    pub fn block_number(&self) -> BlockNumber {
36        match self {
37            MmrLeaf::V0(leaf) => leaf.block_number.clone(),
38        }
39    }
40}
41
42/// MMR v0 leaf data
43#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
44pub struct LeafDataV0<BlockNumber, Hash> {
45    pub block_number: BlockNumber,
46    pub block_hash: Hash,
47    /// Can be used to prove specific storage after block was pruned
48    pub state_root: Hash,
49    /// Can be used to prove block body
50    pub extrinsics_root: Hash,
51}
52
53/// Consensus chain MMR leaf and its Proof at specific block.
54///
55/// The verifier is not required to contains any the MMR offchain data but this proof
56/// will be expired after `N` blocks where `N` is the number of MMR root stored in the
57// consensus chain runtime.
58#[derive(Debug, Clone, Encode, Decode, Eq, PartialEq, TypeInfo)]
59pub struct ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash> {
60    /// Consensus block info from which this proof was generated.
61    pub consensus_block_number: CBlockNumber,
62    pub consensus_block_hash: CBlockHash,
63    /// Encoded MMR leaf
64    pub opaque_mmr_leaf: EncodableOpaqueLeaf,
65    /// MMR proof for the leaf above.
66    pub proof: MmrProof<MmrHash>,
67}
68
69/// Trait to verify MMR proofs
70pub trait MmrProofVerifier<MmrHash, CBlockNumber: Decode, CBlockHash: Decode> {
71    /// Returns consensus state root if the given MMR proof is valid
72    fn verify_proof_and_extract_leaf(
73        mmr_leaf_proof: ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>,
74    ) -> Option<MmrLeaf<CBlockNumber, CBlockHash>>;
75
76    fn verify_proof_stateless(
77        _mmr_root: MmrHash,
78        _mmr_leaf_proof: ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>,
79    ) -> Option<MmrLeaf<CBlockNumber, CBlockHash>> {
80        None
81    }
82
83    fn extract_leaf_without_verifying(
84        mmr_leaf_proof: ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>,
85    ) -> Option<MmrLeaf<CBlockNumber, CBlockHash>> {
86        mmr_leaf_proof
87            .opaque_mmr_leaf
88            .into_opaque_leaf()
89            .try_decode()
90    }
91}
92
93impl<MmrHash, CBlockNumber: Decode, CBlockHash: Decode>
94    MmrProofVerifier<MmrHash, CBlockNumber, CBlockHash> for ()
95{
96    fn verify_proof_and_extract_leaf(
97        _mmr_leaf_proof: ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>,
98    ) -> Option<MmrLeaf<CBlockNumber, CBlockHash>> {
99        None
100    }
101}