Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
+31 -21
View File
@@ -21,11 +21,11 @@ use super::*;
use crate::Pallet as Staking;
use testing_utils::*;
use sp_runtime::traits::One;
use frame_system::RawOrigin;
pub use frame_benchmarking::{
benchmarks, account, whitelisted_caller, whitelist_account, impl_benchmark_test_suite,
account, benchmarks, impl_benchmark_test_suite, whitelist_account, whitelisted_caller,
};
use frame_system::RawOrigin;
use sp_runtime::traits::One;
const SEED: u32 = 0;
const MAX_SPANS: u32 = 100;
@@ -36,13 +36,15 @@ const MAX_SLASHES: u32 = 1000;
// Add slashing spans to a user account. Not relevant for actual use, only to benchmark
// read and write operations.
fn add_slashing_spans<T: Config>(who: &T::AccountId, spans: u32) {
if spans == 0 { return }
if spans == 0 {
return
}
// For the first slashing span, we initialize
let mut slashing_spans = crate::slashing::SlashingSpans::new(0);
SpanSlash::<T>::insert((who, 0), crate::slashing::SpanRecord::default());
for i in 1 .. spans {
for i in 1..spans {
assert!(slashing_spans.end_span(i));
SpanSlash::<T>::insert((who, i), crate::slashing::SpanRecord::default());
}
@@ -56,7 +58,7 @@ pub fn create_validator_with_nominators<T: Config>(
n: u32,
upper_bound: u32,
dead: bool,
destination: RewardDestination<T::AccountId>
destination: RewardDestination<T::AccountId>,
) -> Result<(T::AccountId, Vec<(T::AccountId, T::AccountId)>), &'static str> {
// Clean up any existing state.
clear_validators_and_nominators::<T>();
@@ -64,10 +66,8 @@ pub fn create_validator_with_nominators<T: Config>(
let mut points_individual = Vec::new();
let (v_stash, v_controller) = create_stash_controller::<T>(0, 100, destination.clone())?;
let validator_prefs = ValidatorPrefs {
commission: Perbill::from_percent(50),
.. Default::default()
};
let validator_prefs =
ValidatorPrefs { commission: Perbill::from_percent(50), ..Default::default() };
Staking::<T>::validate(RawOrigin::Signed(v_controller).into(), validator_prefs)?;
let stash_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(v_stash.clone());
@@ -77,14 +77,17 @@ pub fn create_validator_with_nominators<T: Config>(
let mut nominators = Vec::new();
// Give the validator n nominators, but keep total users in the system the same.
for i in 0 .. upper_bound {
for i in 0..upper_bound {
let (n_stash, n_controller) = if !dead {
create_stash_controller::<T>(u32::MAX - i, 100, destination.clone())?
} else {
create_stash_and_dead_controller::<T>(u32::MAX - i, 100, destination.clone())?
};
if i < n {
Staking::<T>::nominate(RawOrigin::Signed(n_controller.clone()).into(), vec![stash_lookup.clone()])?;
Staking::<T>::nominate(
RawOrigin::Signed(n_controller.clone()).into(),
vec![stash_lookup.clone()],
)?;
nominators.push((n_stash, n_controller));
}
}
@@ -639,7 +642,7 @@ benchmarks! {
#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{ExtBuilder, Test, Balances, Staking, Origin};
use crate::mock::{Balances, ExtBuilder, Origin, Staking, Test};
use frame_support::assert_ok;
#[test]
@@ -654,7 +657,8 @@ mod tests {
<Test as Config>::MAX_NOMINATIONS as usize,
false,
None,
).unwrap();
)
.unwrap();
let count_validators = Validators::<Test>::iter().count();
let count_nominators = Nominators::<Test>::iter().count();
@@ -674,7 +678,8 @@ mod tests {
<Test as Config>::MaxNominatorRewardedPerValidator::get() as u32,
false,
RewardDestination::Staked,
).unwrap();
)
.unwrap();
assert_eq!(nominators.len() as u32, n);
@@ -698,7 +703,8 @@ mod tests {
<Test as Config>::MaxNominatorRewardedPerValidator::get() as u32,
false,
RewardDestination::Staked,
).unwrap();
)
.unwrap();
// Add 20 slashing spans
let num_of_slashing_spans = 20;
@@ -706,14 +712,14 @@ mod tests {
let slashing_spans = SlashingSpans::<Test>::get(&validator_stash).unwrap();
assert_eq!(slashing_spans.iter().count(), num_of_slashing_spans as usize);
for i in 0 .. num_of_slashing_spans {
for i in 0..num_of_slashing_spans {
assert!(SpanSlash::<Test>::contains_key((&validator_stash, i)));
}
// Test everything is cleaned up
assert_ok!(Staking::kill_stash(&validator_stash, num_of_slashing_spans));
assert!(SlashingSpans::<Test>::get(&validator_stash).is_none());
for i in 0 .. num_of_slashing_spans {
for i in 0..num_of_slashing_spans {
assert!(!SpanSlash::<Test>::contains_key((&validator_stash, i)));
}
});
@@ -726,13 +732,17 @@ mod tests {
let n = 100;
let selected_benchmark = SelectedBenchmark::payout_all;
let c = vec![(frame_benchmarking::BenchmarkParameter::v, v), (frame_benchmarking::BenchmarkParameter::n, n)];
let c = vec![
(frame_benchmarking::BenchmarkParameter::v, v),
(frame_benchmarking::BenchmarkParameter::n, n),
];
let closure_to_benchmark =
<SelectedBenchmark as frame_benchmarking::BenchmarkingSetup<Test>>::instance(
&selected_benchmark,
&c,
true
).unwrap();
true,
)
.unwrap();
assert_ok!(closure_to_benchmark());
});
+12 -9
View File
@@ -20,7 +20,7 @@
//! The staking rate in NPoS is the total amount of tokens staked by nominators and validators,
//! divided by the total token supply.
use sp_runtime::{Perbill, traits::AtLeast32BitUnsigned, curve::PiecewiseLinear};
use sp_runtime::{curve::PiecewiseLinear, traits::AtLeast32BitUnsigned, Perbill};
/// The total payout to all validators (and their nominators) per era and maximum payout.
///
@@ -33,16 +33,18 @@ pub fn compute_total_payout<N>(
yearly_inflation: &PiecewiseLinear<'static>,
npos_token_staked: N,
total_tokens: N,
era_duration: u64
) -> (N, N) where N: AtLeast32BitUnsigned + Clone {
era_duration: u64,
) -> (N, N)
where
N: AtLeast32BitUnsigned + Clone,
{
// Milliseconds per year for the Julian year (365.25 days).
const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
let portion = Perbill::from_rational(era_duration as u64, MILLISECONDS_PER_YEAR);
let payout = portion * yearly_inflation.calculate_for_fraction_times_denominator(
npos_token_staked,
total_tokens.clone(),
);
let payout = portion *
yearly_inflation
.calculate_for_fraction_times_denominator(npos_token_staked, total_tokens.clone());
let maximum = portion * (yearly_inflation.maximum * total_tokens);
(payout, maximum)
}
@@ -70,7 +72,7 @@ mod test {
// not 10_000 due to rounding error.
assert_eq!(super::compute_total_payout(&I_NPOS, 0, 100_000u64, YEAR).1, 9_993);
//super::I_NPOS.calculate_for_fraction_times_denominator(25, 100)
// super::I_NPOS.calculate_for_fraction_times_denominator(25, 100)
assert_eq!(super::compute_total_payout(&I_NPOS, 0, 100_000u64, YEAR).0, 2_498);
assert_eq!(super::compute_total_payout(&I_NPOS, 5_000, 100_000u64, YEAR).0, 3_248);
assert_eq!(super::compute_total_payout(&I_NPOS, 25_000, 100_000u64, YEAR).0, 6_246);
@@ -98,7 +100,8 @@ mod test {
2_500_000_000_000_000_000_000_000_000u128,
5_000_000_000_000_000_000_000_000_000u128,
HOUR
).0,
)
.0,
57_038_500_000_000_000_000_000
);
}
File diff suppressed because it is too large Load Diff
+97 -116
View File
@@ -17,8 +17,9 @@
//! Test utilities
use crate::*;
use crate as staking;
use crate::*;
use frame_election_provider_support::onchain;
use frame_support::{
assert_ok, parameter_types,
traits::{Currency, FindAuthor, Get, OnInitialize, OneSessionHandler},
@@ -33,7 +34,6 @@ use sp_runtime::{
};
use sp_staking::offence::{OffenceDetails, OnOffenceHandler};
use std::{cell::RefCell, collections::HashSet};
use frame_election_provider_support::onchain;
pub const INIT_TIMESTAMP: u64 = 30_000;
pub const BLOCK_TIME: u64 = 1000;
@@ -54,16 +54,19 @@ impl OneSessionHandler<AccountId> for OtherSessionHandler {
type Key = UintAuthorityId;
fn on_genesis_session<'a, I: 'a>(_: I)
where I: Iterator<Item=(&'a AccountId, Self::Key)>, AccountId: 'a {}
where
I: Iterator<Item = (&'a AccountId, Self::Key)>,
AccountId: 'a,
{
}
fn on_new_session<'a, I: 'a>(_: bool, validators: I, _: I,)
where I: Iterator<Item=(&'a AccountId, Self::Key)>, AccountId: 'a
fn on_new_session<'a, I: 'a>(_: bool, validators: I, _: I)
where
I: Iterator<Item = (&'a AccountId, Self::Key)>,
AccountId: 'a,
{
SESSION.with(|x| {
*x.borrow_mut() = (
validators.map(|x| x.0.clone()).collect(),
HashSet::new(),
)
*x.borrow_mut() = (validators.map(|x| x.0.clone()).collect(), HashSet::new())
});
}
@@ -107,7 +110,8 @@ frame_support::construct_runtime!(
pub struct Author11;
impl FindAuthor<AccountId> for Author11 {
fn find_author<'a, I>(_digests: I) -> Option<AccountId>
where I: 'a + IntoIterator<Item = (frame_support::ConsensusEngineId, &'a [u8])>,
where
I: 'a + IntoIterator<Item = (frame_support::ConsensusEngineId, &'a [u8])>,
{
Some(11)
}
@@ -376,21 +380,14 @@ impl ExtBuilder {
}
fn build(self) -> sp_io::TestExternalities {
sp_tracing::try_init_simple();
let mut storage = frame_system::GenesisConfig::default()
.build_storage::<Test>()
.unwrap();
let balance_factor = if ExistentialDeposit::get() > 1 {
256
} else {
1
};
let mut storage = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
let balance_factor = if ExistentialDeposit::get() > 1 { 256 } else { 1 };
let num_validators = self.num_validators.unwrap_or(self.validator_count);
// Check that the number of validators is sensible.
assert!(num_validators <= 8);
let validators = (0..num_validators)
.map(|x| ((x + 1) * 10 + 1) as AccountId)
.collect::<Vec<_>>();
let validators =
(0..num_validators).map(|x| ((x + 1) * 10 + 1) as AccountId).collect::<Vec<_>>();
let _ = pallet_balances::GenesisConfig::<Test> {
balances: vec![
@@ -419,7 +416,8 @@ impl ExtBuilder {
// This allows us to have a total_payout different from 0.
(999, 1_000_000_000_000),
],
}.assimilate_storage(&mut storage);
}
.assimilate_storage(&mut storage);
let mut stakers = vec![];
if self.has_stakers {
@@ -438,11 +436,11 @@ impl ExtBuilder {
(31, 30, stake_31, StakerStatus::<AccountId>::Validator),
(41, 40, balance_factor * 1000, status_41),
// nominator
(101, 100, balance_factor * 500, StakerStatus::<AccountId>::Nominator(nominated))
(101, 100, balance_factor * 500, StakerStatus::<AccountId>::Nominator(nominated)),
];
}
let _ = staking::GenesisConfig::<Test>{
stakers: stakers,
let _ = staking::GenesisConfig::<Test> {
stakers,
validator_count: self.validator_count,
minimum_validator_count: self.minimum_validator_count,
invulnerables: self.invulnerables,
@@ -454,12 +452,12 @@ impl ExtBuilder {
.assimilate_storage(&mut storage);
let _ = pallet_session::GenesisConfig::<Test> {
keys: validators.iter().map(|x| (
*x,
*x,
SessionKeys { other: UintAuthorityId(*x as u64) }
)).collect(),
}.assimilate_storage(&mut storage);
keys: validators
.iter()
.map(|x| (*x, *x, SessionKeys { other: UintAuthorityId(*x as u64) }))
.collect(),
}
.assimilate_storage(&mut storage);
let mut ext = sp_io::TestExternalities::from(storage);
ext.execute_with(|| {
@@ -524,42 +522,46 @@ fn check_nominators() {
// in if the nomination was submitted before the current era.
let era = active_era();
<Nominators<Test>>::iter()
.filter_map(|(nominator, nomination)|
if nomination.submitted_in > era {
Some(nominator)
} else {
None
})
.filter_map(
|(nominator, nomination)| {
if nomination.submitted_in > era {
Some(nominator)
} else {
None
}
},
)
.for_each(|nominator| {
// must be bonded.
assert_is_stash(nominator);
let mut sum = 0;
Session::validators()
.iter()
.map(|v| Staking::eras_stakers(era, v))
.for_each(|e| {
let individual = e.others.iter().filter(|e| e.who == nominator).collect::<Vec<_>>();
let len = individual.len();
match len {
0 => { /* not supporting this validator at all. */ },
1 => sum += individual[0].value,
_ => panic!("nominator cannot back a validator more than once."),
};
});
// must be bonded.
assert_is_stash(nominator);
let mut sum = 0;
Session::validators()
.iter()
.map(|v| Staking::eras_stakers(era, v))
.for_each(|e| {
let individual =
e.others.iter().filter(|e| e.who == nominator).collect::<Vec<_>>();
let len = individual.len();
match len {
0 => { /* not supporting this validator at all. */ },
1 => sum += individual[0].value,
_ => panic!("nominator cannot back a validator more than once."),
};
});
let nominator_stake = Staking::slashable_balance_of(&nominator);
// a nominator cannot over-spend.
assert!(
nominator_stake >= sum,
"failed: Nominator({}) stake({}) >= sum divided({})",
nominator,
nominator_stake,
sum,
);
let nominator_stake = Staking::slashable_balance_of(&nominator);
// a nominator cannot over-spend.
assert!(
nominator_stake >= sum,
"failed: Nominator({}) stake({}) >= sum divided({})",
nominator,
nominator_stake,
sum,
);
let diff = nominator_stake - sum;
assert!(diff < 100);
});
let diff = nominator_stake - sum;
assert!(diff < 100);
});
}
fn assert_is_stash(acc: AccountId) {
@@ -569,10 +571,7 @@ fn assert_is_stash(acc: AccountId) {
fn assert_ledger_consistent(ctrl: AccountId) {
// ensures ledger.total == ledger.active + sum(ledger.unlocking).
let ledger = Staking::ledger(ctrl).expect("Not a controller.");
let real_total: Balance = ledger
.unlocking
.iter()
.fold(ledger.active, |a, c| a + c.value);
let real_total: Balance = ledger.unlocking.iter().fold(ledger.active, |a, c| a + c.value);
assert_eq!(real_total, ledger.total);
assert!(
ledger.active >= Balances::minimum_balance() || ledger.active == 0,
@@ -594,16 +593,8 @@ pub(crate) fn current_era() -> EraIndex {
pub(crate) fn bond_validator(stash: AccountId, ctrl: AccountId, val: Balance) {
let _ = Balances::make_free_balance_be(&stash, val);
let _ = Balances::make_free_balance_be(&ctrl, val);
assert_ok!(Staking::bond(
Origin::signed(stash),
ctrl,
val,
RewardDestination::Controller,
));
assert_ok!(Staking::validate(
Origin::signed(ctrl),
ValidatorPrefs::default()
));
assert_ok!(Staking::bond(Origin::signed(stash), ctrl, val, RewardDestination::Controller,));
assert_ok!(Staking::validate(Origin::signed(ctrl), ValidatorPrefs::default()));
}
pub(crate) fn bond_nominator(
@@ -614,12 +605,7 @@ pub(crate) fn bond_nominator(
) {
let _ = Balances::make_free_balance_be(&stash, val);
let _ = Balances::make_free_balance_be(&ctrl, val);
assert_ok!(Staking::bond(
Origin::signed(stash),
ctrl,
val,
RewardDestination::Controller,
));
assert_ok!(Staking::bond(Origin::signed(stash), ctrl, val, RewardDestination::Controller,));
assert_ok!(Staking::nominate(Origin::signed(ctrl), target));
}
@@ -715,9 +701,7 @@ pub(crate) fn reward_time_per_era() -> u64 {
}
pub(crate) fn reward_all_elected() {
let rewards = <Test as Config>::SessionInterface::validators()
.into_iter()
.map(|v| (v, 1));
let rewards = <Test as Config>::SessionInterface::validators().into_iter().map(|v| (v, 1));
<Pallet<Test>>::reward_by_ids(rewards)
}
@@ -741,26 +725,28 @@ pub(crate) fn on_offence_in_era(
for &(bonded_era, start_session) in bonded_eras.iter() {
if bonded_era == era {
let _ = Staking::on_offence(offenders, slash_fraction, start_session);
return;
return
} else if bonded_era > era {
break;
break
}
}
if Staking::active_era().unwrap().index == era {
let _ =
Staking::on_offence(
offenders,
slash_fraction,
Staking::eras_start_session_index(era).unwrap()
);
let _ = Staking::on_offence(
offenders,
slash_fraction,
Staking::eras_start_session_index(era).unwrap(),
);
} else {
panic!("cannot slash in era {}", era);
}
}
pub(crate) fn on_offence_now(
offenders: &[OffenceDetails<AccountId, pallet_session::historical::IdentificationTuple<Test>>],
offenders: &[OffenceDetails<
AccountId,
pallet_session::historical::IdentificationTuple<Test>,
>],
slash_fraction: &[Perbill],
) {
let now = Staking::active_era().unwrap().index;
@@ -769,29 +755,26 @@ pub(crate) fn on_offence_now(
pub(crate) fn add_slash(who: &AccountId) {
on_offence_now(
&[
OffenceDetails {
offender: (who.clone(), Staking::eras_stakers(active_era(), who.clone())),
reporters: vec![],
},
],
&[OffenceDetails {
offender: (who.clone(), Staking::eras_stakers(active_era(), who.clone())),
reporters: vec![],
}],
&[Perbill::from_percent(10)],
);
}
/// Make all validator and nominator request their payment
pub(crate) fn make_all_reward_payment(era: EraIndex) {
let validators_with_reward =
ErasRewardPoints::<Test>::get(era).individual.keys().cloned().collect::<Vec<_>>();
let validators_with_reward = ErasRewardPoints::<Test>::get(era)
.individual
.keys()
.cloned()
.collect::<Vec<_>>();
// reward validators
for validator_controller in validators_with_reward.iter().filter_map(Staking::bonded) {
let ledger = <Ledger<Test>>::get(&validator_controller).unwrap();
assert_ok!(Staking::payout_stakers(
Origin::signed(1337),
ledger.stash,
era
));
assert_ok!(Staking::payout_stakers(Origin::signed(1337), ledger.stash, era));
}
}
@@ -816,13 +799,11 @@ macro_rules! assert_session_era {
}
pub(crate) fn staking_events() -> Vec<staking::Event<Test>> {
System::events().into_iter().map(|r| r.event).filter_map(|e| {
if let Event::Staking(inner) = e {
Some(inner)
} else {
None
}
}).collect()
System::events()
.into_iter()
.map(|r| r.event)
.filter_map(|e| if let Event::Staking(inner) = e { Some(inner) } else { None })
.collect()
}
pub(crate) fn balances(who: &AccountId) -> (Balance, Balance) {
+47 -83
View File
@@ -50,16 +50,19 @@
//! Based on research at <https://w3f-research.readthedocs.io/en/latest/polkadot/slashing/npos.html>
use super::{
EraIndex, Config, Pallet, Store, BalanceOf, Exposure, Perbill, SessionInterface,
NegativeImbalanceOf, UnappliedSlash, Error,
BalanceOf, Config, EraIndex, Error, Exposure, NegativeImbalanceOf, Pallet, Perbill,
SessionInterface, Store, UnappliedSlash,
};
use sp_runtime::{traits::{Zero, Saturating}, RuntimeDebug, DispatchResult};
use codec::{Decode, Encode};
use frame_support::{
ensure,
traits::{Currency, OnUnbalanced, Imbalance},
traits::{Currency, Imbalance, OnUnbalanced},
};
use sp_runtime::{
traits::{Saturating, Zero},
DispatchResult, RuntimeDebug,
};
use sp_std::vec::Vec;
use codec::{Encode, Decode};
/// The proportion of the slashing reward to be paid out on the first slashing detection.
/// This is f_1 in the paper.
@@ -118,7 +121,9 @@ impl SlashingSpans {
// that internal state is unchanged.
pub(crate) fn end_span(&mut self, now: EraIndex) -> bool {
let next_start = now + 1;
if next_start <= self.last_start { return false }
if next_start <= self.last_start {
return false
}
let last_length = next_start - self.last_start;
self.prior.insert(0, last_length);
@@ -153,7 +158,8 @@ impl SlashingSpans {
// If this returns `Some`, then it includes a range start..end of all the span
// indices which were pruned.
fn prune(&mut self, window_start: EraIndex) -> Option<(SpanIndex, SpanIndex)> {
let old_idx = self.iter()
let old_idx = self
.iter()
.skip(1) // skip ongoing span.
.position(|span| span.length.map_or(false, |len| span.start + len <= window_start));
@@ -163,7 +169,7 @@ impl SlashingSpans {
self.prior.truncate(o);
let new_earliest = self.span_index - self.prior.len() as SpanIndex;
Some((earliest_span_index, new_earliest))
}
},
None => None,
};
@@ -214,18 +220,11 @@ pub(crate) struct SlashParams<'a, T: 'a + Config> {
///
/// The pending slash record returned does not have initialized reporters. Those have
/// to be set at a higher level, if any.
pub(crate) fn compute_slash<T: Config>(params: SlashParams<T>)
-> Option<UnappliedSlash<T::AccountId, BalanceOf<T>>>
{
let SlashParams {
stash,
slash,
exposure,
slash_era,
window_start,
now,
reward_proportion,
} = params.clone();
pub(crate) fn compute_slash<T: Config>(
params: SlashParams<T>,
) -> Option<UnappliedSlash<T::AccountId, BalanceOf<T>>> {
let SlashParams { stash, slash, exposure, slash_era, window_start, now, reward_proportion } =
params.clone();
let mut reward_payout = Zero::zero();
let mut val_slashed = Zero::zero();
@@ -236,22 +235,17 @@ pub(crate) fn compute_slash<T: Config>(params: SlashParams<T>)
// kick out the validator even if they won't be slashed,
// as long as the misbehavior is from their most recent slashing span.
kick_out_if_recent::<T>(params);
return None;
return None
}
let (prior_slash_p, _era_slash) = <Pallet<T> as Store>::ValidatorSlashInEra::get(
&slash_era,
stash,
).unwrap_or((Perbill::zero(), Zero::zero()));
let (prior_slash_p, _era_slash) =
<Pallet<T> as Store>::ValidatorSlashInEra::get(&slash_era, stash)
.unwrap_or((Perbill::zero(), Zero::zero()));
// compare slash proportions rather than slash values to avoid issues due to rounding
// error.
if slash.deconstruct() > prior_slash_p.deconstruct() {
<Pallet<T> as Store>::ValidatorSlashInEra::insert(
&slash_era,
stash,
&(slash, own_slash),
);
<Pallet<T> as Store>::ValidatorSlashInEra::insert(&slash_era, stash, &(slash, own_slash));
} else {
// we slash based on the max in era - this new event is not the max,
// so neither the validator or any nominators will need an update.
@@ -260,7 +254,7 @@ pub(crate) fn compute_slash<T: Config>(params: SlashParams<T>)
// pays out some reward even if the latest report is not max-in-era.
// we opt to avoid the nominator lookups and edits and leave more rewards
// for more drastic misbehavior.
return None;
return None
}
// apply slash to validator.
@@ -273,10 +267,7 @@ pub(crate) fn compute_slash<T: Config>(params: SlashParams<T>)
reward_proportion,
);
let target_span = spans.compare_and_update_span_slash(
slash_era,
own_slash,
);
let target_span = spans.compare_and_update_span_slash(slash_era, own_slash);
if target_span == Some(spans.span_index()) {
// misbehavior occurred within the current slashing span - take appropriate
@@ -309,9 +300,7 @@ pub(crate) fn compute_slash<T: Config>(params: SlashParams<T>)
// doesn't apply any slash, but kicks out the validator if the misbehavior is from
// the most recent slashing span.
fn kick_out_if_recent<T: Config>(
params: SlashParams<T>,
) {
fn kick_out_if_recent<T: Config>(params: SlashParams<T>) {
// these are not updated by era-span or end-span.
let mut reward_payout = Zero::zero();
let mut val_slashed = Zero::zero();
@@ -343,15 +332,8 @@ fn slash_nominators<T: Config>(
prior_slash_p: Perbill,
nominators_slashed: &mut Vec<(T::AccountId, BalanceOf<T>)>,
) -> BalanceOf<T> {
let SlashParams {
stash: _,
slash,
exposure,
slash_era,
window_start,
now,
reward_proportion,
} = params;
let SlashParams { stash: _, slash, exposure, slash_era, window_start, now, reward_proportion } =
params;
let mut reward_payout = Zero::zero();
@@ -367,18 +349,12 @@ fn slash_nominators<T: Config>(
let own_slash_by_validator = slash * nominator.value;
let own_slash_difference = own_slash_by_validator.saturating_sub(own_slash_prior);
let mut era_slash = <Pallet<T> as Store>::NominatorSlashInEra::get(
&slash_era,
stash,
).unwrap_or_else(|| Zero::zero());
let mut era_slash = <Pallet<T> as Store>::NominatorSlashInEra::get(&slash_era, stash)
.unwrap_or_else(|| Zero::zero());
era_slash += own_slash_difference;
<Pallet<T> as Store>::NominatorSlashInEra::insert(
&slash_era,
stash,
&era_slash,
);
<Pallet<T> as Store>::NominatorSlashInEra::insert(&slash_era, stash, &era_slash);
era_slash
};
@@ -393,10 +369,7 @@ fn slash_nominators<T: Config>(
reward_proportion,
);
let target_span = spans.compare_and_update_span_slash(
slash_era,
era_slash,
);
let target_span = spans.compare_and_update_span_slash(slash_era, era_slash);
if target_span == Some(spans.span_index()) {
// End the span, but don't chill the nominator. its nomination
@@ -497,8 +470,8 @@ impl<'a, T: 'a + Config> InspectingSpans<'a, T> {
span_record.slashed = slash;
// compute reward.
let reward = REWARD_F1
* (self.reward_proportion * slash).saturating_sub(span_record.paid_out);
let reward =
REWARD_F1 * (self.reward_proportion * slash).saturating_sub(span_record.paid_out);
self.add_slash(difference, slash_era);
changed = true;
@@ -529,7 +502,9 @@ impl<'a, T: 'a + Config> InspectingSpans<'a, T> {
impl<'a, T: 'a + Config> Drop for InspectingSpans<'a, T> {
fn drop(&mut self) {
// only update on disk if we slashed this account.
if !self.dirty { return }
if !self.dirty {
return
}
if let Some((start, end)) = self.spans.prune(self.window_start) {
for span_index in start..end {
@@ -557,7 +532,10 @@ pub(crate) fn clear_stash_metadata<T: Config>(
Some(s) => s,
};
ensure!(num_slashing_spans as usize >= spans.iter().count(), Error::<T>::IncorrectSlashingSpans);
ensure!(
num_slashing_spans as usize >= spans.iter().count(),
Error::<T>::IncorrectSlashingSpans
);
<Pallet<T> as Store>::SlashingSpans::remove(stash);
@@ -606,9 +584,7 @@ pub fn do_slash<T: Config>(
<Pallet<T>>::update_ledger(&controller, &ledger);
// trigger the event
<Pallet<T>>::deposit_event(
super::Event::<T>::Slash(stash.clone(), value)
);
<Pallet<T>>::deposit_event(super::Event::<T>::Slash(stash.clone(), value));
}
}
@@ -625,18 +601,12 @@ pub(crate) fn apply_slash<T: Config>(unapplied_slash: UnappliedSlash<T::AccountI
);
for &(ref nominator, nominator_slash) in &unapplied_slash.others {
do_slash::<T>(
&nominator,
nominator_slash,
&mut reward_payout,
&mut slashed_imbalance,
);
do_slash::<T>(&nominator, nominator_slash, &mut reward_payout, &mut slashed_imbalance);
}
pay_reporters::<T>(reward_payout, slashed_imbalance, &unapplied_slash.reporters);
}
/// Apply a reward payout to some reporters, paying the rewards out of the slashed imbalance.
fn pay_reporters<T: Config>(
reward_payout: BalanceOf<T>,
@@ -774,17 +744,13 @@ mod tests {
assert_eq!(spans.prune(1000), Some((8, 10)));
assert_eq!(
spans.iter().collect::<Vec<_>>(),
vec![
SlashingSpan { index: 10, start: 1000, length: None },
],
vec![SlashingSpan { index: 10, start: 1000, length: None },],
);
assert_eq!(spans.prune(2000), None);
assert_eq!(
spans.iter().collect::<Vec<_>>(),
vec![
SlashingSpan { index: 10, start: 2000, length: None },
],
vec![SlashingSpan { index: 10, start: 2000, length: None },],
);
// now all in one shot.
@@ -797,9 +763,7 @@ mod tests {
assert_eq!(spans.prune(2000), Some((6, 10)));
assert_eq!(
spans.iter().collect::<Vec<_>>(),
vec![
SlashingSpan { index: 10, start: 2000, length: None },
],
vec![SlashingSpan { index: 10, start: 2000, length: None },],
);
}
+45 -36
View File
@@ -18,12 +18,14 @@
//! Testing utils for staking. Provides some common functions to setup staking state, such as
//! bonding validators, nominators, and generating different types of solutions.
use crate::*;
use crate::Pallet as Staking;
use crate::{Pallet as Staking, *};
use frame_benchmarking::account;
use frame_system::RawOrigin;
use rand_chacha::{
rand_core::{RngCore, SeedableRng},
ChaChaRng,
};
use sp_io::hashing::blake2_256;
use rand_chacha::{rand_core::{RngCore, SeedableRng}, ChaChaRng};
const SEED: u32 = 0;
@@ -54,14 +56,18 @@ pub fn create_stash_controller<T: Config>(
n: u32,
balance_factor: u32,
destination: RewardDestination<T::AccountId>,
)
-> Result<(T::AccountId, T::AccountId), &'static str>
{
) -> Result<(T::AccountId, T::AccountId), &'static str> {
let stash = create_funded_user::<T>("stash", n, balance_factor);
let controller = create_funded_user::<T>("controller", n, balance_factor);
let controller_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(controller.clone());
let controller_lookup: <T::Lookup as StaticLookup>::Source =
T::Lookup::unlookup(controller.clone());
let amount = T::Currency::minimum_balance() * (balance_factor / 10).max(1).into();
Staking::<T>::bond(RawOrigin::Signed(stash.clone()).into(), controller_lookup, amount, destination)?;
Staking::<T>::bond(
RawOrigin::Signed(stash.clone()).into(),
controller_lookup,
amount,
destination,
)?;
return Ok((stash, controller))
}
@@ -71,15 +77,19 @@ pub fn create_stash_and_dead_controller<T: Config>(
n: u32,
balance_factor: u32,
destination: RewardDestination<T::AccountId>,
)
-> Result<(T::AccountId, T::AccountId), &'static str>
{
) -> Result<(T::AccountId, T::AccountId), &'static str> {
let stash = create_funded_user::<T>("stash", n, balance_factor);
// controller has no funds
let controller = create_funded_user::<T>("controller", n, 0);
let controller_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(controller.clone());
let controller_lookup: <T::Lookup as StaticLookup>::Source =
T::Lookup::unlookup(controller.clone());
let amount = T::Currency::minimum_balance() * (balance_factor / 10).max(1).into();
Staking::<T>::bond(RawOrigin::Signed(stash.clone()).into(), controller_lookup, amount, destination)?;
Staking::<T>::bond(
RawOrigin::Signed(stash.clone()).into(),
controller_lookup,
amount,
destination,
)?;
return Ok((stash, controller))
}
@@ -89,12 +99,11 @@ pub fn create_validators<T: Config>(
balance_factor: u32,
) -> Result<Vec<<T::Lookup as StaticLookup>::Source>, &'static str> {
let mut validators: Vec<<T::Lookup as StaticLookup>::Source> = Vec::with_capacity(max as usize);
for i in 0 .. max {
let (stash, controller) = create_stash_controller::<T>(i, balance_factor, RewardDestination::Staked)?;
let validator_prefs = ValidatorPrefs {
commission: Perbill::from_percent(50),
.. Default::default()
};
for i in 0..max {
let (stash, controller) =
create_stash_controller::<T>(i, balance_factor, RewardDestination::Staked)?;
let validator_prefs =
ValidatorPrefs { commission: Perbill::from_percent(50), ..Default::default() };
Staking::<T>::validate(RawOrigin::Signed(controller).into(), validator_prefs)?;
let stash_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(stash);
validators.push(stash_lookup);
@@ -126,20 +135,20 @@ pub fn create_validators_with_nominators_for_era<T: Config>(
) -> Result<Vec<<T::Lookup as StaticLookup>::Source>, &'static str> {
clear_validators_and_nominators::<T>();
let mut validators_stash: Vec<<T::Lookup as StaticLookup>::Source>
= Vec::with_capacity(validators as usize);
let mut validators_stash: Vec<<T::Lookup as StaticLookup>::Source> =
Vec::with_capacity(validators as usize);
let mut rng = ChaChaRng::from_seed(SEED.using_encoded(blake2_256));
// Create validators
for i in 0 .. validators {
for i in 0..validators {
let balance_factor = if randomize_stake { rng.next_u32() % 255 + 10 } else { 100u32 };
let (v_stash, v_controller) = create_stash_controller::<T>(i, balance_factor, RewardDestination::Staked)?;
let validator_prefs = ValidatorPrefs {
commission: Perbill::from_percent(50),
.. Default::default()
};
let (v_stash, v_controller) =
create_stash_controller::<T>(i, balance_factor, RewardDestination::Staked)?;
let validator_prefs =
ValidatorPrefs { commission: Perbill::from_percent(50), ..Default::default() };
Staking::<T>::validate(RawOrigin::Signed(v_controller.clone()).into(), validator_prefs)?;
let stash_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(v_stash.clone());
let stash_lookup: <T::Lookup as StaticLookup>::Source =
T::Lookup::unlookup(v_stash.clone());
validators_stash.push(stash_lookup.clone());
}
@@ -147,25 +156,25 @@ pub fn create_validators_with_nominators_for_era<T: Config>(
let validator_chosen = validators_stash[0..to_nominate].to_vec();
// Create nominators
for j in 0 .. nominators {
for j in 0..nominators {
let balance_factor = if randomize_stake { rng.next_u32() % 255 + 10 } else { 100u32 };
let (_n_stash, n_controller) = create_stash_controller::<T>(
u32::MAX - j,
balance_factor,
RewardDestination::Staked,
)?;
let (_n_stash, n_controller) =
create_stash_controller::<T>(u32::MAX - j, balance_factor, RewardDestination::Staked)?;
// Have them randomly validate
let mut available_validators = validator_chosen.clone();
let mut selected_validators: Vec<<T::Lookup as StaticLookup>::Source> =
Vec::with_capacity(edge_per_nominator);
for _ in 0 .. validators.min(edge_per_nominator as u32) {
for _ in 0..validators.min(edge_per_nominator as u32) {
let selected = rng.next_u32() as usize % available_validators.len();
let validator = available_validators.remove(selected);
selected_validators.push(validator);
}
Staking::<T>::nominate(RawOrigin::Signed(n_controller.clone()).into(), selected_validators)?;
Staking::<T>::nominate(
RawOrigin::Signed(n_controller.clone()).into(),
selected_validators,
)?;
}
ValidatorCount::<T>::put(validators);
File diff suppressed because it is too large Load Diff
+1
View File
@@ -36,6 +36,7 @@
// --template=./.maintain/frame-weight-template.hbs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]