Update elections-phragmen weight to WeightInfo (#7161)

* Update elections-phragmen weight to WeightInfo

* Fix benchmark tests

* Update weights

* Update test

* Update another thest :"

* Weights from benchmarking machine

./substrate2/target/release/substrate benchmark --chain dev --steps 50 --repeat 20 --pallet pallet_elections_phragmen --extrinsic "*" --raw --execution=wasm --wasm-execution=compiled --output

* Update weights from the benchmarking machine

* Fix tests one last time

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Kian Paimani
2020-09-22 14:06:15 +02:00
committed by GitHub
parent fc77d1d466
commit f70ef87a0c
7 changed files with 336 additions and 128 deletions
+41 -67
View File
@@ -91,12 +91,12 @@ use sp_runtime::{
};
use frame_support::{
decl_storage, decl_event, ensure, decl_module, decl_error,
weights::{Weight, constants::{WEIGHT_PER_MICROS, WEIGHT_PER_NANOS}},
weights::Weight,
storage::{StorageMap, IterableStorageMap},
dispatch::{DispatchResultWithPostInfo, WithPostDispatchInfo},
traits::{
Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons,
ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus, InitializeMembers,
ChangeMembers, OnUnbalanced, WithdrawReason, Contains, InitializeMembers, BalanceStatus,
ContainsLengthBound,
}
};
@@ -104,6 +104,7 @@ use sp_npos_elections::{build_support_map, ExtendedBalance, VoteWeight, Election
use frame_system::{ensure_signed, ensure_root};
mod benchmarking;
mod default_weights;
/// The maximum votes allowed per voter.
pub const MAXIMUM_VOTE: usize = 16;
@@ -138,35 +139,17 @@ pub struct DefunctVoter<AccountId> {
}
pub trait WeightInfo {
fn vote(u: u32, ) -> Weight;
fn vote_update(u: u32, ) -> Weight;
fn remove_voter(u: u32, ) -> Weight;
fn vote(v: u32, ) -> Weight;
fn vote_update(v: u32, ) -> Weight;
fn remove_voter() -> Weight;
fn report_defunct_voter_correct(c: u32, v: u32, ) -> Weight;
fn report_defunct_voter_incorrect(c: u32, v: u32, ) -> Weight;
fn submit_candidacy(c: u32, ) -> Weight;
fn renounce_candidacy_candidate(c: u32, ) -> Weight;
fn renounce_candidacy_member_runner_up(u: u32, ) -> Weight;
fn remove_member_without_replacement(c: u32, ) -> Weight;
fn remove_member_with_replacement(u: u32, ) -> Weight;
fn remove_member_wrong_refund(u: u32, ) -> Weight;
fn on_initialize(c: u32, ) -> Weight;
fn phragmen(c: u32, v: u32, e: u32, ) -> Weight;
}
impl WeightInfo for () {
fn vote(_u: u32, ) -> Weight { 1_000_000_000 }
fn vote_update(_u: u32, ) -> Weight { 1_000_000_000 }
fn remove_voter(_u: u32, ) -> Weight { 1_000_000_000 }
fn report_defunct_voter_correct(_c: u32, _v: u32, ) -> Weight { 1_000_000_000 }
fn report_defunct_voter_incorrect(_c: u32, _v: u32, ) -> Weight { 1_000_000_000 }
fn submit_candidacy(_c: u32, ) -> Weight { 1_000_000_000 }
fn renounce_candidacy_candidate(_c: u32, ) -> Weight { 1_000_000_000 }
fn renounce_candidacy_member_runner_up(_u: u32, ) -> Weight { 1_000_000_000 }
fn remove_member_without_replacement(_c: u32, ) -> Weight { 1_000_000_000 }
fn remove_member_with_replacement(_u: u32, ) -> Weight { 1_000_000_000 }
fn remove_member_wrong_refund(_u: u32, ) -> Weight { 1_000_000_000 }
fn on_initialize(_c: u32, ) -> Weight { 1_000_000_000 }
fn phragmen(_c: u32, _v: u32, _e: u32, ) -> Weight { 1_000_000_000 }
fn renounce_candidacy_members() -> Weight;
fn renounce_candidacy_runners_up() -> Weight;
fn remove_member_with_replacement() -> Weight;
fn remove_member_wrong_refund() -> Weight;
}
pub trait Trait: frame_system::Trait {
@@ -350,13 +333,14 @@ decl_module! {
/// State reads:
/// - Candidates.len() + Members.len() + RunnersUp.len()
/// - Voting (is_voter)
/// - Lock
/// - [AccountBalance(who) (unreserve + total_balance)]
/// State writes:
/// - Voting
/// - Lock
/// - [AccountBalance(who) (unreserve -- only when creating a new voter)]
/// # </weight>
#[weight = 50 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(4, 2)]
#[weight = T::WeightInfo::vote(votes.len() as u32)]
fn vote(
origin,
votes: Vec<T::AccountId>,
@@ -412,7 +396,7 @@ decl_module! {
/// - Locks
/// - [AccountData(who)]
/// # </weight>
#[weight = 35 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 2)]
#[weight = T::WeightInfo::remove_voter()]
fn remove_voter(origin) {
let who = ensure_signed(origin)?;
ensure!(Self::is_voter(&who), Error::<T>::MustBeVoter);
@@ -447,15 +431,14 @@ decl_module! {
/// - Voting(reporter || target)
/// Note: the db access is worse with respect to db, which is when the report is correct.
/// # </weight>
#[weight =
Weight::from(defunct.candidate_count).saturating_mul(2 * WEIGHT_PER_MICROS)
.saturating_add(Weight::from(defunct.vote_count).saturating_mul(19 * WEIGHT_PER_MICROS))
.saturating_add(T::DbWeight::get().reads_writes(6, 3))
]
#[weight = T::WeightInfo::report_defunct_voter_correct(
defunct.candidate_count,
defunct.vote_count,
)]
fn report_defunct_voter(
origin,
defunct: DefunctVoter<<T::Lookup as StaticLookup>::Source>,
) {
) -> DispatchResultWithPostInfo {
let reporter = ensure_signed(origin)?;
let target = T::Lookup::lookup(defunct.who)?;
@@ -482,19 +465,25 @@ decl_module! {
);
let valid = Self::is_defunct_voter(&votes);
if valid {
let maybe_refund = if valid {
// reporter will get the voting bond of the target
T::Currency::repatriate_reserved(&target, &reporter, T::VotingBond::get(), BalanceStatus::Free)?;
// remove the target. They are defunct.
Self::do_remove_voter(&target, false);
None
} else {
// slash the bond of the reporter.
let imbalance = T::Currency::slash_reserved(&reporter, T::VotingBond::get()).0;
T::BadReport::on_unbalanced(imbalance);
// remove the reporter.
Self::do_remove_voter(&reporter, false);
}
Some(T::WeightInfo::report_defunct_voter_incorrect(
defunct.candidate_count,
defunct.vote_count,
))
};
Self::deposit_event(RawEvent::VoterReported(target, reporter, valid));
Ok(maybe_refund.into())
}
/// Submit oneself for candidacy.
@@ -509,7 +498,6 @@ decl_module! {
/// Base weight = 33.33 µs
/// Complexity of candidate_count: 0.375 µs
/// State reads:
/// - Candidates.len()
/// - Candidates
/// - Members
/// - RunnersUp
@@ -518,11 +506,7 @@ decl_module! {
/// - [AccountBalance(who)]
/// - Candidates
/// # </weight>
#[weight =
(35 * WEIGHT_PER_MICROS)
.saturating_add(Weight::from(*candidate_count).saturating_mul(375 * WEIGHT_PER_NANOS))
.saturating_add(T::DbWeight::get().reads_writes(4, 1))
]
#[weight = T::WeightInfo::submit_candidacy(*candidate_count)]
fn submit_candidacy(origin, #[compact] candidate_count: u32) {
let who = ensure_signed(origin)?;
@@ -582,23 +566,11 @@ decl_module! {
/// State writes:
/// - RunnersUp (remove_and_replace_member),
/// - [AccountData(who) (unreserve)]
///
/// Weight note: The call into changeMembers need to be accounted for.
/// </weight>
#[weight = match *renouncing {
Renouncing::Candidate(count) => {
(18 * WEIGHT_PER_MICROS)
.saturating_add(Weight::from(count).saturating_mul(235 * WEIGHT_PER_NANOS))
.saturating_add(T::DbWeight::get().reads_writes(1, 1))
},
Renouncing::Member => {
46 * WEIGHT_PER_MICROS +
T::DbWeight::get().reads_writes(2, 2)
},
Renouncing::RunnerUp => {
46 * WEIGHT_PER_MICROS +
T::DbWeight::get().reads_writes(1, 1)
}
Renouncing::Candidate(count) => T::WeightInfo::renounce_candidacy_candidate(count),
Renouncing::Member => T::WeightInfo::renounce_candidacy_members(),
Renouncing::RunnerUp => T::WeightInfo::renounce_candidacy_runners_up(),
}]
fn renounce_candidacy(origin, renouncing: Renouncing) {
let who = ensure_signed(origin)?;
@@ -659,7 +631,7 @@ decl_module! {
/// Else, since this is a root call and will go into phragmen, we assume full block for now.
/// # </weight>
#[weight = if *has_replacement {
50 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(3, 2)
T::WeightInfo::remove_member_with_replacement()
} else {
T::MaximumBlockWeight::get()
}]
@@ -677,7 +649,7 @@ decl_module! {
return Err(Error::<T>::InvalidReplacement.with_weight(
// refund. The weight value comes from a benchmark which is special to this.
// 5.751 µs
6 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 0)
T::WeightInfo::remove_member_wrong_refund()
));
} // else, prediction was correct.
@@ -832,7 +804,9 @@ impl<T: Trait> Module<T> {
/// Reads Members, RunnersUp, Candidates and Voting(who) from database.
fn is_defunct_voter(votes: &[T::AccountId]) -> bool {
votes.iter().all(|v|
!Self::is_member(v) && !Self::is_runner_up(v) && !Self::is_candidate(v).is_ok()
!Self::is_member(v) &&
!Self::is_runner_up(v) &&
!Self::is_candidate(v).is_ok()
)
}
@@ -906,12 +880,12 @@ impl<T: Trait> Module<T> {
// used for prime election.
let voters_and_stakes = Voting::<T>::iter()
.map(|(voter, (stake, targets))| { (voter, stake, targets) })
.map(|(voter, (stake, votes))| { (voter, stake, votes) })
.collect::<Vec<_>>();
// used for phragmen.
let voters_and_votes = voters_and_stakes.iter()
.cloned()
.map(|(voter, stake, targets)| { (voter, to_votes(stake), targets)} )
.map(|(voter, stake, votes)| { (voter, to_votes(stake), votes)} )
.collect::<Vec<_>>();
let maybe_phragmen_result = sp_npos_elections::seq_phragmen::<T::AccountId, Perbill>(
num_to_elect,
@@ -976,8 +950,8 @@ impl<T: Trait> Module<T> {
// 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 `MAXIMUM_VOTE` = 16)
let mut prime_votes: Vec<_> = new_members.iter().map(|c| (&c.0, BalanceOf::<T>::zero())).collect();
for (_, stake, targets) in voters_and_stakes.into_iter() {
for (vote_multiplier, who) in targets.iter()
for (_, stake, votes) in voters_and_stakes.into_iter() {
for (vote_multiplier, who) in votes.iter()
.enumerate()
.map(|(vote_position, who)| ((MAXIMUM_VOTE - vote_position) as u32, who))
{
@@ -2434,7 +2408,7 @@ mod tests {
assert_err_with_weight!(
Elections::remove_member(Origin::root(), 4, true),
Error::<Test>::InvalidReplacement,
Some(6000000),
Some(33777000), // only thing that matters for now is that it is NOT the full block.
);
});
@@ -2456,7 +2430,7 @@ mod tests {
assert_err_with_weight!(
Elections::remove_member(Origin::root(), 4, false),
Error::<Test>::InvalidReplacement,
Some(6000000) // only thing that matters for now is that it is NOT the full block.
Some(33777000) // only thing that matters for now is that it is NOT the full block.
);
});
}