From e96dd81931689aca6ffd7dd9f378592615b2811c Mon Sep 17 00:00:00 2001 From: Erwan Renaut <73958772+renauter@users.noreply.github.com> Date: Fri, 2 Jun 2023 04:12:58 -0300 Subject: [PATCH] feat(benchmark): benchmarking pallets [2/4] (#698) --- .../pallets/pallet-burning/Cargo.toml | 7 + .../pallet-burning/src/benchmarking.rs | 34 ++ .../pallets/pallet-burning/src/lib.rs | 9 +- .../pallets/pallet-burning/src/mock.rs | 2 + .../pallets/pallet-burning/src/tests.rs | 4 +- .../pallets/pallet-burning/src/weights.rs | 58 ++++ substrate-node/pallets/pallet-dao/Cargo.toml | 17 +- .../pallets/pallet-dao/src/benchmarking.rs | 328 +++++++++++------- substrate-node/pallets/pallet-dao/src/lib.rs | 9 +- substrate-node/pallets/pallet-dao/src/mock.rs | 60 ++-- .../pallets/pallet-dao/src/tests.rs | 122 +++---- .../pallets/pallet-dao/src/weights.rs | 167 +++++---- .../pallets/pallet-kvstore/Cargo.toml | 11 +- .../pallet-kvstore/src/benchmarking.rs | 47 +++ .../pallets/pallet-kvstore/src/lib.rs | 15 +- .../pallets/pallet-kvstore/src/tests.rs | 43 +-- .../pallets/pallet-kvstore/src/weights.rs | 71 ++++ .../pallets/pallet-runtime-upgrade/src/lib.rs | 5 +- .../pallets/pallet-smart-contract/src/mock.rs | 1 + .../pallets/pallet-tft-price/src/mock.rs | 1 + .../pallets/pallet-validator/Cargo.toml | 7 + .../pallet-validator/src/benchmarking.rs | 175 ++++++++++ .../pallets/pallet-validator/src/lib.rs | 19 +- .../pallets/pallet-validator/src/mock.rs | 3 + .../pallets/pallet-validator/src/weights.rs | 159 +++++++++ .../substrate-validator-set/Cargo.toml | 7 + .../src/benchmarking.rs | 73 ++++ .../substrate-validator-set/src/lib.rs | 20 +- .../substrate-validator-set/src/mock.rs | 26 +- .../substrate-validator-set/src/tests.rs | 6 +- .../substrate-validator-set/src/weights.rs | 94 +++++ substrate-node/runtime/Cargo.toml | 5 + substrate-node/runtime/src/lib.rs | 9 + 33 files changed, 1259 insertions(+), 355 deletions(-) create mode 100644 substrate-node/pallets/pallet-burning/src/benchmarking.rs create mode 100644 substrate-node/pallets/pallet-burning/src/weights.rs create mode 100644 substrate-node/pallets/pallet-kvstore/src/benchmarking.rs create mode 100644 substrate-node/pallets/pallet-kvstore/src/weights.rs create mode 100644 substrate-node/pallets/pallet-validator/src/benchmarking.rs create mode 100644 substrate-node/pallets/pallet-validator/src/weights.rs create mode 100644 substrate-node/pallets/substrate-validator-set/src/benchmarking.rs create mode 100644 substrate-node/pallets/substrate-validator-set/src/weights.rs diff --git a/substrate-node/pallets/pallet-burning/Cargo.toml b/substrate-node/pallets/pallet-burning/Cargo.toml index d6289185c..cb092fe22 100644 --- a/substrate-node/pallets/pallet-burning/Cargo.toml +++ b/substrate-node/pallets/pallet-burning/Cargo.toml @@ -27,6 +27,9 @@ sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkad pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +# Benchmarking +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } + [dev-dependencies] sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } @@ -36,6 +39,7 @@ std = [ 'pallet-balances/std', 'frame-support/std', 'frame-system/std', + 'frame-benchmarking/std', 'sp-runtime/std', 'sp-std/std', 'sp-storage/std', @@ -44,6 +48,9 @@ std = [ 'sp-io/std', 'scale-info/std' ] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", +] try-runtime = [ "frame-support/try-runtime", ] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-burning/src/benchmarking.rs b/substrate-node/pallets/pallet-burning/src/benchmarking.rs new file mode 100644 index 000000000..cb31cc643 --- /dev/null +++ b/substrate-node/pallets/pallet-burning/src/benchmarking.rs @@ -0,0 +1,34 @@ +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use crate::Pallet as BurningModule; +use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_system::{EventRecord, Pallet as System, RawOrigin}; +use sp_runtime::{traits::StaticLookup, SaturatedConversion}; + +benchmarks! { + // burn_tft() + burn_tft { + let target: T::AccountId = whitelisted_caller(); + let target_lookup = T::Lookup::unlookup(target.clone()); + let amount = BalanceOf::::saturated_from(1000 as u128); + T::Currency::make_free_balance_be(&target, amount); + let message = b"some_message".to_vec(); + }: _(RawOrigin::Signed(target.clone()), amount.clone(), message.clone()) + verify { + let block = T::BlockNumber::from(1 as u32); + assert_eq!(T::Currency::free_balance(&target).saturated_into::(), 0 as u128); + assert_last_event::(Event::BurnTransactionCreated(target, amount, block, message).into()); + } + + // Calling the `impl_benchmark_test_suite` macro inside the `benchmarks` + // block will generate one #[test] function per benchmark + impl_benchmark_test_suite!(BurningModule, crate::mock::new_test_ext(), crate::mock::TestRuntime) +} + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = System::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} diff --git a/substrate-node/pallets/pallet-burning/src/lib.rs b/substrate-node/pallets/pallet-burning/src/lib.rs index c339040a5..2590a664d 100644 --- a/substrate-node/pallets/pallet-burning/src/lib.rs +++ b/substrate-node/pallets/pallet-burning/src/lib.rs @@ -16,6 +16,11 @@ mod tests; #[cfg(test)] mod mock; +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; + +pub mod weights; + #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] pub struct Burn { pub target: AccountId, @@ -29,6 +34,7 @@ pub use pallet::*; #[frame_support::pallet] pub mod pallet { + use super::weights::WeightInfo; use frame_support::{ pallet_prelude::*, traits::{Currency, OnUnbalanced, ReservableCurrency}, @@ -57,6 +63,7 @@ pub mod pallet { type Currency: Currency + ReservableCurrency; /// Handler for the unbalanced decrement when slashing (burning collateral) type Burn: OnUnbalanced>; + type WeightInfo: crate::weights::WeightInfo; } #[pallet::event] @@ -78,7 +85,7 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::burn_tft())] pub fn burn_tft( origin: OriginFor, amount: BalanceOf, diff --git a/substrate-node/pallets/pallet-burning/src/mock.rs b/substrate-node/pallets/pallet-burning/src/mock.rs index 26b83609a..57d64ac89 100644 --- a/substrate-node/pallets/pallet-burning/src/mock.rs +++ b/substrate-node/pallets/pallet-burning/src/mock.rs @@ -83,10 +83,12 @@ impl pallet_balances::Config for TestRuntime { type WeightInfo = pallet_balances::weights::SubstrateWeight; } +use weights; impl Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type Burn = (); + type WeightInfo = weights::SubstrateWeight; } type AccountPublic = ::Signer; diff --git a/substrate-node/pallets/pallet-burning/src/tests.rs b/substrate-node/pallets/pallet-burning/src/tests.rs index 661c56a64..ca52fbb0b 100644 --- a/substrate-node/pallets/pallet-burning/src/tests.rs +++ b/substrate-node/pallets/pallet-burning/src/tests.rs @@ -8,7 +8,7 @@ fn test_burn() { assert_ok!(BurningModule::burn_tft( RuntimeOrigin::signed(alice()), 900000000000, - "some_message".as_bytes().to_vec() + b"some_message".to_vec() )); let b = Balances::free_balance(alice()); @@ -24,7 +24,7 @@ fn test_burn_to_much_fails() { BurningModule::burn_tft( RuntimeOrigin::signed(alice()), 1200000000000, - "some_message".as_bytes().to_vec() + b"some_message".to_vec() ), Error::::NotEnoughBalanceToBurn ); diff --git a/substrate-node/pallets/pallet-burning/src/weights.rs b/substrate-node/pallets/pallet-burning/src/weights.rs new file mode 100644 index 000000000..bf87d65d0 --- /dev/null +++ b/substrate-node/pallets/pallet-burning/src/weights.rs @@ -0,0 +1,58 @@ + +//! Autogenerated weights for pallet_burning +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-16, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `R1-HP-ProBook-630-G8`, CPU: `11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/tfchain +// benchmark +// pallet +// --chain=dev +// --pallet=pallet_burning +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --execution=wasm +// --heap-pages=4096 +// --output +// pallets/pallet-burning/src/weights.rs +// --template +// ./.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![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_burning. +pub trait WeightInfo { + fn burn_tft() -> Weight; +} + +/// Weights for pallet_burning using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: BurningModule Burns (r:1 w:1) + fn burn_tft() -> Weight { + // Minimum execution time: 58_615 nanoseconds. + Weight::from_ref_time(63_829_000) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: BurningModule Burns (r:1 w:1) + fn burn_tft() -> Weight { + // Minimum execution time: 58_615 nanoseconds. + Weight::from_ref_time(63_829_000) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } +} diff --git a/substrate-node/pallets/pallet-dao/Cargo.toml b/substrate-node/pallets/pallet-dao/Cargo.toml index 4059a1956..05e0661aa 100644 --- a/substrate-node/pallets/pallet-dao/Cargo.toml +++ b/substrate-node/pallets/pallet-dao/Cargo.toml @@ -23,7 +23,6 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } @@ -33,11 +32,14 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkad sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +# Benchmarking +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } + tfchain-support = { path = "../../support", default-features = false } pallet-tfgrid = { path = "../pallet-tfgrid", default-features = false } [dev-dependencies] -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } env_logger = "*" [features] @@ -55,10 +57,13 @@ std = [ "pallet-timestamp/std", "pallet-tfgrid/std", "tfchain-support/std", - 'scale-info/std', - 'serde/std', - 'log/std' + "scale-info/std", + "serde/std", + "log/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", -] +] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-dao/src/benchmarking.rs b/substrate-node/pallets/pallet-dao/src/benchmarking.rs index 9022a838d..7a4f6a9d8 100644 --- a/substrate-node/pallets/pallet-dao/src/benchmarking.rs +++ b/substrate-node/pallets/pallet-dao/src/benchmarking.rs @@ -1,191 +1,257 @@ -// This file is part of Substrate. - -// Copyright (C) 2022 Threefold Tech -// Copyright (C) 2020-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. - -//! Vesting pallet benchmarking. - #![cfg(feature = "runtime-benchmarks")] use super::*; - -use crate::Module as DaoModule; +use crate::Pallet as DaoModule; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; -use frame_support::traits::{Box, Vec}; -use sp_runtime::traits::Bounded; -use frame_system::RawOrigin; -use sp_std::vec; - -use frame_system::Call as SystemCall; -use frame_system::Module as System; - -use tfchain_support::types::{Location, Resources}; +use frame_support::{assert_ok, BoundedVec}; +use frame_system::{Call as SystemCall, EventRecord, Pallet as System, RawOrigin}; +use pallet_membership::Pallet as CouncilMembership; +use pallet_tfgrid::{ + types::LocationInput, CityNameInput, CountryNameInput, DocumentHashInput, DocumentLinkInput, + Gw4Input, Ip4Input, LatitudeInput, LongitudeInput, Pallet as TfgridModule, PkInput, RelayInput, + ResourcesInput, +}; +use sp_runtime::traits::StaticLookup; +use sp_std::convert::{TryFrom, TryInto}; +use tfchain_support::types::IP4; + +const GIGABYTE: u64 = 1024 * 1024 * 1024; benchmarks! { + // propose() propose { let caller: T::AccountId = whitelisted_caller(); - add_council_member::(caller.clone()); - - let remark = "remark".as_bytes().to_vec(); - let proposal: T::Proposal = SystemCall::::remark(remark).into(); + assert_ok!(_add_council_member::(caller.clone())); let threshold = 1; - - let description = "some_description".as_bytes().to_vec(); - let link = "some_link".as_bytes().to_vec(); - }: _ (RawOrigin::Signed(caller.clone()), 1, Box::new(proposal.clone()), description, link) + let proposal: T::Proposal = SystemCall::::remark { remark: b"remark".to_vec() }.into(); + let description = b"some_description".to_vec(); + let link = b"some_link".to_vec(); + }: _( + RawOrigin::Signed(caller.clone()), + threshold, + Box::new(proposal.clone()), + description, + link, + None + ) verify { + let proposal_count = DaoModule::::proposal_count(); + assert_eq!(proposal_count, 1); + let proposal_index = 0; assert_eq!(DaoModule::::proposals_list_hashes().len(), 1); + let proposal_hash = DaoModule::::proposals_list_hashes().into_iter().next().unwrap(); + assert!(DaoModule::::proposal_list(proposal_hash).is_some()); + assert!(DaoModule::::proposal_of(proposal_hash).is_some()); + assert!(DaoModule::::voting(&proposal_hash).is_some()); + assert_last_event::(Event::Proposed { account: caller, proposal_index, proposal_hash, threshold }.into()); } + // vote() vote { - let a1: T::AccountId = account("Alice", 0, 0); - prepare_farm_and_node::(a1.clone()); + let farmer: T::AccountId = account("Alice", 0, 0); + _prepare_farm_with_node::(farmer.clone()); + let farm_id = 1; let caller: T::AccountId = whitelisted_caller(); - add_council_member::(caller.clone()); + let proposal_hash = _create_proposal::(caller.clone()); - let hash = create_proposal::(caller.clone()); - }: _ (RawOrigin::Signed(a1.clone()), 1, hash, true) + let approve = true; + }: _(RawOrigin::Signed(farmer.clone()), farm_id, proposal_hash, approve) verify { - let voting = DaoModule::::voting(&hash).ok_or("Proposal missing")?; + assert!(DaoModule::::proposal_list(proposal_hash).is_some()); + assert!(DaoModule::::proposal_of(proposal_hash).is_some()); + assert!(DaoModule::::voting(&proposal_hash).is_some()); + let voting = DaoModule::::voting(&proposal_hash).unwrap(); assert_eq!(voting.ayes.len(), 1); + assert_eq!(voting.nays.len(), 0); + assert_last_event::(Event::Voted { + account: farmer, + proposal_hash, + voted: approve, + yes: 1 as u32, + no: 0 as u32 + }.into()); } - close { - let a1: T::AccountId = account("Alice", 0, 0); - prepare_farm_and_node::(a1.clone()); + // veto() + veto { + let farmer: T::AccountId = account("Alice", 0, 0); + _prepare_farm_with_node::(farmer.clone()); + let farm_id = 1; let caller: T::AccountId = whitelisted_caller(); - add_council_member::(caller.clone()); + let proposal_hash = _create_proposal::(caller.clone()); + }: _(RawOrigin::Signed(caller.clone()), proposal_hash) + verify { + assert!(DaoModule::::proposal_list(proposal_hash).is_some()); + assert!(DaoModule::::proposal_of(proposal_hash).is_some()); + assert!(DaoModule::::voting(proposal_hash).is_some()); + let voting = DaoModule::::voting(&proposal_hash).unwrap(); + assert_eq!(voting.vetos, vec![caller.clone()]); + assert_last_event::(Event::CouncilMemberVeto { proposal_hash, who: caller }.into()); + } - let hash = create_proposal::(caller.clone()); - vote_proposal::(a1.clone(), 1, hash, true); + // close() + close { + let farmer: T::AccountId = account("Alice", 0, 0); + _prepare_farm_with_node::(farmer.clone()); + let farm_id = 1; - System::::set_block_number(::BlockNumber::max_value()); - }: _ (RawOrigin::Signed(a1.clone()), hash, 0) - verify { + let caller: T::AccountId = whitelisted_caller(); + let proposal_hash = _create_proposal::(caller.clone()); + let proposal_index = 0; + let approve = false; + DaoModule::::vote(RawOrigin::Signed(farmer.clone()).into(), farm_id, proposal_hash, approve).unwrap(); + }: _(RawOrigin::Signed(caller.clone()), proposal_hash, proposal_index) + verify { + assert!(DaoModule::::proposal_list(proposal_hash).is_none()); + assert!(DaoModule::::proposal_of(proposal_hash).is_none()); + assert!(DaoModule::::voting(proposal_hash).is_none()); + assert_last_event::(Event::Disapproved { proposal_hash }.into()); } -} -#[cfg(test)] -mod benchmarktests { - use super::*; - use crate::mock::{new_test_ext, TestRuntime}; - use frame_support::assert_ok; + // Calling the `impl_benchmark_test_suite` macro inside the `benchmarks` + // block will generate one #[test] function per benchmark + impl_benchmark_test_suite! (DaoModule, crate::mock::new_test_ext(), crate::mock::TestRuntime) +} - #[test] - fn test_benchmarks() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_propose::()); - assert_ok!(test_benchmark_vote::()); - }); - } +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = System::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); } -pub fn create_twin(source: T::AccountId) { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); +pub fn _prepare_farm_with_node(source: T::AccountId) { + _create_twin::(source.clone()); + _create_farm::(source.clone()); + _create_node::(source.clone()); +} - pallet_tfgrid::Module::::user_accept_tc( +fn _create_twin(source: T::AccountId) { + assert_ok!(TfgridModule::::user_accept_tc( RawOrigin::Signed(source.clone()).into(), - document.clone(), - hash.clone(), - ) - .unwrap(); - let ip = "10.2.3.3"; - pallet_tfgrid::Module::::create_twin( + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), + )); + + assert_ok!(TfgridModule::::create_twin( RawOrigin::Signed(source).into(), - ip.as_bytes().to_vec(), - ) - .unwrap(); + get_relay_input(b"somerelay.io"), + get_public_key_input(b"0x6c8fd181adc178cea218e168e8549f0b0ff30627c879db9eac4318927e87c901"), + )); } -pub fn prepare_farm_and_node(source: T::AccountId) { - create_twin::(source.clone()); - prepare_farm::(source.clone()); +fn _create_farm(source: T::AccountId) { + let mut pub_ips = Vec::new(); + pub_ips.push(IP4 { + ip: get_public_ip_ip_input(b"185.206.122.33/24"), + gw: get_public_ip_gw_input(b"185.206.122.1"), + }); + pub_ips.push(IP4 { + ip: get_public_ip_ip_input(b"185.206.122.34/24"), + gw: get_public_ip_gw_input(b"185.206.122.1"), + }); + + assert_ok!(TfgridModule::::create_farm( + RawOrigin::Signed(source).into(), + b"testfarm".to_vec().try_into().unwrap(), + pub_ips.clone().try_into().unwrap(), + )); +} - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), +fn _create_node(source: T::AccountId) { + let resources = ResourcesInput { + hru: 1024 * GIGABYTE, + sru: 512 * GIGABYTE, + cru: 8, + mru: 16 * GIGABYTE, }; - let resources = Resources { - hru: 9001778946048, - sru: 512110190592, - cru: 64, - mru: 202802909184, + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), }; - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); - pallet_tfgrid::Module::::create_node( - RawOrigin::Signed(source).into(), + assert_ok!(TfgridModule::::create_node( + RawOrigin::Signed(source.clone()).into(), 1, resources, location, - country, - city, - Vec::new(), + Vec::new().try_into().unwrap(), false, false, - "some_serial".as_bytes().to_vec(), - ) - .unwrap(); + None, + )); } -pub fn prepare_farm(source: T::AccountId) { - let farm_name = "test_farm"; - pallet_tfgrid::Module::::create_farm( - RawOrigin::Signed(source).into(), - farm_name.as_bytes().to_vec(), - Vec::new(), - ) - .unwrap(); -} +pub fn _create_proposal(source: T::AccountId) -> T::Hash { + assert_ok!(_add_council_member::(source.clone())); -pub fn create_proposal(source: T::AccountId) -> T::Hash { - let remark = "remark".as_bytes().to_vec(); - let proposal: T::Proposal = SystemCall::::remark(remark).into(); let threshold = 1; - let description = "some_description".as_bytes().to_vec(); - let link = "some_link".as_bytes().to_vec(); - let hash = T::Hashing::hash_of(&proposal); + let proposal: T::Proposal = SystemCall::::remark { + remark: b"remark".to_vec(), + } + .into(); DaoModule::::propose( RawOrigin::Signed(source).into(), threshold, - Box::new(proposal), - description, - link - ).unwrap(); + Box::new(proposal.clone()), + b"some_description".to_vec(), + b"some_link".to_vec(), + None, + ) + .unwrap(); - hash + T::Hashing::hash_of(&proposal) } -pub fn vote_proposal(source: T::AccountId, farm_id: u32, hash: T::Hash, approve: bool) { - DaoModule::::vote( - RawOrigin::Signed(source).into(), - farm_id, - hash, - approve - ).unwrap(); +fn _add_council_member(source: T::AccountId) -> Result<(), DispatchError> { + let source_lookup = T::Lookup::unlookup(source.clone()); + CouncilMembership::::add_member(RawOrigin::Root.into(), source_lookup) +} + +pub(crate) fn get_city_name_input(city_input: &[u8]) -> CityNameInput { + BoundedVec::try_from(city_input.to_vec()).expect("Invalid city name input.") +} + +pub(crate) fn get_country_name_input(country_input: &[u8]) -> CountryNameInput { + BoundedVec::try_from(country_input.to_vec()).expect("Invalid country name input.") +} + +pub(crate) fn get_latitude_input(latitude_input: &[u8]) -> LatitudeInput { + BoundedVec::try_from(latitude_input.to_vec()).expect("Invalid latitude input.") +} + +pub(crate) fn get_longitude_input(longitude_input: &[u8]) -> LongitudeInput { + BoundedVec::try_from(longitude_input.to_vec()).expect("Invalid longitude input.") +} + +pub(crate) fn get_document_link_input(document_link_input: &[u8]) -> DocumentLinkInput { + BoundedVec::try_from(document_link_input.to_vec()).expect("Invalid document link input.") +} + +pub(crate) fn get_document_hash_input(document_hash_input: &[u8]) -> DocumentHashInput { + BoundedVec::try_from(document_hash_input.to_vec()).expect("Invalid document hash input.") +} + +pub(crate) fn get_relay_input(relay_input: &[u8]) -> RelayInput { + Some(BoundedVec::try_from(relay_input.to_vec()).expect("Invalid relay input.")) +} + +pub(crate) fn get_public_key_input(pk_input: &[u8]) -> PkInput { + Some(BoundedVec::try_from(pk_input.to_vec()).expect("Invalid document public key input.")) +} + +pub(crate) fn get_public_ip_ip_input(public_ip_ip_input: &[u8]) -> Ip4Input { + BoundedVec::try_from(public_ip_ip_input.to_vec()).expect("Invalid public ip (ip) input.") } -fn add_council_member(source: T::AccountId) { - pallet_membership::Module::::add_member(RawOrigin::Root.into(), source).unwrap(); +pub(crate) fn get_public_ip_gw_input(public_ip_gw_input: &[u8]) -> Gw4Input { + BoundedVec::try_from(public_ip_gw_input.to_vec()).expect("Invalid public ip (gw) input.") } diff --git a/substrate-node/pallets/pallet-dao/src/lib.rs b/substrate-node/pallets/pallet-dao/src/lib.rs index b85677d6c..b04f3fb9f 100644 --- a/substrate-node/pallets/pallet-dao/src/lib.rs +++ b/substrate-node/pallets/pallet-dao/src/lib.rs @@ -29,6 +29,7 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; + pub mod weights; mod proposal; @@ -188,7 +189,7 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight((::WeightInfo::propose(), DispatchClass::Operational))] + #[pallet::weight((::WeightInfo::propose(), DispatchClass::Operational))] pub fn propose( origin: OriginFor, #[pallet::compact] threshold: u32, @@ -255,7 +256,7 @@ pub mod pallet { } #[pallet::call_index(1)] - #[pallet::weight((::WeightInfo::vote(), DispatchClass::Operational))] + #[pallet::weight((::WeightInfo::vote(), DispatchClass::Operational))] pub fn vote( origin: OriginFor, farm_id: u32, @@ -336,7 +337,7 @@ pub mod pallet { } #[pallet::call_index(2)] - #[pallet::weight((::WeightInfo::vote(), DispatchClass::Operational))] + #[pallet::weight((::WeightInfo::veto(), DispatchClass::Operational))] pub fn veto(origin: OriginFor, proposal_hash: T::Hash) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; @@ -371,7 +372,7 @@ pub mod pallet { } #[pallet::call_index(3)] - #[pallet::weight((::WeightInfo::close(), DispatchClass::Operational))] + #[pallet::weight((::WeightInfo::close(), DispatchClass::Operational))] pub fn close( origin: OriginFor, proposal_hash: T::Hash, diff --git a/substrate-node/pallets/pallet-dao/src/mock.rs b/substrate-node/pallets/pallet-dao/src/mock.rs index a4f8bdbce..079dadeda 100644 --- a/substrate-node/pallets/pallet-dao/src/mock.rs +++ b/substrate-node/pallets/pallet-dao/src/mock.rs @@ -22,12 +22,12 @@ use sp_std::convert::{TryFrom, TryInto}; use tfchain_support::traits::{ChangeNode, PublicIpModifier}; use tfchain_support::types::PublicIP; -type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. construct_runtime!( - pub enum Test where + pub enum TestRuntime where Block = Block, NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic, @@ -45,7 +45,7 @@ parameter_types! { pub const BlockHashCount: u64 = 250; } -impl frame_system::Config for Test { +impl frame_system::Config for TestRuntime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); @@ -78,11 +78,11 @@ parameter_types! { pub const MinVetos: u32 = 2; } -pub(crate) type Serial = pallet_tfgrid::pallet::SerialNumberOf; -pub(crate) type Loc = pallet_tfgrid::pallet::LocationOf; -pub(crate) type Interface = pallet_tfgrid::pallet::InterfaceOf; +pub(crate) type Serial = pallet_tfgrid::pallet::SerialNumberOf; +pub(crate) type Loc = pallet_tfgrid::pallet::LocationOf; +pub(crate) type Interface = pallet_tfgrid::pallet::InterfaceOf; -pub(crate) type TfgridNode = pallet_tfgrid::pallet::TfgridNode; +pub(crate) type TfgridNode = pallet_tfgrid::pallet::TfgridNode; pub struct NodeChanged; impl ChangeNode for NodeChanged { @@ -100,7 +100,7 @@ impl PublicIpModifier for PublicIpModifierType { } use super::weights; -impl pallet_dao::Config for Test { +impl pallet_dao::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type CouncilOrigin = EnsureRoot; type Proposal = RuntimeCall; @@ -108,7 +108,7 @@ impl pallet_dao::Config for Test { type MinVetos = MinVetos; type Tfgrid = TfgridModule; type NodeChanged = NodeChanged; - type WeightInfo = weights::SubstrateWeight; + type WeightInfo = weights::SubstrateWeight; } parameter_types! { @@ -118,23 +118,23 @@ parameter_types! { pub const MaxFarmPublicIps: u32 = 512; } -pub(crate) type TestTermsAndConditions = TermsAndConditions; +pub(crate) type TestTermsAndConditions = TermsAndConditions; -pub(crate) type TestFarmName = FarmName; +pub(crate) type TestFarmName = FarmName; -pub(crate) type TestInterfaceName = InterfaceName; -pub(crate) type TestInterfaceMac = InterfaceMac; -pub(crate) type TestInterfaceIp = InterfaceIp; +pub(crate) type TestInterfaceName = InterfaceName; +pub(crate) type TestInterfaceMac = InterfaceMac; +pub(crate) type TestInterfaceIp = InterfaceIp; -pub(crate) type TestCountryName = CountryName; -pub(crate) type TestCityName = CityName; -pub(crate) type TestLocation = Location; -pub(crate) type TestSerialNumber = SerialNumber; +pub(crate) type TestCountryName = CountryName; +pub(crate) type TestCityName = CityName; +pub(crate) type TestLocation = Location; +pub(crate) type TestSerialNumber = SerialNumber; -impl pallet_tfgrid::Config for Test { +impl pallet_tfgrid::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type RestrictedOrigin = EnsureRoot; - type WeightInfo = pallet_tfgrid::weights::SubstrateWeight; + type WeightInfo = pallet_tfgrid::weights::SubstrateWeight; type NodeChanged = NodeChanged; type PublicIpModifier = PublicIpModifierType; type TermsAndConditions = TestTermsAndConditions; @@ -152,11 +152,11 @@ impl pallet_tfgrid::Config for Test { type SerialNumber = TestSerialNumber; } -impl pallet_timestamp::Config for Test { +impl pallet_timestamp::Config for TestRuntime { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = (); - type WeightInfo = pallet_timestamp::weights::SubstrateWeight; + type WeightInfo = pallet_timestamp::weights::SubstrateWeight; } parameter_types! { @@ -166,7 +166,7 @@ parameter_types! { } pub type CouncilCollective = pallet_collective::Instance1; -impl pallet_collective::Config for Test { +impl pallet_collective::Config for TestRuntime { type RuntimeOrigin = RuntimeOrigin; type Proposal = RuntimeCall; type RuntimeEvent = RuntimeEvent; @@ -177,7 +177,7 @@ impl pallet_collective::Config for Test { type WeightInfo = (); } -impl pallet_membership::Config for Test { +impl pallet_membership::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type AddOrigin = EnsureRoot; type RemoveOrigin = EnsureRoot; @@ -187,7 +187,7 @@ impl pallet_membership::Config for Test { type MembershipInitialized = Council; type MembershipChanged = (); type MaxMembers = CouncilMaxMembers; - type WeightInfo = pallet_membership::weights::SubstrateWeight; + type WeightInfo = pallet_membership::weights::SubstrateWeight; } pub(crate) fn get_document_link_input(document_link_input: &[u8]) -> DocumentLinkInput { @@ -233,19 +233,19 @@ pub(crate) fn get_longitude_input(longitude_input: &[u8]) -> LongitudeInput { // Build genesis storage according to the mock runtime. pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default() - .build_storage::() + .build_storage::() .unwrap(); - let genesis = pallet_collective::GenesisConfig::::default(); + let genesis = pallet_collective::GenesisConfig::::default(); genesis.assimilate_storage(&mut t).unwrap(); - let genesis = pallet_membership::GenesisConfig:: { + let genesis = pallet_membership::GenesisConfig:: { members: vec![1, 2, 3].try_into().unwrap(), phantom: Default::default(), }; genesis.assimilate_storage(&mut t).unwrap(); - let genesis = pallet_tfgrid::GenesisConfig:: { + let genesis = pallet_tfgrid::GenesisConfig:: { su_price_value: 300000, su_price_unit: 4, nu_price_value: 2000, diff --git a/substrate-node/pallets/pallet-dao/src/tests.rs b/substrate-node/pallets/pallet-dao/src/tests.rs index 5ef0d933b..2dd882189 100644 --- a/substrate-node/pallets/pallet-dao/src/tests.rs +++ b/substrate-node/pallets/pallet-dao/src/tests.rs @@ -12,7 +12,7 @@ use tfchain_support::types::{FarmCertification, NodeCertification, IP4}; #[test] fn farmers_vote_no_farm_fails() { new_test_ext().execute_with(|| { - let proposal = make_proposal("some_remark".as_bytes().to_vec()); + let proposal = make_proposal(b"some_remark".to_vec()); let _proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); @@ -20,14 +20,14 @@ fn farmers_vote_no_farm_fails() { RuntimeOrigin::signed(1), 3, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); assert_noop!( DaoModule::vote(RuntimeOrigin::signed(10), 1, hash.clone(), true), - Error::::NotAuthorizedToVote + Error::::NotAuthorizedToVote ); }); } @@ -38,7 +38,7 @@ fn farmers_vote_proposal_works() { System::set_block_number(1); create_farming_policies(); - let proposal = make_proposal("some_remark".as_bytes().to_vec()); + let proposal = make_proposal(b"some_remark".to_vec()); let _proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); @@ -46,12 +46,12 @@ fn farmers_vote_proposal_works() { RuntimeOrigin::signed(1), 3, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); - prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); + prepare_twin_farm_and_node(10, b"farm1".to_vec(), 1); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(10), 1, @@ -59,7 +59,7 @@ fn farmers_vote_proposal_works() { true )); - prepare_twin_farm_and_node(11, "farm2".as_bytes().to_vec(), 2); + prepare_twin_farm_and_node(11, b"farm2".to_vec(), 2); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(11), 2, @@ -75,7 +75,7 @@ fn farmers_vote_proposal_if_no_nodes_fails() { System::set_block_number(1); create_farming_policies(); - let proposal = make_proposal("some_remark".as_bytes().to_vec()); + let proposal = make_proposal(b"some_remark".to_vec()); let _proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); @@ -83,16 +83,16 @@ fn farmers_vote_proposal_if_no_nodes_fails() { RuntimeOrigin::signed(1), 1, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); prepare_twin(10); - prepare_farm(10, "farm1".as_bytes().to_vec()); + prepare_farm(10, b"farm1".to_vec()); assert_noop!( DaoModule::vote(RuntimeOrigin::signed(10), 1, hash.clone(), true), - Error::::FarmHasNoNodes + Error::::FarmHasNoNodes ); let votes = DaoModule::voting(hash).unwrap(); @@ -106,7 +106,7 @@ fn farmer_weight_is_set_properly_when_node_is_added_works() { System::set_block_number(1); create_farming_policies(); - prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); + prepare_twin_farm_and_node(10, b"farm1".to_vec(), 1); let weight = DaoModule::farm_weight(1); assert_ne!(weight, 0); @@ -119,7 +119,7 @@ fn farmer_weight_is_set_properly_when_node_is_added_and_removed_works() { System::set_block_number(1); create_farming_policies(); - prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); + prepare_twin_farm_and_node(10, b"farm1".to_vec(), 1); let weight = DaoModule::farm_weight(1); assert_ne!(weight, 0); @@ -137,7 +137,7 @@ fn close_works() { System::set_block_number(1); create_farming_policies(); - let proposal = make_proposal("some_remark".as_bytes().to_vec()); + let proposal = make_proposal(b"some_remark".to_vec()); let hash = BlakeTwo256::hash_of(&proposal); let threshold = 2; @@ -145,13 +145,13 @@ fn close_works() { RuntimeOrigin::signed(1), threshold, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); // Farmer 1 votes yes - prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); + prepare_twin_farm_and_node(10, b"farm1".to_vec(), 1); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(10), 1, @@ -162,15 +162,15 @@ fn close_works() { System::set_block_number(4); assert_noop!( DaoModule::close(RuntimeOrigin::signed(4), hash.clone(), 0,), - Error::::NotCouncilMember + Error::::NotCouncilMember ); assert_noop!( DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,), - Error::::OngoingVoteAndTresholdStillNotMet + Error::::OngoingVoteAndTresholdStillNotMet ); // Farmer 2 votes yes - prepare_twin_farm_and_node(11, "farm2".as_bytes().to_vec(), 2); + prepare_twin_farm_and_node(11, b"farm2".to_vec(), 2); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(11), 2, @@ -245,15 +245,15 @@ fn close_after_proposal_duration_works() { new_test_ext().execute_with(|| { System::set_block_number(1); - let proposal = make_proposal("some_remark".as_bytes().to_vec()); + let proposal = make_proposal(b"some_remark".to_vec()); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); @@ -265,15 +265,15 @@ fn close_after_proposal_duration_works() { #[test] fn close_if_not_council_member_fails() { new_test_ext().execute_with(|| { - let proposal = make_proposal("some_remark".as_bytes().to_vec()); + let proposal = make_proposal(b"some_remark".to_vec()); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); @@ -281,7 +281,7 @@ fn close_if_not_council_member_fails() { assert_noop!( DaoModule::close(not_council_member, hash.clone(), 0,), - Error::::NotCouncilMember + Error::::NotCouncilMember ); }); } @@ -302,13 +302,13 @@ fn motion_approval_works() { RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); // Farmer 1 votes yes - prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); + prepare_twin_farm_and_node(10, b"farm1".to_vec(), 1); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(10), 1, @@ -317,7 +317,7 @@ fn motion_approval_works() { )); // Farmer 2 votes yes - prepare_twin_farm_and_node(11, "farm2".as_bytes().to_vec(), 2); + prepare_twin_farm_and_node(11, b"farm2".to_vec(), 2); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(11), 2, @@ -417,8 +417,8 @@ fn motion_veto_works() { RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); @@ -523,13 +523,13 @@ fn weighted_voting_works() { RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); // Farmer 1 votes yes - prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); + prepare_twin_farm_and_node(10, b"farm1".to_vec(), 1); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(10), 1, @@ -538,7 +538,7 @@ fn weighted_voting_works() { )); // Farmer 2 votes no - prepare_twin_farm_and_big_node(11, "farm2".as_bytes().to_vec(), 2); + prepare_twin_farm_and_big_node(11, b"farm2".to_vec(), 2); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(11), 2, @@ -629,13 +629,13 @@ fn voting_tfgridmodule_call_works() { RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), None )); // Farmer 1 votes yes - prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); + prepare_twin_farm_and_node(10, b"farm1".to_vec(), 1); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(10), 1, @@ -644,7 +644,7 @@ fn voting_tfgridmodule_call_works() { )); // Farmer 2 votes no - prepare_twin_farm_and_node(11, "farm2".as_bytes().to_vec(), 2); + prepare_twin_farm_and_node(11, b"farm2".to_vec(), 2); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(11), 2, @@ -739,20 +739,20 @@ fn customize_proposal_duration_works() { System::set_block_number(1); create_farming_policies(); - let proposal = make_proposal("some_remark".as_bytes().to_vec()); + let proposal = make_proposal(b"some_remark".to_vec()); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), Some(10) )); // Farmer 1 votes yes - prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); + prepare_twin_farm_and_node(10, b"farm1".to_vec(), 1); assert_ok!(DaoModule::vote( RuntimeOrigin::signed(10), 1, @@ -763,7 +763,7 @@ fn customize_proposal_duration_works() { System::set_block_number(9); assert_noop!( DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,), - Error::::OngoingVoteAndTresholdStillNotMet + Error::::OngoingVoteAndTresholdStillNotMet ); System::set_block_number(11); @@ -776,17 +776,17 @@ fn customize_proposal_duration_out_of_bounds_fails() { new_test_ext().execute_with(|| { System::set_block_number(1); create_farming_policies(); - let proposal = make_proposal("some_remark".as_bytes().to_vec()); + let proposal = make_proposal(b"some_remark".to_vec()); // assert_noop!( // DaoModule::propose( // RuntimeOrigin::signed(1), // 2, // Box::new(proposal.clone()), - // "some_description".as_bytes().to_vec(), - // "some_link".as_bytes().to_vec(), + // b"some_description".to_vec(), + // b"some_link".to_vec(), // Some(1000000000) // ), - // Error::::InvalidProposalDuration + // Error::::InvalidProposalDuration // ); assert_noop!( @@ -794,11 +794,11 @@ fn customize_proposal_duration_out_of_bounds_fails() { RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), - "some_description".as_bytes().to_vec(), - "some_link".as_bytes().to_vec(), + b"some_description".to_vec(), + b"some_link".to_vec(), Some(1000000000) ), - Error::::InvalidProposalDuration + Error::::InvalidProposalDuration ); }); } @@ -902,7 +902,7 @@ fn prepare_big_node(account_id: u64, farm_id: u32) { } pub fn prepare_farm(account_id: u64, farm_name: Vec) { - let mut pub_ips: PublicIpListInput = bounded_vec![]; + let mut pub_ips: PublicIpListInput = bounded_vec![]; let ip = get_public_ip_ip_input(b"185.206.122.33/24"); let gw = get_public_ip_gw_input(b"185.206.122.1"); @@ -917,7 +917,7 @@ pub fn prepare_farm(account_id: u64, farm_name: Vec) { } fn create_farming_policies() { - let name = "farm_1".as_bytes().to_vec(); + let name = b"farm_1".to_vec(); assert_ok!(TfgridModule::create_farming_policy( RawOrigin::Root.into(), name, @@ -933,7 +933,7 @@ fn create_farming_policies() { FarmCertification::Gold, )); - let name = "farm2".as_bytes().to_vec(); + let name = b"farm2".to_vec(); assert_ok!(TfgridModule::create_farming_policy( RawOrigin::Root.into(), name, @@ -949,7 +949,7 @@ fn create_farming_policies() { FarmCertification::NotCertified, )); - let name = "farm3".as_bytes().to_vec(); + let name = b"farm3".to_vec(); assert_ok!(TfgridModule::create_farming_policy( RawOrigin::Root.into(), name, @@ -965,7 +965,7 @@ fn create_farming_policies() { FarmCertification::Gold, )); - let name = "farm1".as_bytes().to_vec(); + let name = b"farm1".to_vec(); assert_ok!(TfgridModule::create_farming_policy( RawOrigin::Root.into(), name, diff --git a/substrate-node/pallets/pallet-dao/src/weights.rs b/substrate-node/pallets/pallet-dao/src/weights.rs index ba5432250..a1904982e 100644 --- a/substrate-node/pallets/pallet-dao/src/weights.rs +++ b/substrate-node/pallets/pallet-dao/src/weights.rs @@ -1,96 +1,133 @@ -// This file is part of Substrate. - -// Copyright (C) 2022 Threefold Tech -// 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_dao //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2022-05-06, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Interpreted, CHAIN: Some("dev"), DB CACHE: 128 +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-16, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `R1-HP-ProBook-630-G8`, CPU: `11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: // ./target/release/tfchain // benchmark +// pallet // --chain=dev +// --pallet=pallet_dao +// --extrinsic=* // --steps=50 // --repeat=20 -// --pallet -// pallet_dao -// --extrinsic -// * -// --execution -// wasm +// --execution=wasm // --heap-pages=4096 -// --output=./pallets/pallet-dao/src/weights.rs -// --raw +// --output +// pallets/pallet-dao/src/weights.rs // --template // ./.maintain/frame-weight-template.hbs +#![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] -use frame_support::{ - traits::Get, - weights::{constants::RocksDbWeight, Weight}, -}; +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; /// Weight functions needed for pallet_dao. pub trait WeightInfo { - fn propose() -> Weight; - fn vote() -> Weight; - fn close() -> Weight; + fn propose() -> Weight; + fn vote() -> Weight; + fn veto() -> Weight; + fn close() -> Weight; } /// Weights for pallet_dao using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn propose() -> Weight { - Weight::from_ref_time(162_531_000 as u64) - .saturating_add(T::DbWeight::get().reads(4 as u64)) - .saturating_add(T::DbWeight::get().writes(5 as u64)) - } - fn vote() -> Weight { - Weight::from_ref_time(147_194_000 as u64) - .saturating_add(T::DbWeight::get().reads(5 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) - } - fn close() -> Weight { - Weight::from_ref_time(257_076_000 as u64) - .saturating_add(T::DbWeight::get().reads(3 as u64)) - .saturating_add(T::DbWeight::get().writes(4 as u64)) - } + // Storage: CouncilMembership Members (r:1 w:0) + // Storage: Dao ProposalOf (r:1 w:1) + // Storage: Dao ProposalCount (r:1 w:1) + // Storage: Dao ProposalList (r:1 w:1) + // Storage: Dao Voting (r:0 w:1) + // Storage: Dao Proposals (r:0 w:1) + fn propose() -> Weight { + // Minimum execution time: 36_945 nanoseconds. + Weight::from_ref_time(38_554_000) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(5)) + } + // Storage: TfgridModule Farms (r:1 w:0) + // Storage: TfgridModule Twins (r:1 w:0) + // Storage: Dao Proposals (r:1 w:0) + // Storage: Dao Voting (r:1 w:1) + // Storage: Dao FarmWeight (r:1 w:0) + fn vote() -> Weight { + // Minimum execution time: 47_469 nanoseconds. + Weight::from_ref_time(53_175_000) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: CouncilMembership Members (r:1 w:0) + // Storage: Dao Proposals (r:1 w:0) + // Storage: Dao Voting (r:1 w:1) + fn veto() -> Weight { + // Minimum execution time: 36_026 nanoseconds. + Weight::from_ref_time(41_143_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: CouncilMembership Members (r:1 w:0) + // Storage: Dao Voting (r:1 w:1) + // Storage: Dao ProposalList (r:1 w:1) + // Storage: Dao Proposals (r:0 w:1) + // Storage: Dao ProposalOf (r:0 w:1) + fn close() -> Weight { + // Minimum execution time: 48_673 nanoseconds. + Weight::from_ref_time(68_560_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } } // For backwards compatibility and tests impl WeightInfo for () { - fn propose() -> Weight { - Weight::from_ref_time(162_531_000 as u64) - .saturating_add(RocksDbWeight::get().reads(4 as u64)) - .saturating_add(RocksDbWeight::get().writes(5 as u64)) - } - fn vote() -> Weight { - Weight::from_ref_time(147_194_000 as u64) - .saturating_add(RocksDbWeight::get().reads(5 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) - } - fn close() -> Weight { - Weight::from_ref_time(257_076_000 as u64) - .saturating_add(RocksDbWeight::get().reads(3 as u64)) - .saturating_add(RocksDbWeight::get().writes(4 as u64)) - } + // Storage: CouncilMembership Members (r:1 w:0) + // Storage: Dao ProposalOf (r:1 w:1) + // Storage: Dao ProposalCount (r:1 w:1) + // Storage: Dao ProposalList (r:1 w:1) + // Storage: Dao Voting (r:0 w:1) + // Storage: Dao Proposals (r:0 w:1) + fn propose() -> Weight { + // Minimum execution time: 36_945 nanoseconds. + Weight::from_ref_time(38_554_000) + .saturating_add(RocksDbWeight::get().reads(4)) + .saturating_add(RocksDbWeight::get().writes(5)) + } + // Storage: TfgridModule Farms (r:1 w:0) + // Storage: TfgridModule Twins (r:1 w:0) + // Storage: Dao Proposals (r:1 w:0) + // Storage: Dao Voting (r:1 w:1) + // Storage: Dao FarmWeight (r:1 w:0) + fn vote() -> Weight { + // Minimum execution time: 47_469 nanoseconds. + Weight::from_ref_time(53_175_000) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: CouncilMembership Members (r:1 w:0) + // Storage: Dao Proposals (r:1 w:0) + // Storage: Dao Voting (r:1 w:1) + fn veto() -> Weight { + // Minimum execution time: 36_026 nanoseconds. + Weight::from_ref_time(41_143_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: CouncilMembership Members (r:1 w:0) + // Storage: Dao Voting (r:1 w:1) + // Storage: Dao ProposalList (r:1 w:1) + // Storage: Dao Proposals (r:0 w:1) + // Storage: Dao ProposalOf (r:0 w:1) + fn close() -> Weight { + // Minimum execution time: 48_673 nanoseconds. + Weight::from_ref_time(68_560_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(4)) + } } diff --git a/substrate-node/pallets/pallet-kvstore/Cargo.toml b/substrate-node/pallets/pallet-kvstore/Cargo.toml index 99a13ef12..f8d620501 100644 --- a/substrate-node/pallets/pallet-kvstore/Cargo.toml +++ b/substrate-node/pallets/pallet-kvstore/Cargo.toml @@ -25,6 +25,9 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot- sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +# Benchmarking +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } + [dev-dependencies] sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } @@ -38,8 +41,12 @@ std = [ 'sp-std/std', 'sp-storage/std', 'sp-io/std', - 'scale-info/std' + 'scale-info/std', + 'frame-benchmarking/std', +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", -] +] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-kvstore/src/benchmarking.rs b/substrate-node/pallets/pallet-kvstore/src/benchmarking.rs new file mode 100644 index 000000000..6e8edfdc6 --- /dev/null +++ b/substrate-node/pallets/pallet-kvstore/src/benchmarking.rs @@ -0,0 +1,47 @@ +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use crate::Pallet as TFKVStoreModule; +use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_support::assert_ok; +use frame_system::{EventRecord, Pallet as System, RawOrigin}; + +benchmarks! { + // set() + set { + let caller: T::AccountId = whitelisted_caller(); + let key = b"name".to_vec(); + let value = b"nametest".to_vec(); + }: _(RawOrigin::Signed(caller.clone()), key.clone(), value.clone()) + verify { + assert_eq!(TFKVStoreModule::::key_value_store(caller.clone(), key.clone()), value.clone()); + assert_last_event::(Event::EntrySet(caller, key, value).into()); + } + + // delete() + delete { + let caller: T::AccountId = whitelisted_caller(); + let key = b"Address".to_vec(); + let value = b"Cairo".to_vec(); + assert_ok!(TFKVStoreModule::::set( + RawOrigin::Signed(caller.clone()).into(), + key.clone(), + value.clone() + )); + }: _(RawOrigin::Signed(caller.clone()), key.clone()) + verify { + assert_eq!(TFKVStoreModule::::key_value_store(caller.clone(), key.clone()), b"".to_vec()); + assert_last_event::(Event::EntryTaken(caller, key, value).into()); + } + + // Calling the `impl_benchmark_test_suite` macro inside the `benchmarks` + // block will generate one #[test] function per benchmark + impl_benchmark_test_suite! (TFKVStoreModule, crate::tests::ExternalityBuilder::build(), crate::tests::TestRuntime) +} + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = System::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} diff --git a/substrate-node/pallets/pallet-kvstore/src/lib.rs b/substrate-node/pallets/pallet-kvstore/src/lib.rs index 9078eb693..64bba9435 100644 --- a/substrate-node/pallets/pallet-kvstore/src/lib.rs +++ b/substrate-node/pallets/pallet-kvstore/src/lib.rs @@ -1,13 +1,19 @@ //! A pallet for Threefold key-value store #![cfg_attr(not(feature = "std"), no_std)] +pub use pallet::*; + #[cfg(test)] mod tests; -pub use pallet::*; +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; + +pub mod weights; #[frame_support::pallet] pub mod pallet { + use super::weights::WeightInfo; use frame_support::{ensure, pallet_prelude::*, traits::IsType}; use frame_system::{ensure_signed, pallet_prelude::*}; use sp_std::convert::TryInto; @@ -21,6 +27,7 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type WeightInfo: crate::weights::WeightInfo; } #[pallet::event] @@ -58,7 +65,7 @@ pub mod pallet { impl Pallet { /// Set the value stored at a particular key #[pallet::call_index(0)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::set())] pub fn set( origin: OriginFor, key: Vec, @@ -76,7 +83,7 @@ pub mod pallet { /// Read the value stored at a particular key, while removing it from the map. /// Also emit the read value in an event #[pallet::call_index(1)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::delete())] pub fn delete(origin: OriginFor, key: Vec) -> DispatchResultWithPostInfo { // A user can only take (delete) their own entry let user = ensure_signed(origin)?; @@ -90,4 +97,4 @@ pub mod pallet { Ok(().into()) } } -} \ No newline at end of file +} diff --git a/substrate-node/pallets/pallet-kvstore/src/tests.rs b/substrate-node/pallets/pallet-kvstore/src/tests.rs index 40cf1780e..8f12d1e95 100644 --- a/substrate-node/pallets/pallet-kvstore/src/tests.rs +++ b/substrate-node/pallets/pallet-kvstore/src/tests.rs @@ -1,4 +1,5 @@ use super::Event as KvStoreEvent; +use super::*; use crate::{self as pallet_kvstore, Config}; use frame_support::{assert_ok, construct_runtime, parameter_types, traits::ConstU32}; use frame_system::{EventRecord, Phase}; @@ -55,11 +56,13 @@ impl frame_system::Config for TestRuntime { type MaxConsumers = ConstU32<16>; } +use weights; impl Config for TestRuntime { type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::SubstrateWeight; } -struct ExternalityBuilder; +pub struct ExternalityBuilder; impl ExternalityBuilder { pub fn build() -> TestExternalities { @@ -75,13 +78,13 @@ impl ExternalityBuilder { #[test] fn test_set_and_get() { ExternalityBuilder::build().execute_with(|| { - let key = "name"; - let value = "nametest"; + let key = b"name".to_vec(); + let value = b"nametest".to_vec(); // make sure Entry does not exists assert_ok!(TFKVStoreModule::set( RuntimeOrigin::signed(1), - key.as_bytes().to_vec(), - value.as_bytes().to_vec() + key.clone(), + value.clone() )); let our_events = System::events(); @@ -91,26 +94,26 @@ fn test_set_and_get() { TestRuntime, >::EntrySet( 1, - key.as_bytes().to_vec(), - value.as_bytes().to_vec(), + key.clone(), + value.clone(), )))), true ); - let entry_value = TFKVStoreModule::key_value_store(1, key.as_bytes().to_vec()); - assert_eq!(entry_value, value.as_bytes().to_vec()); + let entry_value = TFKVStoreModule::key_value_store(1, key); + assert_eq!(entry_value, value); }) } #[test] fn test_delete() { ExternalityBuilder::build().execute_with(|| { - let key = "Address"; - let value = "Cairo"; + let key = b"Address".to_vec(); + let value = b"Cairo".to_vec(); assert_ok!(TFKVStoreModule::set( RuntimeOrigin::signed(1), - key.as_bytes().to_vec(), - value.as_bytes().to_vec() + key.clone(), + value.clone() )); let our_events = System::events(); @@ -120,15 +123,15 @@ fn test_delete() { TestRuntime, >::EntrySet( 1, - key.as_bytes().to_vec(), - value.as_bytes().to_vec(), + key.clone(), + value.clone(), )))), true ); assert_ok!(TFKVStoreModule::delete( RuntimeOrigin::signed(1), - key.as_bytes().to_vec() + key.clone() )); let our_events = System::events(); @@ -138,15 +141,15 @@ fn test_delete() { TestRuntime, >::EntryTaken( 1, - key.as_bytes().to_vec(), - value.as_bytes().to_vec(), + key.clone(), + value.clone(), )))), true ); // check if value get deleted - let entry_value = TFKVStoreModule::key_value_store(1, key.as_bytes().to_vec()); - let expected_value = "".as_bytes().to_vec(); + let entry_value = TFKVStoreModule::key_value_store(1, key); + let expected_value = b"".to_vec(); assert_eq!(entry_value, expected_value); }) } diff --git a/substrate-node/pallets/pallet-kvstore/src/weights.rs b/substrate-node/pallets/pallet-kvstore/src/weights.rs new file mode 100644 index 000000000..935a67489 --- /dev/null +++ b/substrate-node/pallets/pallet-kvstore/src/weights.rs @@ -0,0 +1,71 @@ + +//! Autogenerated weights for pallet_kvstore +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-16, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `R1-HP-ProBook-630-G8`, CPU: `11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/tfchain +// benchmark +// pallet +// --chain=dev +// --pallet=pallet_kvstore +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --execution=wasm +// --heap-pages=4096 +// --output +// pallets/pallet-kvstore/src/weights.rs +// --template +// ./.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![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_kvstore. +pub trait WeightInfo { + fn set() -> Weight; + fn delete() -> Weight; +} + +/// Weights for pallet_kvstore using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: TFKVStore TFKVStore (r:0 w:1) + fn set() -> Weight { + // Minimum execution time: 29_881 nanoseconds. + Weight::from_ref_time(30_479_000) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: TFKVStore TFKVStore (r:1 w:1) + fn delete() -> Weight { + // Minimum execution time: 33_783 nanoseconds. + Weight::from_ref_time(34_581_000) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: TFKVStore TFKVStore (r:0 w:1) + fn set() -> Weight { + // Minimum execution time: 29_881 nanoseconds. + Weight::from_ref_time(30_479_000) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: TFKVStore TFKVStore (r:1 w:1) + fn delete() -> Weight { + // Minimum execution time: 33_783 nanoseconds. + Weight::from_ref_time(34_581_000) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } +} diff --git a/substrate-node/pallets/pallet-runtime-upgrade/src/lib.rs b/substrate-node/pallets/pallet-runtime-upgrade/src/lib.rs index 26677f84d..2c99a4d72 100644 --- a/substrate-node/pallets/pallet-runtime-upgrade/src/lib.rs +++ b/substrate-node/pallets/pallet-runtime-upgrade/src/lib.rs @@ -22,11 +22,12 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight(100_000_000)] + // Give same weight as set_code() wrapped extrinsic from frame_system + #[pallet::weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] pub fn set_code(origin: OriginFor, code: Vec) -> DispatchResultWithPostInfo { T::SetCodeOrigin::ensure_origin(origin)?; frame_system::Pallet::::set_code(frame_system::RawOrigin::Root.into(), code)?; Ok(Pays::No.into()) } } -} \ No newline at end of file +} diff --git a/substrate-node/pallets/pallet-smart-contract/src/mock.rs b/substrate-node/pallets/pallet-smart-contract/src/mock.rs index aa281649a..1a7cc849e 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/mock.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/mock.rs @@ -342,6 +342,7 @@ impl substrate_validator_set::Config for TestRuntime { type AddRemoveOrigin = EnsureRoot; type RuntimeEvent = RuntimeEvent; type MinAuthorities = MinAuthorities; + type WeightInfo = substrate_validator_set::weights::SubstrateWeight; } impl pallet_session::Config for TestRuntime { diff --git a/substrate-node/pallets/pallet-tft-price/src/mock.rs b/substrate-node/pallets/pallet-tft-price/src/mock.rs index 130f3bf55..ef4aa375c 100644 --- a/substrate-node/pallets/pallet-tft-price/src/mock.rs +++ b/substrate-node/pallets/pallet-tft-price/src/mock.rs @@ -190,6 +190,7 @@ impl substrate_validator_set::Config for TestRuntime { type AddRemoveOrigin = EnsureRoot; type RuntimeEvent = RuntimeEvent; type MinAuthorities = MinAuthorities; + type WeightInfo = substrate_validator_set::weights::SubstrateWeight; } impl pallet_session::Config for TestRuntime { diff --git a/substrate-node/pallets/pallet-validator/Cargo.toml b/substrate-node/pallets/pallet-validator/Cargo.toml index acf69b6cb..cd9065dc9 100644 --- a/substrate-node/pallets/pallet-validator/Cargo.toml +++ b/substrate-node/pallets/pallet-validator/Cargo.toml @@ -19,6 +19,9 @@ pallet-collective = { git = "https://github.com/paritytech/substrate", branch = pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +# Benchmarking +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } + [dev-dependencies] sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } @@ -34,6 +37,7 @@ std = [ 'sp-runtime/std', 'frame-support/std', 'frame-system/std', + 'frame-benchmarking/std', 'substrate-validator-set/std', 'pallet-membership/std', 'pallet-collective/std', @@ -41,6 +45,9 @@ std = [ 'sp-io/std', 'scale-info/std' ] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", +] try-runtime = [ "frame-support/try-runtime", ] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-validator/src/benchmarking.rs b/substrate-node/pallets/pallet-validator/src/benchmarking.rs new file mode 100644 index 000000000..9720a4b61 --- /dev/null +++ b/substrate-node/pallets/pallet-validator/src/benchmarking.rs @@ -0,0 +1,175 @@ +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use crate::Pallet as ValidatorModule; +use frame_benchmarking::{account, benchmarks, whitelisted_caller}; +use frame_support::assert_ok; +use frame_system::{EventRecord, Pallet as System, RawOrigin}; +use pallet_membership::Pallet as CouncilMembership; + +benchmarks! { + // create_validator_request() + create_validator_request { + let caller: T::AccountId = whitelisted_caller(); + let validator_node_account: T::AccountId = account("Alice", 0, 0); + let stash_account: T::AccountId = account("Bob", 0, 1); + let description = b"description".to_vec(); + let tf_connect_id = b"tf_connect_id".to_vec(); + let info = b"validator_candidate_info".to_vec(); + }: _( + RawOrigin::Signed(caller.clone()), + validator_node_account.clone(), + stash_account.clone(), + description.clone(), + tf_connect_id.clone(), + info.clone() + ) + verify { + let validator_created = _get_validator::(types::ValidatorRequestState::Created); + assert_eq!( + ValidatorModule::::validator_requests(caller.clone()), + Some(validator_created.clone()), + ); + assert_last_event::(Event::ValidatorRequestCreated(caller, validator_created).into()); + } + + // activate_validator_node() + activate_validator_node { + _create_validator_and_approve::(); + let caller: T::AccountId = whitelisted_caller(); + }: _(RawOrigin::Signed(caller.clone())) + verify { + let validator_validating = _get_validator::(types::ValidatorRequestState::Validating); + assert_eq!( + ValidatorModule::::validator_requests(caller), + Some(validator_validating.clone()), + ); + assert_last_event::(Event::ValidatorActivated(validator_validating).into()); + } + + // change_validator_node_account() + change_validator_node_account { + _create_validator_and_start_validating::(); + let caller: T::AccountId = whitelisted_caller(); + let validator_node_account: T::AccountId = account("Ferdie", 0, 2); + }: _(RawOrigin::Signed(caller.clone()), validator_node_account.clone()) + verify { + let mut validator_validating = _get_validator::(crate::types::ValidatorRequestState::Validating); + validator_validating.validator_node_account = validator_node_account.clone(); + assert_eq!( + ValidatorModule::::validator_requests(caller), + Some(validator_validating), + ); + assert_last_event::(Event::NodeValidatorChanged(validator_node_account).into()); + } + + // bond() + bond { + let caller: T::AccountId = whitelisted_caller(); + let caller_lookup = T::Lookup::unlookup(caller.clone()); + let stash: T::AccountId = account("Bob", 0, 1); + }: _(RawOrigin::Signed(stash.clone()), caller_lookup) + verify { + assert_eq!( + ValidatorModule::::bonded(stash.clone()), + Some(caller), + ); + assert_last_event::(Event::Bonded(stash).into()); + } + + // approve_validator() + approve_validator { + _create_validator::(); + let caller: T::AccountId = whitelisted_caller(); + let caller_lookup = T::Lookup::unlookup(caller.clone()); + + let council_members = CouncilMembership::::members(); + assert!(council_members.len() > 0); + let council_member = council_members.into_iter().next().unwrap(); + }: _(RawOrigin::Signed(council_member.clone()), caller_lookup) + verify { + let validator_approved = _get_validator::(types::ValidatorRequestState::Approved); + assert_eq!( + ValidatorModule::::validator_requests(caller.clone()), + Some(validator_approved.clone()), + ); + assert!(CouncilMembership::::members().contains(&caller)); + assert_last_event::(Event::ValidatorRequestApproved(validator_approved).into()); + } + + // remove_validator() + remove_validator { + _create_validator_and_approve::(); + let caller: T::AccountId = whitelisted_caller(); + let caller_lookup = T::Lookup::unlookup(caller.clone()); + + let council_members = CouncilMembership::::members(); + assert!(council_members.len() > 0); + let council_member = council_members.into_iter().next().unwrap(); + }: _(RawOrigin::Signed(council_member.clone()), caller_lookup.clone()) + verify { + assert!(ValidatorModule::::validator_requests(caller.clone()).is_none()); + assert!(!CouncilMembership::::members().contains(&caller)); + } + + // Calling the `impl_benchmark_test_suite` macro inside the `benchmarks` + // block will generate one #[test] function per benchmark + impl_benchmark_test_suite! (ValidatorModule, crate::mock::new_test_ext(), crate::mock::TestRuntime) +} + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = System::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +fn _get_validator( + state: crate::types::ValidatorRequestState, +) -> crate::types::Validator { + crate::types::Validator { + validator_node_account: account("Alice", 0, 0), + stash_account: account("Bob", 0, 1), + description: b"description".to_vec(), + tf_connect_id: b"tf_connect_id".to_vec(), + info: b"validator_candidate_info".to_vec(), + state, + } +} + +fn _create_validator() { + assert_ok!(ValidatorModule::::create_validator_request( + RawOrigin::Signed(whitelisted_caller()).into(), + account("Alice", 0, 0), + account("Bob", 0, 1), + b"description".to_vec(), + b"tf_connect_id".to_vec(), + b"validator_candidate_info".to_vec(), + )); +} + +fn _create_validator_and_approve() { + _create_validator::(); + + let caller: T::AccountId = whitelisted_caller(); + let caller_lookup = T::Lookup::unlookup(caller.clone()); + + let council_members = CouncilMembership::::members(); + assert!(council_members.len() > 0); + let council_member = council_members.into_iter().next().unwrap(); + + assert_ok!(ValidatorModule::::approve_validator( + RawOrigin::Signed(council_member).into(), + caller_lookup, + )); +} + +fn _create_validator_and_start_validating() { + _create_validator_and_approve::(); + + let caller: T::AccountId = whitelisted_caller(); + + assert_ok!(ValidatorModule::::activate_validator_node( + RawOrigin::Signed(caller).into(), + )); +} diff --git a/substrate-node/pallets/pallet-validator/src/lib.rs b/substrate-node/pallets/pallet-validator/src/lib.rs index 45d8bbbda..67a0e677a 100644 --- a/substrate-node/pallets/pallet-validator/src/lib.rs +++ b/substrate-node/pallets/pallet-validator/src/lib.rs @@ -22,8 +22,14 @@ mod tests; #[cfg(test)] mod mock; +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; + +pub mod weights; + #[frame_support::pallet] pub mod pallet { + use super::weights::WeightInfo; use super::*; use frame_system::pallet_prelude::*; pub type BalanceOf = @@ -39,6 +45,7 @@ pub mod pallet { type RuntimeEvent: From> + IsType<::RuntimeEvent>; type Currency: Currency; type CouncilOrigin: EnsureOrigin; + type WeightInfo: crate::weights::WeightInfo; } #[pallet::pallet] @@ -116,7 +123,7 @@ pub mod pallet { /// Info: some public info about the validator (website link, blog link, ..) /// A user can only have 1 validator request at a time #[pallet::call_index(0)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::create_validator_request())] pub fn create_validator_request( origin: OriginFor, validator_node_account: T::AccountId, @@ -155,7 +162,7 @@ pub mod pallet { /// A user can only call this if his request to be a validator is approved by the council /// Should be called when his node is synced and ready to start validating #[pallet::call_index(1)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::activate_validator_node())] pub fn activate_validator_node(origin: OriginFor) -> DispatchResultWithPostInfo { let address = ensure_signed(origin)?; @@ -191,7 +198,7 @@ pub mod pallet { /// he can call this method with the new node validator account /// this new account will be added as a new consensus validator if he is validating already #[pallet::call_index(2)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::change_validator_node_account())] pub fn change_validator_node_account( origin: OriginFor, new_node_validator_account: T::AccountId, @@ -232,7 +239,7 @@ pub mod pallet { /// Bond an account to a validator account /// Just proves that the stash account is indeed under control of the validator account #[pallet::call_index(3)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::bond())] pub fn bond( origin: OriginFor, validator: ::Source, @@ -256,7 +263,7 @@ pub mod pallet { /// Approves a validator to be added as a council member and /// to participate in consensus #[pallet::call_index(4)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::approve_validator())] pub fn approve_validator( origin: OriginFor, validator_account: ::Source, @@ -291,7 +298,7 @@ pub mod pallet { /// 3. Consensus /// Can only be called by the user or the council #[pallet::call_index(5)] - #[pallet::weight(100_000_000)] + #[pallet::weight(::WeightInfo::remove_validator())] pub fn remove_validator( origin: OriginFor, validator_account: ::Source, diff --git a/substrate-node/pallets/pallet-validator/src/mock.rs b/substrate-node/pallets/pallet-validator/src/mock.rs index 8a6cc087b..5c5417bb7 100644 --- a/substrate-node/pallets/pallet-validator/src/mock.rs +++ b/substrate-node/pallets/pallet-validator/src/mock.rs @@ -31,10 +31,12 @@ construct_runtime!( } ); +use weights; impl pallet_validator::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type CouncilOrigin = EnsureRoot; type Currency = (); + type WeightInfo = weights::SubstrateWeight; } parameter_types! { @@ -76,6 +78,7 @@ impl substrate_validator_set::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type AddRemoveOrigin = EnsureRoot; type MinAuthorities = MinAuthorities; + type WeightInfo = substrate_validator_set::weights::SubstrateWeight; } thread_local! { diff --git a/substrate-node/pallets/pallet-validator/src/weights.rs b/substrate-node/pallets/pallet-validator/src/weights.rs new file mode 100644 index 000000000..1a7ca776e --- /dev/null +++ b/substrate-node/pallets/pallet-validator/src/weights.rs @@ -0,0 +1,159 @@ + +//! Autogenerated weights for pallet_validator +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-17, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `R1-HP-ProBook-630-G8`, CPU: `11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/tfchain +// benchmark +// pallet +// --chain=dev +// --pallet=pallet_validator +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --execution=wasm +// --heap-pages=4096 +// --output +// pallets/pallet-validator/src/weights.rs +// --template +// ./.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![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_validator. +pub trait WeightInfo { + fn create_validator_request() -> Weight; + fn activate_validator_node() -> Weight; + fn change_validator_node_account() -> Weight; + fn bond() -> Weight; + fn approve_validator() -> Weight; + fn remove_validator() -> Weight; +} + +/// Weights for pallet_validator using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: Validator Validator (r:1 w:1) + fn create_validator_request() -> Weight { + // Minimum execution time: 23_331 nanoseconds. + Weight::from_ref_time(25_562_000) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: Validator Validator (r:1 w:1) + // Storage: ValidatorSet Validators (r:1 w:1) + // Storage: ValidatorSet ApprovedValidators (r:1 w:1) + fn activate_validator_node() -> Weight { + // Minimum execution time: 42_958 nanoseconds. + Weight::from_ref_time(44_151_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: Validator Validator (r:1 w:1) + // Storage: ValidatorSet Validators (r:1 w:1) + // Storage: ValidatorSet ApprovedValidators (r:1 w:1) + fn change_validator_node_account() -> Weight { + // Minimum execution time: 56_451 nanoseconds. + Weight::from_ref_time(63_248_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + // Storage: Validator Bonded (r:1 w:1) + fn bond() -> Weight { + // Minimum execution time: 20_742 nanoseconds. + Weight::from_ref_time(23_165_000) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: CouncilMembership Members (r:1 w:1) + // Storage: Validator Validator (r:1 w:1) + // Storage: Council Proposals (r:1 w:0) + // Storage: Council Members (r:0 w:1) + // Storage: Council Prime (r:0 w:1) + fn approve_validator() -> Weight { + // Minimum execution time: 48_121 nanoseconds. + Weight::from_ref_time(50_967_000) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(4)) + } + // Storage: CouncilMembership Members (r:1 w:1) + // Storage: Validator Validator (r:1 w:1) + // Storage: Council Proposals (r:1 w:0) + // Storage: CouncilMembership Prime (r:1 w:0) + // Storage: Council Members (r:0 w:1) + // Storage: Council Prime (r:0 w:1) + fn remove_validator() -> Weight { + // Minimum execution time: 39_847 nanoseconds. + Weight::from_ref_time(41_288_000) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: Validator Validator (r:1 w:1) + fn create_validator_request() -> Weight { + // Minimum execution time: 23_331 nanoseconds. + Weight::from_ref_time(25_562_000) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: Validator Validator (r:1 w:1) + // Storage: ValidatorSet Validators (r:1 w:1) + // Storage: ValidatorSet ApprovedValidators (r:1 w:1) + fn activate_validator_node() -> Weight { + // Minimum execution time: 42_958 nanoseconds. + Weight::from_ref_time(44_151_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) + } + // Storage: Validator Validator (r:1 w:1) + // Storage: ValidatorSet Validators (r:1 w:1) + // Storage: ValidatorSet ApprovedValidators (r:1 w:1) + fn change_validator_node_account() -> Weight { + // Minimum execution time: 56_451 nanoseconds. + Weight::from_ref_time(63_248_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) + } + // Storage: Validator Bonded (r:1 w:1) + fn bond() -> Weight { + // Minimum execution time: 20_742 nanoseconds. + Weight::from_ref_time(23_165_000) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: CouncilMembership Members (r:1 w:1) + // Storage: Validator Validator (r:1 w:1) + // Storage: Council Proposals (r:1 w:0) + // Storage: Council Members (r:0 w:1) + // Storage: Council Prime (r:0 w:1) + fn approve_validator() -> Weight { + // Minimum execution time: 48_121 nanoseconds. + Weight::from_ref_time(50_967_000) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + // Storage: CouncilMembership Members (r:1 w:1) + // Storage: Validator Validator (r:1 w:1) + // Storage: Council Proposals (r:1 w:0) + // Storage: CouncilMembership Prime (r:1 w:0) + // Storage: Council Members (r:0 w:1) + // Storage: Council Prime (r:0 w:1) + fn remove_validator() -> Weight { + // Minimum execution time: 39_847 nanoseconds. + Weight::from_ref_time(41_288_000) + .saturating_add(RocksDbWeight::get().reads(4)) + .saturating_add(RocksDbWeight::get().writes(4)) + } +} diff --git a/substrate-node/pallets/substrate-validator-set/Cargo.toml b/substrate-node/pallets/substrate-validator-set/Cargo.toml index 90a2ff467..fcb247d5b 100644 --- a/substrate-node/pallets/substrate-validator-set/Cargo.toml +++ b/substrate-node/pallets/substrate-validator-set/Cargo.toml @@ -21,6 +21,9 @@ frame-system = { git = "https://github.com/paritytech/substrate", branch = "pol pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +# Benchmarking +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } + [dependencies.log] default-features = false version = '0.4.14' @@ -35,6 +38,7 @@ std = [ 'sp-std/std', 'sp-runtime/std', 'frame-support/std', + 'frame-benchmarking/std', 'sp-staking/std', 'serde', 'frame-system/std', @@ -43,6 +47,9 @@ std = [ 'scale-info/std', 'log/std' ] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", +] try-runtime = [ "frame-support/try-runtime", ] \ No newline at end of file diff --git a/substrate-node/pallets/substrate-validator-set/src/benchmarking.rs b/substrate-node/pallets/substrate-validator-set/src/benchmarking.rs new file mode 100644 index 000000000..f3cfa9fa3 --- /dev/null +++ b/substrate-node/pallets/substrate-validator-set/src/benchmarking.rs @@ -0,0 +1,73 @@ +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use crate::Pallet as ValidatorSet; +use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_support::assert_ok; +use frame_system::{EventRecord, Pallet as System, RawOrigin}; + +benchmarks! { + // add_validator() + add_validator { + let mut validators = ValidatorSet::::validators(); + let caller: T::AccountId = whitelisted_caller(); + }: _(RawOrigin::Root, caller.clone()) + verify { + validators.push(caller.clone()); + assert_eq!( + ValidatorSet::::validators(), + validators + ); + assert_last_event::(Event::ValidatorAdditionInitiated(caller).into()); + } + + // remove_validator() + remove_validator { + let validators = ValidatorSet::::validators(); + let caller: T::AccountId = whitelisted_caller(); + assert_ok!(ValidatorSet::::add_validator( + RawOrigin::Root.into(), + caller.clone(), + )); + }: _(RawOrigin::Root, caller.clone()) + verify { + assert_eq!( + ValidatorSet::::validators(), + validators + ); + assert_last_event::(Event::ValidatorRemovalInitiated(caller).into()); + } + + // add_validator_again() + add_validator_again { + let mut validators = ValidatorSet::::validators(); + let caller: T::AccountId = whitelisted_caller(); + assert_ok!(ValidatorSet::::add_validator( + RawOrigin::Root.into(), + caller.clone(), + )); + assert_ok!(ValidatorSet::::remove_validator( + RawOrigin::Root.into(), + caller.clone(), + )); + }: _(RawOrigin::Signed(caller.clone()), caller.clone()) + verify { + validators.push(caller.clone()); + assert_eq!( + ValidatorSet::::validators(), + validators + ); + assert_last_event::(Event::ValidatorAdditionInitiated(caller).into()); + } + + // Calling the `impl_benchmark_test_suite` macro inside the `benchmarks` + // block will generate one #[test] function per benchmark + impl_benchmark_test_suite! (ValidatorSet, crate::mock::new_test_ext(), crate::mock::TestRuntime) +} + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = System::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} diff --git a/substrate-node/pallets/substrate-validator-set/src/lib.rs b/substrate-node/pallets/substrate-validator-set/src/lib.rs index b828820ba..595bb0ecc 100644 --- a/substrate-node/pallets/substrate-validator-set/src/lib.rs +++ b/substrate-node/pallets/substrate-validator-set/src/lib.rs @@ -13,9 +13,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -mod mock; -mod tests; - use frame_support::{ ensure, pallet_prelude::*, @@ -28,10 +25,19 @@ use sp_staking::offence::{Offence, OffenceError, ReportOffence}; use sp_std::convert::TryInto; use sp_std::{collections::btree_set::BTreeSet, prelude::*}; +mod mock; +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; + +pub mod weights; + pub const LOG_TARGET: &'static str = "runtime::validator-set"; #[frame_support::pallet] pub mod pallet { + use super::weights::WeightInfo; use super::*; use frame_system::pallet_prelude::*; @@ -48,6 +54,8 @@ pub mod pallet { /// Minimum number of validators to leave in the validator set during /// auto removal. type MinAuthorities: Get; + + type WeightInfo: crate::weights::WeightInfo; } #[pallet::pallet] @@ -124,7 +132,7 @@ pub mod pallet { /// The origin can be configured using the `AddRemoveOrigin` type in the /// host runtime. Can also be set to sudo/root. #[pallet::call_index(0)] - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::add_validator())] pub fn add_validator(origin: OriginFor, validator_id: T::AccountId) -> DispatchResult { T::AddRemoveOrigin::ensure_origin(origin)?; @@ -139,7 +147,7 @@ pub mod pallet { /// The origin can be configured using the `AddRemoveOrigin` type in the /// host runtime. Can also be set to sudo/root. #[pallet::call_index(1)] - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::remove_validator())] pub fn remove_validator( origin: OriginFor, validator_id: T::AccountId, @@ -156,7 +164,7 @@ pub mod pallet { /// /// For this call, the dispatch origin must be the validator itself. #[pallet::call_index(2)] - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::add_validator_again())] pub fn add_validator_again( origin: OriginFor, validator_id: T::AccountId, diff --git a/substrate-node/pallets/substrate-validator-set/src/mock.rs b/substrate-node/pallets/substrate-validator-set/src/mock.rs index 3d97ec74d..1e115ea07 100644 --- a/substrate-node/pallets/substrate-validator-set/src/mock.rs +++ b/substrate-node/pallets/substrate-validator-set/src/mock.rs @@ -54,11 +54,11 @@ impl OpaqueKeys for PreUpgradeMockSessionKeys { } } -type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub enum Test where + pub enum TestRuntime where Block = Block, NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic, @@ -125,7 +125,7 @@ pub fn authorities() -> Vec { pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default() - .build_storage::() + .build_storage::() .unwrap(); let keys: Vec<_> = NEXT_VALIDATORS.with(|l| { l.borrow() @@ -136,17 +136,17 @@ pub fn new_test_ext() -> sp_io::TestExternalities { }); BasicExternalities::execute_with_storage(&mut t, || { for (ref k, ..) in &keys { - frame_system::Pallet::::inc_providers(k); + frame_system::Pallet::::inc_providers(k); } - frame_system::Pallet::::inc_providers(&4); - frame_system::Pallet::::inc_providers(&69); + frame_system::Pallet::::inc_providers(&4); + frame_system::Pallet::::inc_providers(&69); }); - validator_set::GenesisConfig:: { + validator_set::GenesisConfig:: { initial_validators: keys.iter().map(|x| x.0).collect::>(), } .assimilate_storage(&mut t) .unwrap(); - pallet_session::GenesisConfig:: { keys: keys.clone() } + pallet_session::GenesisConfig:: { keys: keys.clone() } .assimilate_storage(&mut t) .unwrap(); sp_io::TestExternalities::new(t) @@ -157,7 +157,7 @@ parameter_types! { pub const BlockHashCount: u64 = 250; } -impl frame_system::Config for Test { +impl frame_system::Config for TestRuntime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); @@ -188,13 +188,15 @@ parameter_types! { pub const MinAuthorities: u32 = 2; } -impl validator_set::Config for Test { +use validator_set::weights; +impl validator_set::Config for TestRuntime { type AddRemoveOrigin = EnsureRoot; type RuntimeEvent = RuntimeEvent; type MinAuthorities = MinAuthorities; + type WeightInfo = weights::SubstrateWeight; } -impl pallet_session::Config for Test { +impl pallet_session::Config for TestRuntime { type ValidatorId = ::AccountId; type ValidatorIdOf = validator_set::ValidatorOf; type ShouldEndSession = TestShouldEndSession; diff --git a/substrate-node/pallets/substrate-validator-set/src/tests.rs b/substrate-node/pallets/substrate-validator-set/src/tests.rs index 76f205c21..d5eb37188 100644 --- a/substrate-node/pallets/substrate-validator-set/src/tests.rs +++ b/substrate-node/pallets/substrate-validator-set/src/tests.rs @@ -4,8 +4,8 @@ use super::*; use crate::mock::*; -use crate::mock::{authorities, new_test_ext, Session, Test, ValidatorSet}; -use frame_support::{assert_noop, assert_ok, pallet_prelude::*}; +use crate::mock::{authorities, new_test_ext, Session, TestRuntime, ValidatorSet}; +use frame_support::{assert_noop, assert_ok}; use frame_system::RawOrigin; use sp_runtime::testing::UintAuthorityId; @@ -64,7 +64,7 @@ fn duplicate_check() { assert_eq!(ValidatorSet::validators(), vec![1u64, 2u64, 3u64, 4u64]); assert_noop!( ValidatorSet::add_validator(RawOrigin::Root.into(), 4), - Error::::Duplicate + Error::::Duplicate ); }); } diff --git a/substrate-node/pallets/substrate-validator-set/src/weights.rs b/substrate-node/pallets/substrate-validator-set/src/weights.rs new file mode 100644 index 000000000..7c0c720d7 --- /dev/null +++ b/substrate-node/pallets/substrate-validator-set/src/weights.rs @@ -0,0 +1,94 @@ + +//! Autogenerated weights for validatorset +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-17, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! HOSTNAME: `R1-HP-ProBook-630-G8`, CPU: `11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/tfchain +// benchmark +// pallet +// --chain=dev +// --pallet=validatorset +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --execution=wasm +// --heap-pages=4096 +// --output +// pallets/substrate-validator-set/src/weights.rs +// --template +// ./.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for validatorset. +pub trait WeightInfo { + fn add_validator() -> Weight; + fn remove_validator() -> Weight; + fn add_validator_again() -> Weight; +} + +/// Weights for validatorset using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: ValidatorSet Validators (r:1 w:1) + // Storage: ValidatorSet ApprovedValidators (r:1 w:1) + fn add_validator() -> Weight { + // Minimum execution time: 40_423 nanoseconds. + Weight::from_ref_time(44_665_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + // Storage: ValidatorSet Validators (r:1 w:1) + // Storage: ValidatorSet ApprovedValidators (r:1 w:0) + fn remove_validator() -> Weight { + // Minimum execution time: 32_687 nanoseconds. + Weight::from_ref_time(33_450_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + // Storage: ValidatorSet ApprovedValidators (r:1 w:0) + // Storage: ValidatorSet Validators (r:1 w:1) + fn add_validator_again() -> Weight { + // Minimum execution time: 38_498 nanoseconds. + Weight::from_ref_time(39_292_000) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: ValidatorSet Validators (r:1 w:1) + // Storage: ValidatorSet ApprovedValidators (r:1 w:1) + fn add_validator() -> Weight { + // Minimum execution time: 40_423 nanoseconds. + Weight::from_ref_time(44_665_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(2)) + } + // Storage: ValidatorSet Validators (r:1 w:1) + // Storage: ValidatorSet ApprovedValidators (r:1 w:0) + fn remove_validator() -> Weight { + // Minimum execution time: 32_687 nanoseconds. + Weight::from_ref_time(33_450_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + // Storage: ValidatorSet ApprovedValidators (r:1 w:0) + // Storage: ValidatorSet Validators (r:1 w:1) + fn add_validator_again() -> Weight { + // Minimum execution time: 38_498 nanoseconds. + Weight::from_ref_time(39_292_000) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } +} diff --git a/substrate-node/runtime/Cargo.toml b/substrate-node/runtime/Cargo.toml index 59d686921..76dc33211 100644 --- a/substrate-node/runtime/Cargo.toml +++ b/substrate-node/runtime/Cargo.toml @@ -122,6 +122,11 @@ runtime-benchmarks = [ 'pallet-collective/runtime-benchmarks', 'pallet-smart-contract/runtime-benchmarks', 'pallet-tft-price/runtime-benchmarks', + 'pallet-burning/runtime-benchmarks', + 'pallet-dao/runtime-benchmarks', + 'pallet-kvstore/runtime-benchmarks', + 'validatorset/runtime-benchmarks', + 'pallet-validator/runtime-benchmarks', ] try-runtime = [ "frame-executive/try-runtime", diff --git a/substrate-node/runtime/src/lib.rs b/substrate-node/runtime/src/lib.rs index 4ae4b4dfb..a4ea0c6b3 100644 --- a/substrate-node/runtime/src/lib.rs +++ b/substrate-node/runtime/src/lib.rs @@ -421,10 +421,12 @@ impl pallet_burning::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type Burn = (); + type WeightInfo = pallet_burning::weights::SubstrateWeight; } impl pallet_kvstore::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_kvstore::weights::SubstrateWeight; } impl pallet_tft_price::Config for Runtime { @@ -439,6 +441,7 @@ impl pallet_validator::Config for Runtime { type RuntimeEvent = RuntimeEvent; type CouncilOrigin = EnsureRootOrCouncilApproval; type Currency = Balances; + type WeightInfo = pallet_validator::weights::SubstrateWeight; } parameter_types! { @@ -449,6 +452,7 @@ impl validatorset::Config for Runtime { type RuntimeEvent = RuntimeEvent; type AddRemoveOrigin = EnsureRootOrCouncilApproval; type MinAuthorities = MinAuthorities; + type WeightInfo = validatorset::weights::SubstrateWeight; } parameter_types! { @@ -779,6 +783,11 @@ mod benches { define_benchmarks!( [pallet_smart_contract, SmartContractModule] [pallet_tft_price, TFTPriceModule] + [pallet_burning, BurningModule] + [pallet_dao, Dao] + [pallet_kvstore, TFKVStore] + [validatorset, ValidatorSet] + [pallet_validator, Validator] // Substrate [frame_benchmarking::baseline, Baseline::] [frame_system, SystemBench::]