mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 04:01:10 +00:00
pallet-mmr: RPC API and Runtime API work with block numbers (#12345)
* pallet-mmr: RPC API works with block_numbers * fixes * update rpc * fmt * final touches in the rpc * temporary fix * fix * fmt * docs * Update lib.rs * use NumberFor * validate input * update runtime * convert block_number to u64 * small edit * update runtime api * test fix * runtime fix * update test function * fmt * fix nits * remove block_num_to_leaf_index from runtime api * Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Robert Hambrock <roberthambrock@gmail.com> * fix tests * get the code to compile after merge * get the tests to compile * fix in tests? * fix test * Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update primitives/merkle-mountain-range/src/lib.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * fix errors & nits * change block_num_to_leaf_index * don't make any assumptions * Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Update frame/merkle-mountain-range/src/tests.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * fix * small fix * use best_known_block_number * best_known_block_number instead of leaves_count * more readable? * remove warning * Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Robert Hambrock <roberthambrock@gmail.com> * simplify * update docs * nits * fmt & fix * merge fixes * fix * small fix * docs & nit fixes * Nit fixes * remove leaf_indices_to_block_numbers() * fmt Co-authored-by: Robert Hambrock <roberthambrock@gmail.com> Co-authored-by: Adrian Catangiu <adrian@parity.io>
This commit is contained in:
@@ -59,7 +59,7 @@
|
||||
use codec::Encode;
|
||||
use frame_support::weights::Weight;
|
||||
use sp_runtime::{
|
||||
traits::{self, One, Saturating},
|
||||
traits::{self, CheckedSub, One, Saturating},
|
||||
SaturatedConversion,
|
||||
};
|
||||
|
||||
@@ -318,37 +318,73 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
.saturating_add(leaf_index.saturated_into())
|
||||
}
|
||||
|
||||
/// Generate a MMR proof for the given `leaf_indices`.
|
||||
/// Convert a `block_num` into a leaf index.
|
||||
fn block_num_to_leaf_index(block_num: T::BlockNumber) -> Result<LeafIndex, primitives::Error>
|
||||
where
|
||||
T: frame_system::Config,
|
||||
{
|
||||
// leaf_idx = (leaves_count - 1) - (current_block_num - block_num);
|
||||
let best_block_num = <frame_system::Pallet<T>>::block_number();
|
||||
let blocks_diff = best_block_num.checked_sub(&block_num).ok_or_else(|| {
|
||||
primitives::Error::BlockNumToLeafIndex
|
||||
.log_debug("The provided block_number is greater than the best block number.")
|
||||
})?;
|
||||
let blocks_diff_as_leaf_idx = blocks_diff.try_into().map_err(|_| {
|
||||
primitives::Error::BlockNumToLeafIndex
|
||||
.log_debug("The `blocks_diff` couldn't be converted to `LeafIndex`.")
|
||||
})?;
|
||||
|
||||
let leaf_idx = Self::mmr_leaves()
|
||||
.checked_sub(1)
|
||||
.and_then(|last_leaf_idx| last_leaf_idx.checked_sub(blocks_diff_as_leaf_idx))
|
||||
.ok_or_else(|| {
|
||||
primitives::Error::BlockNumToLeafIndex
|
||||
.log_debug("There aren't enough leaves in the chain.")
|
||||
})?;
|
||||
Ok(leaf_idx)
|
||||
}
|
||||
|
||||
/// Generate a MMR proof for the given `block_numbers`.
|
||||
///
|
||||
/// Note this method can only be used from an off-chain context
|
||||
/// (Offchain Worker or Runtime API call), since it requires
|
||||
/// all the leaves to be present.
|
||||
/// It may return an error or panic if used incorrectly.
|
||||
pub fn generate_batch_proof(
|
||||
leaf_indices: Vec<LeafIndex>,
|
||||
block_numbers: Vec<T::BlockNumber>,
|
||||
) -> Result<
|
||||
(Vec<LeafOf<T, I>>, primitives::BatchProof<<T as Config<I>>::Hash>),
|
||||
primitives::Error,
|
||||
> {
|
||||
Self::generate_historical_batch_proof(leaf_indices, Self::mmr_leaves())
|
||||
Self::generate_historical_batch_proof(
|
||||
block_numbers,
|
||||
<frame_system::Pallet<T>>::block_number(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate a MMR proof for the given `leaf_indices` for the MMR of `leaves_count` size.
|
||||
/// Generate a MMR proof for the given `block_numbers` given the `best_known_block_number`.
|
||||
///
|
||||
/// Note this method can only be used from an off-chain context
|
||||
/// (Offchain Worker or Runtime API call), since it requires
|
||||
/// all the leaves to be present.
|
||||
/// It may return an error or panic if used incorrectly.
|
||||
pub fn generate_historical_batch_proof(
|
||||
leaf_indices: Vec<LeafIndex>,
|
||||
leaves_count: LeafIndex,
|
||||
block_numbers: Vec<T::BlockNumber>,
|
||||
best_known_block_number: T::BlockNumber,
|
||||
) -> Result<
|
||||
(Vec<LeafOf<T, I>>, primitives::BatchProof<<T as Config<I>>::Hash>),
|
||||
primitives::Error,
|
||||
> {
|
||||
if leaves_count > Self::mmr_leaves() {
|
||||
return Err(Error::InvalidLeavesCount)
|
||||
}
|
||||
let leaves_count =
|
||||
Self::block_num_to_leaf_index(best_known_block_number)?.saturating_add(1);
|
||||
|
||||
// we need to translate the block_numbers into leaf indices.
|
||||
let leaf_indices = block_numbers
|
||||
.iter()
|
||||
.map(|block_num| -> Result<LeafIndex, primitives::Error> {
|
||||
Self::block_num_to_leaf_index(*block_num)
|
||||
})
|
||||
.collect::<Result<Vec<LeafIndex>, _>>()?;
|
||||
|
||||
let mmr: ModuleMmr<mmr::storage::OffchainStorage, T, I> = mmr::Mmr::new(leaves_count);
|
||||
mmr.generate_batch_proof(leaf_indices)
|
||||
|
||||
Reference in New Issue
Block a user