#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
pub mod host_functions;
mod runtime_interface;
#[cfg(feature = "std")]
pub use runtime_interface::domain_mmr_runtime_interface::HostFunctions as DomainHostFunctions;
#[cfg(feature = "std")]
pub use runtime_interface::subspace_mmr_runtime_interface::HostFunctions;
pub use runtime_interface::{domain_mmr_runtime_interface, subspace_mmr_runtime_interface};
#[cfg(not(feature = "std"))]
extern crate alloc;
use codec::{Codec, Decode, Encode};
use scale_info::TypeInfo;
use sp_mmr_primitives::{EncodableOpaqueLeaf, LeafProof as MmrProof};
use sp_runtime::generic::OpaqueDigestItemId;
use sp_runtime::DigestItem;
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub enum MmrLeaf<BlockNumber, Hash> {
V0(LeafDataV0<BlockNumber, Hash>),
}
impl<BlockNumber: Clone, Hash: Clone> MmrLeaf<BlockNumber, Hash> {
pub fn state_root(&self) -> Hash {
match self {
MmrLeaf::V0(leaf) => leaf.state_root.clone(),
}
}
pub fn block_number(&self) -> BlockNumber {
match self {
MmrLeaf::V0(leaf) => leaf.block_number.clone(),
}
}
}
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub struct LeafDataV0<BlockNumber, Hash> {
pub block_number: BlockNumber,
pub block_hash: Hash,
pub state_root: Hash,
pub extrinsics_root: Hash,
}
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)]
pub enum MmrDigestItem<MmrRootHash: Codec> {
NewMmrRoot(MmrRootHash),
}
pub trait MmrDigest<MmrRootHash> {
fn new_mmr_root(root: MmrRootHash) -> Self;
fn as_new_mmr_root(&self) -> Option<MmrRootHash>;
}
impl<MmrRootHash: Codec> MmrDigest<MmrRootHash> for DigestItem {
fn new_mmr_root(root: MmrRootHash) -> Self {
DigestItem::Other(MmrDigestItem::NewMmrRoot(root).encode())
}
fn as_new_mmr_root(&self) -> Option<MmrRootHash> {
match self.try_to::<MmrDigestItem<MmrRootHash>>(OpaqueDigestItemId::Other) {
Some(MmrDigestItem::NewMmrRoot(root)) => Some(root),
_ => None,
}
}
}
#[derive(Debug, Encode, Decode, Eq, PartialEq, TypeInfo)]
pub struct ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash> {
pub consensus_block_number: CBlockNumber,
pub consensus_block_hash: CBlockHash,
pub opaque_mmr_leaf: EncodableOpaqueLeaf,
pub proof: MmrProof<MmrHash>,
}
impl<CBlockNumber: Clone, CBlockHash: Clone, MmrHash: Clone> Clone
for ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>
{
fn clone(&self) -> Self {
Self {
consensus_block_number: self.consensus_block_number.clone(),
consensus_block_hash: self.consensus_block_hash.clone(),
opaque_mmr_leaf: EncodableOpaqueLeaf(self.opaque_mmr_leaf.0.clone()),
proof: self.proof.clone(),
}
}
}
pub trait MmrProofVerifier<MmrHash, CBlockNumber: Decode, CBlockHash: Decode> {
fn verify_proof_and_extract_leaf(
mmr_leaf_proof: ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>,
) -> Option<MmrLeaf<CBlockNumber, CBlockHash>>;
fn verify_proof_stateless(
_mmr_root: MmrHash,
_mmr_leaf_proof: ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>,
) -> Option<MmrLeaf<CBlockNumber, CBlockHash>> {
None
}
fn extract_leaf_without_verifying(
mmr_leaf_proof: ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>,
) -> Option<MmrLeaf<CBlockNumber, CBlockHash>> {
mmr_leaf_proof
.opaque_mmr_leaf
.into_opaque_leaf()
.try_decode()
}
}
impl<MmrHash, CBlockNumber: Decode, CBlockHash: Decode>
MmrProofVerifier<MmrHash, CBlockNumber, CBlockHash> for ()
{
fn verify_proof_and_extract_leaf(
_mmr_leaf_proof: ConsensusChainMmrLeafProof<CBlockNumber, CBlockHash, MmrHash>,
) -> Option<MmrLeaf<CBlockNumber, CBlockHash>> {
None
}
}