Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
404 changes: 210 additions & 194 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pallet-indices = { version = "2.0.0-alpha.5", default-features = false, path = "
pallet-identity = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/identity" }
pallet-membership = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/membership" }
pallet-offences = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/offences" }
pallet-offences-benchmarking = { version = "2.0.0-alpha.5", path = "../../../frame/offences/benchmarking", default-features = false, optional = true }
pallet-randomness-collective-flip = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/randomness-collective-flip" }
pallet-recovery = { version = "2.0.0-alpha.5", default-features = false, path = "../../../frame/recovery" }
pallet-session = { version = "2.0.0-alpha.5", features = ["historical"], path = "../../../frame/session", default-features = false }
Expand Down Expand Up @@ -150,6 +151,7 @@ runtime-benchmarks = [
"pallet-utility/runtime-benchmarks",
"pallet-vesting/runtime-benchmarks",
"pallet-collective/runtime-benchmarks",
"pallet-offences-benchmarking",
"pallet-session-benchmarking",
]

Expand Down
6 changes: 6 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,10 +887,14 @@ impl_runtime_apis! {
// To get around that, we separated the Session benchmarks into its own crate, which is why
// we need these two lines below.
use pallet_session_benchmarking::Module as SessionBench;
use pallet_offences_benchmarking::Module as OffencesBench;

impl pallet_session_benchmarking::Trait for Runtime {}
impl pallet_offences_benchmarking::Trait for Runtime {}

let mut batches = Vec::<BenchmarkBatch>::new();
let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat);

add_benchmark!(params, batches, b"balances", Balances);
add_benchmark!(params, batches, b"collective", Council);
add_benchmark!(params, batches, b"democracy", Democracy);
Expand All @@ -902,6 +906,8 @@ impl_runtime_apis! {
add_benchmark!(params, batches, b"treasury", Treasury);
add_benchmark!(params, batches, b"utility", Utility);
add_benchmark!(params, batches, b"vesting", Vesting);
add_benchmark!(params, batches, b"offences", OffencesBench::<Runtime>);

if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
Ok(batches)
}
Expand Down
6 changes: 3 additions & 3 deletions frame/im-online/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,11 +679,11 @@ pub struct UnresponsivenessOffence<Offender> {
///
/// It acts as a time measure for unresponsiveness reports and effectively will always point
/// at the end of the session.
session_index: SessionIndex,
pub session_index: SessionIndex,
/// The size of the validator set in current session/era.
validator_set_count: u32,
pub validator_set_count: u32,
/// Authorities that were unresponsive during the current era.
offenders: Vec<Offender>,
pub offenders: Vec<Offender>,
}

impl<Offender: Clone> Offence<Offender> for UnresponsivenessOffence<Offender> {
Expand Down
1 change: 1 addition & 0 deletions frame/offences/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ std = [
"frame-support/std",
"frame-system/std",
]
runtime-benchmarks = []

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
43 changes: 43 additions & 0 deletions frame/offences/benchmarking/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[package]
name = "pallet-offences-benchmarking"
version = "2.0.0-alpha.5"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
license = "GPL-3.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "FRAME offences pallet benchmarking"

[dependencies]
codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false }

sp-std = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/std" }
sp-staking = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/staking" }
sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../../primitives/runtime" }
frame-benchmarking = { version = "2.0.0-alpha.5", default-features = false, path = "../../benchmarking" }
frame-system = { version = "2.0.0-alpha.5", default-features = false, path = "../../system" }
frame-support = { version = "2.0.0-alpha.5", default-features = false, path = "../../support" }
pallet-im-online = { version = "2.0.0-alpha.5", default-features = false, path = "../../im-online" }
pallet-offences = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../offences" }
pallet-staking = { version = "2.0.0-alpha.5", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" }
pallet-session = { version = "2.0.0-alpha.5", default-features = false, path = "../../session" }
sp-io = { path = "../../../primitives/io", default-features = false, version = "2.0.0-alpha.5"}


[features]
default = ["std"]
std = [
"sp-runtime/std",
"sp-std/std",
"sp-staking/std",
"frame-benchmarking/std",
"frame-support/std",
"frame-system/std",
"pallet-offences/std",
"pallet-im-online/std",
"pallet-staking/std",
"pallet-session/std",
]

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
175 changes: 175 additions & 0 deletions frame/offences/benchmarking/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.

// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

//! Offences pallet benchmarking.

#![cfg_attr(not(feature = "std"), no_std)]

use sp_std::prelude::*;
use sp_std::vec;

use frame_system::RawOrigin;
use frame_benchmarking::{benchmarks, account};
use frame_support::traits::{Currency, OnInitialize};

use sp_runtime::{Perbill, traits::{Convert, StaticLookup}};
use sp_staking::offence::ReportOffence;

use pallet_im_online::{Trait as ImOnlineTrait, Module as ImOnline, UnresponsivenessOffence};
use pallet_offences::{Trait as OffencesTrait, Module as Offences};
use pallet_staking::{
Module as Staking, Trait as StakingTrait, RewardDestination, ValidatorPrefs,
Exposure, IndividualExposure, ElectionStatus
Comment thread
marcio-diaz marked this conversation as resolved.
};
use pallet_session::Trait as SessionTrait;
use pallet_session::historical::{Trait as HistoricalTrait, IdentificationTuple};

const SEED: u32 = 0;

const MAX_USERS: u32 = 1000;
const MAX_REPORTERS: u32 = 100;
const MAX_OFFENDERS: u32 = 100;
const MAX_NOMINATORS: u32 = 100;
const MAX_DEFERRED_OFFENCES: u32 = 100;

pub struct Module<T: Trait>(Offences<T>);

pub trait Trait: SessionTrait + StakingTrait + OffencesTrait + ImOnlineTrait + HistoricalTrait {}

fn create_offender<T: Trait>(n: u32, nominators: u32) -> Result<T::AccountId, &'static str> {
let stash: T::AccountId = account("stash", n, SEED);
let controller: T::AccountId = account("controller", n, SEED);
let controller_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(controller.clone());
let reward_destination = RewardDestination::Staked;
let amount = T::Currency::minimum_balance();

Staking::<T>::bond(
RawOrigin::Signed(stash.clone()).into(),
controller_lookup.clone(),
amount.clone(),
reward_destination.clone(),
)?;

let validator_prefs = ValidatorPrefs {
commission: Perbill::from_percent(50),
};
Staking::<T>::validate(RawOrigin::Signed(controller.clone()).into(), validator_prefs)?;

let mut individual_exposures = vec![];

// Create n nominators
for i in 0 .. nominators {
let nominator_stash: T::AccountId = account("nominator stash", n * MAX_NOMINATORS + i, SEED);
let nominator_controller: T::AccountId = account("nominator controller", n * MAX_NOMINATORS + i, SEED);
let nominator_controller_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(nominator_controller.clone());

Staking::<T>::bond(
RawOrigin::Signed(nominator_stash.clone()).into(),
nominator_controller_lookup.clone(),
amount,
reward_destination,
)?;

let selected_validators: Vec<<T::Lookup as StaticLookup>::Source> = vec![controller_lookup.clone()];
Staking::<T>::nominate(RawOrigin::Signed(nominator_controller.clone()).into(), selected_validators)?;

individual_exposures.push(IndividualExposure {
who: nominator_controller.clone(),
value: amount.clone(),
});
}

let exposure = Exposure {
total: amount.clone() * n.into(),
own: amount,
others: individual_exposures,
};
let current_era = 0u32;
Staking::<T>::add_era_stakers(current_era.into(), stash.clone().into(), exposure);

Ok(controller)
}

fn make_offenders<T: Trait>(num_offenders: u32, num_nominators: u32) -> Result<Vec<IdentificationTuple<T>>, &'static str> {
let mut offenders: Vec<T::AccountId> = vec![];

for i in 0 .. num_offenders {
let offender = create_offender::<T>(i, num_nominators)?;
offenders.push(offender);
}

Ok(offenders.iter()
.map(|id|
<T as SessionTrait>::ValidatorIdOf::convert(id.clone())
.expect("failed to get validator id from account id"))
.map(|validator_id|
<T as HistoricalTrait>::FullIdentificationOf::convert(validator_id.clone())
.map(|full_id| (validator_id, full_id))
.expect("failed to convert validator id to full identification"))
.collect::<Vec<IdentificationTuple<T>>>())
}

