mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 05:51:02 +00:00
Abstracts elections-phragmen pallet to use NposSolver (#12588)
* Abstracts elections-phragmen pallet to use NposSolver * Update frame/elections-phragmen/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/elections-phragmen/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * changes the name of the pallet; adds changelog * update changelog * Adds weight testing * Adds log macro_rules * renames elections-phragment dir to elections * weights rename * fixes typo in cargo toml * pre/post solve weight scafolding * refactor do_post_election * refactors into pre and post election solve for independent benchmarking * deconstructs PreElectionResults struct * updates benchmarking pre and post election solve; mock weights * Update frame/elections/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/elections/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * addresses PR comments * adds pre_solve and post_sove weights * Adds comments on election pallet id param name change * ".git/.scripts/bench-bot.sh" pallet dev pallet_elections * Finishes pre-post solve weights * Update frame/elections/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/elections/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Addresses PR comments: no panic in on_init path; nits * Fixes node build * Implements approval voting to use as a `NposSolver` (#13367) * Implements the approval voting methods in sp_npos_elections * fmt * remove unecessary file * comment clarification * re-run weights * fix typo * updates MaxVoters in tests for integrity_tests to pass * Refactors election provider support benchmarks outside its own crate (#13431) * Refactors election provider support benchmarks outside its own crate --------- Co-authored-by: command-bot <> --------- Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: parity-processbot <> Co-authored-by: Ross Bulat <ross@parity.io>
This commit is contained in:
@@ -33,7 +33,6 @@ frame-election-provider-support = { version = "4.0.0-dev", default-features = fa
|
||||
|
||||
# Optional imports for benchmarking
|
||||
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true }
|
||||
pallet-election-provider-support-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../election-provider-support/benchmarking", optional = true }
|
||||
rand = { version = "0.8.5", default-features = false, features = ["alloc", "small_rng"], optional = true }
|
||||
strum = { version = "0.24.1", default-features = false, features = ["derive"], optional = true }
|
||||
|
||||
@@ -50,7 +49,6 @@ frame-benchmarking = { version = "4.0.0-dev", path = "../benchmarking" }
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"pallet-election-provider-support-benchmarking?/std",
|
||||
"codec/std",
|
||||
"scale-info/std",
|
||||
"log/std",
|
||||
|
||||
@@ -23,6 +23,8 @@ sp-runtime = { version = "7.0.0", default-features = false, path = "../../primit
|
||||
sp-std = { version = "5.0.0", default-features = false, path = "../../primitives/std" }
|
||||
sp-core = { version = "7.0.0", default-features = false, path = "../../primitives/core" }
|
||||
|
||||
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||
sp-io = { version = "7.0.0", path = "../../primitives/io" }
|
||||
@@ -41,6 +43,10 @@ std = [
|
||||
"sp-core/std",
|
||||
"sp-runtime/std",
|
||||
"sp-std/std",
|
||||
|
||||
"frame-benchmarking?/std",
|
||||
]
|
||||
runtime-benchmarks = [
|
||||
"frame-benchmarking/runtime-benchmarks",
|
||||
]
|
||||
runtime-benchmarks = []
|
||||
try-runtime = []
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
[package]
|
||||
name = "pallet-election-provider-support-benchmarking"
|
||||
version = "4.0.0-dev"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://substrate.io"
|
||||
repository = "https://github.com/paritytech/substrate/"
|
||||
description = "Benchmarking for election provider support onchain config trait"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = [
|
||||
"derive",
|
||||
] }
|
||||
frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../../benchmarking" }
|
||||
frame-election-provider-support = { version = "4.0.0-dev", default-features = false, path = ".." }
|
||||
frame-system = { version = "4.0.0-dev", default-features = false, path = "../../system" }
|
||||
sp-npos-elections = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/npos-elections" }
|
||||
sp-runtime = { version = "7.0.0", default-features = false, path = "../../../primitives/runtime" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"codec/std",
|
||||
"frame-benchmarking?/std",
|
||||
"frame-election-provider-support/std",
|
||||
"frame-system/std",
|
||||
"sp-npos-elections/std",
|
||||
"sp-runtime/std",
|
||||
]
|
||||
runtime-benchmarks = [
|
||||
"frame-benchmarking/runtime-benchmarks",
|
||||
"frame-election-provider-support/runtime-benchmarks",
|
||||
]
|
||||
+14
-4
@@ -18,12 +18,9 @@
|
||||
//! Election provider support pallet benchmarking.
|
||||
//! This is separated into its own crate to avoid bloating the size of the runtime.
|
||||
|
||||
#![cfg(feature = "runtime-benchmarks")]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use crate::{ApprovalVoting, NposSolver, PhragMMS, SequentialPhragmen};
|
||||
use codec::Decode;
|
||||
use frame_benchmarking::v1::{benchmarks, Vec};
|
||||
use frame_election_provider_support::{NposSolver, PhragMMS, SequentialPhragmen};
|
||||
|
||||
pub struct Pallet<T: Config>(frame_system::Pallet<T>);
|
||||
pub trait Config: frame_system::Config {}
|
||||
@@ -88,4 +85,17 @@ benchmarks! {
|
||||
::solve(d as usize, targets, voters).is_ok()
|
||||
);
|
||||
}
|
||||
|
||||
approval_voting {
|
||||
let v in (VOTERS[0]) .. VOTERS[1];
|
||||
let t in (TARGETS[0]) .. TARGETS[1];
|
||||
let d in (VOTES_PER_VOTER[0]) .. VOTES_PER_VOTER[1];
|
||||
|
||||
let (voters, targets) = set_up_voters_targets::<T::AccountId>(v, t, d as usize);
|
||||
}: {
|
||||
assert!(
|
||||
ApprovalVoting::<T::AccountId, sp_runtime::Perbill>
|
||||
::solve(d as usize, targets, voters).is_ok()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -199,6 +199,9 @@ pub use sp_arithmetic;
|
||||
#[doc(hidden)]
|
||||
pub use sp_std;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub mod benchmarking;
|
||||
|
||||
pub mod weights;
|
||||
pub use weights::WeightInfo;
|
||||
|
||||
@@ -660,6 +663,29 @@ impl<AccountId: IdentifierT, Accuracy: PerThing128, Balancing: Get<Option<Balanc
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper for [`sp_npos_elections::approval_voting()`] that implements [`NposSolver`]. See the
|
||||
/// documentation of [`sp_npos_elections::approval_voting()`] for more info.
|
||||
pub struct ApprovalVoting<AccountId, Accuracy>(sp_std::marker::PhantomData<(AccountId, Accuracy)>);
|
||||
|
||||
impl<AccountId: IdentifierT, Accuracy: PerThing128> NposSolver
|
||||
for ApprovalVoting<AccountId, Accuracy>
|
||||
{
|
||||
type AccountId = AccountId;
|
||||
type Accuracy = Accuracy;
|
||||
type Error = sp_npos_elections::Error;
|
||||
fn solve(
|
||||
winners: usize,
|
||||
targets: Vec<Self::AccountId>,
|
||||
voters: Vec<(Self::AccountId, VoteWeight, impl IntoIterator<Item = Self::AccountId>)>,
|
||||
) -> Result<ElectionResult<Self::AccountId, Self::Accuracy>, Self::Error> {
|
||||
sp_npos_elections::approval_voting(winners, targets, voters)
|
||||
}
|
||||
|
||||
fn weight<T: WeightInfo>(voters: u32, targets: u32, vote_degree: u32) -> Weight {
|
||||
T::approval_voting(voters, targets, vote_degree)
|
||||
}
|
||||
}
|
||||
|
||||
/// A voter, at the level of abstraction of this crate.
|
||||
pub type Voter<AccountId, Bound> = (AccountId, VoteWeight, BoundedVec<AccountId, Bound>);
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ impl<T: Config> ElectionProvider for OnChainExecution<T> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{ElectionProvider, PhragMMS, SequentialPhragmen};
|
||||
use crate::{ApprovalVoting, ElectionProvider, PhragMMS, SequentialPhragmen};
|
||||
use frame_support::{assert_noop, parameter_types, traits::ConstU32};
|
||||
use sp_npos_elections::Support;
|
||||
use sp_runtime::Perbill;
|
||||
@@ -235,6 +235,7 @@ mod tests {
|
||||
|
||||
struct PhragmenParams;
|
||||
struct PhragMMSParams;
|
||||
struct ApprovalVotingParams;
|
||||
|
||||
parameter_types! {
|
||||
pub static MaxWinners: u32 = 10;
|
||||
@@ -261,6 +262,16 @@ mod tests {
|
||||
type TargetsBound = ConstU32<400>;
|
||||
}
|
||||
|
||||
impl Config for ApprovalVotingParams {
|
||||
type System = Runtime;
|
||||
type Solver = ApprovalVoting<AccountId, Perbill>;
|
||||
type DataProvider = mock_data_provider::DataProvider;
|
||||
type WeightInfo = ();
|
||||
type MaxWinners = MaxWinners;
|
||||
type VotersBound = ConstU32<600>;
|
||||
type TargetsBound = ConstU32<400>;
|
||||
}
|
||||
|
||||
mod mock_data_provider {
|
||||
use frame_support::{bounded_vec, traits::ConstU32};
|
||||
|
||||
@@ -333,4 +344,21 @@ mod tests {
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn onchain_approval_voting_works() {
|
||||
sp_io::TestExternalities::new_empty().execute_with(|| {
|
||||
DesiredTargets::set(3);
|
||||
|
||||
// note that the `OnChainExecution::elect` implementation normalizes the vote weights.
|
||||
assert_eq!(
|
||||
<OnChainExecution::<ApprovalVotingParams> as ElectionProvider>::elect().unwrap(),
|
||||
vec![
|
||||
(10, Support { total: 20, voters: vec![(1, 5), (3, 15)] }),
|
||||
(20, Support { total: 15, voters: vec![(1, 5), (2, 10)] }),
|
||||
(30, Support { total: 25, voters: vec![(2, 10), (3, 15)] })
|
||||
]
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// Copyright (C) 2023 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
|
||||
// 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,
|
||||
@@ -15,25 +15,29 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Autogenerated weights for pallet_election_provider_support_benchmarking
|
||||
//! Autogenerated weights for frame_election_provider_support
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
|
||||
//! DATE: 2022-04-23, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2023-02-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `runner-ehxwxxsd-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
|
||||
|
||||
// Executed Command:
|
||||
// target/release/substrate
|
||||
// target/production/substrate
|
||||
// benchmark
|
||||
// pallet
|
||||
// --chain=dev
|
||||
// --steps=1
|
||||
// --repeat=1
|
||||
// --pallet=pallet_election_provider_support_benchmarking
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --extrinsic=*
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --heap-pages=4096
|
||||
// --output=frame/election-provider-support/src/weights.rs
|
||||
// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json
|
||||
// --pallet=frame_election_provider_support
|
||||
// --chain=dev
|
||||
// --header=./HEADER-APACHE2
|
||||
// --output=./frame/election-provider-support/src/weights.rs
|
||||
// --template=./.maintain/frame-weight-template.hbs
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
@@ -43,53 +47,108 @@
|
||||
use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Weight functions needed for pallet_election_provider_support_benchmarking.
|
||||
/// Weight functions needed for frame_election_provider_support.
|
||||
pub trait WeightInfo {
|
||||
fn phragmen(v: u32, t: u32, d: u32, ) -> Weight;
|
||||
fn phragmms(v: u32, t: u32, d: u32, ) -> Weight;
|
||||
fn approval_voting(v: u32, t: u32, d: u32, ) -> Weight;
|
||||
}
|
||||
|
||||
/// Weights for pallet_election_provider_support_benchmarking using the Substrate node and recommended hardware.
|
||||
/// Weights for frame_election_provider_support using the Substrate node and recommended hardware.
|
||||
pub struct SubstrateWeight<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||
fn phragmen(v: u32, t: u32, d: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
// Standard Error: 667_000
|
||||
.saturating_add(Weight::from_ref_time(32_973_000 as u64).saturating_mul(v as u64))
|
||||
// Standard Error: 1_334_000
|
||||
.saturating_add(Weight::from_ref_time(1_334_000 as u64).saturating_mul(t as u64))
|
||||
// Standard Error: 60_644_000
|
||||
.saturating_add(Weight::from_ref_time(2_636_364_000 as u64).saturating_mul(d as u64))
|
||||
/// The range of component `v` is `[1000, 2000]`.
|
||||
/// The range of component `t` is `[500, 1000]`.
|
||||
/// The range of component `d` is `[5, 16]`.
|
||||
fn phragmen(v: u32, _t: u32, d: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 5_789_174 nanoseconds.
|
||||
Weight::from_ref_time(5_826_449_000)
|
||||
.saturating_add(Weight::from_proof_size(0))
|
||||
// Standard Error: 130_342
|
||||
.saturating_add(Weight::from_ref_time(5_332_741).saturating_mul(v.into()))
|
||||
// Standard Error: 13_325_769
|
||||
.saturating_add(Weight::from_ref_time(1_416_874_101).saturating_mul(d.into()))
|
||||
}
|
||||
fn phragmms(v: u32, t: u32, d: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
// Standard Error: 73_000
|
||||
.saturating_add(Weight::from_ref_time(21_073_000 as u64).saturating_mul(v as u64))
|
||||
// Standard Error: 146_000
|
||||
.saturating_add(Weight::from_ref_time(65_000 as u64).saturating_mul(t as u64))
|
||||
// Standard Error: 6_649_000
|
||||
.saturating_add(Weight::from_ref_time(1_711_424_000 as u64).saturating_mul(d as u64))
|
||||
/// The range of component `v` is `[1000, 2000]`.
|
||||
/// The range of component `t` is `[500, 1000]`.
|
||||
/// The range of component `d` is `[5, 16]`.
|
||||
fn phragmms(v: u32, _t: u32, d: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 4_151_790 nanoseconds.
|
||||
Weight::from_ref_time(4_215_936_000)
|
||||
.saturating_add(Weight::from_proof_size(0))
|
||||
// Standard Error: 125_135
|
||||
.saturating_add(Weight::from_ref_time(4_730_609).saturating_mul(v.into()))
|
||||
// Standard Error: 12_793_390
|
||||
.saturating_add(Weight::from_ref_time(1_474_383_961).saturating_mul(d.into()))
|
||||
}
|
||||
/// The range of component `v` is `[1000, 2000]`.
|
||||
/// The range of component `t` is `[500, 1000]`.
|
||||
/// The range of component `d` is `[5, 16]`.
|
||||
fn approval_voting(v: u32, _t: u32, d: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 1_800_445 nanoseconds.
|
||||
Weight::from_ref_time(1_824_645_000)
|
||||
.saturating_add(Weight::from_proof_size(0))
|
||||
// Standard Error: 26_266
|
||||
.saturating_add(Weight::from_ref_time(1_229_576).saturating_mul(v.into()))
|
||||
// Standard Error: 2_685_343
|
||||
.saturating_add(Weight::from_ref_time(213_080_804).saturating_mul(d.into()))
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility and tests
|
||||
impl WeightInfo for () {
|
||||
fn phragmen(v: u32, t: u32, d: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
// Standard Error: 667_000
|
||||
.saturating_add(Weight::from_ref_time(32_973_000 as u64).saturating_mul(v as u64))
|
||||
// Standard Error: 1_334_000
|
||||
.saturating_add(Weight::from_ref_time(1_334_000 as u64).saturating_mul(t as u64))
|
||||
// Standard Error: 60_644_000
|
||||
.saturating_add(Weight::from_ref_time(2_636_364_000 as u64).saturating_mul(d as u64))
|
||||
/// The range of component `v` is `[1000, 2000]`.
|
||||
/// The range of component `t` is `[500, 1000]`.
|
||||
/// The range of component `d` is `[5, 16]`.
|
||||
fn phragmen(v: u32, _t: u32, d: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 5_789_174 nanoseconds.
|
||||
Weight::from_ref_time(5_826_449_000)
|
||||
.saturating_add(Weight::from_proof_size(0))
|
||||
// Standard Error: 130_342
|
||||
.saturating_add(Weight::from_ref_time(5_332_741).saturating_mul(v.into()))
|
||||
// Standard Error: 13_325_769
|
||||
.saturating_add(Weight::from_ref_time(1_416_874_101).saturating_mul(d.into()))
|
||||
}
|
||||
fn phragmms(v: u32, t: u32, d: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
// Standard Error: 73_000
|
||||
.saturating_add(Weight::from_ref_time(21_073_000 as u64).saturating_mul(v as u64))
|
||||
// Standard Error: 146_000
|
||||
.saturating_add(Weight::from_ref_time(65_000 as u64).saturating_mul(t as u64))
|
||||
// Standard Error: 6_649_000
|
||||
.saturating_add(Weight::from_ref_time(1_711_424_000 as u64).saturating_mul(d as u64))
|
||||
/// The range of component `v` is `[1000, 2000]`.
|
||||
/// The range of component `t` is `[500, 1000]`.
|
||||
/// The range of component `d` is `[5, 16]`.
|
||||
fn phragmms(v: u32, _t: u32, d: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 4_151_790 nanoseconds.
|
||||
Weight::from_ref_time(4_215_936_000)
|
||||
.saturating_add(Weight::from_proof_size(0))
|
||||
// Standard Error: 125_135
|
||||
.saturating_add(Weight::from_ref_time(4_730_609).saturating_mul(v.into()))
|
||||
// Standard Error: 12_793_390
|
||||
.saturating_add(Weight::from_ref_time(1_474_383_961).saturating_mul(d.into()))
|
||||
}
|
||||
/// The range of component `v` is `[1000, 2000]`.
|
||||
/// The range of component `t` is `[500, 1000]`.
|
||||
/// The range of component `d` is `[5, 16]`.
|
||||
fn approval_voting(v: u32, _t: u32, d: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 1_800_445 nanoseconds.
|
||||
Weight::from_ref_time(1_824_645_000)
|
||||
.saturating_add(Weight::from_proof_size(0))
|
||||
// Standard Error: 26_266
|
||||
.saturating_add(Weight::from_ref_time(1_229_576).saturating_mul(v.into()))
|
||||
// Standard Error: 2_685_343
|
||||
.saturating_add(Weight::from_ref_time(213_080_804).saturating_mul(d.into()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,559 +0,0 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Autogenerated weights for pallet_elections_phragmen
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
|
||||
//! DATE: 2023-02-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `runner-b3zmxxc-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
|
||||
|
||||
// Executed Command:
|
||||
// target/production/substrate
|
||||
// benchmark
|
||||
// pallet
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --extrinsic=*
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --heap-pages=4096
|
||||
// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json
|
||||
// --pallet=pallet_elections_phragmen
|
||||
// --chain=dev
|
||||
// --header=./HEADER-APACHE2
|
||||
// --output=./frame/elections-phragmen/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_elections_phragmen.
|
||||
pub trait WeightInfo {
|
||||
fn vote_equal(v: u32, ) -> Weight;
|
||||
fn vote_more(v: u32, ) -> Weight;
|
||||
fn vote_less(v: u32, ) -> Weight;
|
||||
fn remove_voter() -> Weight;
|
||||
fn submit_candidacy(c: u32, ) -> Weight;
|
||||
fn renounce_candidacy_candidate(c: u32, ) -> Weight;
|
||||
fn renounce_candidacy_members() -> Weight;
|
||||
fn renounce_candidacy_runners_up() -> Weight;
|
||||
fn remove_member_without_replacement() -> Weight;
|
||||
fn remove_member_with_replacement() -> Weight;
|
||||
fn clean_defunct_voters(v: u32, d: u32, ) -> Weight;
|
||||
fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight;
|
||||
}
|
||||
|
||||
/// Weights for pallet_elections_phragmen using the Substrate node and recommended hardware.
|
||||
pub struct SubstrateWeight<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||
/// Storage: Elections Candidates (r:1 w:0)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Voting (r:1 w:1)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:1 w:1)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
/// The range of component `v` is `[1, 16]`.
|
||||
fn vote_equal(v: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `499 + v * (80 ±0)`
|
||||
// Estimated: `9726 + v * (320 ±0)`
|
||||
// Minimum execution time: 27_362 nanoseconds.
|
||||
Weight::from_parts(28_497_963, 9726)
|
||||
// Standard Error: 3_968
|
||||
.saturating_add(Weight::from_ref_time(176_840).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2_u64))
|
||||
.saturating_add(Weight::from_proof_size(320).saturating_mul(v.into()))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:0)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Voting (r:1 w:1)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:1 w:1)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
/// The range of component `v` is `[2, 16]`.
|
||||
fn vote_more(v: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `467 + v * (80 ±0)`
|
||||
// Estimated: `9598 + v * (320 ±0)`
|
||||
// Minimum execution time: 37_120 nanoseconds.
|
||||
Weight::from_parts(38_455_302, 9598)
|
||||
// Standard Error: 5_478
|
||||
.saturating_add(Weight::from_ref_time(219_678).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2_u64))
|
||||
.saturating_add(Weight::from_proof_size(320).saturating_mul(v.into()))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:0)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Voting (r:1 w:1)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:1 w:1)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
/// The range of component `v` is `[2, 16]`.
|
||||
fn vote_less(v: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `499 + v * (80 ±0)`
|
||||
// Estimated: `9726 + v * (320 ±0)`
|
||||
// Minimum execution time: 36_928 nanoseconds.
|
||||
Weight::from_parts(38_334_669, 9726)
|
||||
// Standard Error: 5_271
|
||||
.saturating_add(Weight::from_ref_time(232_355).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2_u64))
|
||||
.saturating_add(Weight::from_proof_size(320).saturating_mul(v.into()))
|
||||
}
|
||||
/// Storage: Elections Voting (r:1 w:1)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:1 w:1)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
fn remove_voter() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `989`
|
||||
// Estimated: `7238`
|
||||
// Minimum execution time: 34_338 nanoseconds.
|
||||
Weight::from_parts(35_672_000, 7238)
|
||||
.saturating_add(T::DbWeight::get().reads(2_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2_u64))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:1)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// The range of component `c` is `[1, 64]`.
|
||||
fn submit_candidacy(c: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1697 + c * (48 ±0)`
|
||||
// Estimated: `6576 + c * (144 ±0)`
|
||||
// Minimum execution time: 31_864 nanoseconds.
|
||||
Weight::from_parts(33_490_161, 6576)
|
||||
// Standard Error: 2_643
|
||||
.saturating_add(Weight::from_ref_time(158_386).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(3_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1_u64))
|
||||
.saturating_add(Weight::from_proof_size(144).saturating_mul(c.into()))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:1)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// The range of component `c` is `[1, 64]`.
|
||||
fn renounce_candidacy_candidate(c: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `349 + c * (48 ±0)`
|
||||
// Estimated: `844 + c * (48 ±0)`
|
||||
// Minimum execution time: 27_292 nanoseconds.
|
||||
Weight::from_parts(28_364_955, 844)
|
||||
// Standard Error: 1_335
|
||||
.saturating_add(Weight::from_ref_time(78_086).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(1_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1_u64))
|
||||
.saturating_add(Weight::from_proof_size(48).saturating_mul(c.into()))
|
||||
}
|
||||
/// Storage: Elections Members (r:1 w:1)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:1)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Prime (r:1 w:1)
|
||||
/// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Proposals (r:1 w:0)
|
||||
/// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Members (r:0 w:1)
|
||||
/// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
fn renounce_candidacy_members() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `2027`
|
||||
// Estimated: `12115`
|
||||
// Minimum execution time: 45_975 nanoseconds.
|
||||
Weight::from_parts(47_103_000, 12115)
|
||||
.saturating_add(T::DbWeight::get().reads(4_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(4_u64))
|
||||
}
|
||||
/// Storage: Elections RunnersUp (r:1 w:1)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
fn renounce_candidacy_runners_up() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `975`
|
||||
// Estimated: `1470`
|
||||
// Minimum execution time: 29_243 nanoseconds.
|
||||
Weight::from_parts(30_582_000, 1470)
|
||||
.saturating_add(T::DbWeight::get().reads(1_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1_u64))
|
||||
}
|
||||
/// Storage: Benchmark Override (r:0 w:0)
|
||||
/// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured)
|
||||
fn remove_member_without_replacement() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_000_000_000 nanoseconds.
|
||||
Weight::from_ref_time(2_000_000_000_000)
|
||||
}
|
||||
/// Storage: Elections Members (r:1 w:1)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: System Account (r:1 w:1)
|
||||
/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
|
||||
/// Storage: Elections RunnersUp (r:1 w:1)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Prime (r:1 w:1)
|
||||
/// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Proposals (r:1 w:0)
|
||||
/// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Members (r:0 w:1)
|
||||
/// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
fn remove_member_with_replacement() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `2027`
|
||||
// Estimated: `14718`
|
||||
// Minimum execution time: 52_527 nanoseconds.
|
||||
Weight::from_parts(53_538_000, 14718)
|
||||
.saturating_add(T::DbWeight::get().reads(5_u64))
|
||||
.saturating_add(T::DbWeight::get().writes(5_u64))
|
||||
}
|
||||
/// Storage: Elections Voting (r:513 w:512)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Candidates (r:1 w:0)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:512 w:512)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
/// Storage: System Account (r:512 w:512)
|
||||
/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
|
||||
/// The range of component `v` is `[256, 512]`.
|
||||
/// The range of component `d` is `[0, 256]`.
|
||||
fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1115 + v * (875 ±0)`
|
||||
// Estimated: `8448 + v * (12352 ±0)`
|
||||
// Minimum execution time: 14_934_185 nanoseconds.
|
||||
Weight::from_parts(15_014_057_000, 8448)
|
||||
// Standard Error: 245_588
|
||||
.saturating_add(Weight::from_ref_time(35_586_946).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(4_u64))
|
||||
.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(v.into())))
|
||||
.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into())))
|
||||
.saturating_add(Weight::from_proof_size(12352).saturating_mul(v.into()))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:1)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:1)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:1)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Voting (r:513 w:0)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Council Proposals (r:1 w:0)
|
||||
/// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: System Account (r:44 w:44)
|
||||
/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
|
||||
/// Storage: Elections ElectionRounds (r:1 w:1)
|
||||
/// Proof Skipped: Elections ElectionRounds (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Members (r:0 w:1)
|
||||
/// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Prime (r:0 w:1)
|
||||
/// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// The range of component `c` is `[1, 64]`.
|
||||
/// The range of component `v` is `[1, 512]`.
|
||||
/// The range of component `e` is `[512, 8192]`.
|
||||
fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0 + v * (638 ±0) + e * (28 ±0)`
|
||||
// Estimated: `330033 + v * (5229 ±6) + e * (89 ±0) + c * (2135 ±7)`
|
||||
// Minimum execution time: 1_273_671 nanoseconds.
|
||||
Weight::from_parts(1_279_716_000, 330033)
|
||||
// Standard Error: 543_277
|
||||
.saturating_add(Weight::from_ref_time(20_613_753).saturating_mul(v.into()))
|
||||
// Standard Error: 34_857
|
||||
.saturating_add(Weight::from_ref_time(688_354).saturating_mul(e.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(21_u64))
|
||||
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into())))
|
||||
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into())))
|
||||
.saturating_add(T::DbWeight::get().writes(6_u64))
|
||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into())))
|
||||
.saturating_add(Weight::from_proof_size(5229).saturating_mul(v.into()))
|
||||
.saturating_add(Weight::from_proof_size(89).saturating_mul(e.into()))
|
||||
.saturating_add(Weight::from_proof_size(2135).saturating_mul(c.into()))
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility and tests
|
||||
impl WeightInfo for () {
|
||||
/// Storage: Elections Candidates (r:1 w:0)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Voting (r:1 w:1)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:1 w:1)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
/// The range of component `v` is `[1, 16]`.
|
||||
fn vote_equal(v: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `499 + v * (80 ±0)`
|
||||
// Estimated: `9726 + v * (320 ±0)`
|
||||
// Minimum execution time: 27_362 nanoseconds.
|
||||
Weight::from_parts(28_497_963, 9726)
|
||||
// Standard Error: 3_968
|
||||
.saturating_add(Weight::from_ref_time(176_840).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2_u64))
|
||||
.saturating_add(Weight::from_proof_size(320).saturating_mul(v.into()))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:0)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Voting (r:1 w:1)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:1 w:1)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
/// The range of component `v` is `[2, 16]`.
|
||||
fn vote_more(v: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `467 + v * (80 ±0)`
|
||||
// Estimated: `9598 + v * (320 ±0)`
|
||||
// Minimum execution time: 37_120 nanoseconds.
|
||||
Weight::from_parts(38_455_302, 9598)
|
||||
// Standard Error: 5_478
|
||||
.saturating_add(Weight::from_ref_time(219_678).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2_u64))
|
||||
.saturating_add(Weight::from_proof_size(320).saturating_mul(v.into()))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:0)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Voting (r:1 w:1)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:1 w:1)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
/// The range of component `v` is `[2, 16]`.
|
||||
fn vote_less(v: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `499 + v * (80 ±0)`
|
||||
// Estimated: `9726 + v * (320 ±0)`
|
||||
// Minimum execution time: 36_928 nanoseconds.
|
||||
Weight::from_parts(38_334_669, 9726)
|
||||
// Standard Error: 5_271
|
||||
.saturating_add(Weight::from_ref_time(232_355).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2_u64))
|
||||
.saturating_add(Weight::from_proof_size(320).saturating_mul(v.into()))
|
||||
}
|
||||
/// Storage: Elections Voting (r:1 w:1)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:1 w:1)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
fn remove_voter() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `989`
|
||||
// Estimated: `7238`
|
||||
// Minimum execution time: 34_338 nanoseconds.
|
||||
Weight::from_parts(35_672_000, 7238)
|
||||
.saturating_add(RocksDbWeight::get().reads(2_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2_u64))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:1)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// The range of component `c` is `[1, 64]`.
|
||||
fn submit_candidacy(c: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1697 + c * (48 ±0)`
|
||||
// Estimated: `6576 + c * (144 ±0)`
|
||||
// Minimum execution time: 31_864 nanoseconds.
|
||||
Weight::from_parts(33_490_161, 6576)
|
||||
// Standard Error: 2_643
|
||||
.saturating_add(Weight::from_ref_time(158_386).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(3_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1_u64))
|
||||
.saturating_add(Weight::from_proof_size(144).saturating_mul(c.into()))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:1)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// The range of component `c` is `[1, 64]`.
|
||||
fn renounce_candidacy_candidate(c: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `349 + c * (48 ±0)`
|
||||
// Estimated: `844 + c * (48 ±0)`
|
||||
// Minimum execution time: 27_292 nanoseconds.
|
||||
Weight::from_parts(28_364_955, 844)
|
||||
// Standard Error: 1_335
|
||||
.saturating_add(Weight::from_ref_time(78_086).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(1_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1_u64))
|
||||
.saturating_add(Weight::from_proof_size(48).saturating_mul(c.into()))
|
||||
}
|
||||
/// Storage: Elections Members (r:1 w:1)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:1)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Prime (r:1 w:1)
|
||||
/// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Proposals (r:1 w:0)
|
||||
/// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Members (r:0 w:1)
|
||||
/// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
fn renounce_candidacy_members() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `2027`
|
||||
// Estimated: `12115`
|
||||
// Minimum execution time: 45_975 nanoseconds.
|
||||
Weight::from_parts(47_103_000, 12115)
|
||||
.saturating_add(RocksDbWeight::get().reads(4_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(4_u64))
|
||||
}
|
||||
/// Storage: Elections RunnersUp (r:1 w:1)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
fn renounce_candidacy_runners_up() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `975`
|
||||
// Estimated: `1470`
|
||||
// Minimum execution time: 29_243 nanoseconds.
|
||||
Weight::from_parts(30_582_000, 1470)
|
||||
.saturating_add(RocksDbWeight::get().reads(1_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1_u64))
|
||||
}
|
||||
/// Storage: Benchmark Override (r:0 w:0)
|
||||
/// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured)
|
||||
fn remove_member_without_replacement() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_000_000_000 nanoseconds.
|
||||
Weight::from_ref_time(2_000_000_000_000)
|
||||
}
|
||||
/// Storage: Elections Members (r:1 w:1)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: System Account (r:1 w:1)
|
||||
/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
|
||||
/// Storage: Elections RunnersUp (r:1 w:1)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Prime (r:1 w:1)
|
||||
/// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Proposals (r:1 w:0)
|
||||
/// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Members (r:0 w:1)
|
||||
/// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
fn remove_member_with_replacement() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `2027`
|
||||
// Estimated: `14718`
|
||||
// Minimum execution time: 52_527 nanoseconds.
|
||||
Weight::from_parts(53_538_000, 14718)
|
||||
.saturating_add(RocksDbWeight::get().reads(5_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(5_u64))
|
||||
}
|
||||
/// Storage: Elections Voting (r:513 w:512)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:0)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Candidates (r:1 w:0)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Balances Locks (r:512 w:512)
|
||||
/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
|
||||
/// Storage: System Account (r:512 w:512)
|
||||
/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
|
||||
/// The range of component `v` is `[256, 512]`.
|
||||
/// The range of component `d` is `[0, 256]`.
|
||||
fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `1115 + v * (875 ±0)`
|
||||
// Estimated: `8448 + v * (12352 ±0)`
|
||||
// Minimum execution time: 14_934_185 nanoseconds.
|
||||
Weight::from_parts(15_014_057_000, 8448)
|
||||
// Standard Error: 245_588
|
||||
.saturating_add(Weight::from_ref_time(35_586_946).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(4_u64))
|
||||
.saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(v.into())))
|
||||
.saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(v.into())))
|
||||
.saturating_add(Weight::from_proof_size(12352).saturating_mul(v.into()))
|
||||
}
|
||||
/// Storage: Elections Candidates (r:1 w:1)
|
||||
/// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Members (r:1 w:1)
|
||||
/// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections RunnersUp (r:1 w:1)
|
||||
/// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Elections Voting (r:513 w:0)
|
||||
/// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured)
|
||||
/// Storage: Council Proposals (r:1 w:0)
|
||||
/// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: System Account (r:44 w:44)
|
||||
/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
|
||||
/// Storage: Elections ElectionRounds (r:1 w:1)
|
||||
/// Proof Skipped: Elections ElectionRounds (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Members (r:0 w:1)
|
||||
/// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// Storage: Council Prime (r:0 w:1)
|
||||
/// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured)
|
||||
/// The range of component `c` is `[1, 64]`.
|
||||
/// The range of component `v` is `[1, 512]`.
|
||||
/// The range of component `e` is `[512, 8192]`.
|
||||
fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0 + v * (638 ±0) + e * (28 ±0)`
|
||||
// Estimated: `330033 + v * (5229 ±6) + e * (89 ±0) + c * (2135 ±7)`
|
||||
// Minimum execution time: 1_273_671 nanoseconds.
|
||||
Weight::from_parts(1_279_716_000, 330033)
|
||||
// Standard Error: 543_277
|
||||
.saturating_add(Weight::from_ref_time(20_613_753).saturating_mul(v.into()))
|
||||
// Standard Error: 34_857
|
||||
.saturating_add(Weight::from_ref_time(688_354).saturating_mul(e.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(21_u64))
|
||||
.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(c.into())))
|
||||
.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into())))
|
||||
.saturating_add(RocksDbWeight::get().writes(6_u64))
|
||||
.saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(c.into())))
|
||||
.saturating_add(Weight::from_proof_size(5229).saturating_mul(v.into()))
|
||||
.saturating_add(Weight::from_proof_size(89).saturating_mul(e.into()))
|
||||
.saturating_add(Weight::from_proof_size(2135).saturating_mul(c.into()))
|
||||
}
|
||||
}
|
||||
+11
@@ -4,6 +4,17 @@ All notable changes to this crate will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [5.0.0] - UNRELEASED
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
Generalized the pallet to use `NposSolver` instead of hard coding the phragmen algorithm; Changed the name of the pallet from `pallet-elections-phragmen` to `pallet-elections`
|
||||
|
||||
### Fixed
|
||||
|
||||
### Security
|
||||
|
||||
## [4.0.0] - UNRELEASED
|
||||
|
||||
### Added
|
||||
+3
-2
@@ -1,12 +1,12 @@
|
||||
[package]
|
||||
name = "pallet-elections-phragmen"
|
||||
name = "pallet-elections"
|
||||
version = "5.0.0-dev"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://substrate.io"
|
||||
repository = "https://github.com/paritytech/substrate/"
|
||||
description = "FRAME pallet based on seq-Phragmén election method."
|
||||
description = "FRAME pallet for generic elections."
|
||||
readme = "README.md"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
@@ -24,6 +24,7 @@ frame-system = { version = "4.0.0-dev", default-features = false, path = "../sys
|
||||
sp-core = { version = "7.0.0", default-features = false, path = "../../primitives/core" }
|
||||
sp-io = { version = "7.0.0", default-features = false, path = "../../primitives/io" }
|
||||
sp-npos-elections = { version = "4.0.0-dev", default-features = false, path = "../../primitives/npos-elections" }
|
||||
frame-election-provider-support = { version = "4.0.0-dev", default-features = false, path = "../election-provider-support" }
|
||||
sp-runtime = { version = "7.0.0", default-features = false, path = "../../primitives/runtime" }
|
||||
sp-std = { version = "5.0.0", default-features = false, path = "../../primitives/std" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Phragmén Election Module.
|
||||
# Generic Elections Module.
|
||||
|
||||
An election module based on sequential phragmen.
|
||||
A generic elections module.
|
||||
|
||||
### Term and Round
|
||||
|
||||
@@ -60,7 +60,7 @@ being re-elected at the end of each round.
|
||||
|
||||
### Module Information
|
||||
|
||||
- [`election_sp_phragmen::Config`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/trait.Config.html)
|
||||
- [`elections::Config`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/trait.Config.html)
|
||||
- [`Call`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/enum.Call.html)
|
||||
- [`Module`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/struct.Module.html)
|
||||
|
||||
+47
-10
@@ -15,14 +15,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Elections-Phragmen pallet benchmarking.
|
||||
//! Elections pallet benchmarking.
|
||||
|
||||
#![cfg(feature = "runtime-benchmarks")]
|
||||
|
||||
use super::*;
|
||||
|
||||
use frame_benchmarking::v1::{account, benchmarks, whitelist, BenchmarkError, BenchmarkResult};
|
||||
use frame_support::{dispatch::DispatchResultWithPostInfo, traits::OnInitialize};
|
||||
use frame_support::dispatch::DispatchResultWithPostInfo;
|
||||
use frame_system::RawOrigin;
|
||||
|
||||
use crate::Pallet as Elections;
|
||||
@@ -37,7 +37,7 @@ fn endowed_account<T: Config>(name: &'static str, index: u32) -> T::AccountId {
|
||||
let amount = default_stake::<T>(T::MaxVoters::get()) * BalanceOf::<T>::from(BALANCE_FACTOR);
|
||||
let _ = T::Currency::make_free_balance_be(&account, amount);
|
||||
// important to increase the total issuance since T::CurrencyToVote will need it to be sane for
|
||||
// phragmen to work.
|
||||
// the election to work.
|
||||
T::Currency::issue(amount);
|
||||
|
||||
account
|
||||
@@ -122,7 +122,7 @@ fn distribute_voters<T: Config>(
|
||||
fn fill_seats_up_to<T: Config>(m: u32) -> Result<Vec<T::AccountId>, &'static str> {
|
||||
let _ = submit_candidates_with_self_vote::<T>(m, "fill_seats_up_to")?;
|
||||
assert_eq!(<Elections<T>>::candidates().len() as u32, m, "wrong number of candidates.");
|
||||
<Elections<T>>::do_phragmen();
|
||||
<Elections<T>>::do_election();
|
||||
assert_eq!(<Elections<T>>::candidates().len(), 0, "some candidates remaining.");
|
||||
assert_eq!(
|
||||
<Elections<T>>::members().len() + <Elections<T>>::runners_up().len(),
|
||||
@@ -382,11 +382,11 @@ benchmarks! {
|
||||
assert_eq!(<Voting<T>>::iter().count() as u32, 0);
|
||||
}
|
||||
|
||||
election_phragmen {
|
||||
// This is just to focus on phragmen in the context of this module. We always select 20
|
||||
// members, this is hard-coded in the runtime and cannot be trivially changed at this stage.
|
||||
// Yet, change the number of voters, candidates and edge per voter to see the impact. Note
|
||||
// that we give all candidates a self vote to make sure they are all considered.
|
||||
pre_solve_election {
|
||||
// We always select 20 members, this is hard-coded in the runtime and cannot be trivially
|
||||
// changed at this stage. Yet, change the number of voters, candidates and edge per voter
|
||||
// to see the impact. Note that we give all candidates a self vote to make sure they are
|
||||
// all considered.
|
||||
let c in 1 .. T::MaxCandidates::get();
|
||||
let v in 1 .. T::MaxVoters::get();
|
||||
let e in (T::MaxVoters::get()) .. T::MaxVoters::get() * T::MaxVotesPerVoter::get();
|
||||
@@ -404,7 +404,44 @@ benchmarks! {
|
||||
let all_candidates = submit_candidates_with_self_vote::<T>(c, "candidates")?;
|
||||
let _ = distribute_voters::<T>(all_candidates, v.saturating_sub(c), votes_per_voter as usize)?;
|
||||
}: {
|
||||
<Elections<T>>::on_initialize(T::TermDuration::get());
|
||||
<Elections<T>>::do_pre_solve_election().unwrap();
|
||||
}
|
||||
|
||||
post_solve_election {
|
||||
// We always select 20 members, this is hard-coded in the runtime and cannot be trivially
|
||||
// changed at this stage. Yet, change the number of voters, candidates and edge per voter
|
||||
// to see the impact. Note that we give all candidates a self vote to make sure they are
|
||||
// all considered.
|
||||
let c in 1 .. T::MaxCandidates::get();
|
||||
let v in 1 .. T::MaxVoters::get();
|
||||
let e in (T::MaxVoters::get()) .. T::MaxVoters::get() as u32 * T::MaxVotesPerVoter::get() as u32;
|
||||
clean::<T>();
|
||||
|
||||
// so we have a situation with v and e. we want e to basically always be in the range of `e
|
||||
// -> e * T::MaxVotesPerVoter`, but we cannot express that now with the benchmarks. So what we do
|
||||
// is: when c is being iterated, v, and e are max and fine. when v is being iterated, e is
|
||||
// being set to max and this is a problem. In these cases, we cap e to a lower value, namely
|
||||
// v * `T::MaxVotesPerVoter`. when e is being iterated, v is at max, and again fine. all in all,
|
||||
// votes_per_voter can never be more than `T::MaxVotesPerVoter`. Note that this might cause `v` to be
|
||||
// an overestimate.
|
||||
let votes_per_voter = (e / v).min(T::MaxVotesPerVoter::get() as u32);
|
||||
|
||||
let all_candidates = submit_candidates_with_self_vote::<T>(c, "candidates")?;
|
||||
let _ = distribute_voters::<T>(all_candidates, v.saturating_sub(c), votes_per_voter as usize)?;
|
||||
|
||||
let pre_election_result = <Elections<T>>::do_pre_solve_election().unwrap();
|
||||
let election_result = T::ElectionSolver::solve(
|
||||
pre_election_result.num_to_elect,
|
||||
pre_election_result.candidate_ids,
|
||||
pre_election_result.voters_and_votes,
|
||||
).unwrap();
|
||||
|
||||
}: {
|
||||
<Elections<T>>::do_post_solve_election(
|
||||
election_result.winners,
|
||||
pre_election_result.candidates_and_deposit,
|
||||
pre_election_result.voters_and_stakes,
|
||||
);
|
||||
}
|
||||
verify {
|
||||
assert_eq!(<Elections<T>>::members().len() as u32, T::DesiredMembers::get().min(c));
|
||||
+276
-188
@@ -15,9 +15,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! # Phragmén Election Module.
|
||||
//! # Generic Election Module.
|
||||
//!
|
||||
//! An election module based on sequential phragmen.
|
||||
//! An election module based on a generic election algorithm.
|
||||
//!
|
||||
//! ### Term and Round
|
||||
//!
|
||||
@@ -99,6 +99,7 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use frame_election_provider_support::NposSolver;
|
||||
use frame_support::{
|
||||
traits::{
|
||||
defensive_prelude::*, ChangeMembers, Contains, ContainsLengthBound, Currency,
|
||||
@@ -108,12 +109,12 @@ use frame_support::{
|
||||
weights::Weight,
|
||||
};
|
||||
use scale_info::TypeInfo;
|
||||
use sp_npos_elections::{ElectionResult, ExtendedBalance};
|
||||
use sp_npos_elections::{ElectionResult, ExtendedBalance, VoteWeight};
|
||||
use sp_runtime::{
|
||||
traits::{Saturating, StaticLookup, Zero},
|
||||
DispatchError, Perbill, RuntimeDebug,
|
||||
DispatchError, RuntimeDebug,
|
||||
};
|
||||
use sp_std::{cmp::Ordering, prelude::*};
|
||||
use sp_std::{cmp::Ordering, iter::IntoIterator, prelude::*};
|
||||
|
||||
mod benchmarking;
|
||||
pub mod weights;
|
||||
@@ -122,7 +123,17 @@ pub use weights::WeightInfo;
|
||||
/// All migrations.
|
||||
pub mod migrations;
|
||||
|
||||
const LOG_TARGET: &str = "runtime::elections-phragmen";
|
||||
pub(crate) const LOG_TARGET: &str = "runtime::elections";
|
||||
|
||||
// logging helper.
|
||||
macro_rules! log {
|
||||
($level:tt, $patter:expr $(, $values:expr)* $(,)?) => {
|
||||
log::$level!(
|
||||
target: crate::LOG_TARGET,
|
||||
concat!("[{:?}] 🗳️ ", $patter), <frame_system::Pallet<T>>::block_number() $(, $values)*
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
type BalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
@@ -173,6 +184,17 @@ pub struct SeatHolder<AccountId, Balance> {
|
||||
pub deposit: Balance,
|
||||
}
|
||||
|
||||
/// The results of running the pre-election step.
|
||||
#[derive(Debug, Clone)]
|
||||
struct PreElectionResults<T: Config> {
|
||||
pub num_to_elect: usize,
|
||||
pub candidate_ids: Vec<T::AccountId>,
|
||||
pub candidates_and_deposit: Vec<(T::AccountId, BalanceOf<T>)>,
|
||||
pub voters_and_stakes: Vec<(T::AccountId, BalanceOf<T>, Vec<T::AccountId>)>,
|
||||
pub voters_and_votes: Vec<(T::AccountId, VoteWeight, Vec<T::AccountId>)>,
|
||||
pub num_edges: u32,
|
||||
}
|
||||
|
||||
pub use pallet::*;
|
||||
|
||||
type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
|
||||
@@ -196,7 +218,7 @@ pub mod pallet {
|
||||
pub trait Config: frame_system::Config {
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||
|
||||
/// Identifier for the elections-phragmen pallet's lock
|
||||
/// Identifier for the elections pallet's lock
|
||||
#[pallet::constant]
|
||||
type PalletId: Get<LockIdentifier>;
|
||||
|
||||
@@ -249,7 +271,7 @@ pub mod pallet {
|
||||
#[pallet::constant]
|
||||
type TermDuration: Get<Self::BlockNumber>;
|
||||
|
||||
/// The maximum number of candidates in a phragmen election.
|
||||
/// The maximum number of candidates in an election.
|
||||
///
|
||||
/// Warning: This impacts the size of the election which is run onchain. Chose wisely, and
|
||||
/// consider how it will impact `T::WeightInfo::election_phragmen`.
|
||||
@@ -258,7 +280,7 @@ pub mod pallet {
|
||||
#[pallet::constant]
|
||||
type MaxCandidates: Get<u32>;
|
||||
|
||||
/// The maximum number of voters to allow in a phragmen election.
|
||||
/// The maximum number of voters to allow in an election.
|
||||
///
|
||||
/// Warning: This impacts the size of the election which is run onchain. Chose wisely, and
|
||||
/// consider how it will impact `T::WeightInfo::election_phragmen`.
|
||||
@@ -267,6 +289,12 @@ pub mod pallet {
|
||||
#[pallet::constant]
|
||||
type MaxVoters: Get<u32>;
|
||||
|
||||
/// Something that will calculate the result of elections.
|
||||
type ElectionSolver: NposSolver<AccountId = Self::AccountId>;
|
||||
|
||||
/// Weight information for the [`Config::ElectionSolver`].
|
||||
type SolverWeightInfo: frame_election_provider_support::WeightInfo;
|
||||
|
||||
/// Maximum numbers of votes per voter.
|
||||
///
|
||||
/// Warning: This impacts the size of the election which is run onchain. Chose wisely, and
|
||||
@@ -286,7 +314,7 @@ pub mod pallet {
|
||||
fn on_initialize(n: T::BlockNumber) -> Weight {
|
||||
let term_duration = T::TermDuration::get();
|
||||
if !term_duration.is_zero() && (n % term_duration).is_zero() {
|
||||
Self::do_phragmen()
|
||||
Self::do_election()
|
||||
} else {
|
||||
Weight::zero()
|
||||
}
|
||||
@@ -295,11 +323,26 @@ pub mod pallet {
|
||||
fn integrity_test() {
|
||||
let block_weight = T::BlockWeights::get().max_block;
|
||||
// mind the order.
|
||||
let election_weight = T::WeightInfo::election_phragmen(
|
||||
let pre_solve_weight = T::WeightInfo::pre_solve_election(
|
||||
T::MaxCandidates::get(),
|
||||
T::MaxVoters::get(),
|
||||
T::MaxVotesPerVoter::get() * T::MaxVoters::get(),
|
||||
);
|
||||
// mind the order.
|
||||
let post_solve_weight = T::WeightInfo::post_solve_election(
|
||||
T::MaxCandidates::get(),
|
||||
T::MaxVoters::get(),
|
||||
T::MaxVotesPerVoter::get() * T::MaxVoters::get(),
|
||||
);
|
||||
// mind the order.
|
||||
let election_weight = T::ElectionSolver::weight::<T::SolverWeightInfo>(
|
||||
T::MaxCandidates::get(),
|
||||
T::MaxVoters::get(),
|
||||
T::MaxVotesPerVoter::get() * T::MaxVoters::get(),
|
||||
);
|
||||
let election_weight = pre_solve_weight
|
||||
.saturating_sub(post_solve_weight)
|
||||
.saturating_add(election_weight);
|
||||
|
||||
let to_seconds = |w: &Weight| {
|
||||
w.ref_time() as f32 /
|
||||
@@ -534,8 +577,8 @@ pub mod pallet {
|
||||
/// the outgoing member is slashed.
|
||||
///
|
||||
/// If a runner-up is available, then the best runner-up will be removed and replaces the
|
||||
/// outgoing member. Otherwise, if `rerun_election` is `true`, a new phragmen election is
|
||||
/// started, else, nothing happens.
|
||||
/// outgoing member. Otherwise, if `rerun_election` is `true`, a new election is started,
|
||||
/// else, nothing happens.
|
||||
///
|
||||
/// If `slash_bond` is set to true, the bond of the member being removed is slashed. Else,
|
||||
/// it is returned.
|
||||
@@ -565,7 +608,7 @@ pub mod pallet {
|
||||
Self::deposit_event(Event::MemberKicked { member: who });
|
||||
|
||||
if rerun_election {
|
||||
Self::do_phragmen();
|
||||
Self::do_election();
|
||||
}
|
||||
|
||||
// no refund needed.
|
||||
@@ -664,6 +707,8 @@ pub mod pallet {
|
||||
InvalidRenouncing,
|
||||
/// Prediction regarding replacement after member removal is wrong.
|
||||
InvalidReplacement,
|
||||
/// No candidates for the next term.
|
||||
EmptyTerm,
|
||||
}
|
||||
|
||||
/// The current elected members.
|
||||
@@ -742,7 +787,7 @@ pub mod pallet {
|
||||
Members::<T>::mutate(|members| {
|
||||
match members.binary_search_by(|m| m.who.cmp(member)) {
|
||||
Ok(_) => {
|
||||
panic!("Duplicate member in elections-phragmen genesis: {}", member)
|
||||
panic!("Duplicate member in elections genesis: {}", member)
|
||||
},
|
||||
Err(pos) => members.insert(
|
||||
pos,
|
||||
@@ -934,11 +979,77 @@ impl<T: Config> Pallet<T> {
|
||||
debug_assert!(_remainder.is_zero());
|
||||
}
|
||||
|
||||
/// Run the phragmen election with all required side processes and state updates, if election
|
||||
/// succeeds. Else, it will emit an `ElectionError` event.
|
||||
/// Run an election with all required side processes and state updates, if election
|
||||
/// succeeds. Else, it will emit an `ElectionError` event. The election algorithm is defined
|
||||
/// by the implementor of `Self::ElectionSolver`.
|
||||
///
|
||||
/// Calls the appropriate [`ChangeMembers`] function variant internally.
|
||||
fn do_phragmen() -> Weight {
|
||||
fn do_election() -> Weight {
|
||||
let PreElectionResults {
|
||||
num_to_elect,
|
||||
candidate_ids,
|
||||
candidates_and_deposit,
|
||||
voters_and_stakes,
|
||||
voters_and_votes,
|
||||
num_edges,
|
||||
} = match Self::do_pre_solve_election() {
|
||||
Ok(results) => results,
|
||||
Err(err) => match err {
|
||||
Error::EmptyTerm => {
|
||||
Self::deposit_event(Event::EmptyTerm);
|
||||
return T::DbWeight::get().reads(3)
|
||||
},
|
||||
Error::TooManyVotes => {
|
||||
Self::deposit_event(Event::ElectionError);
|
||||
log!(error, "Failed to run election. Number of voters exceeded",);
|
||||
let max_voters = <T as Config>::MaxVoters::get() as usize;
|
||||
return T::DbWeight::get().reads(3 + max_voters as u64)
|
||||
},
|
||||
_ => {
|
||||
log!(error, "Unexpected pre-election error",);
|
||||
let max_voters = <T as Config>::MaxVoters::get() as usize;
|
||||
return T::DbWeight::get().reads(3 + max_voters as u64)
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let num_candidates = candidates_and_deposit.len() as u32;
|
||||
let num_voters = voters_and_votes.len() as u32;
|
||||
let num_edges = num_edges;
|
||||
|
||||
let election_winners =
|
||||
T::ElectionSolver::solve(num_to_elect, candidate_ids, voters_and_votes)
|
||||
.map(
|
||||
|ElectionResult::<
|
||||
T::AccountId,
|
||||
<T::ElectionSolver as NposSolver>::Accuracy,
|
||||
> {
|
||||
winners,
|
||||
assignments: _,
|
||||
}| winners,
|
||||
)
|
||||
.map_err(|e| {
|
||||
log!(warn, "Failed to run election [{:?}].", e);
|
||||
Self::deposit_event(Event::ElectionError);
|
||||
});
|
||||
|
||||
let post_election_weight = if let Ok(winners) = election_winners {
|
||||
Self::do_post_solve_election(winners, candidates_and_deposit, voters_and_stakes);
|
||||
T::WeightInfo::post_solve_election(num_candidates, num_voters, num_edges)
|
||||
} else {
|
||||
Weight::zero()
|
||||
};
|
||||
|
||||
T::ElectionSolver::weight::<T::SolverWeightInfo>(num_candidates, num_voters, num_edges)
|
||||
.saturating_add(T::WeightInfo::pre_solve_election(
|
||||
num_candidates,
|
||||
num_voters,
|
||||
num_edges,
|
||||
))
|
||||
.saturating_add(post_election_weight)
|
||||
}
|
||||
|
||||
fn do_pre_solve_election() -> Result<PreElectionResults<T>, Error<T>> {
|
||||
let desired_seats = T::DesiredMembers::get() as usize;
|
||||
let desired_runners_up = T::DesiredRunnersUp::get() as usize;
|
||||
let num_to_elect = desired_runners_up + desired_seats;
|
||||
@@ -948,44 +1059,33 @@ impl<T: Config> Pallet<T> {
|
||||
candidates_and_deposit.append(&mut Self::implicit_candidates_with_deposit());
|
||||
|
||||
if candidates_and_deposit.len().is_zero() {
|
||||
Self::deposit_event(Event::EmptyTerm);
|
||||
return T::DbWeight::get().reads(3)
|
||||
return Err(Error::EmptyTerm)
|
||||
}
|
||||
|
||||
// All of the new winners that come out of phragmen will thus have a deposit recorded.
|
||||
// All of the new winners that come out of the election will thus have a deposit recorded.
|
||||
let candidate_ids =
|
||||
candidates_and_deposit.iter().map(|(x, _)| x).cloned().collect::<Vec<_>>();
|
||||
|
||||
// helper closures to deal with balance/stake.
|
||||
let total_issuance = T::Currency::total_issuance();
|
||||
let to_votes = |b: BalanceOf<T>| T::CurrencyToVote::to_vote(b, total_issuance);
|
||||
let to_balance = |e: ExtendedBalance| T::CurrencyToVote::to_currency(e, total_issuance);
|
||||
|
||||
let mut num_edges: u32 = 0;
|
||||
|
||||
let max_voters = <T as Config>::MaxVoters::get() as usize;
|
||||
// used for prime election.
|
||||
let mut voters_and_stakes = Vec::new();
|
||||
match Voting::<T>::iter().try_for_each(|(voter, Voter { stake, votes, .. })| {
|
||||
|
||||
Voting::<T>::iter().try_for_each(|(voter, Voter { stake, votes, .. })| {
|
||||
if voters_and_stakes.len() < max_voters {
|
||||
voters_and_stakes.push((voter, stake, votes));
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::TooManyVotes)
|
||||
}
|
||||
}) {
|
||||
Ok(_) => (),
|
||||
Err(_) => {
|
||||
log::error!(
|
||||
target: LOG_TARGET,
|
||||
"Failed to run election. Number of voters exceeded",
|
||||
);
|
||||
Self::deposit_event(Event::ElectionError);
|
||||
return T::DbWeight::get().reads(3 + max_voters as u64)
|
||||
},
|
||||
}
|
||||
})?;
|
||||
|
||||
// used for phragmen.
|
||||
// used for elections.
|
||||
let voters_and_votes = voters_and_stakes
|
||||
.iter()
|
||||
.cloned()
|
||||
@@ -995,157 +1095,144 @@ impl<T: Config> Pallet<T> {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let weight_candidates = candidates_and_deposit.len() as u32;
|
||||
let weight_voters = voters_and_votes.len() as u32;
|
||||
let weight_edges = num_edges;
|
||||
let _ =
|
||||
sp_npos_elections::seq_phragmen(num_to_elect, candidate_ids, voters_and_votes, None)
|
||||
.map(|ElectionResult::<T::AccountId, Perbill> { winners, assignments: _ }| {
|
||||
// this is already sorted by id.
|
||||
let old_members_ids_sorted = <Members<T>>::take()
|
||||
.into_iter()
|
||||
.map(|m| m.who)
|
||||
.collect::<Vec<T::AccountId>>();
|
||||
// this one needs a sort by id.
|
||||
let mut old_runners_up_ids_sorted = <RunnersUp<T>>::take()
|
||||
.into_iter()
|
||||
.map(|r| r.who)
|
||||
.collect::<Vec<T::AccountId>>();
|
||||
old_runners_up_ids_sorted.sort();
|
||||
Ok(PreElectionResults {
|
||||
num_to_elect,
|
||||
candidate_ids,
|
||||
candidates_and_deposit,
|
||||
voters_and_stakes,
|
||||
voters_and_votes,
|
||||
num_edges,
|
||||
})
|
||||
}
|
||||
|
||||
// filter out those who end up with no backing stake.
|
||||
let mut new_set_with_stake = winners
|
||||
.into_iter()
|
||||
.filter_map(
|
||||
|(m, b)| if b.is_zero() { None } else { Some((m, to_balance(b))) },
|
||||
)
|
||||
.collect::<Vec<(T::AccountId, BalanceOf<T>)>>();
|
||||
fn do_post_solve_election(
|
||||
winners: Vec<(T::AccountId, u128)>,
|
||||
candidates_and_deposit: Vec<(T::AccountId, BalanceOf<T>)>,
|
||||
voters_and_stakes: Vec<(T::AccountId, BalanceOf<T>, Vec<T::AccountId>)>,
|
||||
) {
|
||||
let desired_seats = T::DesiredMembers::get() as usize;
|
||||
let total_issuance = T::Currency::total_issuance();
|
||||
let to_balance = |e: ExtendedBalance| T::CurrencyToVote::to_currency(e, total_issuance);
|
||||
|
||||
// OPTIMIZATION NOTE: we could bail out here if `new_set.len() == 0`. There
|
||||
// isn't much left to do. Yet, re-arranging the code would require duplicating
|
||||
// the slashing of exposed candidates, cleaning any previous members, and so on.
|
||||
// For now, in favor of readability and veracity, we keep it simple.
|
||||
// this is already sorted by id.
|
||||
let old_members_ids_sorted =
|
||||
<Members<T>>::take().into_iter().map(|m| m.who).collect::<Vec<T::AccountId>>();
|
||||
// this one needs sorted by id.
|
||||
let mut old_runners_up_ids_sorted =
|
||||
<RunnersUp<T>>::take().into_iter().map(|r| r.who).collect::<Vec<T::AccountId>>();
|
||||
old_runners_up_ids_sorted.sort();
|
||||
|
||||
// split new set into winners and runners up.
|
||||
let split_point = desired_seats.min(new_set_with_stake.len());
|
||||
let mut new_members_sorted_by_id =
|
||||
new_set_with_stake.drain(..split_point).collect::<Vec<_>>();
|
||||
new_members_sorted_by_id.sort_by(|i, j| i.0.cmp(&j.0));
|
||||
// filter out those who end up with no backing stake.
|
||||
let mut new_set_with_stake = winners
|
||||
.into_iter()
|
||||
.filter_map(|(m, b)| if b.is_zero() { None } else { Some((m, to_balance(b))) })
|
||||
.collect::<Vec<(T::AccountId, BalanceOf<T>)>>();
|
||||
|
||||
// all the rest will be runners-up
|
||||
new_set_with_stake.reverse();
|
||||
let new_runners_up_sorted_by_rank = new_set_with_stake;
|
||||
let mut new_runners_up_ids_sorted = new_runners_up_sorted_by_rank
|
||||
.iter()
|
||||
.map(|(r, _)| r.clone())
|
||||
.collect::<Vec<_>>();
|
||||
new_runners_up_ids_sorted.sort();
|
||||
// OPTIMIZATION NOTE: we could bail out here if `new_set.len() == 0`. There
|
||||
// isn't much left to do. Yet, re-arranging the code would require duplicating
|
||||
// the slashing of exposed candidates, cleaning any previous members, and so on.
|
||||
// For now, in favor of readability and veracity, we keep it simple.
|
||||
|
||||
// Now we select a prime member using a [Borda
|
||||
// count](https://en.wikipedia.org/wiki/Borda_count). We weigh everyone's vote for
|
||||
// that new member by a multiplier based on the order of the votes. i.e. the
|
||||
// first person a voter votes for gets a 16x multiplier, the next person gets a
|
||||
// 15x multiplier, an so on... (assuming `T::MaxVotesPerVoter` = 16)
|
||||
let mut prime_votes = new_members_sorted_by_id
|
||||
.iter()
|
||||
.map(|c| (&c.0, BalanceOf::<T>::zero()))
|
||||
.collect::<Vec<_>>();
|
||||
for (_, stake, votes) in voters_and_stakes.into_iter() {
|
||||
for (vote_multiplier, who) in
|
||||
votes.iter().enumerate().map(|(vote_position, who)| {
|
||||
((T::MaxVotesPerVoter::get() as usize - vote_position) as u32, who)
|
||||
}) {
|
||||
if let Ok(i) = prime_votes.binary_search_by_key(&who, |k| k.0) {
|
||||
prime_votes[i].1 = prime_votes[i]
|
||||
.1
|
||||
.saturating_add(stake.saturating_mul(vote_multiplier.into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// We then select the new member with the highest weighted stake. In the case of
|
||||
// a tie, the last person in the list with the tied score is selected. This is
|
||||
// the person with the "highest" account id based on the sort above.
|
||||
let prime = prime_votes.into_iter().max_by_key(|x| x.1).map(|x| x.0.clone());
|
||||
// split new set into winners and runners up.
|
||||
let split_point = desired_seats.min(new_set_with_stake.len());
|
||||
let mut new_members_sorted_by_id =
|
||||
new_set_with_stake.drain(..split_point).collect::<Vec<_>>();
|
||||
new_members_sorted_by_id.sort_by(|i, j| i.0.cmp(&j.0));
|
||||
|
||||
// new_members_sorted_by_id is sorted by account id.
|
||||
let new_members_ids_sorted = new_members_sorted_by_id
|
||||
.iter()
|
||||
.map(|(m, _)| m.clone())
|
||||
.collect::<Vec<T::AccountId>>();
|
||||
// all the rest will be runners-up
|
||||
new_set_with_stake.reverse();
|
||||
let new_runners_up_sorted_by_rank = new_set_with_stake;
|
||||
let mut new_runners_up_ids_sorted =
|
||||
new_runners_up_sorted_by_rank.iter().map(|(r, _)| r.clone()).collect::<Vec<_>>();
|
||||
new_runners_up_ids_sorted.sort();
|
||||
|
||||
// report member changes. We compute diff because we need the outgoing list.
|
||||
let (incoming, outgoing) = T::ChangeMembers::compute_members_diff_sorted(
|
||||
&new_members_ids_sorted,
|
||||
&old_members_ids_sorted,
|
||||
);
|
||||
T::ChangeMembers::change_members_sorted(
|
||||
&incoming,
|
||||
&outgoing,
|
||||
&new_members_ids_sorted,
|
||||
);
|
||||
T::ChangeMembers::set_prime(prime);
|
||||
// Now we select a prime member using a [Borda
|
||||
// count](https://en.wikipedia.org/wiki/Borda_count). We weigh everyone's vote for
|
||||
// that new member by a multiplier based on the order of the votes. i.e. the
|
||||
// first person a voter votes for gets a 16x multiplier, the next person gets a
|
||||
// 15x multiplier, an so on... (assuming `T::MaxVotesPerVoter` = 16).
|
||||
let mut prime_votes = new_members_sorted_by_id
|
||||
.iter()
|
||||
.map(|c| (&c.0, BalanceOf::<T>::zero()))
|
||||
.collect::<Vec<_>>();
|
||||
for (_, stake, votes) in voters_and_stakes.into_iter() {
|
||||
for (vote_multiplier, who) in votes.iter().enumerate().map(|(vote_position, who)| {
|
||||
((T::MaxVotesPerVoter::get() as usize - vote_position) as u32, who)
|
||||
}) {
|
||||
if let Ok(i) = prime_votes.binary_search_by_key(&who, |k| k.0) {
|
||||
prime_votes[i].1 = prime_votes[i]
|
||||
.1
|
||||
.saturating_add(stake.saturating_mul(vote_multiplier.into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// We then select the new member with the highest weighted stake. In the case of
|
||||
// a tie, the last person in the list with the tied score is selected. This is
|
||||
// the person with the "highest" account id based on the sort above.
|
||||
let prime = prime_votes.into_iter().max_by_key(|x| x.1).map(|x| x.0.clone());
|
||||
|
||||
// All candidates/members/runners-up who are no longer retaining a position as a
|
||||
// seat holder will lose their bond.
|
||||
candidates_and_deposit.iter().for_each(|(c, d)| {
|
||||
if new_members_ids_sorted.binary_search(c).is_err() &&
|
||||
new_runners_up_ids_sorted.binary_search(c).is_err()
|
||||
{
|
||||
let (imbalance, _) = T::Currency::slash_reserved(c, *d);
|
||||
T::LoserCandidate::on_unbalanced(imbalance);
|
||||
Self::deposit_event(Event::CandidateSlashed {
|
||||
candidate: c.clone(),
|
||||
amount: *d,
|
||||
});
|
||||
}
|
||||
});
|
||||
// new_members_sorted_by_id is sorted by account id.
|
||||
let new_members_ids_sorted = new_members_sorted_by_id
|
||||
.iter()
|
||||
.map(|(m, _)| m.clone())
|
||||
.collect::<Vec<T::AccountId>>();
|
||||
|
||||
// write final values to storage.
|
||||
let deposit_of_candidate = |x: &T::AccountId| -> BalanceOf<T> {
|
||||
// defensive-only. This closure is used against the new members and new
|
||||
// runners-up, both of which are phragmen winners and thus must have
|
||||
// deposit.
|
||||
candidates_and_deposit
|
||||
.iter()
|
||||
.find_map(|(c, d)| if c == x { Some(*d) } else { None })
|
||||
.defensive_unwrap_or_default()
|
||||
};
|
||||
// fetch deposits from the one recorded one. This will make sure that a
|
||||
// candidate who submitted candidacy before a change to candidacy deposit will
|
||||
// have the correct amount recorded.
|
||||
<Members<T>>::put(
|
||||
new_members_sorted_by_id
|
||||
.iter()
|
||||
.map(|(who, stake)| SeatHolder {
|
||||
deposit: deposit_of_candidate(who),
|
||||
who: who.clone(),
|
||||
stake: *stake,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
<RunnersUp<T>>::put(
|
||||
new_runners_up_sorted_by_rank
|
||||
.into_iter()
|
||||
.map(|(who, stake)| SeatHolder {
|
||||
deposit: deposit_of_candidate(&who),
|
||||
who,
|
||||
stake,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
// report member changes. We compute diff because we need the outgoing list.
|
||||
let (incoming, outgoing) = T::ChangeMembers::compute_members_diff_sorted(
|
||||
&new_members_ids_sorted,
|
||||
&old_members_ids_sorted,
|
||||
);
|
||||
T::ChangeMembers::change_members_sorted(&incoming, &outgoing, &new_members_ids_sorted);
|
||||
T::ChangeMembers::set_prime(prime);
|
||||
|
||||
// clean candidates.
|
||||
<Candidates<T>>::kill();
|
||||
// All candidates/members/runners-up who are no longer retaining a position as a
|
||||
// seat holder will lose their bond.
|
||||
candidates_and_deposit.iter().for_each(|(c, d)| {
|
||||
if new_members_ids_sorted.binary_search(c).is_err() &&
|
||||
new_runners_up_ids_sorted.binary_search(c).is_err()
|
||||
{
|
||||
let (imbalance, _) = T::Currency::slash_reserved(c, *d);
|
||||
T::LoserCandidate::on_unbalanced(imbalance);
|
||||
Self::deposit_event(Event::CandidateSlashed { candidate: c.clone(), amount: *d });
|
||||
}
|
||||
});
|
||||
|
||||
Self::deposit_event(Event::NewTerm { new_members: new_members_sorted_by_id });
|
||||
<ElectionRounds<T>>::mutate(|v| *v += 1);
|
||||
// write final values to storage.
|
||||
let deposit_of_candidate = |x: &T::AccountId| -> BalanceOf<T> {
|
||||
// defensive-only. This closure is used against the new members and new
|
||||
// runners-up, both of which are election winners and thus must have
|
||||
// deposit.
|
||||
candidates_and_deposit
|
||||
.iter()
|
||||
.find_map(|(c, d)| if c == x { Some(*d) } else { None })
|
||||
.defensive_unwrap_or_default()
|
||||
};
|
||||
// fetch deposits from the one recorded one. This will make sure that a
|
||||
// candidate who submitted candidacy before a change to candidacy deposit will
|
||||
// have the correct amount recorded.
|
||||
<Members<T>>::put(
|
||||
new_members_sorted_by_id
|
||||
.iter()
|
||||
.map(|(who, stake)| SeatHolder {
|
||||
deposit: deposit_of_candidate(who),
|
||||
who: who.clone(),
|
||||
stake: *stake,
|
||||
})
|
||||
.map_err(|e| {
|
||||
log::error!(target: LOG_TARGET, "Failed to run election [{:?}].", e,);
|
||||
Self::deposit_event(Event::ElectionError);
|
||||
});
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
<RunnersUp<T>>::put(
|
||||
new_runners_up_sorted_by_rank
|
||||
.into_iter()
|
||||
.map(|(who, stake)| SeatHolder { deposit: deposit_of_candidate(&who), who, stake })
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
T::WeightInfo::election_phragmen(weight_candidates, weight_voters, weight_edges)
|
||||
// clean candidates.
|
||||
<Candidates<T>>::kill();
|
||||
|
||||
log!(info, "New term election successful.");
|
||||
Self::deposit_event(Event::NewTerm { new_members: new_members_sorted_by_id });
|
||||
<ElectionRounds<T>>::mutate(|v| *v += 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1196,7 +1283,8 @@ impl<T: Config> ContainsLengthBound for Pallet<T> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate as elections_phragmen;
|
||||
use crate as elections;
|
||||
use frame_election_provider_support::{weights::SubstrateWeight, ApprovalVoting};
|
||||
use frame_support::{
|
||||
assert_noop, assert_ok,
|
||||
dispatch::DispatchResultWithPostInfo,
|
||||
@@ -1208,7 +1296,7 @@ mod tests {
|
||||
use sp_runtime::{
|
||||
testing::Header,
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
BuildStorage,
|
||||
BuildStorage, Perbill,
|
||||
};
|
||||
use substrate_test_utils::assert_eq_uvec;
|
||||
|
||||
@@ -1307,13 +1395,13 @@ mod tests {
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ElectionsPhragmenPalletId: LockIdentifier = *b"phrelect";
|
||||
pub const PhragmenMaxVoters: u32 = 1000;
|
||||
pub const PhragmenMaxCandidates: u32 = 100;
|
||||
pub const ElectionsPalletId: LockIdentifier = *b"phrelect";
|
||||
pub const MaxVoters: u32 = 256;
|
||||
pub const MaxCandidates: u32 = 64;
|
||||
}
|
||||
|
||||
impl Config for Test {
|
||||
type PalletId = ElectionsPhragmenPalletId;
|
||||
type PalletId = ElectionsPalletId;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Currency = Balances;
|
||||
type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote;
|
||||
@@ -1328,9 +1416,11 @@ mod tests {
|
||||
type LoserCandidate = ();
|
||||
type KickedMember = ();
|
||||
type WeightInfo = ();
|
||||
type MaxVoters = PhragmenMaxVoters;
|
||||
type MaxVoters = MaxVoters;
|
||||
type MaxCandidates = MaxCandidates;
|
||||
type ElectionSolver = ApprovalVoting<Self::AccountId, Perbill>;
|
||||
type SolverWeightInfo = SubstrateWeight<Test>;
|
||||
type MaxVotesPerVoter = ConstU32<16>;
|
||||
type MaxCandidates = PhragmenMaxCandidates;
|
||||
}
|
||||
|
||||
pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
|
||||
@@ -1345,7 +1435,7 @@ mod tests {
|
||||
{
|
||||
System: frame_system::{Pallet, Call, Event<T>},
|
||||
Balances: pallet_balances::{Pallet, Call, Event<T>, Config<T>},
|
||||
Elections: elections_phragmen::{Pallet, Call, Event<T>, Config<T>},
|
||||
Elections: elections::{Pallet, Call, Event<T>, Config<T>},
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1406,9 +1496,7 @@ mod tests {
|
||||
(6, 60 * self.balance_factor),
|
||||
],
|
||||
},
|
||||
elections: elections_phragmen::GenesisConfig::<Test> {
|
||||
members: self.genesis_members,
|
||||
},
|
||||
elections: elections::GenesisConfig::<Test> { members: self.genesis_members },
|
||||
}
|
||||
.build_storage()
|
||||
.unwrap()
|
||||
@@ -1466,7 +1554,7 @@ mod tests {
|
||||
.get(0)
|
||||
.cloned()
|
||||
.map(|lock| {
|
||||
assert_eq!(lock.id, ElectionsPhragmenPalletId::get());
|
||||
assert_eq!(lock.id, ElectionsPalletId::get());
|
||||
lock.amount
|
||||
})
|
||||
.unwrap_or_default()
|
||||
@@ -1657,7 +1745,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Duplicate member in elections-phragmen genesis: 2"]
|
||||
#[should_panic = "Duplicate member in elections genesis: 2"]
|
||||
fn genesis_members_cannot_be_duplicate() {
|
||||
ExtBuilder::default()
|
||||
.desired_members(3)
|
||||
@@ -0,0 +1,397 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2022 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_elections
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
|
||||
//! DATE: 2022-11-22, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
|
||||
|
||||
// Executed Command:
|
||||
// /home/benchbot/cargo_target_dir/production/substrate
|
||||
// benchmark
|
||||
// pallet
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --extrinsic=*
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --heap-pages=4096
|
||||
// --json-file=/var/lib/gitlab-runner/builds/zyw4fam_/0/parity/mirrors/substrate/.git/.artifacts/bench.json
|
||||
// --pallet=pallet_elections
|
||||
// --chain=dev
|
||||
// --header=./HEADER-APACHE2
|
||||
// --output=./frame/elections/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_elections.
|
||||
pub trait WeightInfo {
|
||||
fn vote_equal(v: u32, ) -> Weight;
|
||||
fn vote_more(v: u32, ) -> Weight;
|
||||
fn vote_less(v: u32, ) -> Weight;
|
||||
fn remove_voter() -> Weight;
|
||||
fn submit_candidacy(c: u32, ) -> Weight;
|
||||
fn renounce_candidacy_candidate(c: u32, ) -> Weight;
|
||||
fn renounce_candidacy_members() -> Weight;
|
||||
fn renounce_candidacy_runners_up() -> Weight;
|
||||
fn remove_member_without_replacement() -> Weight;
|
||||
fn remove_member_with_replacement() -> Weight;
|
||||
fn clean_defunct_voters(v: u32, d: u32, ) -> Weight;
|
||||
fn pre_solve_election(c: u32, v: u32, e: u32, ) -> Weight;
|
||||
fn post_solve_election(c: u32, v: u32, e: u32, ) -> Weight;
|
||||
}
|
||||
|
||||
/// Weights for pallet_elections using the Substrate node and recommended hardware.
|
||||
pub struct SubstrateWeight<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Voting (r:1 w:1)
|
||||
// Storage: Balances Locks (r:1 w:1)
|
||||
/// The range of component `v` is `[1, 16]`.
|
||||
fn vote_equal(v: u32, ) -> Weight {
|
||||
// Minimum execution time: 37_500 nanoseconds.
|
||||
Weight::from_ref_time(38_575_649)
|
||||
// Standard Error: 2_961
|
||||
.saturating_add(Weight::from_ref_time(154_225).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Voting (r:1 w:1)
|
||||
// Storage: Balances Locks (r:1 w:1)
|
||||
/// The range of component `v` is `[2, 16]`.
|
||||
fn vote_more(v: u32, ) -> Weight {
|
||||
// Minimum execution time: 48_836 nanoseconds.
|
||||
Weight::from_ref_time(49_566_969)
|
||||
// Standard Error: 3_258
|
||||
.saturating_add(Weight::from_ref_time(153_342).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Voting (r:1 w:1)
|
||||
// Storage: Balances Locks (r:1 w:1)
|
||||
/// The range of component `v` is `[2, 16]`.
|
||||
fn vote_less(v: u32, ) -> Weight {
|
||||
// Minimum execution time: 47_664 nanoseconds.
|
||||
Weight::from_ref_time(48_768_157)
|
||||
// Standard Error: 3_321
|
||||
.saturating_add(Weight::from_ref_time(215_112).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: Elections Voting (r:1 w:1)
|
||||
// Storage: Balances Locks (r:1 w:1)
|
||||
fn remove_voter() -> Weight {
|
||||
// Minimum execution time: 47_146 nanoseconds.
|
||||
Weight::from_ref_time(47_846_000)
|
||||
.saturating_add(T::DbWeight::get().reads(2))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:1)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// The range of component `c` is `[1, 1000]`.
|
||||
fn submit_candidacy(c: u32, ) -> Weight {
|
||||
// Minimum execution time: 42_799 nanoseconds.
|
||||
Weight::from_ref_time(46_920_164)
|
||||
// Standard Error: 780
|
||||
.saturating_add(Weight::from_ref_time(81_672).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(3))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:1)
|
||||
/// The range of component `c` is `[1, 1000]`.
|
||||
fn renounce_candidacy_candidate(c: u32, ) -> Weight {
|
||||
// Minimum execution time: 40_946 nanoseconds.
|
||||
Weight::from_ref_time(53_109_738)
|
||||
// Standard Error: 1_220
|
||||
.saturating_add(Weight::from_ref_time(60_643).saturating_mul(c.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
// Storage: Elections Members (r:1 w:1)
|
||||
// Storage: Elections RunnersUp (r:1 w:1)
|
||||
// Storage: Council Prime (r:1 w:1)
|
||||
// Storage: Council Proposals (r:1 w:0)
|
||||
// Storage: Council Members (r:0 w:1)
|
||||
fn renounce_candidacy_members() -> Weight {
|
||||
// Minimum execution time: 53_454 nanoseconds.
|
||||
Weight::from_ref_time(53_921_000)
|
||||
.saturating_add(T::DbWeight::get().reads(4))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
// Storage: Elections RunnersUp (r:1 w:1)
|
||||
fn renounce_candidacy_runners_up() -> Weight {
|
||||
// Minimum execution time: 41_275 nanoseconds.
|
||||
Weight::from_ref_time(42_444_000)
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
// Storage: Benchmark Override (r:0 w:0)
|
||||
fn remove_member_without_replacement() -> Weight {
|
||||
// Minimum execution time: 2_000_000_000 nanoseconds.
|
||||
Weight::from_ref_time(2_000_000_000_000)
|
||||
}
|
||||
// Storage: Elections Members (r:1 w:1)
|
||||
// Storage: System Account (r:1 w:1)
|
||||
// Storage: Elections RunnersUp (r:1 w:1)
|
||||
// Storage: Council Prime (r:1 w:1)
|
||||
// Storage: Council Proposals (r:1 w:0)
|
||||
// Storage: Council Members (r:0 w:1)
|
||||
fn remove_member_with_replacement() -> Weight {
|
||||
// Minimum execution time: 62_040 nanoseconds.
|
||||
Weight::from_ref_time(62_569_000)
|
||||
.saturating_add(T::DbWeight::get().reads(5))
|
||||
.saturating_add(T::DbWeight::get().writes(5))
|
||||
}
|
||||
// Storage: Elections Voting (r:5001 w:5000)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Balances Locks (r:5000 w:5000)
|
||||
// Storage: System Account (r:5000 w:5000)
|
||||
/// The range of component `v` is `[5000, 10000]`.
|
||||
/// The range of component `d` is `[0, 5000]`.
|
||||
fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight {
|
||||
// Minimum execution time: 298_212_195 nanoseconds.
|
||||
Weight::from_ref_time(298_678_889_000)
|
||||
// Standard Error: 264_713
|
||||
.saturating_add(Weight::from_ref_time(38_222_955).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(4))
|
||||
.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(v.into())))
|
||||
.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into())))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Voting (r:10001 w:0)
|
||||
/// The range of component `c` is `[1, 1000]`.
|
||||
/// The range of component `v` is `[1, 10000]`.
|
||||
/// The range of component `e` is `[10000, 160000]`.
|
||||
fn pre_solve_election(_c: u32, v: u32, _e: u32, ) -> Weight {
|
||||
// Minimum execution time: 6_543_626 nanoseconds.
|
||||
Weight::from_ref_time(6_627_885_000)
|
||||
// Standard Error: 14_605
|
||||
.saturating_add(Weight::from_ref_time(7_613_226).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(296))
|
||||
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into())))
|
||||
}
|
||||
// Storage: Elections Members (r:1 w:1)
|
||||
// Storage: Elections RunnersUp (r:1 w:1)
|
||||
// Storage: Council Proposals (r:1 w:0)
|
||||
// Storage: Elections ElectionRounds (r:1 w:1)
|
||||
// Storage: Elections Candidates (r:0 w:1)
|
||||
// Storage: Council Members (r:0 w:1)
|
||||
// Storage: Council Prime (r:0 w:1)
|
||||
// Storage: System Account (r:1 w:1)
|
||||
/// The range of component `c` is `[1, 1000]`.
|
||||
/// The range of component `v` is `[1, 10000]`.
|
||||
/// The range of component `e` is `[10000, 160000]`.
|
||||
fn post_solve_election(c: u32, v: u32, _e: u32, ) -> Weight {
|
||||
// Minimum execution time: 3_843_566 nanoseconds.
|
||||
Weight::from_ref_time(3_854_020_000)
|
||||
// Standard Error: 59_766
|
||||
.saturating_add(Weight::from_ref_time(9_622_797).saturating_mul(c.into()))
|
||||
// Standard Error: 5_975
|
||||
.saturating_add(Weight::from_ref_time(541_471).saturating_mul(v.into()))
|
||||
.saturating_add(T::DbWeight::get().reads(4))
|
||||
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into())))
|
||||
.saturating_add(T::DbWeight::get().writes(6))
|
||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into())))
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility and tests
|
||||
impl WeightInfo for () {
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Voting (r:1 w:1)
|
||||
// Storage: Balances Locks (r:1 w:1)
|
||||
/// The range of component `v` is `[1, 16]`.
|
||||
fn vote_equal(v: u32, ) -> Weight {
|
||||
// Minimum execution time: 37_500 nanoseconds.
|
||||
Weight::from_ref_time(38_575_649)
|
||||
// Standard Error: 2_961
|
||||
.saturating_add(Weight::from_ref_time(154_225).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Voting (r:1 w:1)
|
||||
// Storage: Balances Locks (r:1 w:1)
|
||||
/// The range of component `v` is `[2, 16]`.
|
||||
fn vote_more(v: u32, ) -> Weight {
|
||||
// Minimum execution time: 48_836 nanoseconds.
|
||||
Weight::from_ref_time(49_566_969)
|
||||
// Standard Error: 3_258
|
||||
.saturating_add(Weight::from_ref_time(153_342).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Voting (r:1 w:1)
|
||||
// Storage: Balances Locks (r:1 w:1)
|
||||
/// The range of component `v` is `[2, 16]`.
|
||||
fn vote_less(v: u32, ) -> Weight {
|
||||
// Minimum execution time: 47_664 nanoseconds.
|
||||
Weight::from_ref_time(48_768_157)
|
||||
// Standard Error: 3_321
|
||||
.saturating_add(Weight::from_ref_time(215_112).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: Elections Voting (r:1 w:1)
|
||||
// Storage: Balances Locks (r:1 w:1)
|
||||
fn remove_voter() -> Weight {
|
||||
// Minimum execution time: 47_146 nanoseconds.
|
||||
Weight::from_ref_time(47_846_000)
|
||||
.saturating_add(RocksDbWeight::get().reads(2))
|
||||
.saturating_add(RocksDbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:1)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
/// The range of component `c` is `[1, 1000]`.
|
||||
fn submit_candidacy(c: u32, ) -> Weight {
|
||||
// Minimum execution time: 42_799 nanoseconds.
|
||||
Weight::from_ref_time(46_920_164)
|
||||
// Standard Error: 780
|
||||
.saturating_add(Weight::from_ref_time(81_672).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(3))
|
||||
.saturating_add(RocksDbWeight::get().writes(1))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:1)
|
||||
/// The range of component `c` is `[1, 1000]`.
|
||||
fn renounce_candidacy_candidate(c: u32, ) -> Weight {
|
||||
// Minimum execution time: 40_946 nanoseconds.
|
||||
Weight::from_ref_time(53_109_738)
|
||||
// Standard Error: 1_220
|
||||
.saturating_add(Weight::from_ref_time(60_643).saturating_mul(c.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(1))
|
||||
.saturating_add(RocksDbWeight::get().writes(1))
|
||||
}
|
||||
// Storage: Elections Members (r:1 w:1)
|
||||
// Storage: Elections RunnersUp (r:1 w:1)
|
||||
// Storage: Council Prime (r:1 w:1)
|
||||
// Storage: Council Proposals (r:1 w:0)
|
||||
// Storage: Council Members (r:0 w:1)
|
||||
fn renounce_candidacy_members() -> Weight {
|
||||
// Minimum execution time: 53_454 nanoseconds.
|
||||
Weight::from_ref_time(53_921_000)
|
||||
.saturating_add(RocksDbWeight::get().reads(4))
|
||||
.saturating_add(RocksDbWeight::get().writes(4))
|
||||
}
|
||||
// Storage: Elections RunnersUp (r:1 w:1)
|
||||
fn renounce_candidacy_runners_up() -> Weight {
|
||||
// Minimum execution time: 41_275 nanoseconds.
|
||||
Weight::from_ref_time(42_444_000)
|
||||
.saturating_add(RocksDbWeight::get().reads(1))
|
||||
.saturating_add(RocksDbWeight::get().writes(1))
|
||||
}
|
||||
// Storage: Benchmark Override (r:0 w:0)
|
||||
fn remove_member_without_replacement() -> Weight {
|
||||
// Minimum execution time: 2_000_000_000 nanoseconds.
|
||||
Weight::from_ref_time(2_000_000_000_000)
|
||||
}
|
||||
// Storage: Elections Members (r:1 w:1)
|
||||
// Storage: System Account (r:1 w:1)
|
||||
// Storage: Elections RunnersUp (r:1 w:1)
|
||||
// Storage: Council Prime (r:1 w:1)
|
||||
// Storage: Council Proposals (r:1 w:0)
|
||||
// Storage: Council Members (r:0 w:1)
|
||||
fn remove_member_with_replacement() -> Weight {
|
||||
// Minimum execution time: 62_040 nanoseconds.
|
||||
Weight::from_ref_time(62_569_000)
|
||||
.saturating_add(RocksDbWeight::get().reads(5))
|
||||
.saturating_add(RocksDbWeight::get().writes(5))
|
||||
}
|
||||
// Storage: Elections Voting (r:5001 w:5000)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Balances Locks (r:5000 w:5000)
|
||||
// Storage: System Account (r:5000 w:5000)
|
||||
/// The range of component `v` is `[5000, 10000]`.
|
||||
/// The range of component `d` is `[0, 5000]`.
|
||||
fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight {
|
||||
// Minimum execution time: 298_212_195 nanoseconds.
|
||||
Weight::from_ref_time(298_678_889_000)
|
||||
// Standard Error: 264_713
|
||||
.saturating_add(Weight::from_ref_time(38_222_955).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(4))
|
||||
.saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(v.into())))
|
||||
.saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(v.into())))
|
||||
}
|
||||
// Storage: Elections Candidates (r:1 w:0)
|
||||
// Storage: Elections Members (r:1 w:0)
|
||||
// Storage: Elections RunnersUp (r:1 w:0)
|
||||
// Storage: Elections Voting (r:10001 w:0)
|
||||
/// The range of component `c` is `[1, 1000]`.
|
||||
/// The range of component `v` is `[1, 10000]`.
|
||||
/// The range of component `e` is `[10000, 160000]`.
|
||||
fn pre_solve_election(_c: u32, v: u32, _e: u32, ) -> Weight {
|
||||
// Minimum execution time: 6_543_626 nanoseconds.
|
||||
Weight::from_ref_time(6_627_885_000)
|
||||
// Standard Error: 14_605
|
||||
.saturating_add(Weight::from_ref_time(7_613_226).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(296))
|
||||
.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into())))
|
||||
}
|
||||
// Storage: Elections Members (r:1 w:1)
|
||||
// Storage: Elections RunnersUp (r:1 w:1)
|
||||
// Storage: Council Proposals (r:1 w:0)
|
||||
// Storage: Elections ElectionRounds (r:1 w:1)
|
||||
// Storage: Elections Candidates (r:0 w:1)
|
||||
// Storage: Council Members (r:0 w:1)
|
||||
// Storage: Council Prime (r:0 w:1)
|
||||
// Storage: System Account (r:1 w:1)
|
||||
/// The range of component `c` is `[1, 1000]`.
|
||||
/// The range of component `v` is `[1, 10000]`.
|
||||
/// The range of component `e` is `[10000, 160000]`.
|
||||
fn post_solve_election(c: u32, v: u32, _e: u32, ) -> Weight {
|
||||
// Minimum execution time: 3_843_566 nanoseconds.
|
||||
Weight::from_ref_time(3_854_020_000)
|
||||
// Standard Error: 59_766
|
||||
.saturating_add(Weight::from_ref_time(9_622_797).saturating_mul(c.into()))
|
||||
// Standard Error: 5_975
|
||||
.saturating_add(Weight::from_ref_time(541_471).saturating_mul(v.into()))
|
||||
.saturating_add(RocksDbWeight::get().reads(4))
|
||||
.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(c.into())))
|
||||
.saturating_add(RocksDbWeight::get().writes(6))
|
||||
.saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(c.into())))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user