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
+36
View File
@@ -0,0 +1,36 @@
[package]
name = "pezpallet-multisig"
version = "28.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
homepage.workspace = true
repository.workspace = true
description = "FRAME multi-signature dispatch pallet"
readme = "README.md"
[lints]
workspace = true
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { workspace = true }
frame = { workspace = true, features = ["runtime"] }
scale-info = { features = ["derive"], workspace = true }
# third party
log = { workspace = true }
[dev-dependencies]
pezpallet-balances = { workspace = true, default-features = true }
[features]
default = ["std"]
std = ["codec/std", "frame/std", "log/std", "scale-info/std"]
runtime-benchmarks = [
"frame/runtime-benchmarks",
"pezpallet-balances/runtime-benchmarks",
]
try-runtime = ["frame/try-runtime", "pezpallet-balances/try-runtime"]
+29
View File
@@ -0,0 +1,29 @@
# Multisig Module
A module for doing multisig dispatch.
- [`Config`](https://docs.rs/pezpallet-multisig/latest/pallet_multisig/pallet/trait.Config.html)
- [`Call`](https://docs.rs/pezpallet-multisig/latest/pallet_multisig/pallet/enum.Call.html)
## Overview
This module contains functionality for multi-signature dispatch, a (potentially) stateful
operation, allowing multiple signed
origins (accounts) to coordinate and dispatch a call from a well-known origin, derivable
deterministically from the set of account IDs and the threshold number of accounts from the
set that must approve it. In the case that the threshold is just one then this is a stateless
operation. This is useful for multisig wallets where cryptographic threshold signatures are
not available or desired.
## Interface
### Dispatchable Functions
- `as_multi` - Approve and if possible dispatch a call from a composite origin formed from a
number of signed origins.
- `approve_as_multi` - Approve a call from a composite origin.
- `cancel_as_multi` - Cancel a call from a composite origin.
[`Call`]: ./enum.Call.html
[`Config`]: ./trait.Config.html
License: Apache-2.0
@@ -0,0 +1,363 @@
// 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.
// Benchmarks for Multisig Pallet
#![cfg(feature = "runtime-benchmarks")]
use super::*;
use frame::benchmarking::prelude::*;
use crate::Pallet as Multisig;
const SEED: u32 = 0;
fn setup_multi<T: Config>(
s: u32,
z: u32,
) -> Result<(Vec<T::AccountId>, Box<<T as Config>::RuntimeCall>), &'static str> {
let mut signatories: Vec<T::AccountId> = Vec::new();
for i in 0..s {
let signatory = account("signatory", i, SEED);
// Give them some balance for a possible deposit
let balance = BalanceOf::<T>::max_value();
T::Currency::make_free_balance_be(&signatory, balance);
signatories.push(signatory);
}
signatories.sort();
// Must first convert to runtime call type.
let call: <T as Config>::RuntimeCall =
pezframe_system::Call::<T>::remark { remark: vec![0; z as usize] }.into();
Ok((signatories, Box::new(call)))
}
#[benchmarks]
mod benchmarks {
use super::*;
/// `z`: Transaction Length
#[benchmark]
fn as_multi_threshold_1(z: Linear<0, 10_000>) -> Result<(), BenchmarkError> {
let max_signatories = T::MaxSignatories::get().into();
let (mut signatories, _) = setup_multi::<T>(max_signatories, z)?;
let call: <T as Config>::RuntimeCall =
pezframe_system::Call::<T>::remark { remark: vec![0; z as usize] }.into();
let caller = signatories.pop().ok_or("signatories should have len 2 or more")?;
// Whitelist caller account from further DB operations.
let caller_key = pezframe_system::Account::<T>::hashed_key_for(&caller);
add_to_whitelist(caller_key.into());
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), signatories, Box::new(call));
// If the benchmark resolves, then the call was dispatched successfully.
Ok(())
}
/// `z`: Transaction Length
/// `s`: Signatories, need at least 2 people
#[benchmark]
fn as_multi_create(
s: Linear<2, { T::MaxSignatories::get() }>,
z: Linear<0, 10_000>,
) -> Result<(), BenchmarkError> {
let (mut signatories, call) = setup_multi::<T>(s, z)?;
let call_hash = call.using_encoded(blake2_256);
let multi_account_id = Multisig::<T>::multi_account_id(&signatories, s.try_into().unwrap());
let caller = signatories.pop().ok_or("signatories should have len 2 or more")?;
// Whitelist caller account from further DB operations.
let caller_key = pezframe_system::Account::<T>::hashed_key_for(&caller);
add_to_whitelist(caller_key.into());
#[extrinsic_call]
as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call, Weight::zero());
assert!(Multisigs::<T>::contains_key(multi_account_id, call_hash));
Ok(())
}
/// `z`: Transaction Length
/// `s`: Signatories, need at least 3 people (so we don't complete the multisig)
#[benchmark]
fn as_multi_approve(
s: Linear<3, { T::MaxSignatories::get() }>,
z: Linear<0, 10_000>,
) -> Result<(), BenchmarkError> {
let (mut signatories, call) = setup_multi::<T>(s, z)?;
let call_hash = call.using_encoded(blake2_256);
let multi_account_id = Multisig::<T>::multi_account_id(&signatories, s.try_into().unwrap());
let mut signatories2 = signatories.clone();
let caller = signatories.pop().ok_or("signatories should have len 2 or more")?;
// before the call, get the timepoint
let timepoint = Multisig::<T>::timepoint();
// Create the multi
Multisig::<T>::as_multi(
RawOrigin::Signed(caller).into(),
s as u16,
signatories,
None,
call.clone(),
Weight::zero(),
)?;
let caller2 = signatories2.remove(0);
// Whitelist caller account from further DB operations.
let caller_key = pezframe_system::Account::<T>::hashed_key_for(&caller2);
add_to_whitelist(caller_key.into());
#[extrinsic_call]
as_multi(
RawOrigin::Signed(caller2),
s as u16,
signatories2,
Some(timepoint),
call,
Weight::zero(),
);
let multisig =
Multisigs::<T>::get(multi_account_id, call_hash).ok_or("multisig not created")?;
assert_eq!(multisig.approvals.len(), 2);
Ok(())
}
/// `z`: Transaction Length
/// `s`: Signatories, need at least 2 people
#[benchmark]
fn as_multi_complete(
s: Linear<2, { T::MaxSignatories::get() }>,
z: Linear<0, 10_000>,
) -> Result<(), BenchmarkError> {
let (mut signatories, call) = setup_multi::<T>(s, z)?;
let call_hash = call.using_encoded(blake2_256);
let multi_account_id = Multisig::<T>::multi_account_id(&signatories, s.try_into().unwrap());
let mut signatories2 = signatories.clone();
let caller = signatories.pop().ok_or("signatories should have len 2 or more")?;
// before the call, get the timepoint
let timepoint = Multisig::<T>::timepoint();
// Create the multi
Multisig::<T>::as_multi(
RawOrigin::Signed(caller).into(),
s as u16,
signatories,
None,
call.clone(),
Weight::zero(),
)?;
// Everyone except the first person approves
for i in 1..s - 1 {
let mut signatories_loop = signatories2.clone();
let caller_loop = signatories_loop.remove(i as usize);
let o = RawOrigin::Signed(caller_loop).into();
Multisig::<T>::as_multi(
o,
s as u16,
signatories_loop,
Some(timepoint),
call.clone(),
Weight::zero(),
)?;
}
let caller2 = signatories2.remove(0);
assert!(Multisigs::<T>::contains_key(&multi_account_id, call_hash));
// Whitelist caller account from further DB operations.
let caller_key = pezframe_system::Account::<T>::hashed_key_for(&caller2);
add_to_whitelist(caller_key.into());
#[extrinsic_call]
as_multi(
RawOrigin::Signed(caller2),
s as u16,
signatories2,
Some(timepoint),
call,
Weight::MAX,
);
assert!(!Multisigs::<T>::contains_key(&multi_account_id, call_hash));
Ok(())
}
/// `s`: Signatories, need at least 2 people
#[benchmark]
fn approve_as_multi_create(
s: Linear<2, { T::MaxSignatories::get() }>,
) -> Result<(), BenchmarkError> {
// The call is neither in storage or an argument, so just use any:
let call_len = 10_000;
let (mut signatories, call) = setup_multi::<T>(s, call_len)?;
let multi_account_id = Multisig::<T>::multi_account_id(&signatories, s.try_into().unwrap());
let caller = signatories.pop().ok_or("signatories should have len 2 or more")?;
let call_hash = call.using_encoded(blake2_256);
// Whitelist caller account from further DB operations.
let caller_key = pezframe_system::Account::<T>::hashed_key_for(&caller);
add_to_whitelist(caller_key.into());
// Create the multi
#[extrinsic_call]
approve_as_multi(
RawOrigin::Signed(caller),
s as u16,
signatories,
None,
call_hash,
Weight::zero(),
);
assert!(Multisigs::<T>::contains_key(multi_account_id, call_hash));
Ok(())
}
/// `s`: Signatories, need at least 2 people
#[benchmark]
fn approve_as_multi_approve(
s: Linear<2, { T::MaxSignatories::get() }>,
) -> Result<(), BenchmarkError> {
// The call is neither in storage or an argument, so just use any:
let call_len = 10_000;
let (mut signatories, call) = setup_multi::<T>(s, call_len)?;
let mut signatories2 = signatories.clone();
let multi_account_id = Multisig::<T>::multi_account_id(&signatories, s.try_into().unwrap());
let caller = signatories.pop().ok_or("signatories should have len 2 or more")?;
let call_hash = call.using_encoded(blake2_256);
// before the call, get the timepoint
let timepoint = Multisig::<T>::timepoint();
// Create the multi
Multisig::<T>::as_multi(
RawOrigin::Signed(caller).into(),
s as u16,
signatories,
None,
call,
Weight::zero(),
)?;
let caller2 = signatories2.remove(0);
// Whitelist caller account from further DB operations.
let caller_key = pezframe_system::Account::<T>::hashed_key_for(&caller2);
add_to_whitelist(caller_key.into());
#[extrinsic_call]
approve_as_multi(
RawOrigin::Signed(caller2),
s as u16,
signatories2,
Some(timepoint),
call_hash,
Weight::zero(),
);
let multisig =
Multisigs::<T>::get(multi_account_id, call_hash).ok_or("multisig not created")?;
assert_eq!(multisig.approvals.len(), 2);
Ok(())
}
/// `s`: Signatories, need at least 2 people
#[benchmark]
fn cancel_as_multi(s: Linear<2, { T::MaxSignatories::get() }>) -> Result<(), BenchmarkError> {
// The call is neither in storage or an argument, so just use any:
let call_len = 10_000;
let (mut signatories, call) = setup_multi::<T>(s, call_len)?;
let multi_account_id = Multisig::<T>::multi_account_id(&signatories, s.try_into().unwrap());
let caller = signatories.pop().ok_or("signatories should have len 2 or more")?;
let call_hash = call.using_encoded(blake2_256);
let timepoint = Multisig::<T>::timepoint();
// Create the multi
let o = RawOrigin::Signed(caller.clone()).into();
Multisig::<T>::as_multi(o, s as u16, signatories.clone(), None, call, Weight::zero())?;
assert!(Multisigs::<T>::contains_key(&multi_account_id, call_hash));
// Whitelist caller account from further DB operations.
let caller_key = pezframe_system::Account::<T>::hashed_key_for(&caller);
add_to_whitelist(caller_key.into());
#[extrinsic_call]
_(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash);
assert!(!Multisigs::<T>::contains_key(multi_account_id, call_hash));
Ok(())
}
/// `s`: Signatories, need at least 2 people
#[benchmark]
fn poke_deposit(s: Linear<2, { T::MaxSignatories::get() }>) -> Result<(), BenchmarkError> {
// The call is neither in storage or an argument, so just use any:
let call_len = 10_000;
let (mut signatories, call) = setup_multi::<T>(s, call_len)?;
let multi_account_id = Multisig::<T>::multi_account_id(&signatories, s.try_into().unwrap());
let caller = signatories.pop().ok_or("signatories should have len 2 or more")?;
let call_hash = call.using_encoded(blake2_256);
// Create the multi
Multisig::<T>::as_multi(
RawOrigin::Signed(caller.clone()).into(),
s as u16,
signatories.clone(),
None,
call,
Weight::zero(),
)?;
// Get the current multisig data
let multisig = Multisigs::<T>::get(multi_account_id.clone(), call_hash)
.ok_or("multisig not created")?;
// The original deposit
let old_deposit = multisig.deposit;
assert_eq!(T::Currency::reserved_balance(&caller), old_deposit);
let additional_amount = 2u32.into();
let new_deposit = old_deposit.saturating_add(additional_amount);
// Reserve the additional amount from the caller's balance
T::Currency::reserve(&caller, additional_amount)?;
assert_eq!(T::Currency::reserved_balance(&caller), new_deposit);
// Update the storage with the new deposit
Multisigs::<T>::try_mutate(
&multi_account_id,
call_hash,
|maybe_multisig| -> DispatchResult {
let mut multisig = maybe_multisig.take().ok_or(Error::<T>::NotFound)?;
multisig.deposit = new_deposit;
*maybe_multisig = Some(multisig);
Ok(())
},
)
.map_err(|_| BenchmarkError::Stop("Mutating storage to change deposits failed"))?;
// Check that the deposit was updated in storage
let multisig = Multisigs::<T>::get(multi_account_id.clone(), call_hash)
.ok_or("Multisig not created")?;
assert_eq!(multisig.deposit, new_deposit);
// Whitelist caller account
let caller_key = pezframe_system::Account::<T>::hashed_key_for(&caller);
add_to_whitelist(caller_key.into());
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), s as u16, signatories, call_hash);
let multisig = Multisigs::<T>::get(multi_account_id.clone(), call_hash)
.ok_or("Multisig not created")?;
assert_eq!(multisig.deposit, old_deposit);
assert_eq!(T::Currency::reserved_balance(&caller), old_deposit);
Ok(())
}
impl_benchmark_test_suite!(Multisig, crate::tests::new_test_ext(), crate::tests::Test);
}
+815
View File
@@ -0,0 +1,815 @@
// 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.
//! # Multisig pallet
//! A pallet for doing multisig dispatch.
//!
//! - [`Config`]
//! - [`Call`]
//!
//! ## Overview
//!
//! This pallet contains functionality for multi-signature dispatch, a (potentially) stateful
//! operation, allowing multiple signed
//! origins (accounts) to coordinate and dispatch a call from a well-known origin, derivable
//! deterministically from the set of account IDs and the threshold number of accounts from the
//! set that must approve it. In the case that the threshold is just one then this is a stateless
//! operation. This is useful for multisig wallets where cryptographic threshold signatures are
//! not available or desired.
//!
//! ## Interface
//!
//! ### Dispatchable Functions
//!
//! * `as_multi` - Approve and if possible dispatch a call from a composite origin formed from a
//! number of signed origins.
//! * `approve_as_multi` - Approve a call from a composite origin.
//! * `cancel_as_multi` - Cancel a call from a composite origin.
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
mod benchmarking;
pub mod migrations;
mod tests;
pub mod weights;
extern crate alloc;
use alloc::{boxed::Box, vec, vec::Vec};
use frame::{
prelude::*,
traits::{Currency, ReservableCurrency},
};
use pezframe_system::RawOrigin;
pub use weights::WeightInfo;
/// Re-export all pallet items.
pub use pallet::*;
/// The log target of this pallet.
pub const LOG_TARGET: &'static str = "runtime::multisig";
// syntactic sugar for logging.
#[macro_export]
macro_rules! log {
($level:tt, $patter:expr $(, $values:expr)* $(,)?) => {
log::$level!(
target: crate::LOG_TARGET,
concat!("[{:?}] ✍️ ", $patter), <pezframe_system::Pallet<T>>::block_number() $(, $values)*
)
};
}
pub type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as pezframe_system::Config>::AccountId>>::Balance;
pub type BlockNumberFor<T> =
<<T as Config>::BlockNumberProvider as BlockNumberProvider>::BlockNumber;
/// A global extrinsic index, formed as the extrinsic index within a block, together with that
/// block's height. This allows a transaction in which a multisig operation of a particular
/// composite was created to be uniquely identified.
#[derive(
Copy,
Clone,
Eq,
PartialEq,
Encode,
Decode,
DecodeWithMemTracking,
Default,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
)]
pub struct Timepoint<BlockNumber> {
/// The height of the chain at the point in time.
pub height: BlockNumber,
/// The index of the extrinsic at the point in time.
pub index: u32,
}
/// An open multisig operation.
#[derive(
Clone,
Eq,
PartialEq,
Encode,
Decode,
Default,
RuntimeDebug,
TypeInfo,
MaxEncodedLen,
DecodeWithMemTracking,
)]
#[scale_info(skip_type_params(MaxApprovals))]
pub struct Multisig<BlockNumber, Balance, AccountId, MaxApprovals>
where
MaxApprovals: Get<u32>,
{
/// The extrinsic when the multisig operation was opened.
pub when: Timepoint<BlockNumber>,
/// The amount held in reserve of the `depositor`, to be returned once the operation ends.
pub deposit: Balance,
/// The account who opened it (i.e. the first to approve it).
pub depositor: AccountId,
/// The approvals achieved so far, including the depositor. Always sorted.
pub approvals: BoundedVec<AccountId, MaxApprovals>,
}
type CallHash = [u8; 32];
enum CallOrHash<T: Config> {
Call(<T as Config>::RuntimeCall),
Hash([u8; 32]),
}
#[frame::pallet]
pub mod pallet {
use super::*;
#[pallet::config]
pub trait Config: pezframe_system::Config {
/// The overarching event type.
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self>> + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
/// The overarching call type.
type RuntimeCall: Parameter
+ Dispatchable<RuntimeOrigin = Self::RuntimeOrigin, PostInfo = PostDispatchInfo>
+ GetDispatchInfo
+ From<pezframe_system::Call<Self>>;
/// The currency mechanism.
type Currency: ReservableCurrency<Self::AccountId>;
/// The base amount of currency needed to reserve for creating a multisig execution or to
/// store a dispatch call for later.
///
/// This is held for an additional storage item whose value size is
/// `4 + sizeof((BlockNumber, Balance, AccountId))` bytes and whose key size is
/// `32 + sizeof(AccountId)` bytes.
#[pallet::constant]
type DepositBase: Get<BalanceOf<Self>>;
/// The amount of currency needed per unit threshold when creating a multisig execution.
///
/// This is held for adding 32 bytes more into a pre-existing storage value.
#[pallet::constant]
type DepositFactor: Get<BalanceOf<Self>>;
/// The maximum amount of signatories allowed in the multisig.
#[pallet::constant]
type MaxSignatories: Get<u32>;
/// Weight information for extrinsics in this pallet.
type WeightInfo: weights::WeightInfo;
/// Query the current block number.
///
/// Must return monotonically increasing values when called from consecutive blocks.
/// Can be configured to return either:
/// - the local block number of the runtime via `pezframe_system::Pallet`
/// - a remote block number, eg from the relay chain through `RelaychainDataProvider`
/// - an arbitrary value through a custom implementation of the trait
///
/// There is currently no migration provided to "hot-swap" block number providers and it may
/// result in undefined behavior when doing so. Teyrchains are therefore best off setting
/// this to their local block number provider if they have the pallet already deployed.
///
/// Suggested values:
/// - Solo- and Relay-chains: `pezframe_system::Pallet`
/// - Teyrchains that may produce blocks sparingly or only when needed (on-demand):
/// - already have the pallet deployed: `pezframe_system::Pallet`
/// - are freshly deploying this pallet: `RelaychainDataProvider`
/// - Teyrchains with a reliably block production rate (PLO or bulk-coretime):
/// - already have the pallet deployed: `pezframe_system::Pallet`
/// - are freshly deploying this pallet: no strong recommendation. Both local and remote
/// providers can be used. Relay provider can be a bit better in cases where the
/// teyrchain is lagging its block production to avoid clock skew.
type BlockNumberProvider: BlockNumberProvider;
}
/// The in-code storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(_);
/// The set of open multisig operations.
#[pallet::storage]
pub type Multisigs<T: Config> = StorageDoubleMap<
_,
Twox64Concat,
T::AccountId,
Blake2_128Concat,
[u8; 32],
Multisig<BlockNumberFor<T>, BalanceOf<T>, T::AccountId, T::MaxSignatories>,
>;
#[pallet::error]
pub enum Error<T> {
/// Threshold must be 2 or greater.
MinimumThreshold,
/// Call is already approved by this signatory.
AlreadyApproved,
/// Call doesn't need any (more) approvals.
NoApprovalsNeeded,
/// There are too few signatories in the list.
TooFewSignatories,
/// There are too many signatories in the list.
TooManySignatories,
/// The signatories were provided out of order; they should be ordered.
SignatoriesOutOfOrder,
/// The sender was contained in the other signatories; it shouldn't be.
SenderInSignatories,
/// Multisig operation not found in storage.
NotFound,
/// Only the account that originally created the multisig is able to cancel it or update
/// its deposits.
NotOwner,
/// No timepoint was given, yet the multisig operation is already underway.
NoTimepoint,
/// A different timepoint was given to the multisig operation that is underway.
WrongTimepoint,
/// A timepoint was given, yet no multisig operation is underway.
UnexpectedTimepoint,
/// The maximum weight information provided was too low.
MaxWeightTooLow,
/// The data to be stored is already stored.
AlreadyStored,
}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// A new multisig operation has begun.
NewMultisig { approving: T::AccountId, multisig: T::AccountId, call_hash: CallHash },
/// A multisig operation has been approved by someone.
MultisigApproval {
approving: T::AccountId,
timepoint: Timepoint<BlockNumberFor<T>>,
multisig: T::AccountId,
call_hash: CallHash,
},
/// A multisig operation has been executed.
MultisigExecuted {
approving: T::AccountId,
timepoint: Timepoint<BlockNumberFor<T>>,
multisig: T::AccountId,
call_hash: CallHash,
result: DispatchResult,
},
/// A multisig operation has been cancelled.
MultisigCancelled {
cancelling: T::AccountId,
timepoint: Timepoint<BlockNumberFor<T>>,
multisig: T::AccountId,
call_hash: CallHash,
},
/// The deposit for a multisig operation has been updated/poked.
DepositPoked {
who: T::AccountId,
call_hash: CallHash,
old_deposit: BalanceOf<T>,
new_deposit: BalanceOf<T>,
},
}
#[pallet::hooks]
impl<T: Config> Hooks<pezframe_system::pezpallet_prelude::BlockNumberFor<T>> for Pallet<T> {}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Immediately dispatch a multi-signature call using a single approval from the caller.
///
/// The dispatch origin for this call must be _Signed_.
///
/// - `other_signatories`: The accounts (other than the sender) who are part of the
/// multi-signature, but do not participate in the approval process.
/// - `call`: The call to be executed.
///
/// Result is equivalent to the dispatched result.
///
/// ## Complexity
/// O(Z + C) where Z is the length of the call and C its execution weight.
#[pallet::call_index(0)]
#[pallet::weight({
let dispatch_info = call.get_dispatch_info();
(
T::WeightInfo::as_multi_threshold_1(call.using_encoded(|c| c.len() as u32))
// AccountData for inner call origin accountdata.
.saturating_add(T::DbWeight::get().reads_writes(1, 1))
.saturating_add(dispatch_info.call_weight),
dispatch_info.class,
)
})]
pub fn as_multi_threshold_1(
origin: OriginFor<T>,
other_signatories: Vec<T::AccountId>,
call: Box<<T as Config>::RuntimeCall>,
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
let max_sigs = T::MaxSignatories::get() as usize;
ensure!(!other_signatories.is_empty(), Error::<T>::TooFewSignatories);
let other_signatories_len = other_signatories.len();
ensure!(other_signatories_len < max_sigs, Error::<T>::TooManySignatories);
let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?;
let id = Self::multi_account_id(&signatories, 1);
let (call_len, call_hash) = call.using_encoded(|c| (c.len(), blake2_256(&c)));
let result = call.dispatch(RawOrigin::Signed(id.clone()).into());
Self::deposit_event(Event::MultisigExecuted {
approving: who,
timepoint: Self::timepoint(),
multisig: id,
call_hash,
result: result.map(|_| ()).map_err(|e| e.error),
});
result
.map(|post_dispatch_info| {
post_dispatch_info
.actual_weight
.map(|actual_weight| {
T::WeightInfo::as_multi_threshold_1(call_len as u32)
.saturating_add(actual_weight)
})
.into()
})
.map_err(|err| match err.post_info.actual_weight {
Some(actual_weight) => {
let weight_used = T::WeightInfo::as_multi_threshold_1(call_len as u32)
.saturating_add(actual_weight);
let post_info = Some(weight_used).into();
DispatchErrorWithPostInfo { post_info, error: err.error }
},
None => err,
})
}
/// Register approval for a dispatch to be made from a deterministic composite account if
/// approved by a total of `threshold - 1` of `other_signatories`.
///
/// If there are enough, then dispatch the call.
///
/// Payment: `DepositBase` will be reserved if this is the first approval, plus
/// `threshold` times `DepositFactor`. It is returned once this dispatch happens or
/// is cancelled.
///
/// The dispatch origin for this call must be _Signed_.
///
/// - `threshold`: The total number of approvals for this dispatch before it is executed.
/// - `other_signatories`: The accounts (other than the sender) who can approve this
/// dispatch. May not be empty.
/// - `maybe_timepoint`: If this is the first approval, then this must be `None`. If it is
/// not the first approval, then it must be `Some`, with the timepoint (block number and
/// transaction index) of the first approval transaction.
/// - `call`: The call to be executed.
///
/// NOTE: Unless this is the final approval, you will generally want to use
/// `approve_as_multi` instead, since it only requires a hash of the call.
///
/// Result is equivalent to the dispatched result if `threshold` is exactly `1`. Otherwise
/// on success, result is `Ok` and the result from the interior call, if it was executed,
/// may be found in the deposited `MultisigExecuted` event.
///
/// ## Complexity
/// - `O(S + Z + Call)`.
/// - Up to one balance-reserve or unreserve operation.
/// - One passthrough operation, one insert, both `O(S)` where `S` is the number of
/// signatories. `S` is capped by `MaxSignatories`, with weight being proportional.
/// - One call encode & hash, both of complexity `O(Z)` where `Z` is tx-len.
/// - One encode & hash, both of complexity `O(S)`.
/// - Up to one binary search and insert (`O(logS + S)`).
/// - I/O: 1 read `O(S)`, up to 1 mutate `O(S)`. Up to one remove.
/// - One event.
/// - The weight of the `call`.
/// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a deposit
/// taken for its lifetime of `DepositBase + threshold * DepositFactor`.
#[pallet::call_index(1)]
#[pallet::weight({
let s = other_signatories.len() as u32;
let z = call.using_encoded(|d| d.len()) as u32;
T::WeightInfo::as_multi_create(s, z)
.max(T::WeightInfo::as_multi_approve(s, z))
.max(T::WeightInfo::as_multi_complete(s, z))
.saturating_add(*max_weight)
})]
pub fn as_multi(
origin: OriginFor<T>,
threshold: u16,
other_signatories: Vec<T::AccountId>,
maybe_timepoint: Option<Timepoint<BlockNumberFor<T>>>,
call: Box<<T as Config>::RuntimeCall>,
max_weight: Weight,
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
Self::operate(
who,
threshold,
other_signatories,
maybe_timepoint,
CallOrHash::Call(*call),
max_weight,
)
}
/// Register approval for a dispatch to be made from a deterministic composite account if
/// approved by a total of `threshold - 1` of `other_signatories`.
///
/// Payment: `DepositBase` will be reserved if this is the first approval, plus
/// `threshold` times `DepositFactor`. It is returned once this dispatch happens or
/// is cancelled.
///
/// The dispatch origin for this call must be _Signed_.
///
/// - `threshold`: The total number of approvals for this dispatch before it is executed.
/// - `other_signatories`: The accounts (other than the sender) who can approve this
/// dispatch. May not be empty.
/// - `maybe_timepoint`: If this is the first approval, then this must be `None`. If it is
/// not the first approval, then it must be `Some`, with the timepoint (block number and
/// transaction index) of the first approval transaction.
/// - `call_hash`: The hash of the call to be executed.
///
/// NOTE: If this is the final approval, you will want to use `as_multi` instead.
///
/// ## Complexity
/// - `O(S)`.
/// - Up to one balance-reserve or unreserve operation.
/// - One passthrough operation, one insert, both `O(S)` where `S` is the number of
/// signatories. `S` is capped by `MaxSignatories`, with weight being proportional.
/// - One encode & hash, both of complexity `O(S)`.
/// - Up to one binary search and insert (`O(logS + S)`).
/// - I/O: 1 read `O(S)`, up to 1 mutate `O(S)`. Up to one remove.
/// - One event.
/// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a deposit
/// taken for its lifetime of `DepositBase + threshold * DepositFactor`.
#[pallet::call_index(2)]
#[pallet::weight({
let s = other_signatories.len() as u32;
T::WeightInfo::approve_as_multi_create(s)
.max(T::WeightInfo::approve_as_multi_approve(s))
.saturating_add(*max_weight)
})]
pub fn approve_as_multi(
origin: OriginFor<T>,
threshold: u16,
other_signatories: Vec<T::AccountId>,
maybe_timepoint: Option<Timepoint<BlockNumberFor<T>>>,
call_hash: [u8; 32],
max_weight: Weight,
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
Self::operate(
who,
threshold,
other_signatories,
maybe_timepoint,
CallOrHash::Hash(call_hash),
max_weight,
)
}
/// Cancel a pre-existing, on-going multisig transaction. Any deposit reserved previously
/// for this operation will be unreserved on success.
///
/// The dispatch origin for this call must be _Signed_.
///
/// - `threshold`: The total number of approvals for this dispatch before it is executed.
/// - `other_signatories`: The accounts (other than the sender) who can approve this
/// dispatch. May not be empty.
/// - `timepoint`: The timepoint (block number and transaction index) of the first approval
/// transaction for this dispatch.
/// - `call_hash`: The hash of the call to be executed.
///
/// ## Complexity
/// - `O(S)`.
/// - Up to one balance-reserve or unreserve operation.
/// - One passthrough operation, one insert, both `O(S)` where `S` is the number of
/// signatories. `S` is capped by `MaxSignatories`, with weight being proportional.
/// - One encode & hash, both of complexity `O(S)`.
/// - One event.
/// - I/O: 1 read `O(S)`, one remove.
/// - Storage: removes one item.
#[pallet::call_index(3)]
#[pallet::weight(T::WeightInfo::cancel_as_multi(other_signatories.len() as u32))]
pub fn cancel_as_multi(
origin: OriginFor<T>,
threshold: u16,
other_signatories: Vec<T::AccountId>,
timepoint: Timepoint<BlockNumberFor<T>>,
call_hash: [u8; 32],
) -> DispatchResult {
let who = ensure_signed(origin)?;
ensure!(threshold >= 2, Error::<T>::MinimumThreshold);
let max_sigs = T::MaxSignatories::get() as usize;
ensure!(!other_signatories.is_empty(), Error::<T>::TooFewSignatories);
ensure!(other_signatories.len() < max_sigs, Error::<T>::TooManySignatories);
let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?;
let id = Self::multi_account_id(&signatories, threshold);
let m = <Multisigs<T>>::get(&id, call_hash).ok_or(Error::<T>::NotFound)?;
ensure!(m.when == timepoint, Error::<T>::WrongTimepoint);
ensure!(m.depositor == who, Error::<T>::NotOwner);
let err_amount = T::Currency::unreserve(&m.depositor, m.deposit);
debug_assert!(err_amount.is_zero());
<Multisigs<T>>::remove(&id, &call_hash);
Self::deposit_event(Event::MultisigCancelled {
cancelling: who,
timepoint,
multisig: id,
call_hash,
});
Ok(())
}
/// Poke the deposit reserved for an existing multisig operation.
///
/// The dispatch origin for this call must be _Signed_ and must be the original depositor of
/// the multisig operation.
///
/// The transaction fee is waived if the deposit amount has changed.
///
/// - `threshold`: The total number of approvals needed for this multisig.
/// - `other_signatories`: The accounts (other than the sender) who are part of the
/// multisig.
/// - `call_hash`: The hash of the call this deposit is reserved for.
///
/// Emits `DepositPoked` if successful.
#[pallet::call_index(4)]
#[pallet::weight(T::WeightInfo::poke_deposit(other_signatories.len() as u32))]
pub fn poke_deposit(
origin: OriginFor<T>,
threshold: u16,
other_signatories: Vec<T::AccountId>,
call_hash: [u8; 32],
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
ensure!(threshold >= 2, Error::<T>::MinimumThreshold);
let max_sigs = T::MaxSignatories::get() as usize;
ensure!(!other_signatories.is_empty(), Error::<T>::TooFewSignatories);
ensure!(other_signatories.len() < max_sigs, Error::<T>::TooManySignatories);
// Get the multisig account ID
let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?;
let id = Self::multi_account_id(&signatories, threshold);
Multisigs::<T>::try_mutate(
&id,
call_hash,
|maybe_multisig| -> DispatchResultWithPostInfo {
let mut multisig = maybe_multisig.take().ok_or(Error::<T>::NotFound)?;
ensure!(multisig.depositor == who, Error::<T>::NotOwner);
// Calculate the new deposit
let new_deposit = Self::deposit(threshold);
let old_deposit = multisig.deposit;
if new_deposit == old_deposit {
*maybe_multisig = Some(multisig);
return Ok(Pays::Yes.into());
}
// Update the reserved amount
if new_deposit > old_deposit {
let extra = new_deposit.saturating_sub(old_deposit);
T::Currency::reserve(&who, extra)?;
} else {
let excess = old_deposit.saturating_sub(new_deposit);
let remaining_unreserved = T::Currency::unreserve(&who, excess);
if !remaining_unreserved.is_zero() {
defensive!(
"Failed to unreserve for full amount for multisig. (Call Hash, Requested, Actual): ",
(call_hash, excess, excess.saturating_sub(remaining_unreserved))
);
}
}
// Update storage
multisig.deposit = new_deposit;
*maybe_multisig = Some(multisig);
// Emit event
Self::deposit_event(Event::DepositPoked {
who: who.clone(),
call_hash,
old_deposit,
new_deposit,
});
Ok(Pays::No.into())
},
)
}
}
}
impl<T: Config> Pallet<T> {
/// Derive a multi-account ID from the sorted list of accounts and the threshold that are
/// required.
///
/// NOTE: `who` must be sorted. If it is not, then you'll get the wrong answer.
pub fn multi_account_id(who: &[T::AccountId], threshold: u16) -> T::AccountId {
let entropy = (b"modlpy/utilisuba", who, threshold).using_encoded(blake2_256);
Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref()))
.expect("infinite length input; no invalid inputs for type; qed")
}
fn operate(
who: T::AccountId,
threshold: u16,
other_signatories: Vec<T::AccountId>,
maybe_timepoint: Option<Timepoint<BlockNumberFor<T>>>,
call_or_hash: CallOrHash<T>,
max_weight: Weight,
) -> DispatchResultWithPostInfo {
ensure!(threshold >= 2, Error::<T>::MinimumThreshold);
let max_sigs = T::MaxSignatories::get() as usize;
ensure!(!other_signatories.is_empty(), Error::<T>::TooFewSignatories);
let other_signatories_len = other_signatories.len();
ensure!(other_signatories_len < max_sigs, Error::<T>::TooManySignatories);
let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?;
let id = Self::multi_account_id(&signatories, threshold);
// Threshold > 1; this means it's a multi-step operation. We extract the `call_hash`.
let (call_hash, call_len, maybe_call) = match call_or_hash {
CallOrHash::Call(call) => {
let (call_hash, call_len) = call.using_encoded(|d| (blake2_256(d), d.len()));
(call_hash, call_len, Some(call))
},
CallOrHash::Hash(h) => (h, 0, None),
};
// Branch on whether the operation has already started or not.
if let Some(mut m) = <Multisigs<T>>::get(&id, call_hash) {
// Yes; ensure that the timepoint exists and agrees.
let timepoint = maybe_timepoint.ok_or(Error::<T>::NoTimepoint)?;
ensure!(m.when == timepoint, Error::<T>::WrongTimepoint);
// Ensure that either we have not yet signed or that it is at threshold.
let mut approvals = m.approvals.len() as u16;
// We only bother with the approval if we're below threshold.
let maybe_pos = m.approvals.binary_search(&who).err().filter(|_| approvals < threshold);
// Bump approvals if not yet voted and the vote is needed.
if maybe_pos.is_some() {
approvals += 1;
}
// We only bother fetching/decoding call if we know that we're ready to execute.
if let Some(call) = maybe_call.filter(|_| approvals >= threshold) {
// verify weight
ensure!(
call.get_dispatch_info().call_weight.all_lte(max_weight),
Error::<T>::MaxWeightTooLow
);
// Clean up storage before executing call to avoid an possibility of reentrancy
// attack.
<Multisigs<T>>::remove(&id, call_hash);
T::Currency::unreserve(&m.depositor, m.deposit);
let result = call.dispatch(RawOrigin::Signed(id.clone()).into());
Self::deposit_event(Event::MultisigExecuted {
approving: who,
timepoint,
multisig: id,
call_hash,
result: result.map(|_| ()).map_err(|e| e.error),
});
Ok(get_result_weight(result)
.map(|actual_weight| {
T::WeightInfo::as_multi_complete(
other_signatories_len as u32,
call_len as u32,
)
.saturating_add(actual_weight)
})
.into())
} else {
// We cannot dispatch the call now; either it isn't available, or it is, but we
// don't have threshold approvals even with our signature.
if let Some(pos) = maybe_pos {
// Record approval.
m.approvals
.try_insert(pos, who.clone())
.map_err(|_| Error::<T>::TooManySignatories)?;
<Multisigs<T>>::insert(&id, call_hash, m);
Self::deposit_event(Event::MultisigApproval {
approving: who,
timepoint,
multisig: id,
call_hash,
});
} else {
// If we already approved and didn't store the Call, then this was useless and
// we report an error.
Err(Error::<T>::AlreadyApproved)?
}
let final_weight =
T::WeightInfo::as_multi_approve(other_signatories_len as u32, call_len as u32);
// Call is not made, so the actual weight does not include call
Ok(Some(final_weight).into())
}
} else {
// Not yet started; there should be no timepoint given.
ensure!(maybe_timepoint.is_none(), Error::<T>::UnexpectedTimepoint);
// Just start the operation by recording it in storage.
let deposit = Self::deposit(threshold);
T::Currency::reserve(&who, deposit)?;
let initial_approvals =
vec![who.clone()].try_into().map_err(|_| Error::<T>::TooManySignatories)?;
<Multisigs<T>>::insert(
&id,
call_hash,
Multisig {
when: Self::timepoint(),
deposit,
depositor: who.clone(),
approvals: initial_approvals,
},
);
Self::deposit_event(Event::NewMultisig { approving: who, multisig: id, call_hash });
let final_weight =
T::WeightInfo::as_multi_create(other_signatories_len as u32, call_len as u32);
// Call is not made, so the actual weight does not include call
Ok(Some(final_weight).into())
}
}
/// The current `Timepoint`.
pub fn timepoint() -> Timepoint<BlockNumberFor<T>> {
Timepoint {
height: T::BlockNumberProvider::current_block_number(),
index: <pezframe_system::Pallet<T>>::extrinsic_index().unwrap_or_default(),
}
}
/// Check that signatories is sorted and doesn't contain sender, then insert sender.
fn ensure_sorted_and_insert(
other_signatories: Vec<T::AccountId>,
who: T::AccountId,
) -> Result<Vec<T::AccountId>, DispatchError> {
let mut signatories = other_signatories;
let mut maybe_last = None;
let mut index = 0;
for item in signatories.iter() {
if let Some(last) = maybe_last {
ensure!(last < item, Error::<T>::SignatoriesOutOfOrder);
}
if item <= &who {
ensure!(item != &who, Error::<T>::SenderInSignatories);
index += 1;
}
maybe_last = Some(item);
}
signatories.insert(index, who);
Ok(signatories)
}
/// Calculate the deposit for a multisig operation.
///
/// The deposit is calculated as `DepositBase + DepositFactor * threshold`.
pub fn deposit(threshold: u16) -> BalanceOf<T> {
T::DepositBase::get() + T::DepositFactor::get() * threshold.into()
}
}
/// Return the weight of a dispatch call result as an `Option`.
///
/// Will return the weight regardless of what the state of the result is.
fn get_result_weight(result: DispatchResultWithPostInfo) -> Option<Weight> {
match result {
Ok(post_info) => post_info.actual_weight,
Err(err) => err.post_info.actual_weight,
}
}
@@ -0,0 +1,80 @@
// 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.
// Migrations for Multisig Pallet
use crate::*;
use frame::prelude::*;
pub mod v1 {
use super::*;
type OpaqueCall<T> = frame::traits::WrapperKeepOpaque<<T as Config>::RuntimeCall>;
#[frame::storage_alias]
type Calls<T: Config> = StorageMap<
Pallet<T>,
Identity,
[u8; 32],
(OpaqueCall<T>, <T as pezframe_system::Config>::AccountId, BalanceOf<T>),
>;
pub struct MigrateToV1<T>(core::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, frame::try_runtime::TryRuntimeError> {
log!(info, "Number of calls to refund and delete: {}", Calls::<T>::iter().count());
Ok(Vec::new())
}
fn on_runtime_upgrade() -> Weight {
use frame::traits::ReservableCurrency as _;
let current = Pallet::<T>::in_code_storage_version();
let onchain = Pallet::<T>::on_chain_storage_version();
if onchain > 0 {
log!(info, "MigrateToV1 should be removed");
return T::DbWeight::get().reads(1);
}
let mut call_count = 0u64;
Calls::<T>::drain().for_each(|(_call_hash, (_data, caller, deposit))| {
T::Currency::unreserve(&caller, deposit);
call_count.saturating_inc();
});
current.put::<Pallet<T>>();
T::DbWeight::get().reads_writes(
// Reads: Get Calls + Get Version
call_count.saturating_add(1),
// Writes: Drain Calls + Unreserves + Set version
call_count.saturating_mul(2).saturating_add(1),
)
}
#[cfg(feature = "try-runtime")]
fn post_upgrade(_state: Vec<u8>) -> Result<(), frame::try_runtime::TryRuntimeError> {
ensure!(
Calls::<T>::iter().count() == 0,
"there are some dangling calls that need to be destroyed and refunded"
);
Ok(())
}
}
}
File diff suppressed because it is too large Load Diff
+347
View File
@@ -0,0 +1,347 @@
// 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_multisig`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-02-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `c8c7296f7413`, 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_multisig
// --header=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/HEADER-APACHE2
// --output=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/pezframe/multisig/src/weights.rs
// --wasm-execution=compiled
// --steps=50
// --repeat=20
// --heap-pages=4096
// --template=bizinikiwi/.maintain/frame-umbrella-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 frame::weights_prelude::*;
/// Weight functions needed for `pezpallet_multisig`.
pub trait WeightInfo {
fn as_multi_threshold_1(z: u32, ) -> Weight;
fn as_multi_create(s: u32, z: u32, ) -> Weight;
fn as_multi_approve(s: u32, z: u32, ) -> Weight;
fn as_multi_complete(s: u32, z: u32, ) -> Weight;
fn approve_as_multi_create(s: u32, ) -> Weight;
fn approve_as_multi_approve(s: u32, ) -> Weight;
fn cancel_as_multi(s: u32, ) -> Weight;
fn poke_deposit(s: u32, ) -> Weight;
}
/// Weights for `pezpallet_multisig` using the Bizinikiwi node and recommended hardware.
pub struct BizinikiwiWeight<T>(PhantomData<T>);
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `TxPause::PausedCalls` (r:1 w:0)
/// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`)
/// The range of component `z` is `[0, 10000]`.
fn as_multi_threshold_1(z: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `3997`
// Minimum execution time: 18_622_000 picoseconds.
Weight::from_parts(20_470_382, 3997)
// Standard Error: 21
.saturating_add(Weight::from_parts(397, 0).saturating_mul(z.into()))
.saturating_add(T::DbWeight::get().reads(2_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
/// The range of component `z` is `[0, 10000]`.
fn as_multi_create(s: u32, z: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `229 + s * (2 ±0)`
// Estimated: `6811`
// Minimum execution time: 41_568_000 picoseconds.
Weight::from_parts(29_976_762, 6811)
// Standard Error: 1_712
.saturating_add(Weight::from_parts(144_320, 0).saturating_mul(s.into()))
// Standard Error: 16
.saturating_add(Weight::from_parts(1_819, 0).saturating_mul(z.into()))
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[3, 100]`.
/// The range of component `z` is `[0, 10000]`.
fn as_multi_approve(s: u32, z: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `185`
// Estimated: `6811`
// Minimum execution time: 26_237_000 picoseconds.
Weight::from_parts(14_821_348, 6811)
// Standard Error: 1_425
.saturating_add(Weight::from_parts(127_874, 0).saturating_mul(s.into()))
// Standard Error: 13
.saturating_add(Weight::from_parts(1_968, 0).saturating_mul(z.into()))
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `TxPause::PausedCalls` (r:1 w:0)
/// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
/// The range of component `z` is `[0, 10000]`.
fn as_multi_complete(s: u32, z: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `288 + s * (33 ±0)`
// Estimated: `6811`
// Minimum execution time: 50_942_000 picoseconds.
Weight::from_parts(34_745_418, 6811)
// Standard Error: 2_993
.saturating_add(Weight::from_parts(193_313, 0).saturating_mul(s.into()))
// Standard Error: 29
.saturating_add(Weight::from_parts(2_057, 0).saturating_mul(z.into()))
.saturating_add(T::DbWeight::get().reads(4_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
fn approve_as_multi_create(s: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `233 + s * (2 ±0)`
// Estimated: `6811`
// Minimum execution time: 25_583_000 picoseconds.
Weight::from_parts(27_463_275, 6811)
// Standard Error: 1_158
.saturating_add(Weight::from_parts(139_226, 0).saturating_mul(s.into()))
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
fn approve_as_multi_approve(s: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `185`
// Estimated: `6811`
// Minimum execution time: 13_086_000 picoseconds.
Weight::from_parts(14_074_258, 6811)
// Standard Error: 1_279
.saturating_add(Weight::from_parts(126_544, 0).saturating_mul(s.into()))
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
fn cancel_as_multi(s: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `357 + s * (1 ±0)`
// Estimated: `6811`
// Minimum execution time: 26_950_000 picoseconds.
Weight::from_parts(28_623_566, 6811)
// Standard Error: 1_795
.saturating_add(Weight::from_parts(135_351, 0).saturating_mul(s.into()))
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
fn poke_deposit(s: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `357 + s * (1 ±0)`
// Estimated: `6811`
// Minimum execution time: 25_804_000 picoseconds.
Weight::from_parts(27_349_525, 6811)
// Standard Error: 1_276
.saturating_add(Weight::from_parts(121_813, 0).saturating_mul(s.into()))
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `TxPause::PausedCalls` (r:1 w:0)
/// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`)
/// The range of component `z` is `[0, 10000]`.
fn as_multi_threshold_1(z: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `3997`
// Minimum execution time: 18_622_000 picoseconds.
Weight::from_parts(20_470_382, 3997)
// Standard Error: 21
.saturating_add(Weight::from_parts(397, 0).saturating_mul(z.into()))
.saturating_add(RocksDbWeight::get().reads(2_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
/// The range of component `z` is `[0, 10000]`.
fn as_multi_create(s: u32, z: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `229 + s * (2 ±0)`
// Estimated: `6811`
// Minimum execution time: 41_568_000 picoseconds.
Weight::from_parts(29_976_762, 6811)
// Standard Error: 1_712
.saturating_add(Weight::from_parts(144_320, 0).saturating_mul(s.into()))
// Standard Error: 16
.saturating_add(Weight::from_parts(1_819, 0).saturating_mul(z.into()))
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[3, 100]`.
/// The range of component `z` is `[0, 10000]`.
fn as_multi_approve(s: u32, z: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `185`
// Estimated: `6811`
// Minimum execution time: 26_237_000 picoseconds.
Weight::from_parts(14_821_348, 6811)
// Standard Error: 1_425
.saturating_add(Weight::from_parts(127_874, 0).saturating_mul(s.into()))
// Standard Error: 13
.saturating_add(Weight::from_parts(1_968, 0).saturating_mul(z.into()))
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `TxPause::PausedCalls` (r:1 w:0)
/// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
/// The range of component `z` is `[0, 10000]`.
fn as_multi_complete(s: u32, z: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `288 + s * (33 ±0)`
// Estimated: `6811`
// Minimum execution time: 50_942_000 picoseconds.
Weight::from_parts(34_745_418, 6811)
// Standard Error: 2_993
.saturating_add(Weight::from_parts(193_313, 0).saturating_mul(s.into()))
// Standard Error: 29
.saturating_add(Weight::from_parts(2_057, 0).saturating_mul(z.into()))
.saturating_add(RocksDbWeight::get().reads(4_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
fn approve_as_multi_create(s: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `233 + s * (2 ±0)`
// Estimated: `6811`
// Minimum execution time: 25_583_000 picoseconds.
Weight::from_parts(27_463_275, 6811)
// Standard Error: 1_158
.saturating_add(Weight::from_parts(139_226, 0).saturating_mul(s.into()))
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
fn approve_as_multi_approve(s: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `185`
// Estimated: `6811`
// Minimum execution time: 13_086_000 picoseconds.
Weight::from_parts(14_074_258, 6811)
// Standard Error: 1_279
.saturating_add(Weight::from_parts(126_544, 0).saturating_mul(s.into()))
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
fn cancel_as_multi(s: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `357 + s * (1 ±0)`
// Estimated: `6811`
// Minimum execution time: 26_950_000 picoseconds.
Weight::from_parts(28_623_566, 6811)
// Standard Error: 1_795
.saturating_add(Weight::from_parts(135_351, 0).saturating_mul(s.into()))
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `Multisig::Multisigs` (r:1 w:1)
/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
/// The range of component `s` is `[2, 100]`.
fn poke_deposit(s: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `357 + s * (1 ±0)`
// Estimated: `6811`
// Minimum execution time: 25_804_000 picoseconds.
Weight::from_parts(27_349_525, 6811)
// Standard Error: 1_276
.saturating_add(Weight::from_parts(121_813, 0).saturating_mul(s.into()))
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
}