benchmarks! {
Comment thread
marcio-diaz marked this conversation as resolved.
_ {
let u in 1 .. MAX_USERS => ();
let r in 1 .. MAX_REPORTERS => ();
let o in 1 .. MAX_OFFENDERS => ();
let n in 1 .. MAX_NOMINATORS => ();
let d in 1 .. MAX_DEFERRED_OFFENCES => ();
}

report_offence {
Comment thread
marcio-diaz marked this conversation as resolved.
let r in ...;
let o in ...;
let n in ...;

let mut reporters = vec![];

for i in 0 .. r {
let reporter = account("reporter", i, SEED);
reporters.push(reporter);
}

let offenders = make_offenders::<T>(o, n).expect("failed to create offenders");
let keys = ImOnline::<T>::keys();

let offence = UnresponsivenessOffence {
session_index: 0,
validator_set_count: keys.len() as u32,
offenders,
};

}: {
let _ = <T as ImOnlineTrait>::ReportUnresponsiveness::report_offence(reporters, offence);
}

on_initialize {
let d in ...;

Staking::<T>::put_election_status(ElectionStatus::Closed);

let mut deferred_offences = vec![];

for i in 0 .. d {
deferred_offences.push((vec![], vec![], 0u32));
}

Offences::<T>::set_deferred_offences(deferred_offences);

}: {
Offences::<T>::on_initialize(u.into());
}
}
7 changes: 6 additions & 1 deletion frame/offences/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type OpaqueTimeSlot = Vec<u8>;
type ReportIdOf<T> = <T as frame_system::Trait>::Hash;

