mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-18 06:01:02 +00:00
Benchmarking pallet-example (#8301)
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
Generated
+2
-1
@@ -4953,11 +4953,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pallet-example"
|
name = "pallet-example"
|
||||||
version = "2.0.0"
|
version = "3.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"frame-benchmarking",
|
"frame-benchmarking",
|
||||||
"frame-support",
|
"frame-support",
|
||||||
"frame-system",
|
"frame-system",
|
||||||
|
"log",
|
||||||
"pallet-balances",
|
"pallet-balances",
|
||||||
"parity-scale-codec 2.0.1",
|
"parity-scale-codec 2.0.1",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -1084,7 +1084,7 @@ mod tests {
|
|||||||
type OnNewAccount = ();
|
type OnNewAccount = ();
|
||||||
type OnKilledAccount = ();
|
type OnKilledAccount = ();
|
||||||
type SystemWeightInfo = ();
|
type SystemWeightInfo = ();
|
||||||
type SS58Prefix = ();
|
type SS58Prefix = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "pallet-example"
|
name = "pallet-example"
|
||||||
version = "2.0.0"
|
version = "3.0.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "Unlicense"
|
license = "Unlicense"
|
||||||
@@ -21,8 +21,8 @@ pallet-balances = { version = "3.0.0", default-features = false, path = "../bala
|
|||||||
sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" }
|
sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" }
|
||||||
sp-std = { version = "3.0.0", default-features = false, path = "../../primitives/std" }
|
sp-std = { version = "3.0.0", default-features = false, path = "../../primitives/std" }
|
||||||
sp-io = { version = "3.0.0", default-features = false, path = "../../primitives/io" }
|
sp-io = { version = "3.0.0", default-features = false, path = "../../primitives/io" }
|
||||||
|
|
||||||
frame-benchmarking = { version = "3.1.0", default-features = false, path = "../benchmarking", optional = true }
|
frame-benchmarking = { version = "3.1.0", default-features = false, path = "../benchmarking", optional = true }
|
||||||
|
log = { version = "0.4.14", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
sp-core = { version = "3.0.0", path = "../../primitives/core", default-features = false }
|
sp-core = { version = "3.0.0", path = "../../primitives/core", default-features = false }
|
||||||
@@ -30,14 +30,15 @@ sp-core = { version = "3.0.0", path = "../../primitives/core", default-features
|
|||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = [
|
std = [
|
||||||
"serde",
|
|
||||||
"codec/std",
|
"codec/std",
|
||||||
"sp-runtime/std",
|
|
||||||
"frame-benchmarking/std",
|
"frame-benchmarking/std",
|
||||||
"frame-support/std",
|
"frame-support/std",
|
||||||
"frame-system/std",
|
"frame-system/std",
|
||||||
|
"log/std",
|
||||||
"pallet-balances/std",
|
"pallet-balances/std",
|
||||||
|
"serde",
|
||||||
"sp-io/std",
|
"sp-io/std",
|
||||||
|
"sp-runtime/std",
|
||||||
"sp-std/std"
|
"sp-std/std"
|
||||||
]
|
]
|
||||||
runtime-benchmarks = ["frame-benchmarking"]
|
runtime-benchmarks = ["frame-benchmarking"]
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
// This file is part of Substrate.
|
||||||
|
|
||||||
|
// Copyright (C) 2019-2021 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.
|
||||||
|
|
||||||
|
//! Benchmarking for pallet-example.
|
||||||
|
|
||||||
|
#![cfg(feature = "runtime-benchmarks")]
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
use frame_benchmarking::{benchmarks, whitelisted_caller, impl_benchmark_test_suite};
|
||||||
|
use frame_system::RawOrigin;
|
||||||
|
|
||||||
|
// To actually run this benchmark on pallet-example, we need to put this pallet into the
|
||||||
|
// runtime and compile it with `runtime-benchmarks` feature. The detail procedures are
|
||||||
|
// documented at:
|
||||||
|
// https://substrate.dev/docs/en/knowledgebase/runtime/benchmarking#how-to-benchmark
|
||||||
|
//
|
||||||
|
// The auto-generated weight estimate of this pallet is copied over to the `weights.rs` file.
|
||||||
|
// The exact command of how the estimate generated is printed at the top of the file.
|
||||||
|
|
||||||
|
// Details on using the benchmarks macro can be seen at:
|
||||||
|
// https://substrate.dev/rustdocs/v3.0.0/frame_benchmarking/macro.benchmarks.html
|
||||||
|
benchmarks!{
|
||||||
|
// This will measure the execution time of `set_dummy` for b in [1..1000] range.
|
||||||
|
set_dummy_benchmark {
|
||||||
|
// This is the benchmark setup phase
|
||||||
|
let b in 1 .. 1000;
|
||||||
|
}: set_dummy(RawOrigin::Root, b.into()) // The execution phase is just running `set_dummy` extrinsic call
|
||||||
|
verify {
|
||||||
|
// This is the optional benchmark verification phase, asserting certain states.
|
||||||
|
assert_eq!(Pallet::<T>::dummy(), Some(b.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will measure the execution time of `accumulate_dummy` for b in [1..1000] range.
|
||||||
|
// The benchmark execution phase is shorthanded. When the name of the benchmark case is the same
|
||||||
|
// as the extrinsic call. `_(...)` is used to represent the extrinsic name.
|
||||||
|
// The benchmark verification phase is omitted.
|
||||||
|
accumulate_dummy {
|
||||||
|
let b in 1 .. 1000;
|
||||||
|
// The caller account is whitelisted for DB reads/write by the benchmarking macro.
|
||||||
|
let caller: T::AccountId = whitelisted_caller();
|
||||||
|
}: _(RawOrigin::Signed(caller), b.into())
|
||||||
|
|
||||||
|
// This will measure the execution time of sorting a vector.
|
||||||
|
sort_vector {
|
||||||
|
let x in 0 .. 10000;
|
||||||
|
let mut m = Vec::<u32>::new();
|
||||||
|
for i in (0..x).rev() {
|
||||||
|
m.push(i);
|
||||||
|
}
|
||||||
|
}: {
|
||||||
|
// The benchmark execution phase could also be a closure with custom code
|
||||||
|
m.sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This line generates test cases for benchmarking, and could be run by:
|
||||||
|
// `cargo test -p pallet-example --all-features`, you will see an additional line of:
|
||||||
|
// `test benchmarking::benchmark_tests::test_benchmarks ... ok` in the result.
|
||||||
|
//
|
||||||
|
// The line generates three steps per benchmark, with repeat=1 and the three steps are
|
||||||
|
// [low, mid, high] of the range.
|
||||||
|
impl_benchmark_test_suite!(Pallet, crate::tests::new_test_ext(), crate::tests::Test);
|
||||||
@@ -255,28 +255,45 @@
|
|||||||
// Ensure we're `no_std` when compiling for Wasm.
|
// Ensure we're `no_std` when compiling for Wasm.
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
use sp_std::marker::PhantomData;
|
use sp_std::{
|
||||||
|
prelude::*,
|
||||||
|
marker::PhantomData
|
||||||
|
};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::DispatchResult, traits::IsSubType,
|
dispatch::DispatchResult, traits::IsSubType,
|
||||||
weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, Pays},
|
weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, Pays},
|
||||||
};
|
};
|
||||||
use sp_std::prelude::*;
|
|
||||||
use frame_system::{ensure_signed};
|
use frame_system::{ensure_signed};
|
||||||
use codec::{Encode, Decode};
|
use codec::{Encode, Decode};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{
|
traits::{
|
||||||
SignedExtension, Bounded, SaturatedConversion, DispatchInfoOf,
|
SignedExtension, Bounded, SaturatedConversion, DispatchInfoOf, Saturating
|
||||||
},
|
},
|
||||||
transaction_validity::{
|
transaction_validity::{
|
||||||
ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity,
|
ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
// Re-export pallet items so that they can be accessed from the crate namespace.
|
||||||
|
pub use pallet::*;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
|
mod benchmarking;
|
||||||
|
pub mod weights;
|
||||||
|
pub use weights::*;
|
||||||
|
|
||||||
|
/// A type alias for the balance type from this pallet's point of view.
|
||||||
|
type BalanceOf<T> = <T as pallet_balances::Config>::Balance;
|
||||||
|
const MILLICENTS: u32 = 1_000_000_000;
|
||||||
|
|
||||||
// A custom weight calculator tailored for the dispatch call `set_dummy()`. This actually examines
|
// A custom weight calculator tailored for the dispatch call `set_dummy()`. This actually examines
|
||||||
// the arguments and makes a decision based upon them.
|
// the arguments and makes a decision based upon them.
|
||||||
//
|
//
|
||||||
// The `WeightData<T>` trait has access to the arguments of the dispatch that it wants to assign a
|
// The `WeightData<T>` trait has access to the arguments of the dispatch that it wants to assign a
|
||||||
// weight to. Nonetheless, the trait itself can not make any assumptions about what the generic type
|
// weight to. Nonetheless, the trait itself cannot make any assumptions about what the generic type
|
||||||
// of the arguments (`T`) is. Based on our needs, we could replace `T` with a more concrete type
|
// of the arguments (`T`) is. Based on our needs, we could replace `T` with a more concrete type
|
||||||
// while implementing the trait. The `pallet::weight` expects whatever implements `WeighData<T>` to
|
// while implementing the trait. The `pallet::weight` expects whatever implements `WeighData<T>` to
|
||||||
// replace `T` with a tuple of the dispatch arguments. This is exactly how we will craft the
|
// replace `T` with a tuple of the dispatch arguments. This is exactly how we will craft the
|
||||||
@@ -286,13 +303,22 @@ use sp_runtime::{
|
|||||||
// - The final weight of each dispatch is calculated as the argument of the call multiplied by the
|
// - The final weight of each dispatch is calculated as the argument of the call multiplied by the
|
||||||
// parameter given to the `WeightForSetDummy`'s constructor.
|
// parameter given to the `WeightForSetDummy`'s constructor.
|
||||||
// - assigns a dispatch class `operational` if the argument of the call is more than 1000.
|
// - assigns a dispatch class `operational` if the argument of the call is more than 1000.
|
||||||
|
//
|
||||||
|
// More information can be read at:
|
||||||
|
// - https://substrate.dev/docs/en/knowledgebase/learn-substrate/weight
|
||||||
|
// - https://substrate.dev/docs/en/knowledgebase/runtime/fees#default-weight-annotations
|
||||||
|
//
|
||||||
|
// Manually configuring weight is an advanced operation and what you really need may well be
|
||||||
|
// fulfilled by running the benchmarking toolchain. Refer to `benchmarking.rs` file.
|
||||||
struct WeightForSetDummy<T: pallet_balances::Config>(BalanceOf<T>);
|
struct WeightForSetDummy<T: pallet_balances::Config>(BalanceOf<T>);
|
||||||
|
|
||||||
impl<T: pallet_balances::Config> WeighData<(&BalanceOf<T>,)> for WeightForSetDummy<T>
|
impl<T: pallet_balances::Config> WeighData<(&BalanceOf<T>,)> for WeightForSetDummy<T>
|
||||||
{
|
{
|
||||||
fn weigh_data(&self, target: (&BalanceOf<T>,)) -> Weight {
|
fn weigh_data(&self, target: (&BalanceOf<T>,)) -> Weight {
|
||||||
let multiplier = self.0;
|
let multiplier = self.0;
|
||||||
(*target.0 * multiplier).saturated_into::<Weight>()
|
// *target.0 is the amount passed into the extrinsic
|
||||||
|
let cents = *target.0 / <BalanceOf<T>>::from(MILLICENTS);
|
||||||
|
(cents * multiplier).saturated_into::<Weight>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,12 +338,6 @@ impl<T: pallet_balances::Config> PaysFee<(&BalanceOf<T>,)> for WeightForSetDummy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type alias for the balance type from this pallet's point of view.
|
|
||||||
type BalanceOf<T> = <T as pallet_balances::Config>::Balance;
|
|
||||||
|
|
||||||
// Re-export pallet items so that they can be accessed from the crate namespace.
|
|
||||||
pub use pallet::*;
|
|
||||||
|
|
||||||
// Definition of the pallet logic, to be aggregated at runtime definition through
|
// Definition of the pallet logic, to be aggregated at runtime definition through
|
||||||
// `construct_runtime`.
|
// `construct_runtime`.
|
||||||
#[frame_support::pallet]
|
#[frame_support::pallet]
|
||||||
@@ -334,8 +354,15 @@ pub mod pallet {
|
|||||||
/// `frame_system::Config` should always be included.
|
/// `frame_system::Config` should always be included.
|
||||||
#[pallet::config]
|
#[pallet::config]
|
||||||
pub trait Config: pallet_balances::Config + frame_system::Config {
|
pub trait Config: pallet_balances::Config + frame_system::Config {
|
||||||
|
// Setting a constant config parameter from the runtime
|
||||||
|
#[pallet::constant]
|
||||||
|
type MagicNumber: Get<Self::Balance>;
|
||||||
|
|
||||||
/// The overarching event type.
|
/// The overarching event type.
|
||||||
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
|
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
|
||||||
|
|
||||||
|
/// Type representing the weight of this pallet
|
||||||
|
type WeightInfo: WeightInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple declaration of the `Pallet` type. It is placeholder we use to implement traits and
|
// Simple declaration of the `Pallet` type. It is placeholder we use to implement traits and
|
||||||
@@ -354,14 +381,12 @@ pub mod pallet {
|
|||||||
fn on_initialize(_n: T::BlockNumber) -> Weight {
|
fn on_initialize(_n: T::BlockNumber) -> Weight {
|
||||||
// Anything that needs to be done at the start of the block.
|
// Anything that needs to be done at the start of the block.
|
||||||
// We don't do anything here.
|
// We don't do anything here.
|
||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
// `on_finalize` is executed at the end of block after all extrinsic are dispatched.
|
// `on_finalize` is executed at the end of block after all extrinsic are dispatched.
|
||||||
fn on_finalize(_n: T::BlockNumber) {
|
fn on_finalize(_n: T::BlockNumber) {
|
||||||
// We just kill our dummy storage item.
|
// Perform necessary data/state clean up here.
|
||||||
<Dummy<T>>::kill();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A runtime code run after every block and have access to extended set of APIs.
|
// A runtime code run after every block and have access to extended set of APIs.
|
||||||
@@ -370,7 +395,9 @@ pub mod pallet {
|
|||||||
fn offchain_worker(_n: T::BlockNumber) {
|
fn offchain_worker(_n: T::BlockNumber) {
|
||||||
// We don't do anything here.
|
// We don't do anything here.
|
||||||
// but we could dispatch extrinsic (transaction/unsigned/inherent) using
|
// but we could dispatch extrinsic (transaction/unsigned/inherent) using
|
||||||
// sp_io::submit_extrinsic
|
// sp_io::submit_extrinsic.
|
||||||
|
// To see example on offchain worker, please refer to example-offchain-worker pallet
|
||||||
|
// accompanied in this repository.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,11 +482,16 @@ pub mod pallet {
|
|||||||
// difficulty) of the transaction and the latter demonstrates the [`DispatchClass`] of the
|
// difficulty) of the transaction and the latter demonstrates the [`DispatchClass`] of the
|
||||||
// call. A higher weight means a larger transaction (less of which can be placed in a
|
// call. A higher weight means a larger transaction (less of which can be placed in a
|
||||||
// single block).
|
// single block).
|
||||||
#[pallet::weight(0)]
|
//
|
||||||
|
// The weight for this extrinsic we rely on the auto-generated `WeightInfo` from the benchmark
|
||||||
|
// toolchain.
|
||||||
|
#[pallet::weight(
|
||||||
|
<T as pallet::Config>::WeightInfo::accumulate_dummy((*increase_by).saturated_into())
|
||||||
|
)]
|
||||||
pub(super) fn accumulate_dummy(
|
pub(super) fn accumulate_dummy(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
increase_by: T::Balance
|
increase_by: T::Balance
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResult {
|
||||||
// This is a public call, so we ensure that the origin is some signed account.
|
// This is a public call, so we ensure that the origin is some signed account.
|
||||||
let _sender = ensure_signed(origin)?;
|
let _sender = ensure_signed(origin)?;
|
||||||
|
|
||||||
@@ -478,15 +510,16 @@ pub mod pallet {
|
|||||||
|
|
||||||
// Here's the new one of read and then modify the value.
|
// Here's the new one of read and then modify the value.
|
||||||
<Dummy<T>>::mutate(|dummy| {
|
<Dummy<T>>::mutate(|dummy| {
|
||||||
let new_dummy = dummy.map_or(increase_by, |dummy| dummy + increase_by);
|
// Using `saturating_add` instead of a regular `+` to avoid overflowing
|
||||||
|
let new_dummy = dummy.map_or(increase_by, |d| d.saturating_add(increase_by));
|
||||||
*dummy = Some(new_dummy);
|
*dummy = Some(new_dummy);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Let's deposit an event to let the outside world know this happened.
|
// Let's deposit an event to let the outside world know this happened.
|
||||||
Self::deposit_event(Event::Dummy(increase_by));
|
Self::deposit_event(Event::AccumulateDummy(increase_by));
|
||||||
|
|
||||||
// All good, no refund.
|
// All good, no refund.
|
||||||
Ok(().into())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A privileged call; in this case it resets our dummy value to something new.
|
/// A privileged call; in this case it resets our dummy value to something new.
|
||||||
@@ -496,17 +529,28 @@ pub mod pallet {
|
|||||||
// calls to be executed - we don't need to care why. Because it's privileged, we can
|
// calls to be executed - we don't need to care why. Because it's privileged, we can
|
||||||
// assume it's a one-off operation and substantial processing/storage/memory can be used
|
// assume it's a one-off operation and substantial processing/storage/memory can be used
|
||||||
// without worrying about gameability or attack scenarios.
|
// without worrying about gameability or attack scenarios.
|
||||||
|
//
|
||||||
|
// The weight for this extrinsic we use our own weight object `WeightForSetDummy` to determine
|
||||||
|
// its weight
|
||||||
#[pallet::weight(WeightForSetDummy::<T>(<BalanceOf<T>>::from(100u32)))]
|
#[pallet::weight(WeightForSetDummy::<T>(<BalanceOf<T>>::from(100u32)))]
|
||||||
fn set_dummy(
|
pub(super) fn set_dummy(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
#[pallet::compact] new_value: T::Balance,
|
#[pallet::compact] new_value: T::Balance,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResult {
|
||||||
ensure_root(origin)?;
|
ensure_root(origin)?;
|
||||||
|
|
||||||
|
// Print out log or debug message in the console via log::{error, warn, info, debug, trace},
|
||||||
|
// accepting format strings similar to `println!`.
|
||||||
|
// https://substrate.dev/rustdocs/v3.0.0/log/index.html
|
||||||
|
info!("New value is now: {:?}", new_value);
|
||||||
|
|
||||||
// Put the new value into storage.
|
// Put the new value into storage.
|
||||||
<Dummy<T>>::put(new_value);
|
<Dummy<T>>::put(new_value);
|
||||||
|
|
||||||
|
Self::deposit_event(Event::SetDummy(new_value));
|
||||||
|
|
||||||
// All good, no refund.
|
// All good, no refund.
|
||||||
Ok(().into())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,7 +564,9 @@ pub mod pallet {
|
|||||||
pub enum Event<T: Config> {
|
pub enum Event<T: Config> {
|
||||||
// Just a normal `enum`, here's a dummy event to ensure it compiles.
|
// Just a normal `enum`, here's a dummy event to ensure it compiles.
|
||||||
/// Dummy event, just here so there's a generic type that's used.
|
/// Dummy event, just here so there's a generic type that's used.
|
||||||
Dummy(BalanceOf<T>),
|
AccumulateDummy(BalanceOf<T>),
|
||||||
|
SetDummy(BalanceOf<T>),
|
||||||
|
SetBar(T::AccountId, BalanceOf<T>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// pallet::storage attributes allow for type-safe usage of the Substrate storage database,
|
// pallet::storage attributes allow for type-safe usage of the Substrate storage database,
|
||||||
@@ -545,14 +591,13 @@ pub mod pallet {
|
|||||||
// A map that has enumerable entries.
|
// A map that has enumerable entries.
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
#[pallet::getter(fn bar)]
|
#[pallet::getter(fn bar)]
|
||||||
pub(super) type Bar<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance, ValueQuery>;
|
pub(super) type Bar<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance>;
|
||||||
|
|
||||||
// this one uses the query kind: `ValueQuery`, we'll demonstrate the usage of 'mutate' API.
|
// this one uses the query kind: `ValueQuery`, we'll demonstrate the usage of 'mutate' API.
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
#[pallet::getter(fn foo)]
|
#[pallet::getter(fn foo)]
|
||||||
pub(super) type Foo<T: Config> = StorageValue<_, T::Balance, ValueQuery>;
|
pub(super) type Foo<T: Config> = StorageValue<_, T::Balance, ValueQuery>;
|
||||||
|
|
||||||
|
|
||||||
// The genesis config type.
|
// The genesis config type.
|
||||||
#[pallet::genesis_config]
|
#[pallet::genesis_config]
|
||||||
pub struct GenesisConfig<T: Config> {
|
pub struct GenesisConfig<T: Config> {
|
||||||
@@ -600,7 +645,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
let prev = <Foo<T>>::get();
|
let prev = <Foo<T>>::get();
|
||||||
// Because Foo has 'default', the type of 'foo' in closure is the raw type instead of an Option<> type.
|
// Because Foo has 'default', the type of 'foo' in closure is the raw type instead of an Option<> type.
|
||||||
let result = <Foo<T>>::mutate(|foo| {
|
let result = <Foo<T>>::mutate(|foo| {
|
||||||
*foo = *foo + increase_by;
|
*foo = foo.saturating_add(increase_by);
|
||||||
*foo
|
*foo
|
||||||
});
|
});
|
||||||
assert!(prev + increase_by == result);
|
assert!(prev + increase_by == result);
|
||||||
@@ -640,11 +685,11 @@ impl<T: Config> Pallet<T> {
|
|||||||
// types defined in the runtime. Lookup `pub type SignedExtra = (...)` in `node/runtime` and
|
// types defined in the runtime. Lookup `pub type SignedExtra = (...)` in `node/runtime` and
|
||||||
// `node-template` for an example of this.
|
// `node-template` for an example of this.
|
||||||
|
|
||||||
/// A simple signed extension that checks for the `set_dummy` call. In that case, it increases the
|
// A simple signed extension that checks for the `set_dummy` call. In that case, it increases the
|
||||||
/// priority and prints some log.
|
// priority and prints some log.
|
||||||
///
|
//
|
||||||
/// Additionally, it drops any transaction with an encoded length higher than 200 bytes. No
|
// Additionally, it drops any transaction with an encoded length higher than 200 bytes. No
|
||||||
/// particular reason why, just to demonstrate the power of signed extensions.
|
// particular reason why, just to demonstrate the power of signed extensions.
|
||||||
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
|
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
|
||||||
pub struct WatchDummy<T: Config + Send + Sync>(PhantomData<T>);
|
pub struct WatchDummy<T: Config + Send + Sync>(PhantomData<T>);
|
||||||
|
|
||||||
@@ -691,201 +736,3 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
mod benchmarking {
|
|
||||||
use super::*;
|
|
||||||
use frame_benchmarking::{benchmarks, account, impl_benchmark_test_suite};
|
|
||||||
use frame_system::RawOrigin;
|
|
||||||
|
|
||||||
benchmarks!{
|
|
||||||
// This will measure the execution time of `accumulate_dummy` for b in [1..1000] range.
|
|
||||||
accumulate_dummy {
|
|
||||||
let b in 1 .. 1000;
|
|
||||||
let caller = account("caller", 0, 0);
|
|
||||||
}: _ (RawOrigin::Signed(caller), b.into())
|
|
||||||
|
|
||||||
// This will measure the execution time of `set_dummy` for b in [1..1000] range.
|
|
||||||
set_dummy {
|
|
||||||
let b in 1 .. 1000;
|
|
||||||
}: set_dummy (RawOrigin::Root, b.into())
|
|
||||||
|
|
||||||
// This will measure the execution time of `set_dummy` for b in [1..10] range.
|
|
||||||
another_set_dummy {
|
|
||||||
let b in 1 .. 10;
|
|
||||||
}: set_dummy (RawOrigin::Root, b.into())
|
|
||||||
|
|
||||||
// This will measure the execution time of sorting a vector.
|
|
||||||
sort_vector {
|
|
||||||
let x in 0 .. 10000;
|
|
||||||
let mut m = Vec::<u32>::new();
|
|
||||||
for i in (0..x).rev() {
|
|
||||||
m.push(i);
|
|
||||||
}
|
|
||||||
}: {
|
|
||||||
m.sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_benchmark_test_suite!(Pallet, crate::tests::new_test_ext(), crate::tests::Test);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
use frame_support::{
|
|
||||||
assert_ok, parameter_types,
|
|
||||||
weights::{DispatchInfo, GetDispatchInfo}, traits::{OnInitialize, OnFinalize}
|
|
||||||
};
|
|
||||||
use sp_core::H256;
|
|
||||||
// The testing primitives are very useful for avoiding having to work with signatures
|
|
||||||
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required.
|
|
||||||
use sp_runtime::{
|
|
||||||
testing::Header, BuildStorage,
|
|
||||||
traits::{BlakeTwo256, IdentityLookup},
|
|
||||||
};
|
|
||||||
// Reexport crate as its pallet name for construct_runtime.
|
|
||||||
use crate as pallet_example;
|
|
||||||
|
|
||||||
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
|
|
||||||
type Block = frame_system::mocking::MockBlock<Test>;
|
|
||||||
|
|
||||||
// For testing the pallet, we construct a mock runtime.
|
|
||||||
frame_support::construct_runtime!(
|
|
||||||
pub enum Test where
|
|
||||||
Block = Block,
|
|
||||||
NodeBlock = Block,
|
|
||||||
UncheckedExtrinsic = UncheckedExtrinsic,
|
|
||||||
{
|
|
||||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
|
||||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
|
||||||
Example: pallet_example::{Pallet, Call, Storage, Config<T>, Event<T>},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
parameter_types! {
|
|
||||||
pub const BlockHashCount: u64 = 250;
|
|
||||||
pub BlockWeights: frame_system::limits::BlockWeights =
|
|
||||||
frame_system::limits::BlockWeights::simple_max(1024);
|
|
||||||
}
|
|
||||||
impl frame_system::Config for Test {
|
|
||||||
type BaseCallFilter = ();
|
|
||||||
type BlockWeights = ();
|
|
||||||
type BlockLength = ();
|
|
||||||
type DbWeight = ();
|
|
||||||
type Origin = Origin;
|
|
||||||
type Index = u64;
|
|
||||||
type BlockNumber = u64;
|
|
||||||
type Hash = H256;
|
|
||||||
type Call = Call;
|
|
||||||
type Hashing = BlakeTwo256;
|
|
||||||
type AccountId = u64;
|
|
||||||
type Lookup = IdentityLookup<Self::AccountId>;
|
|
||||||
type Header = Header;
|
|
||||||
type Event = Event;
|
|
||||||
type BlockHashCount = BlockHashCount;
|
|
||||||
type Version = ();
|
|
||||||
type PalletInfo = PalletInfo;
|
|
||||||
type AccountData = pallet_balances::AccountData<u64>;
|
|
||||||
type OnNewAccount = ();
|
|
||||||
type OnKilledAccount = ();
|
|
||||||
type SystemWeightInfo = ();
|
|
||||||
type SS58Prefix = ();
|
|
||||||
}
|
|
||||||
parameter_types! {
|
|
||||||
pub const ExistentialDeposit: u64 = 1;
|
|
||||||
}
|
|
||||||
impl pallet_balances::Config for Test {
|
|
||||||
type MaxLocks = ();
|
|
||||||
type Balance = u64;
|
|
||||||
type DustRemoval = ();
|
|
||||||
type Event = Event;
|
|
||||||
type ExistentialDeposit = ExistentialDeposit;
|
|
||||||
type AccountStore = System;
|
|
||||||
type WeightInfo = ();
|
|
||||||
}
|
|
||||||
impl Config for Test {
|
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function basically just builds a genesis storage key/value store according to
|
|
||||||
// our desired mockup.
|
|
||||||
pub fn new_test_ext() -> sp_io::TestExternalities {
|
|
||||||
let t = GenesisConfig {
|
|
||||||
// We use default for brevity, but you can configure as desired if needed.
|
|
||||||
frame_system: Default::default(),
|
|
||||||
pallet_balances: Default::default(),
|
|
||||||
pallet_example: pallet_example::GenesisConfig {
|
|
||||||
dummy: 42,
|
|
||||||
// we configure the map with (key, value) pairs.
|
|
||||||
bar: vec![(1, 2), (2, 3)],
|
|
||||||
foo: 24,
|
|
||||||
},
|
|
||||||
}.build_storage().unwrap();
|
|
||||||
t.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works_for_optional_value() {
|
|
||||||
new_test_ext().execute_with(|| {
|
|
||||||
// Check that GenesisBuilder works properly.
|
|
||||||
assert_eq!(Example::dummy(), Some(42));
|
|
||||||
|
|
||||||
// Check that accumulate works when we have Some value in Dummy already.
|
|
||||||
assert_ok!(Example::accumulate_dummy(Origin::signed(1), 27));
|
|
||||||
assert_eq!(Example::dummy(), Some(69));
|
|
||||||
|
|
||||||
// Check that finalizing the block removes Dummy from storage.
|
|
||||||
<Example as OnFinalize<u64>>::on_finalize(1);
|
|
||||||
assert_eq!(Example::dummy(), None);
|
|
||||||
|
|
||||||
// Check that accumulate works when we Dummy has None in it.
|
|
||||||
<Example as OnInitialize<u64>>::on_initialize(2);
|
|
||||||
assert_ok!(Example::accumulate_dummy(Origin::signed(1), 42));
|
|
||||||
assert_eq!(Example::dummy(), Some(42));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works_for_default_value() {
|
|
||||||
new_test_ext().execute_with(|| {
|
|
||||||
assert_eq!(Example::foo(), 24);
|
|
||||||
assert_ok!(Example::accumulate_foo(Origin::signed(1), 1));
|
|
||||||
assert_eq!(Example::foo(), 25);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn signed_ext_watch_dummy_works() {
|
|
||||||
new_test_ext().execute_with(|| {
|
|
||||||
let call = <pallet_example::Call<Test>>::set_dummy(10).into();
|
|
||||||
let info = DispatchInfo::default();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
WatchDummy::<Test>(PhantomData).validate(&1, &call, &info, 150)
|
|
||||||
.unwrap()
|
|
||||||
.priority,
|
|
||||||
u64::max_value(),
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
WatchDummy::<Test>(PhantomData).validate(&1, &call, &info, 250),
|
|
||||||
InvalidTransaction::ExhaustsResources.into(),
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn weights_work() {
|
|
||||||
// must have a defined weight.
|
|
||||||
let default_call = <pallet_example::Call<Test>>::accumulate_dummy(10);
|
|
||||||
let info = default_call.get_dispatch_info();
|
|
||||||
// aka. `let info = <Call<Test> as GetDispatchInfo>::get_dispatch_info(&default_call);`
|
|
||||||
assert_eq!(info.weight, 0);
|
|
||||||
|
|
||||||
// must have a custom weight of `100 * arg = 2000`
|
|
||||||
let custom_call = <pallet_example::Call<Test>>::set_dummy(20);
|
|
||||||
let info = custom_call.get_dispatch_info();
|
|
||||||
assert_eq!(info.weight, 2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
// This file is part of Substrate.
|
||||||
|
|
||||||
|
// Copyright (C) 2019-2021 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.
|
||||||
|
|
||||||
|
//! Tests for pallet-example.
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
use frame_support::{
|
||||||
|
assert_ok, parameter_types,
|
||||||
|
weights::{DispatchInfo, GetDispatchInfo}, traits::OnInitialize
|
||||||
|
};
|
||||||
|
use sp_core::H256;
|
||||||
|
// The testing primitives are very useful for avoiding having to work with signatures
|
||||||
|
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required.
|
||||||
|
use sp_runtime::{
|
||||||
|
testing::Header, BuildStorage,
|
||||||
|
traits::{BlakeTwo256, IdentityLookup},
|
||||||
|
};
|
||||||
|
// Reexport crate as its pallet name for construct_runtime.
|
||||||
|
use crate as pallet_example;
|
||||||
|
|
||||||
|
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
|
||||||
|
type Block = frame_system::mocking::MockBlock<Test>;
|
||||||
|
|
||||||
|
// For testing the pallet, we construct a mock runtime.
|
||||||
|
frame_support::construct_runtime!(
|
||||||
|
pub enum Test where
|
||||||
|
Block = Block,
|
||||||
|
NodeBlock = Block,
|
||||||
|
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||||
|
{
|
||||||
|
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
||||||
|
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||||
|
Example: pallet_example::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const BlockHashCount: u64 = 250;
|
||||||
|
pub BlockWeights: frame_system::limits::BlockWeights =
|
||||||
|
frame_system::limits::BlockWeights::simple_max(1024);
|
||||||
|
}
|
||||||
|
impl frame_system::Config for Test {
|
||||||
|
type BaseCallFilter = ();
|
||||||
|
type BlockWeights = ();
|
||||||
|
type BlockLength = ();
|
||||||
|
type DbWeight = ();
|
||||||
|
type Origin = Origin;
|
||||||
|
type Index = u64;
|
||||||
|
type BlockNumber = u64;
|
||||||
|
type Hash = H256;
|
||||||
|
type Call = Call;
|
||||||
|
type Hashing = BlakeTwo256;
|
||||||
|
type AccountId = u64;
|
||||||
|
type Lookup = IdentityLookup<Self::AccountId>;
|
||||||
|
type Header = Header;
|
||||||
|
type Event = Event;
|
||||||
|
type BlockHashCount = BlockHashCount;
|
||||||
|
type Version = ();
|
||||||
|
type PalletInfo = PalletInfo;
|
||||||
|
type AccountData = pallet_balances::AccountData<u64>;
|
||||||
|
type OnNewAccount = ();
|
||||||
|
type OnKilledAccount = ();
|
||||||
|
type SystemWeightInfo = ();
|
||||||
|
type SS58Prefix = ();
|
||||||
|
}
|
||||||
|
parameter_types! {
|
||||||
|
pub const ExistentialDeposit: u64 = 1;
|
||||||
|
}
|
||||||
|
impl pallet_balances::Config for Test {
|
||||||
|
type MaxLocks = ();
|
||||||
|
type Balance = u64;
|
||||||
|
type DustRemoval = ();
|
||||||
|
type Event = Event;
|
||||||
|
type ExistentialDeposit = ExistentialDeposit;
|
||||||
|
type AccountStore = System;
|
||||||
|
type WeightInfo = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const MagicNumber: u64 = 1_000_000_000;
|
||||||
|
}
|
||||||
|
impl Config for Test {
|
||||||
|
type MagicNumber = MagicNumber;
|
||||||
|
type Event = Event;
|
||||||
|
type WeightInfo = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function basically just builds a genesis storage key/value store according to
|
||||||
|
// our desired mockup.
|
||||||
|
pub fn new_test_ext() -> sp_io::TestExternalities {
|
||||||
|
let t = GenesisConfig {
|
||||||
|
// We use default for brevity, but you can configure as desired if needed.
|
||||||
|
frame_system: Default::default(),
|
||||||
|
pallet_balances: Default::default(),
|
||||||
|
pallet_example: pallet_example::GenesisConfig {
|
||||||
|
dummy: 42,
|
||||||
|
// we configure the map with (key, value) pairs.
|
||||||
|
bar: vec![(1, 2), (2, 3)],
|
||||||
|
foo: 24,
|
||||||
|
},
|
||||||
|
}.build_storage().unwrap();
|
||||||
|
t.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works_for_optional_value() {
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
// Check that GenesisBuilder works properly.
|
||||||
|
let val1 = 42;
|
||||||
|
let val2 = 27;
|
||||||
|
assert_eq!(Example::dummy(), Some(val1));
|
||||||
|
|
||||||
|
// Check that accumulate works when we have Some value in Dummy already.
|
||||||
|
assert_ok!(Example::accumulate_dummy(Origin::signed(1), val2));
|
||||||
|
assert_eq!(Example::dummy(), Some(val1 + val2));
|
||||||
|
|
||||||
|
// Check that accumulate works when we Dummy has None in it.
|
||||||
|
<Example as OnInitialize<u64>>::on_initialize(2);
|
||||||
|
assert_ok!(Example::accumulate_dummy(Origin::signed(1), val1));
|
||||||
|
assert_eq!(Example::dummy(), Some(val1 + val2 + val1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works_for_default_value() {
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
assert_eq!(Example::foo(), 24);
|
||||||
|
assert_ok!(Example::accumulate_foo(Origin::signed(1), 1));
|
||||||
|
assert_eq!(Example::foo(), 25);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn set_dummy_works() {
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
let test_val = 133;
|
||||||
|
assert_ok!(Example::set_dummy(Origin::root(), test_val.into()));
|
||||||
|
assert_eq!(Example::dummy(), Some(test_val));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn signed_ext_watch_dummy_works() {
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
let call = <pallet_example::Call<Test>>::set_dummy(10).into();
|
||||||
|
let info = DispatchInfo::default();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
WatchDummy::<Test>(PhantomData).validate(&1, &call, &info, 150)
|
||||||
|
.unwrap()
|
||||||
|
.priority,
|
||||||
|
u64::max_value(),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
WatchDummy::<Test>(PhantomData).validate(&1, &call, &info, 250),
|
||||||
|
InvalidTransaction::ExhaustsResources.into(),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn weights_work() {
|
||||||
|
// must have a defined weight.
|
||||||
|
let default_call = <pallet_example::Call<Test>>::accumulate_dummy(10);
|
||||||
|
let info1 = default_call.get_dispatch_info();
|
||||||
|
// aka. `let info = <Call<Test> as GetDispatchInfo>::get_dispatch_info(&default_call);`
|
||||||
|
assert!(info1.weight > 0);
|
||||||
|
|
||||||
|
|
||||||
|
// `set_dummy` is simpler than `accumulate_dummy`, and the weight
|
||||||
|
// should be less.
|
||||||
|
let custom_call = <pallet_example::Call<Test>>::set_dummy(20);
|
||||||
|
let info2 = custom_call.get_dispatch_info();
|
||||||
|
assert!(info1.weight > info2.weight);
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
// This file is part of Substrate.
|
||||||
|
|
||||||
|
// Copyright (C) 2021 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 pallet_example
|
||||||
|
//!
|
||||||
|
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||||
|
//! DATE: 2021-03-15, STEPS: `[100, ]`, REPEAT: 10, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||||
|
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128
|
||||||
|
|
||||||
|
// Executed Command:
|
||||||
|
// ./target/release/substrate
|
||||||
|
// benchmark
|
||||||
|
// --chain
|
||||||
|
// dev
|
||||||
|
// --execution
|
||||||
|
// wasm
|
||||||
|
// --wasm-execution
|
||||||
|
// compiled
|
||||||
|
// --pallet
|
||||||
|
// pallet_example
|
||||||
|
// --extrinsic
|
||||||
|
// *
|
||||||
|
// --steps
|
||||||
|
// 100
|
||||||
|
// --repeat
|
||||||
|
// 10
|
||||||
|
// --raw
|
||||||
|
// --output
|
||||||
|
// ./
|
||||||
|
// --template
|
||||||
|
// ./.maintain/frame-weight-template.hbs
|
||||||
|
|
||||||
|
|
||||||
|
#![allow(unused_parens)]
|
||||||
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
|
use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
|
||||||
|
use sp_std::marker::PhantomData;
|
||||||
|
|
||||||
|
/// Weight functions needed for pallet_example.
|
||||||
|
pub trait WeightInfo {
|
||||||
|
fn set_dummy_benchmark(b: u32, ) -> Weight;
|
||||||
|
fn accumulate_dummy(b: u32, ) -> Weight;
|
||||||
|
fn sort_vector(x: u32, ) -> Weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Weights for pallet_example using the Substrate node and recommended hardware.
|
||||||
|
pub struct SubstrateWeight<T>(PhantomData<T>);
|
||||||
|
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||||
|
fn set_dummy_benchmark(b: u32, ) -> Weight {
|
||||||
|
(5_834_000 as Weight)
|
||||||
|
.saturating_add((24_000 as Weight).saturating_mul(b as Weight))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||||
|
}
|
||||||
|
fn accumulate_dummy(b: u32, ) -> Weight {
|
||||||
|
(51_353_000 as Weight)
|
||||||
|
.saturating_add((14_000 as Weight).saturating_mul(b as Weight))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||||
|
}
|
||||||
|
fn sort_vector(x: u32, ) -> Weight {
|
||||||
|
(2_569_000 as Weight)
|
||||||
|
// Standard Error: 0
|
||||||
|
.saturating_add((4_000 as Weight).saturating_mul(x as Weight))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For backwards compatibility and tests
|
||||||
|
impl WeightInfo for () {
|
||||||
|
fn set_dummy_benchmark(b: u32, ) -> Weight {
|
||||||
|
(5_834_000 as Weight)
|
||||||
|
.saturating_add((24_000 as Weight).saturating_mul(b as Weight))
|
||||||
|
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||||
|
}
|
||||||
|
fn accumulate_dummy(b: u32, ) -> Weight {
|
||||||
|
(51_353_000 as Weight)
|
||||||
|
.saturating_add((14_000 as Weight).saturating_mul(b as Weight))
|
||||||
|
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
|
||||||
|
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||||
|
}
|
||||||
|
fn sort_vector(x: u32, ) -> Weight {
|
||||||
|
(2_569_000 as Weight)
|
||||||
|
// Standard Error: 0
|
||||||
|
.saturating_add((4_000 as Weight).saturating_mul(x as Weight))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user