pallet_subspace_mmr/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
4
5use frame_system::pallet_prelude::BlockNumberFor;
6pub use pallet::*;
7use sp_core::Get;
8use sp_mmr_primitives::{LeafDataProvider, OnNewRoot};
9use sp_runtime::traits::{CheckedSub, One};
10use sp_subspace_mmr::subspace_mmr_runtime_interface::get_mmr_leaf_data;
11use sp_subspace_mmr::{LeafDataV0, MmrLeaf};
12
13#[frame_support::pallet]
14mod pallet {
15 use frame_support::pallet_prelude::*;
16 use frame_support::Parameter;
17 use frame_system::pallet_prelude::BlockNumberFor;
18 use sp_core::H256;
19
20 #[pallet::pallet]
21 pub struct Pallet<T>(_);
22
23 #[pallet::config]
24 pub trait Config: frame_system::Config<Hash: Into<H256> + From<H256>> {
25 type MmrRootHash: Parameter + Copy + MaxEncodedLen;
26
27 type MmrRootHashCount: Get<u32>;
32 }
33
34 #[pallet::storage]
36 #[pallet::getter(fn mmr_root_hash)]
37 pub type MmrRootHashes<T: Config> =
38 StorageMap<_, Twox64Concat, BlockNumberFor<T>, T::MmrRootHash, OptionQuery>;
39}
40
41impl<T: Config> OnNewRoot<T::MmrRootHash> for Pallet<T> {
42 fn on_new_root(root: &T::MmrRootHash) {
43 let block_number = frame_system::Pallet::<T>::block_number();
44 <MmrRootHashes<T>>::insert(block_number, *root);
45 if let Some(to_prune) = block_number.checked_sub(&T::MmrRootHashCount::get().into()) {
46 <MmrRootHashes<T>>::remove(to_prune);
47 }
48 }
49}
50
51impl<T: Config> LeafDataProvider for Pallet<T> {
52 type LeafData = MmrLeaf<BlockNumberFor<T>, T::Hash>;
53
54 fn leaf_data() -> Self::LeafData {
55 let block_number = frame_system::Pallet::<T>::block_number()
56 .checked_sub(&One::one())
57 .expect("`block_number` will always be >= 1; qed");
58 let block_hash = frame_system::Pallet::<T>::parent_hash();
59 let leaf_data = get_mmr_leaf_data(block_hash.into())
60 .expect("leaf data for parent hash must always be derived; qed");
61 MmrLeaf::V0(LeafDataV0 {
62 block_number,
63 block_hash,
64 state_root: leaf_data.state_root.into(),
65 extrinsics_root: leaf_data.extrinsics_root.into(),
66 })
67 }
68}