/// Type of data stored as a deferred offence
type DeferredOffenceOf<T> = (
pub type DeferredOffenceOf<T> = (
Vec<OffenceDetails<<T as frame_system::Trait>::AccountId, <T as Trait>::IdentificationTuple>>,
Vec<Perbill>,
SessionIndex,
Expand Down Expand Up @@ -249,6 +249,11 @@ impl<T: Trait> Module<T> {
None
}
}

#[cfg(feature = "runtime-benchmarks")]
pub fn set_deferred_offences(offences: Vec<DeferredOffenceOf<T>>) {
<DeferredOffences<T>>::put(offences);
}
}

struct TriageOutcome<T: Trait> {
Expand Down
4 changes: 2 additions & 2 deletions frame/scored-pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ decl_storage! {
<CandidateExists<T, I>>::insert(who, true);
});

/// Sorts the `Pool` by score in a descending order. Entities which
/// have a score of `None` are sorted to the beginning of the vec.
// Sorts the `Pool` by score in a descending order. Entities which
// have a score of `None` are sorted to the beginning of the vec.
pool.sort_by_key(|(_, maybe_score)|
Reverse(maybe_score.unwrap_or_default())
);
Expand Down
20 changes: 15 additions & 5 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,10 +583,10 @@ pub struct Nominations<AccountId> {
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, RuntimeDebug)]
pub struct IndividualExposure<AccountId, Balance: HasCompact> {
/// The stash account of the nominator in question.
who: AccountId,
pub who: AccountId,
/// Amount of funds exposed.
#[codec(compact)]
value: Balance,
pub value: Balance,
}

/// A snapshot of the stake backing a single validator in the system.
Expand Down Expand Up @@ -1252,7 +1252,7 @@ decl_module! {
/// unless the `origin` falls below _existential deposit_ and gets removed as dust.
/// # </weight>
#[weight = SimpleDispatchInfo::FixedNormal(500_000)]
fn bond(origin,
pub fn bond(origin,
controller: <T::Lookup as StaticLookup>::Source,
#[compact] value: BalanceOf<T>,
payee: RewardDestination,
Expand Down Expand Up @@ -1446,7 +1446,7 @@ decl_module! {
/// - Writes are limited to the `origin` account key.
/// # </weight>
#[weight = SimpleDispatchInfo::FixedNormal(750_000)]
fn validate(origin, prefs: ValidatorPrefs) {
pub fn validate(origin, prefs: ValidatorPrefs) {
let controller = ensure_signed(origin)?;
let ledger = Self::ledger(&controller).ok_or(Error::<T>::NotController)?;
let stash = &ledger.stash;
Expand All @@ -1466,7 +1466,7 @@ decl_module! {
/// - Both the reads and writes follow a similar pattern.
/// # </weight>
#[weight = SimpleDispatchInfo::FixedNormal(750_000)]
fn nominate(origin, targets: Vec<<T::Lookup as StaticLookup>::Source>) {
pub fn nominate(origin, targets: Vec<<T::Lookup as StaticLookup>::Source>) {
let controller = ensure_signed(origin)?;
let ledger = Self::ledger(&controller).ok_or(Error::<T>::NotController)?;
let stash = &ledger.stash;
Expand Down Expand Up @@ -2878,6 +2878,16 @@ impl<T: Trait> Module<T> {
_ => ForceEra::put(Forcing::ForceNew),
}
}

#[cfg(feature = "runtime-benchmarks")]
pub fn add_era_stakers(current_era: EraIndex, controller: T::AccountId, exposure: Exposure<T::AccountId, BalanceOf<T>>) {
Comment thread
kianenigma marked this conversation as resolved.
<ErasStakers<T>>::insert(&current_era, &controller, &exposure);
}

#[cfg(feature = "runtime-benchmarks")]
pub fn put_election_status(status: ElectionStatus::<T::BlockNumber>) {
<EraElectionStatus<T>>::put(status);
}
}

/// In this implementation `new_session(session)` must be called before `end_session(session-1)`
Expand Down