Expose MMR root through runtime API - use it in BEEFY client (#11183)

* beefy-gadget: allow custom runtime api provider

* beefy-gadget: use mock runtime api in tests

* pallet-mmr: expose mmr root from state through runtime API

* beefy-gadget: get mmr root from runtime state

* pallet-beefy-mmr: remove MmrRoot from header digests

* frame/mmr: move mmr primitives out of frame

* frame/mmr: completely move primitives out of frame

* address review comments

* beefy-mmr: bring back mmr root from header digest

* clippy fixes for rustc 1.60

* address review comments
This commit is contained in:
Adrian Catangiu
2022-04-13 13:13:06 +03:00
committed by GitHub
parent 3fec108263
commit 80ce5c5768
21 changed files with 403 additions and 335 deletions
@@ -58,7 +58,7 @@
use codec::Encode;
use frame_support::weights::Weight;
use sp_runtime::traits;
use sp_runtime::traits::{self, One, Saturating};
#[cfg(any(feature = "runtime-benchmarks", test))]
mod benchmarking;
@@ -70,7 +70,30 @@ mod mock;
mod tests;
pub use pallet::*;
pub use pallet_mmr_primitives::{self as primitives, NodeIndex};
pub use sp_mmr_primitives::{self as primitives, Error, LeafDataProvider, LeafIndex, NodeIndex};
/// The most common use case for MMRs is to store historical block hashes,
/// so that any point in time in the future we can receive a proof about some past
/// blocks without using excessive on-chain storage.
///
/// Hence we implement the [LeafDataProvider] for [ParentNumberAndHash] which is a
/// crate-local wrapper over [frame_system::Pallet]. Since the current block hash
/// is not available (since the block is not finished yet),
/// we use the `parent_hash` here along with parent block number.
pub struct ParentNumberAndHash<T: frame_system::Config> {
_phanthom: sp_std::marker::PhantomData<T>,
}
impl<T: frame_system::Config> LeafDataProvider for ParentNumberAndHash<T> {
type LeafData = (<T as frame_system::Config>::BlockNumber, <T as frame_system::Config>::Hash);
fn leaf_data() -> Self::LeafData {
(
frame_system::Pallet::<T>::block_number().saturating_sub(One::one()),
frame_system::Pallet::<T>::parent_hash(),
)
}
}
pub trait WeightInfo {
fn on_initialize(peaks: NodeIndex) -> Weight;
@@ -161,7 +184,7 @@ pub mod pallet {
/// Current size of the MMR (number of leaves).
#[pallet::storage]
#[pallet::getter(fn mmr_leaves)]
pub type NumberOfLeaves<T, I = ()> = StorageValue<_, NodeIndex, ValueQuery>;
pub type NumberOfLeaves<T, I = ()> = StorageValue<_, LeafIndex, ValueQuery>;
/// Hashes of the nodes in the MMR.
///
@@ -240,7 +263,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// all the leaves to be present.
/// It may return an error or panic if used incorrectly.
pub fn generate_proof(
leaf_index: NodeIndex,
leaf_index: LeafIndex,
) -> Result<(LeafOf<T, I>, primitives::Proof<<T as Config<I>>::Hash>), primitives::Error> {
let mmr: ModuleMmr<mmr::storage::OffchainStorage, T, I> = mmr::Mmr::new(Self::mmr_leaves());
mmr.generate_proof(leaf_index)
@@ -272,4 +295,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
Err(primitives::Error::Verify.log_debug("The proof is incorrect."))
}
}
/// Return the on-chain MMR root hash.
pub fn mmr_root() -> <T as Config<I>>::Hash {
Self::mmr_root_hash()
}
}
@@ -19,7 +19,7 @@ mod mmr;
pub mod storage;
pub mod utils;
use crate::primitives::FullLeaf;
use sp_mmr_primitives::{DataOrHash, FullLeaf};
use sp_runtime::traits;
pub use self::mmr::{verify_leaf_proof, Mmr};
@@ -28,7 +28,7 @@ pub use self::mmr::{verify_leaf_proof, Mmr};
pub type NodeOf<T, I, L> = Node<<T as crate::Config<I>>::Hashing, L>;
/// A node stored in the MMR.
pub type Node<H, L> = crate::primitives::DataOrHash<H, L>;
pub type Node<H, L> = DataOrHash<H, L>;
/// Default Merging & Hashing behavior for MMR.
pub struct Hasher<H, L>(sp_std::marker::PhantomData<(H, L)>);
@@ -20,8 +20,8 @@ use crate::*;
use codec::{Decode, Encode};
use frame_support::traits::{ConstU32, ConstU64};
use pallet_mmr_primitives::{Compact, LeafDataProvider};
use sp_core::H256;
use sp_mmr_primitives::{Compact, LeafDataProvider};
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup, Keccak256},
@@ -74,7 +74,7 @@ impl Config for Test {
type Hashing = Keccak256;
type Hash = H256;
type LeafData = Compact<Keccak256, (frame_system::Pallet<Test>, LeafData)>;
type LeafData = Compact<Keccak256, (ParentNumberAndHash<Test>, LeafData)>;
type OnNewRoot = ();
type WeightInfo = ();
}
@@ -19,11 +19,11 @@ use crate::{mmr::utils, mock::*, *};
use frame_support::traits::OnInitialize;
use mmr_lib::helper;
use pallet_mmr_primitives::{Compact, Proof};
use sp_core::{
offchain::{testing::TestOffchainExt, OffchainDbExt, OffchainWorkerExt},
H256,
};
use sp_mmr_primitives::{Compact, Proof};
pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
frame_system::GenesisConfig::default().build_storage::<Test>().unwrap().into()