sp_subspace_mmr/
lib.rs

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