feat: Rebrand Polkadot/Substrate references to PezkuwiChain

This commit systematically rebrands various references from Parity Technologies'
Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk.

Key changes include:
- Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks.
- Modified internal documentation and code comments to reflect PezkuwiChain naming and structure.
- Replaced direct references to  with  or specific paths within the  for XCM, Pezkuwi, and other modules.
- Cleaned up deprecated  issue and PR references in various  and  files, particularly in  and  modules.
- Adjusted image and logo URLs in documentation to point to PezkuwiChain assets.
- Removed or rephrased comments related to external Polkadot/Substrate PRs and issues.

This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
2025-12-14 00:04:10 +03:00
parent 286de54384
commit 1c0e57d984
9084 changed files with 997839 additions and 997557 deletions
+87
View File
@@ -0,0 +1,87 @@
[package]
name = "pezpallet-beefy-mmr"
version = "28.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
description = "BEEFY + MMR runtime utilities"
repository.workspace = true
homepage.workspace = true
[lints]
workspace = true
[dependencies]
array-bytes = { optional = true, workspace = true, default-features = true }
binary-merkle-tree = { workspace = true }
codec = { features = ["derive"], workspace = true }
pezframe-benchmarking = { optional = true, workspace = true }
pezframe-support = { workspace = true }
pezframe-system = { workspace = true }
log = { workspace = true }
pezpallet-beefy = { workspace = true }
pezpallet-mmr = { workspace = true }
pezpallet-session = { workspace = true }
scale-info = { features = ["derive"], workspace = true }
serde = { optional = true, workspace = true, default-features = true }
pezsp-api = { workspace = true }
pezsp-consensus-beefy = { workspace = true }
pezsp-core = { workspace = true }
pezsp-io = { workspace = true }
pezsp-runtime = { workspace = true }
pezsp-state-machine = { workspace = true }
[dev-dependencies]
array-bytes = { workspace = true, default-features = true }
pezpallet-balances = { workspace = true }
pezsp-staking = { workspace = true, default-features = true }
[features]
default = ["std"]
std = [
"array-bytes",
"binary-merkle-tree/std",
"codec/std",
"pezframe-benchmarking/std",
"pezframe-support/std",
"pezframe-system/std",
"log/std",
"pezpallet-balances/std",
"pezpallet-beefy/std",
"pezpallet-mmr/std",
"pezpallet-session/std",
"scale-info/std",
"serde",
"pezsp-api/std",
"pezsp-consensus-beefy/std",
"pezsp-core/std",
"pezsp-io/std",
"pezsp-runtime/std",
"pezsp-staking/std",
"pezsp-state-machine/std",
]
try-runtime = [
"pezframe-support/try-runtime",
"pezframe-system/try-runtime",
"pezpallet-balances/try-runtime",
"pezpallet-beefy/try-runtime",
"pezpallet-mmr/try-runtime",
"pezpallet-session/try-runtime",
"pezsp-runtime/try-runtime",
]
runtime-benchmarks = [
"binary-merkle-tree/runtime-benchmarks",
"pezframe-benchmarking/runtime-benchmarks",
"pezframe-support/runtime-benchmarks",
"pezframe-system/runtime-benchmarks",
"pezpallet-balances/runtime-benchmarks",
"pezpallet-beefy/runtime-benchmarks",
"pezpallet-mmr/runtime-benchmarks",
"pezpallet-session/runtime-benchmarks",
"pezsp-api/runtime-benchmarks",
"pezsp-consensus-beefy/runtime-benchmarks",
"pezsp-io/runtime-benchmarks",
"pezsp-runtime/runtime-benchmarks",
"pezsp-staking/runtime-benchmarks",
"pezsp-state-machine/runtime-benchmarks",
]
@@ -0,0 +1,141 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Beefy pallet benchmarking.
#![cfg(feature = "runtime-benchmarks")]
use super::*;
use crate::Pallet as BeefyMmr;
use codec::Encode;
use pezframe_benchmarking::v2::*;
use pezframe_support::traits::Hooks;
use pezframe_system::{Config as SystemConfig, Pallet as System};
use pezpallet_mmr::{Nodes, Pallet as Mmr};
use pezsp_consensus_beefy::Payload;
use pezsp_runtime::traits::One;
pub trait Config:
pezpallet_mmr::Config<Hashing = pezsp_consensus_beefy::MmrHashing> + crate::Config
{
}
impl<T> Config for T where
T: pezpallet_mmr::Config<Hashing = pezsp_consensus_beefy::MmrHashing> + crate::Config
{
}
fn init_block<T: Config>(block_num: u32) {
let block_num = block_num.into();
System::<T>::initialize(&block_num, &<T as SystemConfig>::Hash::default(), &Default::default());
Mmr::<T>::on_initialize(block_num);
}
#[benchmarks]
mod benchmarks {
use super::*;
/// Generate ancestry proofs with `n` leafs and benchmark the logic that checks
/// if the proof is optimal.
#[benchmark]
fn n_leafs_proof_is_optimal(n: Linear<2, 512>) {
pezpallet_mmr::UseLocalStorage::<T>::set(true);
for block_num in 1..=n {
init_block::<T>(block_num);
}
let proof = Mmr::<T>::generate_mock_ancestry_proof().unwrap();
assert_eq!(proof.leaf_count, n as u64);
#[block]
{
<BeefyMmr<T> as AncestryHelper<HeaderFor<T>>>::is_proof_optimal(&proof);
};
}
#[benchmark]
fn extract_validation_context() {
pezpallet_mmr::UseLocalStorage::<T>::set(true);
init_block::<T>(1);
let header = System::<T>::finalize();
pezframe_system::BlockHash::<T>::insert(BlockNumberFor::<T>::one(), header.hash());
let validation_context;
#[block]
{
validation_context =
<BeefyMmr<T> as AncestryHelper<HeaderFor<T>>>::extract_validation_context(header);
}
assert!(validation_context.is_some());
}
#[benchmark]
fn read_peak() {
pezpallet_mmr::UseLocalStorage::<T>::set(true);
init_block::<T>(1);
let peak;
#[block]
{
peak = Nodes::<T>::get(0)
}
assert!(peak.is_some());
}
/// Generate ancestry proofs with `n` nodes and benchmark the verification logic.
/// These proofs are inflated, containing all the leafs, so we won't read any peak during
/// the verification. We need to account for the peaks separately.
#[benchmark]
fn n_items_proof_is_non_canonical(n: Linear<2, 512>) {
pezpallet_mmr::UseLocalStorage::<T>::set(true);
for block_num in 1..=n {
init_block::<T>(block_num);
}
let proof = Mmr::<T>::generate_mock_ancestry_proof().unwrap();
assert_eq!(proof.items.len(), n as usize);
let is_non_canonical;
#[block]
{
is_non_canonical = <BeefyMmr<T> as AncestryHelper<HeaderFor<T>>>::is_non_canonical(
&Commitment {
payload: Payload::from_single_entry(
known_payloads::MMR_ROOT_ID,
MerkleRootOf::<T>::default().encode(),
),
block_number: n.into(),
validator_set_id: 0,
},
proof,
Mmr::<T>::mmr_root(),
);
};
assert_eq!(is_non_canonical, true);
}
impl_benchmark_test_suite!(
Pallet,
crate::mock::new_test_ext(Default::default()),
crate::mock::Test
);
}
+374
View File
@@ -0,0 +1,374 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
//! A BEEFY+MMR pallet combo.
//!
//! While both BEEFY and Merkle Mountain Range (MMR) can be used separately,
//! these tools were designed to work together in unison.
//!
//! The pallet provides a standardized MMR Leaf format that can be used
//! to bridge BEEFY+MMR-based networks (both standalone and Pezkuwi-like).
//!
//! The MMR leaf contains:
//! 1. Block number and parent block hash.
//! 2. Merkle Tree Root Hash of next BEEFY validator set.
//! 3. Arbitrary extra leaf data to be used by downstream pallets to include custom data.
//!
//! and thanks to versioning can be easily updated in the future.
extern crate alloc;
use pezsp_runtime::{
generic::OpaqueDigestItemId,
traits::{Convert, Header, Member},
SaturatedConversion,
};
use alloc::vec::Vec;
use codec::Decode;
use pezpallet_mmr::{primitives::AncestryProof, LeafDataProvider, NodesUtils, ParentNumberAndHash};
use pezsp_consensus_beefy::{
known_payloads,
mmr::{BeefyAuthoritySet, BeefyDataProvider, BeefyNextAuthoritySet, MmrLeaf, MmrLeafVersion},
AncestryHelper, AncestryHelperWeightInfo, Commitment, ConsensusLog,
ValidatorSet as BeefyValidatorSet,
};
use pezframe_support::{crypto::ecdsa::ECDSAExt, pezpallet_prelude::Weight, traits::Get};
use pezframe_system::pezpallet_prelude::{BlockNumberFor, HeaderFor};
pub use pallet::*;
pub use weights::WeightInfo;
mod benchmarking;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
mod weights;
/// A BEEFY consensus digest item with MMR root hash.
pub struct DepositBeefyDigest<T>(core::marker::PhantomData<T>);
impl<T> pezpallet_mmr::primitives::OnNewRoot<pezsp_consensus_beefy::MmrRootHash> for DepositBeefyDigest<T>
where
T: pezpallet_mmr::Config<Hashing = pezsp_consensus_beefy::MmrHashing>,
T: pezpallet_beefy::Config,
{
fn on_new_root(root: &pezsp_consensus_beefy::MmrRootHash) {
let digest = pezsp_runtime::generic::DigestItem::Consensus(
pezsp_consensus_beefy::BEEFY_ENGINE_ID,
codec::Encode::encode(&pezsp_consensus_beefy::ConsensusLog::<
<T as pezpallet_beefy::Config>::BeefyId,
>::MmrRoot(*root)),
);
pezframe_system::Pallet::<T>::deposit_log(digest);
}
}
/// Convert BEEFY secp256k1 public keys into Ethereum addresses
pub struct BeefyEcdsaToEthereum;
impl Convert<pezsp_consensus_beefy::ecdsa_crypto::AuthorityId, Vec<u8>> for BeefyEcdsaToEthereum {
fn convert(beefy_id: pezsp_consensus_beefy::ecdsa_crypto::AuthorityId) -> Vec<u8> {
pezsp_core::ecdsa::Public::from(beefy_id)
.to_eth_address()
.map(|v| v.to_vec())
.map_err(|_| {
log::debug!(target: "runtime::beefy", "Failed to convert BEEFY PublicKey to ETH address!");
})
.unwrap_or_default()
}
}
type MerkleRootOf<T> = <<T as pezpallet_mmr::Config>::Hashing as pezsp_runtime::traits::Hash>::Output;
#[pezframe_support::pallet]
pub mod pallet {
#![allow(missing_docs)]
use super::*;
use pezframe_support::pezpallet_prelude::*;
/// BEEFY-MMR pallet.
#[pallet::pallet]
pub struct Pallet<T>(_);
/// The module's configuration trait.
#[pallet::config]
#[pallet::disable_pezframe_system_supertrait_check]
pub trait Config: pezpallet_mmr::Config + pezpallet_beefy::Config {
/// Current leaf version.
///
/// Specifies the version number added to every leaf that get's appended to the MMR.
/// Read more in [`MmrLeafVersion`] docs about versioning leaves.
type LeafVersion: Get<MmrLeafVersion>;
/// Convert BEEFY AuthorityId to a form that would end up in the Merkle Tree.
///
/// For instance for ECDSA (secp256k1) we want to store uncompressed public keys (65 bytes)
/// and later to Ethereum Addresses (160 bits) to simplify using them on Ethereum chain,
/// but the rest of the Bizinikiwi codebase is storing them compressed (33 bytes) for
/// efficiency reasons.
type BeefyAuthorityToMerkleLeaf: Convert<<Self as pezpallet_beefy::Config>::BeefyId, Vec<u8>>;
/// The type expected for the leaf extra data
type LeafExtra: Member + codec::FullCodec;
/// Retrieve arbitrary data that should be added to the mmr leaf
type BeefyDataProvider: BeefyDataProvider<Self::LeafExtra>;
type WeightInfo: WeightInfo;
}
/// Details of current BEEFY authority set.
#[pallet::storage]
pub type BeefyAuthorities<T: Config> =
StorageValue<_, BeefyAuthoritySet<MerkleRootOf<T>>, ValueQuery>;
/// Details of next BEEFY authority set.
///
/// This storage entry is used as cache for calls to `update_beefy_next_authority_set`.
#[pallet::storage]
pub type BeefyNextAuthorities<T: Config> =
StorageValue<_, BeefyNextAuthoritySet<MerkleRootOf<T>>, ValueQuery>;
}
impl<T: Config> LeafDataProvider for Pallet<T> {
type LeafData = MmrLeaf<
BlockNumberFor<T>,
<T as pezframe_system::Config>::Hash,
MerkleRootOf<T>,
T::LeafExtra,
>;
fn leaf_data() -> Self::LeafData {
MmrLeaf {
version: T::LeafVersion::get(),
parent_number_and_hash: ParentNumberAndHash::<T>::leaf_data(),
leaf_extra: T::BeefyDataProvider::extra_data(),
beefy_next_authority_set: BeefyNextAuthorities::<T>::get(),
}
}
}
impl<T> pezsp_consensus_beefy::OnNewValidatorSet<<T as pezpallet_beefy::Config>::BeefyId> for Pallet<T>
where
T: pallet::Config,
{
/// Compute and cache BEEFY authority sets based on updated BEEFY validator sets.
fn on_new_validator_set(
current_set: &BeefyValidatorSet<<T as pezpallet_beefy::Config>::BeefyId>,
next_set: &BeefyValidatorSet<<T as pezpallet_beefy::Config>::BeefyId>,
) {
let current = Pallet::<T>::compute_authority_set(current_set);
let next = Pallet::<T>::compute_authority_set(next_set);
// cache the result
BeefyAuthorities::<T>::put(&current);
BeefyNextAuthorities::<T>::put(&next);
}
}
impl<T: Config> AncestryHelper<HeaderFor<T>> for Pallet<T>
where
T: pezpallet_mmr::Config<Hashing = pezsp_consensus_beefy::MmrHashing>,
{
type Proof = AncestryProof<MerkleRootOf<T>>;
type ValidationContext = MerkleRootOf<T>;
fn is_proof_optimal(proof: &Self::Proof) -> bool {
let is_proof_optimal = pezpallet_mmr::Pallet::<T>::is_ancestry_proof_optimal(proof);
// We don't check the proof size when running benchmarks, since we use mock proofs
// which would cause the test to fail.
if cfg!(feature = "runtime-benchmarks") {
return true;
}
is_proof_optimal
}
fn extract_validation_context(header: HeaderFor<T>) -> Option<Self::ValidationContext> {
// Check if the provided header is canonical.
let expected_hash = pezframe_system::Pallet::<T>::block_hash(header.number());
if expected_hash != header.hash() {
return None;
}
// Extract the MMR root from the header digest
header.digest().convert_first(|l| {
l.try_to(OpaqueDigestItemId::Consensus(&pezsp_consensus_beefy::BEEFY_ENGINE_ID))
.and_then(|log: ConsensusLog<<T as pezpallet_beefy::Config>::BeefyId>| match log {
ConsensusLog::MmrRoot(mmr_root) => Some(mmr_root),
_ => None,
})
})
}
fn is_non_canonical(
commitment: &Commitment<BlockNumberFor<T>>,
proof: Self::Proof,
context: Self::ValidationContext,
) -> bool {
let commitment_leaf_count =
match pezpallet_mmr::Pallet::<T>::block_num_to_leaf_count(commitment.block_number) {
Ok(commitment_leaf_count) => commitment_leaf_count,
Err(_) => {
// We can't prove that the commitment is non-canonical if the
// `commitment.block_number` is invalid.
return false;
},
};
if commitment_leaf_count != proof.prev_leaf_count {
// Can't prove that the commitment is non-canonical if the `commitment.block_number`
// doesn't match the ancestry proof.
return false;
}
let canonical_mmr_root = context;
let canonical_prev_root =
match pezpallet_mmr::Pallet::<T>::verify_ancestry_proof(canonical_mmr_root, proof) {
Ok(canonical_prev_root) => canonical_prev_root,
Err(_) => {
// Can't prove that the commitment is non-canonical if the proof
// is invalid.
return false;
},
};
let mut found_commitment_root = false;
let commitment_roots = commitment
.payload
.get_all_decoded::<MerkleRootOf<T>>(&known_payloads::MMR_ROOT_ID);
for maybe_commitment_root in commitment_roots {
match maybe_commitment_root {
Some(commitment_root) => {
found_commitment_root = true;
if canonical_prev_root != commitment_root {
// If the commitment contains an MMR root, that is not equal to
// `canonical_prev_root`, the commitment is invalid
return true;
}
},
None => {
// If the commitment contains an MMR root, that can't be decoded, it is invalid.
return true;
},
}
}
if !found_commitment_root {
// If the commitment doesn't contain any MMR root, while the proof is valid,
// the commitment is invalid
return true;
}
false
}
}
impl<T: Config> AncestryHelperWeightInfo<HeaderFor<T>> for Pallet<T>
where
T: pezpallet_mmr::Config<Hashing = pezsp_consensus_beefy::MmrHashing>,
{
fn is_proof_optimal(proof: &<Self as AncestryHelper<HeaderFor<T>>>::Proof) -> Weight {
<T as Config>::WeightInfo::n_leafs_proof_is_optimal(proof.leaf_count.saturated_into())
}
fn extract_validation_context() -> Weight {
<T as Config>::WeightInfo::extract_validation_context()
}
fn is_non_canonical(proof: &<Self as AncestryHelper<HeaderFor<T>>>::Proof) -> Weight {
let mmr_utils = NodesUtils::new(proof.leaf_count);
let num_peaks = mmr_utils.number_of_peaks();
// The approximated cost of verifying an ancestry proof with `n` nodes.
// We add the previous peaks to the total number of nodes,
// since they have to be processed as well.
<T as Config>::WeightInfo::n_items_proof_is_non_canonical(
proof.items.len().saturating_add(proof.prev_peaks.len()).saturated_into(),
)
// `n_items_proof_is_non_canonical()` uses inflated proofs that contain all the leafs,
// where no peak needs to be read. So we need to also add the cost of reading the peaks.
.saturating_add(<T as Config>::WeightInfo::read_peak().saturating_mul(num_peaks))
}
}
impl<T: Config> Pallet<T> {
/// Return the currently active BEEFY authority set proof.
pub fn authority_set_proof() -> BeefyAuthoritySet<MerkleRootOf<T>> {
BeefyAuthorities::<T>::get()
}
/// Return the next/queued BEEFY authority set proof.
pub fn next_authority_set_proof() -> BeefyNextAuthoritySet<MerkleRootOf<T>> {
BeefyNextAuthorities::<T>::get()
}
/// Returns details of a BEEFY authority set.
///
/// Details contain authority set id, authority set length and a merkle root,
/// constructed from uncompressed secp256k1 public keys converted to Ethereum addresses
/// of the next BEEFY authority set.
fn compute_authority_set(
validator_set: &BeefyValidatorSet<<T as pezpallet_beefy::Config>::BeefyId>,
) -> BeefyAuthoritySet<MerkleRootOf<T>> {
let id = validator_set.id();
let beefy_addresses = validator_set
.validators()
.into_iter()
.cloned()
.map(T::BeefyAuthorityToMerkleLeaf::convert)
.collect::<Vec<_>>();
let default_eth_addr = [0u8; 20];
let len = beefy_addresses.len() as u32;
let uninitialized_addresses = beefy_addresses
.iter()
.filter(|&addr| addr.as_slice().eq(&default_eth_addr))
.count();
if uninitialized_addresses > 0 {
log::error!(
target: "runtime::beefy",
"Failed to convert {} out of {} BEEFY PublicKeys to ETH addresses!",
uninitialized_addresses,
len,
);
}
let keyset_commitment = binary_merkle_tree::merkle_root::<
<T as pezpallet_mmr::Config>::Hashing,
_,
>(beefy_addresses)
.into();
BeefyAuthoritySet { id, len, keyset_commitment }
}
}
pezsp_api::decl_runtime_apis! {
/// API useful for BEEFY light clients.
pub trait BeefyMmrApi<H>
where
BeefyAuthoritySet<H>: Decode,
{
/// Return the currently active BEEFY authority set proof.
fn authority_set_proof() -> BeefyAuthoritySet<H>;
/// Return the next/queued BEEFY authority set proof.
fn next_authority_set_proof() -> BeefyNextAuthoritySet<H>;
}
}
+211
View File
@@ -0,0 +1,211 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::vec;
use codec::Encode;
use pezframe_support::{
construct_runtime, derive_impl, parameter_types,
traits::{ConstU32, ConstU64},
};
use pezsp_consensus_beefy::mmr::MmrLeafVersion;
use pezsp_io::TestExternalities;
use pezsp_runtime::{
app_crypto::ecdsa::Public,
impl_opaque_keys,
traits::{ConvertInto, Keccak256, OpaqueKeys},
BuildStorage,
};
use pezsp_state_machine::BasicExternalities;
use crate as pezpallet_beefy_mmr;
pub use pezsp_consensus_beefy::{
ecdsa_crypto::AuthorityId as BeefyId, mmr::BeefyDataProvider, ConsensusLog, BEEFY_ENGINE_ID,
};
use pezsp_core::offchain::{testing::TestOffchainExt, OffchainDbExt, OffchainWorkerExt};
impl_opaque_keys! {
pub struct MockSessionKeys {
pub dummy: pezpallet_beefy::Pallet<Test>,
}
}
type Block = pezframe_system::mocking::MockBlock<Test>;
construct_runtime!(
pub enum Test
{
System: pezframe_system,
Session: pezpallet_session,
Balances: pezpallet_balances,
Mmr: pezpallet_mmr,
Beefy: pezpallet_beefy,
BeefyMmr: pezpallet_beefy_mmr,
}
);
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Test {
type AccountData = pezpallet_balances::AccountData<u64>;
type Block = Block;
}
#[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
impl pezpallet_balances::Config for Test {
type AccountStore = System;
}
impl pezpallet_session::Config for Test {
type RuntimeEvent = RuntimeEvent;
type ValidatorId = u64;
type ValidatorIdOf = ConvertInto;
type ShouldEndSession = pezpallet_session::PeriodicSessions<ConstU64<1>, ConstU64<0>>;
type NextSessionRotation = pezpallet_session::PeriodicSessions<ConstU64<1>, ConstU64<0>>;
type SessionManager = MockSessionManager;
type SessionHandler = <MockSessionKeys as OpaqueKeys>::KeyTypeIdProviders;
type Keys = MockSessionKeys;
type DisablingStrategy = ();
type WeightInfo = ();
type Currency = Balances;
type KeyDeposit = ();
}
pub type MmrLeaf = pezsp_consensus_beefy::mmr::MmrLeaf<
pezframe_system::pezpallet_prelude::BlockNumberFor<Test>,
<Test as pezframe_system::Config>::Hash,
crate::MerkleRootOf<Test>,
Vec<u8>,
>;
impl pezpallet_mmr::Config for Test {
const INDEXING_PREFIX: &'static [u8] = b"mmr";
type Hashing = Keccak256;
type LeafData = BeefyMmr;
type OnNewRoot = pezpallet_beefy_mmr::DepositBeefyDigest<Test>;
type BlockHashProvider = pezpallet_mmr::DefaultBlockHashProvider<Test>;
type WeightInfo = ();
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}
impl pezpallet_beefy::Config for Test {
type BeefyId = BeefyId;
type MaxAuthorities = ConstU32<100>;
type MaxNominators = ConstU32<1000>;
type MaxSetIdSessionEntries = ConstU64<100>;
type OnNewValidatorSet = BeefyMmr;
type AncestryHelper = BeefyMmr;
type WeightInfo = ();
type KeyOwnerProof = pezsp_core::Void;
type EquivocationReportSystem = ();
}
parameter_types! {
pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(1, 5);
}
impl pezpallet_beefy_mmr::Config for Test {
type LeafVersion = LeafVersion;
type BeefyAuthorityToMerkleLeaf = pezpallet_beefy_mmr::BeefyEcdsaToEthereum;
type LeafExtra = Vec<u8>;
type BeefyDataProvider = DummyDataProvider;
type WeightInfo = ();
}
pub struct DummyDataProvider;
impl BeefyDataProvider<Vec<u8>> for DummyDataProvider {
fn extra_data() -> Vec<u8> {
let mut col = vec![(15, vec![1, 2, 3]), (5, vec![4, 5, 6])];
col.sort();
binary_merkle_tree::merkle_root::<<Test as pezpallet_mmr::Config>::Hashing, _>(
col.into_iter().map(|pair| pair.encode()),
)
.as_ref()
.to_vec()
}
}
pub struct MockSessionManager;
impl pezpallet_session::SessionManager<u64> for MockSessionManager {
fn end_session(_: pezsp_staking::SessionIndex) {}
fn start_session(_: pezsp_staking::SessionIndex) {}
fn new_session(idx: pezsp_staking::SessionIndex) -> Option<Vec<u64>> {
if idx == 0 || idx == 1 {
Some(vec![1, 2])
} else if idx == 2 {
Some(vec![3, 4])
} else {
None
}
}
}
// Note, that we can't use `UintAuthorityId` here. Reason is that the implementation
// of `to_public_key()` assumes, that a public key is 32 bytes long. This is true for
// ed25519 and sr25519 but *not* for ecdsa. A compressed ecdsa public key is 33 bytes,
// with the first one containing information to reconstruct the uncompressed key.
pub fn mock_beefy_id(id: u8) -> BeefyId {
let mut buf: [u8; 33] = [id; 33];
// Set to something valid.
buf[0] = 0x02;
let pk = Public::from_raw(buf);
BeefyId::from(pk)
}
pub fn mock_authorities(vec: Vec<u8>) -> Vec<(u64, BeefyId)> {
vec.into_iter().map(|id| ((id as u64), mock_beefy_id(id))).collect()
}
pub fn new_test_ext(ids: Vec<u8>) -> TestExternalities {
new_test_ext_raw_authorities(mock_authorities(ids))
}
pub fn new_test_ext_raw_authorities(authorities: Vec<(u64, BeefyId)>) -> TestExternalities {
let mut t = pezframe_system::GenesisConfig::<Test>::default().build_storage().unwrap();
let session_keys: Vec<_> = authorities
.iter()
.enumerate()
.map(|(_, id)| (id.0 as u64, id.0 as u64, MockSessionKeys { dummy: id.1.clone() }))
.collect();
BasicExternalities::execute_with_storage(&mut t, || {
for (ref id, ..) in &session_keys {
pezframe_system::Pallet::<Test>::inc_providers(id);
}
});
pezpallet_session::GenesisConfig::<Test> { keys: session_keys, ..Default::default() }
.assimilate_storage(&mut t)
.unwrap();
let mut ext: TestExternalities = t.into();
let (offchain, _offchain_state) = TestOffchainExt::with_offchain_db(ext.offchain_db());
ext.register_extension(OffchainDbExt::new(offchain.clone()));
ext.register_extension(OffchainWorkerExt::new(offchain));
ext
}
+391
View File
@@ -0,0 +1,391 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::vec;
use codec::{Decode, Encode};
use pezsp_consensus_beefy::{
known_payloads,
mmr::{BeefyNextAuthoritySet, MmrLeafVersion},
AncestryHelper, Commitment, Payload, ValidatorSet,
};
use pezsp_core::H256;
use pezsp_io::TestExternalities;
use pezsp_runtime::{traits::Keccak256, DigestItem};
use pezframe_support::traits::OnInitialize;
use crate::mock::*;
fn init_block(block: u64, maybe_parent_hash: Option<H256>) {
let parent_hash = maybe_parent_hash.unwrap_or(H256::repeat_byte(block as u8));
System::initialize(&block, &parent_hash, &Default::default());
Session::on_initialize(block);
Mmr::on_initialize(block);
}
pub fn beefy_log(log: ConsensusLog<BeefyId>) -> DigestItem {
DigestItem::Consensus(BEEFY_ENGINE_ID, log.encode())
}
fn read_mmr_leaf(ext: &mut TestExternalities, key: Vec<u8>) -> MmrLeaf {
type Node = pezpallet_mmr::primitives::DataOrHash<Keccak256, MmrLeaf>;
ext.persist_offchain_overlay();
let offchain_db = ext.offchain_db();
offchain_db
.get(&key)
.map(|d| Node::decode(&mut &*d).unwrap())
.map(|n| match n {
Node::Data(d) => d,
_ => panic!("Unexpected MMR node."),
})
.unwrap()
}
#[test]
fn should_contain_mmr_digest() {
let mut ext = new_test_ext(vec![1, 2, 3, 4]);
ext.execute_with(|| {
init_block(1, None);
assert_eq!(
System::digest().logs,
vec![
beefy_log(ConsensusLog::AuthoritiesChange(
ValidatorSet::new(vec![mock_beefy_id(1), mock_beefy_id(2)], 1).unwrap()
)),
beefy_log(ConsensusLog::MmrRoot(H256::from_slice(&[
117, 0, 56, 25, 185, 195, 71, 232, 67, 213, 27, 178, 64, 168, 137, 220, 64,
184, 64, 240, 83, 245, 18, 93, 185, 202, 125, 205, 17, 254, 18, 143
])))
]
);
// unique every time
init_block(2, None);
assert_eq!(
System::digest().logs,
vec![
beefy_log(ConsensusLog::AuthoritiesChange(
ValidatorSet::new(vec![mock_beefy_id(3), mock_beefy_id(4)], 2).unwrap()
)),
beefy_log(ConsensusLog::MmrRoot(H256::from_slice(&[
193, 246, 48, 7, 89, 204, 186, 109, 167, 226, 188, 211, 8, 243, 203, 154, 234,
235, 136, 210, 245, 7, 209, 27, 241, 90, 156, 113, 137, 65, 191, 139
]))),
]
);
});
}
#[test]
fn should_contain_valid_leaf_data() {
fn node_offchain_key(pos: usize, parent_hash: H256) -> Vec<u8> {
(<Test as pezpallet_mmr::Config>::INDEXING_PREFIX, pos as u64, parent_hash).encode()
}
let mut ext = new_test_ext(vec![1, 2, 3, 4]);
let parent_hash = ext.execute_with(|| {
init_block(1, None);
pezframe_system::Pallet::<Test>::parent_hash()
});
let mmr_leaf = read_mmr_leaf(&mut ext, node_offchain_key(0, parent_hash));
assert_eq!(
mmr_leaf,
MmrLeaf {
version: MmrLeafVersion::new(1, 5),
parent_number_and_hash: (0_u64, H256::repeat_byte(1)),
beefy_next_authority_set: BeefyNextAuthoritySet {
id: 2,
len: 2,
keyset_commitment: array_bytes::hex_n_into_unchecked(
"9c6b2c1b0d0b25a008e6c882cc7b415f309965c72ad2b944ac0931048ca31cd5"
)
},
leaf_extra: array_bytes::hex2bytes_unchecked(
"55b8e9e1cc9f0db7776fac0ca66318ef8acfb8ec26db11e373120583e07ee648"
)
}
);
// build second block on top
let parent_hash = ext.execute_with(|| {
init_block(2, None);
pezframe_system::Pallet::<Test>::parent_hash()
});
let mmr_leaf = read_mmr_leaf(&mut ext, node_offchain_key(1, parent_hash));
assert_eq!(
mmr_leaf,
MmrLeaf {
version: MmrLeafVersion::new(1, 5),
parent_number_and_hash: (1_u64, H256::repeat_byte(2)),
beefy_next_authority_set: BeefyNextAuthoritySet {
id: 3,
len: 2,
keyset_commitment: array_bytes::hex_n_into_unchecked(
"9c6b2c1b0d0b25a008e6c882cc7b415f309965c72ad2b944ac0931048ca31cd5"
)
},
leaf_extra: array_bytes::hex2bytes_unchecked(
"55b8e9e1cc9f0db7776fac0ca66318ef8acfb8ec26db11e373120583e07ee648"
)
}
);
}
#[test]
fn should_update_authorities() {
new_test_ext(vec![1, 2, 3, 4]).execute_with(|| {
let auth_set = BeefyMmr::authority_set_proof();
let next_auth_set = BeefyMmr::next_authority_set_proof();
// check current authority set
assert_eq!(0, auth_set.id);
assert_eq!(2, auth_set.len);
let want = array_bytes::hex_n_into_unchecked::<_, H256, 32>(
"176e73f1bf656478b728e28dd1a7733c98621b8acf830bff585949763dca7a96",
);
assert_eq!(want, auth_set.keyset_commitment);
// next authority set should have same validators but different id
assert_eq!(1, next_auth_set.id);
assert_eq!(auth_set.len, next_auth_set.len);
assert_eq!(auth_set.keyset_commitment, next_auth_set.keyset_commitment);
let announced_set = next_auth_set;
init_block(1, None);
let auth_set = BeefyMmr::authority_set_proof();
let next_auth_set = BeefyMmr::next_authority_set_proof();
// check new auth are expected ones
assert_eq!(announced_set, auth_set);
assert_eq!(1, auth_set.id);
// check next auth set
assert_eq!(2, next_auth_set.id);
let want = array_bytes::hex_n_into_unchecked::<_, H256, 32>(
"9c6b2c1b0d0b25a008e6c882cc7b415f309965c72ad2b944ac0931048ca31cd5",
);
assert_eq!(2, next_auth_set.len);
assert_eq!(want, next_auth_set.keyset_commitment);
let announced_set = next_auth_set;
init_block(2, None);
let auth_set = BeefyMmr::authority_set_proof();
let next_auth_set = BeefyMmr::next_authority_set_proof();
// check new auth are expected ones
assert_eq!(announced_set, auth_set);
assert_eq!(2, auth_set.id);
// check next auth set
assert_eq!(3, next_auth_set.id);
let want = array_bytes::hex_n_into_unchecked::<_, H256, 32>(
"9c6b2c1b0d0b25a008e6c882cc7b415f309965c72ad2b944ac0931048ca31cd5",
);
assert_eq!(2, next_auth_set.len);
assert_eq!(want, next_auth_set.keyset_commitment);
});
}
// If you need to modify the test because you added a new event or something to the block or block
// header you need to update the test by replacing the expected_mmr_root with the new one
// you can get the new one by running the test while commenting out the first assert
// and then copy pasting the new mmr root from the log of the second assert
#[test]
fn extract_validation_context_should_work_correctly() {
let mut ext = new_test_ext(vec![1, 2]);
ext.execute_with(|| {
init_block(1, None);
let h1 = System::finalize();
init_block(2, Some(h1.hash()));
let h2 = System::finalize();
// Check the MMR root log
let expected_mmr_root: [u8; 32] = array_bytes::hex_n_into_unchecked(
"322c6a46ac00d3455c87bd9af42ebafb388f589a1b562f5e39b1d0d71bcbe8e0",
);
assert_eq!(
System::digest().logs,
vec![beefy_log(ConsensusLog::MmrRoot(H256::from_slice(&expected_mmr_root)))]
);
// Make sure that all the info about h2 was stored on-chain
init_block(3, Some(h2.hash()));
// `extract_validation_context` should return the MMR root when the provided header
// is part of the chain,
assert_eq!(
BeefyMmr::extract_validation_context(h2.clone()),
Some(H256::from_slice(&expected_mmr_root))
);
// `extract_validation_context` should return `None` when the provided header
// is not part of the chain.
let mut fork_h2 = h2;
fork_h2.state_root = H256::repeat_byte(0);
assert_eq!(BeefyMmr::extract_validation_context(fork_h2), None);
});
}
#[test]
fn is_non_canonical_should_work_correctly() {
let mut ext = new_test_ext(vec![1, 2]);
let mut prev_roots = vec![];
ext.execute_with(|| {
for block_num in 1..=500 {
init_block(block_num, None);
prev_roots.push(Mmr::mmr_root())
}
});
ext.persist_offchain_overlay();
ext.execute_with(|| {
let valid_proof = Mmr::generate_ancestry_proof(250, None).unwrap();
let mut invalid_proof = valid_proof.clone();
invalid_proof.items.push((300, Default::default()));
// The commitment is invalid if it has no MMR root payload and the proof is valid.
assert_eq!(
BeefyMmr::is_non_canonical(
&Commitment {
payload: Payload::from_single_entry([0, 0], vec![]),
block_number: 250,
validator_set_id: 0
},
valid_proof.clone(),
Mmr::mmr_root(),
),
true
);
// If the `commitment.payload` contains an MMR root that doesn't match the ancestry proof,
// it's non-canonical.
assert_eq!(
BeefyMmr::is_non_canonical(
&Commitment {
payload: Payload::from_single_entry(
known_payloads::MMR_ROOT_ID,
prev_roots[250 - 1].encode()
)
.push_raw(known_payloads::MMR_ROOT_ID, H256::repeat_byte(0).encode(),),
block_number: 250,
validator_set_id: 0,
},
valid_proof.clone(),
Mmr::mmr_root(),
),
true
);
// If the `commitment.payload` contains an MMR root that can't be decoded,
// it's non-canonical.
assert_eq!(
BeefyMmr::is_non_canonical(
&Commitment {
payload: Payload::from_single_entry(
known_payloads::MMR_ROOT_ID,
prev_roots[250 - 1].encode()
)
.push_raw(known_payloads::MMR_ROOT_ID, vec![],),
block_number: 250,
validator_set_id: 0,
},
valid_proof.clone(),
Mmr::mmr_root(),
),
true
);
// Should return false if the proof is invalid, no matter the payload.
assert_eq!(
BeefyMmr::is_non_canonical(
&Commitment {
payload: Payload::from_single_entry(
known_payloads::MMR_ROOT_ID,
H256::repeat_byte(0).encode(),
),
block_number: 250,
validator_set_id: 0
},
invalid_proof,
Mmr::mmr_root(),
),
false
);
// Can't prove that the commitment is non-canonical if the `commitment.block_number`
// doesn't match the ancestry proof.
assert_eq!(
BeefyMmr::is_non_canonical(
&Commitment {
payload: Payload::from_single_entry(
known_payloads::MMR_ROOT_ID,
prev_roots[250 - 1].encode(),
),
block_number: 300,
validator_set_id: 0,
},
valid_proof,
Mmr::mmr_root(),
),
false
);
// For each previous block, the check:
// - should return false, if the commitment is targeting the canonical chain
// - should return true if the commitment is NOT targeting the canonical chain
for prev_block_number in 1usize..=500 {
let proof = Mmr::generate_ancestry_proof(prev_block_number as u64, None).unwrap();
assert_eq!(
BeefyMmr::is_non_canonical(
&Commitment {
payload: Payload::from_single_entry(
known_payloads::MMR_ROOT_ID,
prev_roots[prev_block_number - 1].encode(),
),
block_number: prev_block_number as u64,
validator_set_id: 0,
},
proof.clone(),
Mmr::mmr_root(),
),
false
);
assert_eq!(
BeefyMmr::is_non_canonical(
&Commitment {
payload: Payload::from_single_entry(
known_payloads::MMR_ROOT_ID,
H256::repeat_byte(0).encode(),
),
block_number: prev_block_number as u64,
validator_set_id: 0,
},
proof,
Mmr::mmr_root(),
),
true
)
}
});
}
@@ -0,0 +1,178 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Autogenerated weights for `pezpallet_beefy_mmr`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `4563561839a5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024`
// Executed Command:
// frame-omni-bencher
// v1
// benchmark
// pallet
// --extrinsic=*
// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm
// --pallet=pezpallet_beefy_mmr
// --header=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/HEADER-APACHE2
// --output=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/pezframe/beefy-mmr/src/weights.rs
// --wasm-execution=compiled
// --steps=50
// --repeat=20
// --heap-pages=4096
// --template=bizinikiwi/.maintain/frame-weight-template.hbs
// --no-storage-info
// --no-min-squares
// --no-median-slopes
// --genesis-builder-policy=none
// --exclude-pallets=pezpallet_xcm,pezpallet_xcm_benchmarks::fungible,pezpallet_xcm_benchmarks::generic,pezpallet_nomination_pools,pezpallet_remark,pezpallet_transaction_storage,pezpallet_election_provider_multi_block,pezpallet_election_provider_multi_block::signed,pezpallet_election_provider_multi_block::unsigned,pezpallet_election_provider_multi_block::verifier
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
#![allow(dead_code)]
use pezframe_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use core::marker::PhantomData;
/// Weight functions needed for `pezpallet_beefy_mmr`.
pub trait WeightInfo {
fn n_leafs_proof_is_optimal(n: u32, ) -> Weight;
fn extract_validation_context() -> Weight;
fn read_peak() -> Weight;
fn n_items_proof_is_non_canonical(n: u32, ) -> Weight;
}
/// Weights for `pezpallet_beefy_mmr` using the Bizinikiwi node and recommended hardware.
pub struct BizinikiwiWeight<T>(PhantomData<T>);
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
/// The range of component `n` is `[2, 512]`.
fn n_leafs_proof_is_optimal(n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 624_000 picoseconds.
Weight::from_parts(1_113_539, 0)
// Standard Error: 66
.saturating_add(Weight::from_parts(1_511, 0).saturating_mul(n.into()))
}
/// Storage: `System::BlockHash` (r:1 w:0)
/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
fn extract_validation_context() -> Weight {
// Proof Size summary in bytes:
// Measured: `14`
// Estimated: `3509`
// Minimum execution time: 4_653_000 picoseconds.
Weight::from_parts(4_840_000, 3509)
.saturating_add(T::DbWeight::get().reads(1_u64))
}
/// Storage: `Mmr::Nodes` (r:1 w:0)
/// Proof: `Mmr::Nodes` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
fn read_peak() -> Weight {
// Proof Size summary in bytes:
// Measured: `129`
// Estimated: `3505`
// Minimum execution time: 4_524_000 picoseconds.
Weight::from_parts(4_667_000, 3505)
.saturating_add(T::DbWeight::get().reads(1_u64))
}
/// Storage: `Mmr::RootHash` (r:1 w:0)
/// Proof: `Mmr::RootHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
/// Storage: `Mmr::NumberOfLeaves` (r:1 w:0)
/// Proof: `Mmr::NumberOfLeaves` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
/// The range of component `n` is `[2, 512]`.
fn n_items_proof_is_non_canonical(n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `121`
// Estimated: `1517`
// Minimum execution time: 8_958_000 picoseconds.
Weight::from_parts(14_508_704, 1517)
// Standard Error: 1_624
.saturating_add(Weight::from_parts(982_244, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(2_u64))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// The range of component `n` is `[2, 512]`.
fn n_leafs_proof_is_optimal(n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 624_000 picoseconds.
Weight::from_parts(1_113_539, 0)
// Standard Error: 66
.saturating_add(Weight::from_parts(1_511, 0).saturating_mul(n.into()))
}
/// Storage: `System::BlockHash` (r:1 w:0)
/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
fn extract_validation_context() -> Weight {
// Proof Size summary in bytes:
// Measured: `14`
// Estimated: `3509`
// Minimum execution time: 4_653_000 picoseconds.
Weight::from_parts(4_840_000, 3509)
.saturating_add(RocksDbWeight::get().reads(1_u64))
}
/// Storage: `Mmr::Nodes` (r:1 w:0)
/// Proof: `Mmr::Nodes` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
fn read_peak() -> Weight {
// Proof Size summary in bytes:
// Measured: `129`
// Estimated: `3505`
// Minimum execution time: 4_524_000 picoseconds.
Weight::from_parts(4_667_000, 3505)
.saturating_add(RocksDbWeight::get().reads(1_u64))
}
/// Storage: `Mmr::RootHash` (r:1 w:0)
/// Proof: `Mmr::RootHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
/// Storage: `Mmr::NumberOfLeaves` (r:1 w:0)
/// Proof: `Mmr::NumberOfLeaves` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
/// The range of component `n` is `[2, 512]`.
fn n_items_proof_is_non_canonical(n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `121`
// Estimated: `1517`
// Minimum execution time: 8_958_000 picoseconds.
Weight::from_parts(14_508_704, 1517)
// Standard Error: 1_624
.saturating_add(Weight::from_parts(982_244, 0).saturating_mul(n.into()))
.saturating_add(RocksDbWeight::get().reads(2_u64))
}
}