mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-16 17:51:10 +00:00
Merkle Mountain Range pallet improvements (#7891)
* Add stateless verification helper function. * Split MMR primitives. * Add RuntimeAPI * RuntimeAPI with OpaqueLeaves * Bump spec_version,. * Move primitives back to frame. * Fix OpaqueLeaf encoding. * Add block number to frame_system implementation of LeafDataProvider. * Relax leaf codec requirements and fix OpaqueLeaf * Add root to debug line. * Apply suggestions from code review Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> * Typo. Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
This commit is contained in:
@@ -73,7 +73,7 @@ mod mock;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub mod primitives;
|
||||
pub use pallet_mmr_primitives as primitives;
|
||||
|
||||
pub trait WeightInfo {
|
||||
fn on_initialize(peaks: u64) -> Weight;
|
||||
@@ -118,6 +118,9 @@ pub trait Config<I = DefaultInstance>: frame_system::Config {
|
||||
/// [LeafDataProvider](primitives::LeafDataProvider)s can be composed into tuples to put
|
||||
/// multiple elements into the tree. In such a case it might be worth using [primitives::Compact]
|
||||
/// to make MMR proof for one element of the tuple leaner.
|
||||
///
|
||||
/// Note that the leaf at each block MUST be unique. You may want to include a block hash or block
|
||||
/// number as an easiest way to ensure that.
|
||||
type LeafData: primitives::LeafDataProvider;
|
||||
|
||||
/// A hook to act on the new MMR root.
|
||||
@@ -182,6 +185,28 @@ type LeafOf<T, I> = <<T as Config<I>>::LeafData as primitives::LeafDataProvider>
|
||||
/// Hashing used for the pallet.
|
||||
pub(crate) type HashingOf<T, I> = <T as Config<I>>::Hashing;
|
||||
|
||||
/// Stateless MMR proof verification.
|
||||
///
|
||||
/// This function can be used to verify received MMR proof (`proof`)
|
||||
/// for given leaf data (`leaf`) against a known MMR root hash (`root`).
|
||||
///
|
||||
/// The verification does not require any storage access.
|
||||
pub fn verify_leaf_proof<H, L>(
|
||||
root: H::Output,
|
||||
leaf: mmr::Node<H, L>,
|
||||
proof: primitives::Proof<H::Output>,
|
||||
) -> Result<(), primitives::Error> where
|
||||
H: traits::Hash,
|
||||
L: primitives::FullLeaf,
|
||||
{
|
||||
let is_valid = mmr::verify_leaf_proof::<H, L>(root, leaf, proof)?;
|
||||
if is_valid {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(primitives::Error::Verify.log_debug(("The proof is incorrect.", root)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
fn offchain_key(pos: u64) -> sp_std::prelude::Vec<u8> {
|
||||
(T::INDEXING_PREFIX, pos).encode()
|
||||
@@ -195,7 +220,7 @@ impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
/// It may return an error or panic if used incorrectly.
|
||||
pub fn generate_proof(leaf_index: u64) -> Result<
|
||||
(LeafOf<T, I>, primitives::Proof<<T as Config<I>>::Hash>),
|
||||
mmr::Error,
|
||||
primitives::Error,
|
||||
> {
|
||||
let mmr: ModuleMmr<mmr::storage::OffchainStorage, T, I> = mmr::Mmr::new(Self::mmr_leaves());
|
||||
mmr.generate_proof(leaf_index)
|
||||
@@ -210,12 +235,12 @@ impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
pub fn verify_leaf(
|
||||
leaf: LeafOf<T, I>,
|
||||
proof: primitives::Proof<<T as Config<I>>::Hash>,
|
||||
) -> Result<(), mmr::Error> {
|
||||
) -> Result<(), primitives::Error> {
|
||||
if proof.leaf_count > Self::mmr_leaves()
|
||||
|| proof.leaf_count == 0
|
||||
|| proof.items.len() as u32 > mmr::utils::NodesUtils::new(proof.leaf_count).depth()
|
||||
{
|
||||
return Err(mmr::Error::Verify.log_debug(
|
||||
return Err(primitives::Error::Verify.log_debug(
|
||||
"The proof has incorrect number of leaves or proof items."
|
||||
));
|
||||
}
|
||||
@@ -225,7 +250,7 @@ impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
if is_valid {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(mmr::Error::Verify.log_debug("The proof is incorrect."))
|
||||
Err(primitives::Error::Verify.log_debug("The proof is incorrect."))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user