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