From 88667a55fe42a660f17b1d6db9abf43ede86fbb8 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 30 Jul 2022 17:58:29 +0200 Subject: [PATCH 01/54] root-offences pallet --- Cargo.lock | 15 ++++ Cargo.toml | 1 + frame/nomination-pools/src/lib.rs | 4 +- frame/root-offences/Cargo.toml | 40 +++++++++++ frame/root-offences/README.md | 3 + frame/root-offences/src/lib.rs | 114 ++++++++++++++++++++++++++++++ 6 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 frame/root-offences/Cargo.toml create mode 100644 frame/root-offences/README.md create mode 100644 frame/root-offences/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 50603c6235a23..3b9f0414c0015 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6107,6 +6107,21 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-root-offences" +version = "1.0.0" +dependencies = [ + "frame-support", + "frame-system", + "pallet-offences", + "pallet-session", + "pallet-staking", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-staking", +] + [[package]] name = "pallet-scheduler" version = "4.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index 1f22343c002a8..86d9927b814bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -132,6 +132,7 @@ members = [ "frame/staking/reward-fn", "frame/state-trie-migration", "frame/sudo", + "frame/root-offences", "frame/support", "frame/support/procedural", "frame/support/procedural/tools", diff --git a/frame/nomination-pools/src/lib.rs b/frame/nomination-pools/src/lib.rs index 09f1746b8e5ba..487bb47ad3c76 100644 --- a/frame/nomination-pools/src/lib.rs +++ b/frame/nomination-pools/src/lib.rs @@ -2471,8 +2471,8 @@ impl Pallet { impl OnStakerSlash> for Pallet { fn on_slash( pool_account: &T::AccountId, - // Bonded balance is always read directly from staking, therefore we need not update - // anything here. + // Bonded balance is always read directly from staking, therefore we + // don't need to update anything here. slashed_bonded: BalanceOf, slashed_unlocking: &BTreeMap>, ) { diff --git a/frame/root-offences/Cargo.toml b/frame/root-offences/Cargo.toml new file mode 100644 index 0000000000000..9ebbc00a213b8 --- /dev/null +++ b/frame/root-offences/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "pallet-root-offences" +version = "1.0.0" +authors = ["Parity Technologies "] +edition = "2021" +license = "Apache-2.0" +homepage = "https://substrate.io" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME sudo offences pallet" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } + +pallet-session = { version = "4.0.0-dev", features = [ "historical" ], path = "../../frame/session", default-features = false } +pallet-staking = { version = "4.0.0-dev", default-features = false, path = "../../frame/staking" } +pallet-offences = { version = "4.0.0-dev", default-features = false, path = "../../frame/offences" } + +frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } +sp-runtime = { version = "6.0.0", path = "../../primitives/runtime" } +sp-staking = { version = "4.0.0-dev", default-features = false, path = "../../primitives/staking" } + +[features] +runtime-benchmarks = [] +try-runtime = [] +default = ["std"] +std = [ + "codec/std", + "scale-info/std", + "pallet-session/std", + "pallet-staking/std", + "pallet-offences/std", + "frame-support/std", + "frame-system/std", + "sp-runtime/std", +] diff --git a/frame/root-offences/README.md b/frame/root-offences/README.md new file mode 100644 index 0000000000000..81e917d765cab --- /dev/null +++ b/frame/root-offences/README.md @@ -0,0 +1,3 @@ +# Sudo Offences Pallet + +Pallet that allows the root to create an offence. \ No newline at end of file diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs new file mode 100644 index 0000000000000..db410dee39a53 --- /dev/null +++ b/frame/root-offences/src/lib.rs @@ -0,0 +1,114 @@ +// 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. + +//! # Sudo Offences Pallet +//! Pallet that allows the root to create an offence. + +#![cfg_attr(not(feature = "std"), no_std)] + +use pallet_session::Pallet as Session; +use pallet_staking::Pallet as Staking; +use sp_runtime::Perbill; +use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; + +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: + frame_system::Config + + pallet_session::Config + + pallet_staking::Config + + pallet_offences::Config + + pallet_session::historical::Config + { + type Event: From> + IsType<::Event>; + type IdentificationTuple: Parameter; + type OnOffenceHandler: OnOffenceHandler< + Self::AccountId, + ::IdentificationTuple, + Weight, + >; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + #[pallet::call] + impl Pallet { + #[pallet::weight(10_000)] + pub fn slash( + origin: OriginFor, + offenders: Vec<(T::AccountId, Perbill)>, + ) -> DispatchResult { + ensure_root(origin)?; + + let slash_fractions: &[Perbill] = &(offenders + .clone() + .into_iter() + .map(|(_, fraction)| fraction) + .collect::>()); + + // FIX don't use unwrap!! + let now = Staking::::active_era().unwrap().index; + + let offs: Vec< + OffenceDetails>, + > = offenders + .into_iter() + .map(|(o, _)| { + let validator_id = match ::ValidatorId::try_from(o) + { + Ok(id) => id, + Err(_) => panic!("FIX need to add actual error here!"), + }; + OffenceDetails::< + T::AccountId, + pallet_session::historical::IdentificationTuple, + > { + offender: (validator_id, (1, 2)), + reporters: vec![], + } + }) + .collect(); + + ::OnOffenceHandler::on_offence( + &[], + slash_fractions, + now, + DisableStrategy::WhenSlashed, + ); + + Ok(()) + } + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event {} + + #[pallet::error] + pub enum Error { + CantGetValidatorId + } +} From cd95c71838c47a3b9ae2462ef731dc038e424e6a Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 31 Jul 2022 07:58:52 +0200 Subject: [PATCH 02/54] fix errors --- frame/root-offences/src/lib.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index db410dee39a53..b6d3fb1028a5e 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -54,6 +54,11 @@ pub mod pallet { #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); + pub type IdentificationTuple = ( + T::AccountId, + pallet_staking::Exposure::CurrencyBalance>, + ); + #[pallet::call] impl Pallet { #[pallet::weight(10_000)] @@ -73,7 +78,7 @@ pub mod pallet { let now = Staking::::active_era().unwrap().index; let offs: Vec< - OffenceDetails>, + OffenceDetails>, > = offenders .into_iter() .map(|(o, _)| { @@ -84,9 +89,9 @@ pub mod pallet { }; OffenceDetails::< T::AccountId, - pallet_session::historical::IdentificationTuple, + IdentificationTuple, > { - offender: (validator_id, (1, 2)), + offender: (o, Staking::::eras_stakers(now, o)), reporters: vec![], } }) From a95053cd82ef0a4a1a7f3fd8428b3049d9dc445a Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 31 Jul 2022 08:27:55 +0200 Subject: [PATCH 03/54] cleaned up a bit --- frame/root-offences/src/lib.rs | 36 ++++++++++++---------------------- frame/system/src/lib.rs | 3 ++- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index b6d3fb1028a5e..c988d7d1421b9 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -54,9 +54,12 @@ pub mod pallet { #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); - pub type IdentificationTuple = ( - T::AccountId, - pallet_staking::Exposure::CurrencyBalance>, + pub type IdentificationTuple = ( + ::AccountId, + pallet_staking::Exposure< + ::AccountId, + ::CurrencyBalance, + >, ); #[pallet::call] @@ -77,25 +80,14 @@ pub mod pallet { // FIX don't use unwrap!! let now = Staking::::active_era().unwrap().index; - let offs: Vec< - OffenceDetails>, - > = offenders + // TODO come up with a better name for this. + let offs: &[OffenceDetails>] = &(offenders .into_iter() - .map(|(o, _)| { - let validator_id = match ::ValidatorId::try_from(o) - { - Ok(id) => id, - Err(_) => panic!("FIX need to add actual error here!"), - }; - OffenceDetails::< - T::AccountId, - IdentificationTuple, - > { - offender: (o, Staking::::eras_stakers(now, o)), - reporters: vec![], - } + .map(|(o, _)| OffenceDetails::> { + offender: (o.clone(), Staking::::eras_stakers(now, o)), + reporters: vec![], }) - .collect(); + .collect::>>>()); ::OnOffenceHandler::on_offence( &[], @@ -113,7 +105,5 @@ pub mod pallet { pub enum Event {} #[pallet::error] - pub enum Error { - CantGetValidatorId - } + pub enum Error {} } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 94605c2da59bd..bfc91682c6a04 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -278,7 +278,8 @@ pub mod pallet { + Debug + MaybeDisplay + Ord - + MaxEncodedLen; + + MaxEncodedLen + + Clone; /// Converting trait to take a source type and convert to `AccountId`. /// From 3b61dd79a67659aa653da882661c958dbcfa5007 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 31 Jul 2022 08:40:38 +0200 Subject: [PATCH 04/54] remove unwrap() --- frame/root-offences/src/lib.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index c988d7d1421b9..ab5a13c44bbc8 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -20,7 +20,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -use pallet_session::Pallet as Session; use pallet_staking::Pallet as Staking; use sp_runtime::Perbill; use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; @@ -64,8 +63,10 @@ pub mod pallet { #[pallet::call] impl Pallet { + + /// Allows the `root` to create an offence. #[pallet::weight(10_000)] - pub fn slash( + pub fn create_offence( origin: OriginFor, offenders: Vec<(T::AccountId, Perbill)>, ) -> DispatchResult { @@ -77,8 +78,8 @@ pub mod pallet { .map(|(_, fraction)| fraction) .collect::>()); - // FIX don't use unwrap!! - let now = Staking::::active_era().unwrap().index; + let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; + let now = active_era.index; // TODO come up with a better name for this. let offs: &[OffenceDetails>] = &(offenders @@ -101,9 +102,10 @@ pub mod pallet { } #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event {} #[pallet::error] - pub enum Error {} + pub enum Error { + FailedToGetActiveEra, + } } From 535502292f726343c5facadec319cc9cdb43dba9 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 1 Aug 2022 10:31:29 +0200 Subject: [PATCH 05/54] new pallet is getting compiled --- frame/root-offences/src/lib.rs | 46 ++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index ab5a13c44bbc8..589e4a9460e97 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -23,6 +23,8 @@ use pallet_staking::Pallet as Staking; use sp_runtime::Perbill; use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; +use pallet_staking::{Exposure, ExposureOf, BalanceOf}; +use sp_runtime::traits::Convert; pub use pallet::*; @@ -62,8 +64,19 @@ pub mod pallet { ); #[pallet::call] - impl Pallet { - + impl Pallet where + T: pallet_session::Config::AccountId>, + T: pallet_session::historical::Config< + FullIdentification = Exposure<::AccountId, BalanceOf>, + FullIdentificationOf = ExposureOf, + >, + T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::SessionManager: pallet_session::SessionManager<::AccountId>, + T::ValidatorIdOf: Convert< + ::AccountId, + Option<::AccountId>, + >, + { /// Allows the `root` to create an offence. #[pallet::weight(10_000)] pub fn create_offence( @@ -81,17 +94,24 @@ pub mod pallet { let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; let now = active_era.index; - // TODO come up with a better name for this. - let offs: &[OffenceDetails>] = &(offenders - .into_iter() - .map(|(o, _)| OffenceDetails::> { - offender: (o.clone(), Staking::::eras_stakers(now, o)), - reporters: vec![], - }) - .collect::>>>()); - - ::OnOffenceHandler::on_offence( - &[], + let offender_details: &[OffenceDetails< + T::AccountId, + pallet_session::historical::IdentificationTuple + >] = &( + offenders.into_iter().map(|(o, _)| { + let offender: pallet_session::historical::IdentificationTuple = (o.clone(), Staking::::eras_stakers(now, o)); + OffenceDetails::> { + offender, + reporters: vec![], + } + }).collect:: + >>>() + ); + + as OnOffenceHandler, Weight>>::on_offence( + offender_details, slash_fractions, now, DisableStrategy::WhenSlashed, From aa41e2eea1e839a85704bf97f544efa7cddcee3b Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 1 Aug 2022 10:35:40 +0200 Subject: [PATCH 06/54] remove unnecessary type annotations --- frame/root-offences/src/lib.rs | 54 ++++++++++++++-------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 589e4a9460e97..a3652ac09a565 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -20,11 +20,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use pallet_staking::Pallet as Staking; -use sp_runtime::Perbill; +use pallet_session::historical::IdentificationTuple; +use pallet_staking::{BalanceOf, Exposure, ExposureOf, Pallet as Staking}; +use sp_runtime::{traits::Convert, Perbill}; use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; -use pallet_staking::{Exposure, ExposureOf, BalanceOf}; -use sp_runtime::traits::Convert; pub use pallet::*; @@ -43,12 +42,6 @@ pub mod pallet { + pallet_session::historical::Config { type Event: From> + IsType<::Event>; - type IdentificationTuple: Parameter; - type OnOffenceHandler: OnOffenceHandler< - Self::AccountId, - ::IdentificationTuple, - Weight, - >; } #[pallet::pallet] @@ -64,7 +57,8 @@ pub mod pallet { ); #[pallet::call] - impl Pallet where + impl Pallet + where T: pallet_session::Config::AccountId>, T: pallet_session::historical::Config< FullIdentification = Exposure<::AccountId, BalanceOf>, @@ -94,28 +88,24 @@ pub mod pallet { let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; let now = active_era.index; - let offender_details: &[OffenceDetails< + let offender_details: &[OffenceDetails>] = + &(offenders + .into_iter() + .map(|(o, _)| { + let offender: IdentificationTuple = + (o.clone(), Staking::::eras_stakers(now, o)); + OffenceDetails::> { + offender, + reporters: vec![], + } + }) + .collect::>>>()); + + as OnOffenceHandler< T::AccountId, - pallet_session::historical::IdentificationTuple - >] = &( - offenders.into_iter().map(|(o, _)| { - let offender: pallet_session::historical::IdentificationTuple = (o.clone(), Staking::::eras_stakers(now, o)); - OffenceDetails::> { - offender, - reporters: vec![], - } - }).collect:: - >>>() - ); - - as OnOffenceHandler, Weight>>::on_offence( - offender_details, - slash_fractions, - now, - DisableStrategy::WhenSlashed, - ); + IdentificationTuple, + Weight, + >>::on_offence(offender_details, slash_fractions, now, DisableStrategy::WhenSlashed); Ok(()) } From e492fdafd3ed38af7df191e95c753814acd2d22d Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 1 Aug 2022 10:37:57 +0200 Subject: [PATCH 07/54] remove more unnecessary type annotations --- frame/root-offences/src/lib.rs | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index a3652ac09a565..fd67a3412d24c 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -79,33 +79,32 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - let slash_fractions: &[Perbill] = &(offenders + let slash_fractions = offenders .clone() .into_iter() .map(|(_, fraction)| fraction) - .collect::>()); + .collect::>(); let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; let now = active_era.index; - let offender_details: &[OffenceDetails>] = - &(offenders - .into_iter() - .map(|(o, _)| { - let offender: IdentificationTuple = - (o.clone(), Staking::::eras_stakers(now, o)); - OffenceDetails::> { - offender, - reporters: vec![], - } - }) - .collect::>>>()); + let offender_details = offenders + .into_iter() + .map(|(o, _)| { + let offender: IdentificationTuple = + (o.clone(), Staking::::eras_stakers(now, o)); + OffenceDetails::> { + offender, + reporters: vec![], + } + }) + .collect::>>>(); as OnOffenceHandler< T::AccountId, IdentificationTuple, Weight, - >>::on_offence(offender_details, slash_fractions, now, DisableStrategy::WhenSlashed); + >>::on_offence(&offender_details, &slash_fractions, now, DisableStrategy::WhenSlashed); Ok(()) } From 4e56c3017612320715b7712a904ab4fb539734b6 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 1 Aug 2022 10:40:43 +0200 Subject: [PATCH 08/54] addidtional cleaning --- frame/root-offences/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index fd67a3412d24c..0689e8004f0f7 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -64,8 +64,6 @@ pub mod pallet { FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId>, - T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: Convert< ::AccountId, Option<::AccountId>, From 0f3caa21eea92d34db03c695bf6657e226608d1c Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 1 Aug 2022 10:47:51 +0200 Subject: [PATCH 09/54] commit --- frame/root-offences/src/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 0689e8004f0f7..07096c2e462fc 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -20,7 +20,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -use pallet_session::historical::IdentificationTuple; use pallet_staking::{BalanceOf, Exposure, ExposureOf, Pallet as Staking}; use sp_runtime::{traits::Convert, Perbill}; use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; @@ -36,10 +35,7 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config - + pallet_session::Config + pallet_staking::Config - + pallet_offences::Config - + pallet_session::historical::Config { type Event: From> + IsType<::Event>; } From a0ffc68f63c499ff81bd219ce10e82f279e3aa98 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 1 Aug 2022 11:44:43 +0200 Subject: [PATCH 10/54] cleaned up --- frame/root-offences/src/lib.rs | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 07096c2e462fc..99d53fb45054b 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -20,6 +20,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use pallet_session::historical::IdentificationTuple; use pallet_staking::{BalanceOf, Exposure, ExposureOf, Pallet as Staking}; use sp_runtime::{traits::Convert, Perbill}; use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; @@ -33,10 +34,7 @@ pub mod pallet { use frame_system::pallet_prelude::*; #[pallet::config] - pub trait Config: - frame_system::Config - + pallet_staking::Config - { + pub trait Config: frame_system::Config + pallet_staking::Config { type Event: From> + IsType<::Event>; } @@ -44,14 +42,6 @@ pub mod pallet { #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); - pub type IdentificationTuple = ( - ::AccountId, - pallet_staking::Exposure< - ::AccountId, - ::CurrencyBalance, - >, - ); - #[pallet::call] impl Pallet where @@ -82,17 +72,14 @@ pub mod pallet { let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; let now = active_era.index; - let offender_details = offenders - .into_iter() - .map(|(o, _)| { - let offender: IdentificationTuple = - (o.clone(), Staking::::eras_stakers(now, o)); - OffenceDetails::> { - offender, + let offender_details: Vec>> = + offenders + .into_iter() + .map(|(o, _)| OffenceDetails::> { + offender: (o.clone(), Staking::::eras_stakers(now, o)), reporters: vec![], - } - }) - .collect::>>>(); + }) + .collect(); as OnOffenceHandler< T::AccountId, From 7e802f22700853f9180c3d674535c492ae83538f Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 1 Aug 2022 11:57:43 +0200 Subject: [PATCH 11/54] fix in logic --- frame/root-offences/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 99d53fb45054b..66e2aa00b8d1a 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -81,11 +81,15 @@ pub mod pallet { }) .collect(); + let session_index = as frame_support::traits::ValidatorSet>::session_index(); + as OnOffenceHandler< T::AccountId, IdentificationTuple, Weight, - >>::on_offence(&offender_details, &slash_fractions, now, DisableStrategy::WhenSlashed); + >>::on_offence( + &offender_details, &slash_fractions, session_index, DisableStrategy::WhenSlashed + ); Ok(()) } From 9c28dfeeb23d91324ee364a19cd34ea210bfc0c1 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 1 Aug 2022 15:46:38 +0200 Subject: [PATCH 12/54] add event --- frame/root-offences/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 66e2aa00b8d1a..b5101b3007735 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -74,6 +74,7 @@ pub mod pallet { let offender_details: Vec>> = offenders + .clone() .into_iter() .map(|(o, _)| OffenceDetails::> { offender: (o.clone(), Staking::::eras_stakers(now, o)), @@ -91,12 +92,16 @@ pub mod pallet { &offender_details, &slash_fractions, session_index, DisableStrategy::WhenSlashed ); + Self::deposit_event(Event::RootCreatedOffence { offenders }); Ok(()) } } #[pallet::event] - pub enum Event {} + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + RootCreatedOffence { offenders: Vec<(T::AccountId, Perbill)> }, + } #[pallet::error] pub enum Error { From 310d5fe84cabdcc1ac40f73bd278171fc4293f61 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 13 Aug 2022 14:38:01 +0200 Subject: [PATCH 13/54] removed Clone trait from AccountId --- frame/system/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index bfc91682c6a04..94605c2da59bd 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -278,8 +278,7 @@ pub mod pallet { + Debug + MaybeDisplay + Ord - + MaxEncodedLen - + Clone; + + MaxEncodedLen; /// Converting trait to take a source type and convert to `AccountId`. /// From 354dcd1a63ac77bb8c91a4cd9ae1cf7c4ea4127c Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 12:06:01 +0200 Subject: [PATCH 14/54] test module --- Cargo.lock | 5 + frame/root-offences/Cargo.toml | 7 ++ frame/root-offences/src/lib.rs | 176 ++++++++++++++++++++++++++++++++- 3 files changed, 187 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 1a0631ed539f9..88af570a93567 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6119,13 +6119,18 @@ dependencies = [ name = "pallet-root-offences" version = "1.0.0" dependencies = [ + "frame-election-provider-support", "frame-support", "frame-system", + "pallet-balances", "pallet-offences", "pallet-session", "pallet-staking", + "pallet-staking-reward-curve", + "pallet-timestamp", "parity-scale-codec", "scale-info", + "sp-core", "sp-runtime", "sp-staking", ] diff --git a/frame/root-offences/Cargo.toml b/frame/root-offences/Cargo.toml index 9ebbc00a213b8..8057a5e22439b 100644 --- a/frame/root-offences/Cargo.toml +++ b/frame/root-offences/Cargo.toml @@ -24,6 +24,13 @@ frame-system = { version = "4.0.0-dev", default-features = false, path = "../sys sp-runtime = { version = "6.0.0", path = "../../primitives/runtime" } sp-staking = { version = "4.0.0-dev", default-features = false, path = "../../primitives/staking" } +[dev-dependencies] +pallet-balances = { version = "4.0.0-dev", path = "../balances" } +pallet-timestamp = { version = "4.0.0-dev", path = "../timestamp" } +pallet-staking-reward-curve = { version = "4.0.0-dev", path = "../staking/reward-curve" } +sp-core = { version = "6.0.0", path = "../../primitives/core" } +frame-election-provider-support = { version = "4.0.0-dev", path = "../election-provider-support" } + [features] runtime-benchmarks = [] try-runtime = [] diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index b5101b3007735..bff5ccb809f99 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -22,7 +22,7 @@ use pallet_session::historical::IdentificationTuple; use pallet_staking::{BalanceOf, Exposure, ExposureOf, Pallet as Staking}; -use sp_runtime::{traits::Convert, Perbill}; +use sp_runtime::{curve::PiecewiseLinear, traits::Convert, Perbill}; use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; pub use pallet::*; @@ -108,3 +108,177 @@ pub mod pallet { FailedToGetActiveEra, } } + +#[cfg(test)] +mod tests { + use super::*; + use crate as root_offences; + + use frame_election_provider_support::{onchain, SequentialPhragmen}; + use frame_support::{ + assert_noop, assert_ok, ord_parameter_types, parameter_types, + traits::{ConstU32, ConstU64}, + }; + use frame_system::EnsureSignedBy; + use pallet_session::TestSessionHandler; + use sp_core::H256; + use sp_runtime::{ + testing::{Header, UintAuthorityId}, + traits::{BadOrigin, BlakeTwo256, IdentityLookup}, + }; + + type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + type Block = frame_system::mocking::MockBlock; + type AccountId = u64; + type Balance = u64; + type BlockNumber = u64; + + frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + Balances: pallet_balances, + RootOffences: root_offences, + Session: pallet_session, + Staking: pallet_staking, + } + ); + + parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); + } + + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = Call; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; + } + + impl pallet_balances::Config for Test { + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ConstU64<1>; + type AccountStore = System; + type WeightInfo = (); + } + + pallet_staking_reward_curve::build! { + const REWARD_CURVE: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000u64, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); + } + + pub struct OnChainSeqPhragmen; + impl onchain::Config for OnChainSeqPhragmen { + type System = Test; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = (); + } + parameter_types! { + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub static Offset: BlockNumber = 0; + pub const Period: BlockNumber = 1; + } + + impl pallet_staking::Config for Test { + type MaxNominations = ConstU32<16>; + type Currency = Balances; + type CurrencyBalance = ::Balance; + type UnixTime = pallet_timestamp::Pallet; + type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; + type RewardRemainder = (); + type Event = Event; + type Slash = (); + type Reward = (); + type SessionsPerEra = (); + type SlashDeferDuration = (); + type SlashCancelOrigin = frame_system::EnsureRoot; + type BondingDuration = (); + type SessionInterface = Self; + type EraPayout = pallet_staking::ConvertCurve; + type NextNewSession = Session; + type MaxNominatorRewardedPerValidator = ConstU32<64>; + type OffendingValidatorsThreshold = (); + type ElectionProvider = onchain::UnboundedExecution; + type GenesisElectionProvider = Self::ElectionProvider; + type MaxUnlockingChunks = ConstU32<32>; + type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; + type OnStakerSlash = (); + type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; + type WeightInfo = (); + } + + impl pallet_session::historical::Config for Test { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; + } + + sp_runtime::impl_opaque_keys! { + pub struct SessionKeys { + pub foo: sp_runtime::testing::UintAuthorityId, + } + } + + impl pallet_session::Config for Test { + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type Keys = SessionKeys; + type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; + type SessionHandler = TestSessionHandler; + type Event = Event; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type WeightInfo = (); + } + + impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = ConstU64<5>; + type WeightInfo = (); + } + + impl Config for Test { + type Event = Event; + } + + #[test] + fn kill_name_should_work() { + assert_eq!(1, 1); + } +} From 5c01f62512300e168778bf8c6ab356214ec20a7d Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 12:08:56 +0200 Subject: [PATCH 15/54] remove unused imports --- frame/root-offences/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index bff5ccb809f99..759cb50e980e3 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -22,7 +22,7 @@ use pallet_session::historical::IdentificationTuple; use pallet_staking::{BalanceOf, Exposure, ExposureOf, Pallet as Staking}; -use sp_runtime::{curve::PiecewiseLinear, traits::Convert, Perbill}; +use sp_runtime::{traits::Convert, Perbill}; use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; pub use pallet::*; @@ -119,12 +119,12 @@ mod tests { assert_noop, assert_ok, ord_parameter_types, parameter_types, traits::{ConstU32, ConstU64}, }; - use frame_system::EnsureSignedBy; use pallet_session::TestSessionHandler; use sp_core::H256; use sp_runtime::{ - testing::{Header, UintAuthorityId}, - traits::{BadOrigin, BlakeTwo256, IdentityLookup}, + testing::{Header}, + traits::{BlakeTwo256, IdentityLookup}, + curve::PiecewiseLinear, }; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; @@ -278,7 +278,7 @@ mod tests { } #[test] - fn kill_name_should_work() { + fn test() { assert_eq!(1, 1); } } From bb643639452b5712f07afffeb413d2644afa0d42 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 12:10:35 +0200 Subject: [PATCH 16/54] fmt --- frame/root-offences/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 759cb50e980e3..bb7578a1395af 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -122,9 +122,9 @@ mod tests { use pallet_session::TestSessionHandler; use sp_core::H256; use sp_runtime::{ - testing::{Header}, - traits::{BlakeTwo256, IdentityLookup}, curve::PiecewiseLinear, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, }; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; From 41dbdd56aeb8e9c2bd8dd721957ff595eb4ee4b6 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 13:01:18 +0200 Subject: [PATCH 17/54] fix --- frame/root-offences/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index bb7578a1395af..5abb157cfc7be 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -116,7 +116,7 @@ mod tests { use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ - assert_noop, assert_ok, ord_parameter_types, parameter_types, + parameter_types, traits::{ConstU32, ConstU64}, }; use pallet_session::TestSessionHandler; From 0af28810310ea3092e46e87e0cfd050c884716f7 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 14:39:31 +0200 Subject: [PATCH 18/54] separate into functions, still messy --- frame/root-offences/src/lib.rs | 73 +++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 5abb157cfc7be..502dac0576e5b 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -42,6 +42,17 @@ pub mod pallet { #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + RootCreatedOffence { offenders: Vec<(T::AccountId, Perbill)> }, + } + + #[pallet::error] + pub enum Error { + FailedToGetActiveEra, + } + #[pallet::call] impl Pallet where @@ -63,49 +74,57 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - let slash_fractions = offenders + let slash_fraction = offenders .clone() .into_iter() .map(|(_, fraction)| fraction) .collect::>(); - let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; - let now = active_era.index; + let offence_details = Self::get_offence_details(offenders.clone())?; - let offender_details: Vec>> = - offenders - .clone() - .into_iter() - .map(|(o, _)| OffenceDetails::> { - offender: (o.clone(), Staking::::eras_stakers(now, o)), - reporters: vec![], - }) - .collect(); + Self::submit_offence(&offence_details, &slash_fraction); + Self::deposit_event(Event::RootCreatedOffence { offenders }); + Ok(()) + } + } + + impl Pallet + where + T: pallet_session::Config::AccountId>, + T: pallet_session::historical::Config< + FullIdentification = Exposure<::AccountId, BalanceOf>, + FullIdentificationOf = ExposureOf, + >, + { + fn submit_offence( + offenders: &[OffenceDetails>], + slash_fraction: &[Perbill], + ) { let session_index = as frame_support::traits::ValidatorSet>::session_index(); as OnOffenceHandler< T::AccountId, IdentificationTuple, Weight, - >>::on_offence( - &offender_details, &slash_fractions, session_index, DisableStrategy::WhenSlashed - ); - - Self::deposit_event(Event::RootCreatedOffence { offenders }); - Ok(()) + >>::on_offence(&offenders, &slash_fraction, session_index, DisableStrategy::WhenSlashed); } - } - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - RootCreatedOffence { offenders: Vec<(T::AccountId, Perbill)> }, - } + fn get_offence_details( + offenders: Vec<(T::AccountId, Perbill)>, + ) -> Result>>, DispatchError> { + let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; + let now = active_era.index; - #[pallet::error] - pub enum Error { - FailedToGetActiveEra, + Ok(offenders + .clone() + .into_iter() + .map(|(o, _)| OffenceDetails::> { + offender: (o.clone(), Staking::::eras_stakers(now, o)), + reporters: vec![], + }) + .collect()) + } } } From c9e93c572fc4bf8ea866815356f1e2b5522d86b3 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 15:03:32 +0200 Subject: [PATCH 19/54] test --- Cargo.lock | 1 + frame/root-offences/Cargo.toml | 2 ++ frame/root-offences/src/lib.rs | 12 +++++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index f6268b33ee96f..021cd1ef8d547 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6147,6 +6147,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-core", + "sp-io", "sp-runtime", "sp-staking", ] diff --git a/frame/root-offences/Cargo.toml b/frame/root-offences/Cargo.toml index 8057a5e22439b..ff856505adeb7 100644 --- a/frame/root-offences/Cargo.toml +++ b/frame/root-offences/Cargo.toml @@ -28,7 +28,9 @@ sp-staking = { version = "4.0.0-dev", default-features = false, path = "../../pr pallet-balances = { version = "4.0.0-dev", path = "../balances" } pallet-timestamp = { version = "4.0.0-dev", path = "../timestamp" } pallet-staking-reward-curve = { version = "4.0.0-dev", path = "../staking/reward-curve" } + sp-core = { version = "6.0.0", path = "../../primitives/core" } +sp-io = { version = "6.0.0", default-features = false, path = "../../primitives/io" } frame-election-provider-support = { version = "4.0.0-dev", path = "../election-provider-support" } [features] diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 502dac0576e5b..55970390f8a15 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -296,8 +296,18 @@ mod tests { type Event = Event; } + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10)] } + .assimilate_storage(&mut t) + .unwrap(); + t.into() + } + #[test] fn test() { - assert_eq!(1, 1); + new_test_ext().execute_with(|| { + assert_eq!(1, 1); + }) } } From f81c50ab1bfe67e60552dcfa12b167c48c2cda6b Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 18:51:32 +0200 Subject: [PATCH 20/54] first test --- frame/root-offences/src/lib.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 55970390f8a15..922c7c845d4a6 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -135,7 +135,7 @@ mod tests { use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ - parameter_types, + parameter_types, assert_err, traits::{ConstU32, ConstU64}, }; use pallet_session::TestSessionHandler; @@ -305,9 +305,14 @@ mod tests { } #[test] - fn test() { + fn create_offence_fails_given_signed_origin() { + use sp_runtime::traits::BadOrigin; new_test_ext().execute_with(|| { - assert_eq!(1, 1); + let offenders = (&[]).to_vec(); + assert_err!( + RootOffences::create_offence(Origin::signed(1), offenders), + BadOrigin + ); }) } } From b41af4a5737c4be3547049412b5a0d8771fc112d Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 18:52:42 +0200 Subject: [PATCH 21/54] fmt --- frame/root-offences/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 922c7c845d4a6..dee6c378cf92b 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -135,7 +135,7 @@ mod tests { use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ - parameter_types, assert_err, + assert_err, parameter_types, traits::{ConstU32, ConstU64}, }; use pallet_session::TestSessionHandler; @@ -309,10 +309,7 @@ mod tests { use sp_runtime::traits::BadOrigin; new_test_ext().execute_with(|| { let offenders = (&[]).to_vec(); - assert_err!( - RootOffences::create_offence(Origin::signed(1), offenders), - BadOrigin - ); + assert_err!(RootOffences::create_offence(Origin::signed(1), offenders), BadOrigin); }) } } From a0a2200909569cbe90d7c7ae21cb2e468e92513a Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 15 Aug 2022 20:37:51 +0200 Subject: [PATCH 22/54] cleaned up a bit --- frame/root-offences/src/lib.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index dee6c378cf92b..a6bc9855f8e84 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -23,7 +23,7 @@ use pallet_session::historical::IdentificationTuple; use pallet_staking::{BalanceOf, Exposure, ExposureOf, Pallet as Staking}; use sp_runtime::{traits::Convert, Perbill}; -use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler}; +use sp_staking::offence::{DisableStrategy, OnOffenceHandler}; pub use pallet::*; @@ -53,6 +53,10 @@ pub mod pallet { FailedToGetActiveEra, } + #[allow(type_alias_bounds)] + type OffenceDetails = + sp_staking::offence::OffenceDetails>; + #[pallet::call] impl Pallet where @@ -97,10 +101,7 @@ pub mod pallet { FullIdentificationOf = ExposureOf, >, { - fn submit_offence( - offenders: &[OffenceDetails>], - slash_fraction: &[Perbill], - ) { + fn submit_offence(offenders: &[OffenceDetails], slash_fraction: &[Perbill]) { let session_index = as frame_support::traits::ValidatorSet>::session_index(); as OnOffenceHandler< @@ -112,14 +113,14 @@ pub mod pallet { fn get_offence_details( offenders: Vec<(T::AccountId, Perbill)>, - ) -> Result>>, DispatchError> { + ) -> Result>, DispatchError> { let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; let now = active_era.index; Ok(offenders .clone() .into_iter() - .map(|(o, _)| OffenceDetails::> { + .map(|(o, _)| OffenceDetails:: { offender: (o.clone(), Staking::::eras_stakers(now, o)), reporters: vec![], }) @@ -312,4 +313,11 @@ mod tests { assert_err!(RootOffences::create_offence(Origin::signed(1), offenders), BadOrigin); }) } + + #[test] + fn create_offence_works_given_root_origin() { + new_test_ext().execute_with(|| { + //assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); + }) + } } From 3eda44d985aaac3c1b7ccffaa18cab8f57176b26 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 16 Aug 2022 14:25:07 +0300 Subject: [PATCH 23/54] separate into mock.rs and tests.rs --- frame/root-offences/src/lib.rs | 198 +------------------------------ frame/root-offences/src/mock.rs | 173 +++++++++++++++++++++++++++ frame/root-offences/src/tests.rs | 19 +++ 3 files changed, 197 insertions(+), 193 deletions(-) create mode 100644 frame/root-offences/src/mock.rs create mode 100644 frame/root-offences/src/tests.rs diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index a6bc9855f8e84..b0f7bd9a2c60e 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -20,6 +20,11 @@ #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + use pallet_session::historical::IdentificationTuple; use pallet_staking::{BalanceOf, Exposure, ExposureOf, Pallet as Staking}; use sp_runtime::{traits::Convert, Perbill}; @@ -128,196 +133,3 @@ pub mod pallet { } } } - -#[cfg(test)] -mod tests { - use super::*; - use crate as root_offences; - - use frame_election_provider_support::{onchain, SequentialPhragmen}; - use frame_support::{ - assert_err, parameter_types, - traits::{ConstU32, ConstU64}, - }; - use pallet_session::TestSessionHandler; - use sp_core::H256; - use sp_runtime::{ - curve::PiecewiseLinear, - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, - }; - - type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; - type Block = frame_system::mocking::MockBlock; - type AccountId = u64; - type Balance = u64; - type BlockNumber = u64; - - frame_support::construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system, - Balances: pallet_balances, - RootOffences: root_offences, - Session: pallet_session, - Staking: pallet_staking, - } - ); - - parameter_types! { - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); - } - - impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - type Call = Call; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type BlockHashCount = ConstU64<250>; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; - } - - impl pallet_balances::Config for Test { - type MaxLocks = (); - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - type Balance = Balance; - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ConstU64<1>; - type AccountStore = System; - type WeightInfo = (); - } - - pallet_staking_reward_curve::build! { - const REWARD_CURVE: PiecewiseLinear<'static> = curve!( - min_inflation: 0_025_000u64, - max_inflation: 0_100_000, - ideal_stake: 0_500_000, - falloff: 0_050_000, - max_piece_count: 40, - test_precision: 0_005_000, - ); - } - - pub struct OnChainSeqPhragmen; - impl onchain::Config for OnChainSeqPhragmen { - type System = Test; - type Solver = SequentialPhragmen; - type DataProvider = Staking; - type WeightInfo = (); - } - parameter_types! { - pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; - pub static Offset: BlockNumber = 0; - pub const Period: BlockNumber = 1; - } - - impl pallet_staking::Config for Test { - type MaxNominations = ConstU32<16>; - type Currency = Balances; - type CurrencyBalance = ::Balance; - type UnixTime = pallet_timestamp::Pallet; - type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; - type RewardRemainder = (); - type Event = Event; - type Slash = (); - type Reward = (); - type SessionsPerEra = (); - type SlashDeferDuration = (); - type SlashCancelOrigin = frame_system::EnsureRoot; - type BondingDuration = (); - type SessionInterface = Self; - type EraPayout = pallet_staking::ConvertCurve; - type NextNewSession = Session; - type MaxNominatorRewardedPerValidator = ConstU32<64>; - type OffendingValidatorsThreshold = (); - type ElectionProvider = onchain::UnboundedExecution; - type GenesisElectionProvider = Self::ElectionProvider; - type MaxUnlockingChunks = ConstU32<32>; - type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; - type OnStakerSlash = (); - type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; - type WeightInfo = (); - } - - impl pallet_session::historical::Config for Test { - type FullIdentification = pallet_staking::Exposure; - type FullIdentificationOf = pallet_staking::ExposureOf; - } - - sp_runtime::impl_opaque_keys! { - pub struct SessionKeys { - pub foo: sp_runtime::testing::UintAuthorityId, - } - } - - impl pallet_session::Config for Test { - type SessionManager = pallet_session::historical::NoteHistoricalRoot; - type Keys = SessionKeys; - type ShouldEndSession = pallet_session::PeriodicSessions; - type NextSessionRotation = pallet_session::PeriodicSessions; - type SessionHandler = TestSessionHandler; - type Event = Event; - type ValidatorId = AccountId; - type ValidatorIdOf = pallet_staking::StashOf; - type WeightInfo = (); - } - - impl pallet_timestamp::Config for Test { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = ConstU64<5>; - type WeightInfo = (); - } - - impl Config for Test { - type Event = Event; - } - - fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10)] } - .assimilate_storage(&mut t) - .unwrap(); - t.into() - } - - #[test] - fn create_offence_fails_given_signed_origin() { - use sp_runtime::traits::BadOrigin; - new_test_ext().execute_with(|| { - let offenders = (&[]).to_vec(); - assert_err!(RootOffences::create_offence(Origin::signed(1), offenders), BadOrigin); - }) - } - - #[test] - fn create_offence_works_given_root_origin() { - new_test_ext().execute_with(|| { - //assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); - }) - } -} diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs new file mode 100644 index 0000000000000..a3dec02f5b093 --- /dev/null +++ b/frame/root-offences/src/mock.rs @@ -0,0 +1,173 @@ +use super::*; +use crate as root_offences; + +use frame_election_provider_support::{onchain, SequentialPhragmen}; +use frame_support::{ + parameter_types, + traits::{ConstU32, ConstU64}, +}; +use pallet_session::TestSessionHandler; +use sp_core::H256; +use sp_runtime::{ + curve::PiecewiseLinear, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; +type AccountId = u64; +type Balance = u64; +type BlockNumber = u64; + +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + Balances: pallet_balances, + RootOffences: root_offences, + Session: pallet_session, + Staking: pallet_staking, + } +); + +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); +} + +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = Call; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +impl pallet_balances::Config for Test { + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ConstU64<1>; + type AccountStore = System; + type WeightInfo = (); +} + +pallet_staking_reward_curve::build! { + const REWARD_CURVE: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000u64, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} + +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Test; + type Solver = SequentialPhragmen; + type DataProvider = Staking; + type WeightInfo = (); +} +parameter_types! { + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub static Offset: BlockNumber = 0; + pub const Period: BlockNumber = 1; +} + +impl pallet_staking::Config for Test { + type MaxNominations = ConstU32<16>; + type Currency = Balances; + type CurrencyBalance = ::Balance; + type UnixTime = pallet_timestamp::Pallet; + type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; + type RewardRemainder = (); + type Event = Event; + type Slash = (); + type Reward = (); + type SessionsPerEra = (); + type SlashDeferDuration = (); + type SlashCancelOrigin = frame_system::EnsureRoot; + type BondingDuration = (); + type SessionInterface = Self; + type EraPayout = pallet_staking::ConvertCurve; + type NextNewSession = Session; + type MaxNominatorRewardedPerValidator = ConstU32<64>; + type OffendingValidatorsThreshold = (); + type ElectionProvider = onchain::UnboundedExecution; + type GenesisElectionProvider = Self::ElectionProvider; + type MaxUnlockingChunks = ConstU32<32>; + type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; + type OnStakerSlash = (); + type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; + type WeightInfo = (); +} + +impl pallet_session::historical::Config for Test { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +sp_runtime::impl_opaque_keys! { + pub struct SessionKeys { + pub foo: sp_runtime::testing::UintAuthorityId, + } +} + +impl pallet_session::Config for Test { + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type Keys = SessionKeys; + type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; + type SessionHandler = TestSessionHandler; + type Event = Event; + type ValidatorId = AccountId; + type ValidatorIdOf = pallet_staking::StashOf; + type WeightInfo = (); +} + +impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = ConstU64<5>; + type WeightInfo = (); +} + +impl Config for Test { + type Event = Event; +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10)] } + .assimilate_storage(&mut t) + .unwrap(); + t.into() +} diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs new file mode 100644 index 0000000000000..8aa065a8b069c --- /dev/null +++ b/frame/root-offences/src/tests.rs @@ -0,0 +1,19 @@ +use super::*; +use frame_support::assert_err; +use mock::{new_test_ext, Origin, RootOffences}; + +#[test] +fn create_offence_fails_given_signed_origin() { + use sp_runtime::traits::BadOrigin; + new_test_ext().execute_with(|| { + let offenders = (&[]).to_vec(); + assert_err!(RootOffences::create_offence(Origin::signed(1), offenders), BadOrigin); + }) +} + +#[test] +fn create_offence_works_given_root_origin() { + new_test_ext().execute_with(|| { + //assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); + }) +} From 24f34c67cfb77d9d50b45f99fb1edd85dcbf03c8 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 16 Aug 2022 16:05:27 +0300 Subject: [PATCH 24/54] basic docs for now --- frame/root-offences/README.md | 4 +++- frame/root-offences/src/lib.rs | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/frame/root-offences/README.md b/frame/root-offences/README.md index 81e917d765cab..248559e4e398f 100644 --- a/frame/root-offences/README.md +++ b/frame/root-offences/README.md @@ -1,3 +1,5 @@ # Sudo Offences Pallet -Pallet that allows the root to create an offence. \ No newline at end of file +Pallet that allows the root to create an offence. + +NOTE: This pallet should be used for testing purposes. \ No newline at end of file diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index b0f7bd9a2c60e..734c8216ddcfa 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -17,6 +17,8 @@ //! # Sudo Offences Pallet //! Pallet that allows the root to create an offence. +//! +//! NOTE: This pallet should be used for testing purposes. #![cfg_attr(not(feature = "std"), no_std)] @@ -75,7 +77,7 @@ pub mod pallet { Option<::AccountId>, >, { - /// Allows the `root` to create an offence. + /// Allows the `root`, for example sudo to create an offence. #[pallet::weight(10_000)] pub fn create_offence( origin: OriginFor, @@ -106,6 +108,7 @@ pub mod pallet { FullIdentificationOf = ExposureOf, >, { + /// Submits the offence by calling the `on_offence` function. fn submit_offence(offenders: &[OffenceDetails], slash_fraction: &[Perbill]) { let session_index = as frame_support::traits::ValidatorSet>::session_index(); @@ -116,6 +119,7 @@ pub mod pallet { >>::on_offence(&offenders, &slash_fraction, session_index, DisableStrategy::WhenSlashed); } + /// Returns a vector of offenders that are going to be slashed. fn get_offence_details( offenders: Vec<(T::AccountId, Perbill)>, ) -> Result>, DispatchError> { From 3c138238c9a89ad764c4ada0de94df239b00304c Mon Sep 17 00:00:00 2001 From: Szegoo Date: Thu, 18 Aug 2022 18:17:55 +0300 Subject: [PATCH 25/54] pallet_staking GenesisiConfig --- frame/root-offences/src/mock.rs | 20 ++++++++++++++++---- frame/root-offences/src/tests.rs | 3 ++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index a3dec02f5b093..67acd49a3f554 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -7,6 +7,7 @@ use frame_support::{ traits::{ConstU32, ConstU64}, }; use pallet_session::TestSessionHandler; +use pallet_staking::StakerStatus; use sp_core::H256; use sp_runtime::{ curve::PiecewiseLinear, @@ -165,9 +166,20 @@ impl Config for Test { } pub fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10)] } - .assimilate_storage(&mut t) + let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + pallet_balances::GenesisConfig:: { balances: vec![(11, 550), (21, 1100)] } + .assimilate_storage(&mut storage) .unwrap(); - t.into() + + let stakers = vec![ + // (stash, ctrl, stake, status) + (11, 10, 500, StakerStatus::::Validator), + (21, 20, 1000, StakerStatus::::Validator), + ]; + + let _ = + pallet_staking::GenesisConfig:: { stakers: stakers.clone(), ..Default::default() }; + + storage.into() } diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 8aa065a8b069c..21efcaabb8f94 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,6 +1,6 @@ use super::*; use frame_support::assert_err; -use mock::{new_test_ext, Origin, RootOffences}; +use mock::{new_test_ext, Origin, RootOffences, Test}; #[test] fn create_offence_fails_given_signed_origin() { @@ -14,6 +14,7 @@ fn create_offence_fails_given_signed_origin() { #[test] fn create_offence_works_given_root_origin() { new_test_ext().execute_with(|| { + let active_era = Staking::::active_era().unwrap(); //assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); }) } From e4f8d7535469c6666535d36c241f9113af82c4f1 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Thu, 18 Aug 2022 18:23:23 +0300 Subject: [PATCH 26/54] fix --- frame/root-offences/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 21efcaabb8f94..4017519e583d0 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -14,7 +14,7 @@ fn create_offence_fails_given_signed_origin() { #[test] fn create_offence_works_given_root_origin() { new_test_ext().execute_with(|| { - let active_era = Staking::::active_era().unwrap(); + //let active_era = Staking::::active_era().unwrap(); //assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); }) } From 94a134ee55a4c8e66b5b3e1bfacab5ec9be2f7fb Mon Sep 17 00:00:00 2001 From: Szegoo Date: Thu, 18 Aug 2022 18:36:59 +0300 Subject: [PATCH 27/54] added start_session --- frame/root-offences/src/mock.rs | 54 ++++++++++++++++++++++++++++---- frame/root-offences/src/tests.rs | 5 +-- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index 67acd49a3f554..06cea16c48d99 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -4,7 +4,7 @@ use crate as root_offences; use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ parameter_types, - traits::{ConstU32, ConstU64}, + traits::{ConstU32, ConstU64, Hooks}, }; use pallet_session::TestSessionHandler; use pallet_staking::StakerStatus; @@ -12,8 +12,9 @@ use sp_core::H256; use sp_runtime::{ curve::PiecewiseLinear, testing::Header, - traits::{BlakeTwo256, IdentityLookup}, + traits::{BlakeTwo256, IdentityLookup, Zero}, }; +use sp_staking::SessionIndex; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -21,17 +22,22 @@ type AccountId = u64; type Balance = u64; type BlockNumber = u64; +pub const INIT_TIMESTAMP: u64 = 30_000; +pub const BLOCK_TIME: u64 = 1000; + frame_support::construct_runtime!( pub enum Test where Block = Block, NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic, { - System: frame_system, - Balances: pallet_balances, + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, + Session: pallet_session::{Pallet, Call, Storage, Event, Config}, RootOffences: root_offences, - Session: pallet_session, - Staking: pallet_staking, + Historical: pallet_session::historical::{Pallet, Storage}, } ); @@ -183,3 +189,39 @@ pub fn new_test_ext() -> sp_io::TestExternalities { storage.into() } + +/// Progresses from the current block number (whatever that may be) to the `P * session_index + 1`. +pub(crate) fn start_session(session_index: SessionIndex) { + let end: u64 = if Offset::get().is_zero() { + (session_index as u64) * Period::get() + } else { + Offset::get() + (session_index.saturating_sub(1) as u64) * Period::get() + }; + run_to_block(end); + // session must have progressed properly. + assert_eq!( + Session::current_index(), + session_index, + "current session index = {}, expected = {}", + Session::current_index(), + session_index, + ); +} + +/// Progress to the given block, triggering session and era changes as we progress. +/// +/// This will finalize the previous block, initialize up to the given block, essentially simulating +/// a block import/propose process where we first initialize the block, then execute some stuff (not +/// in the function), and then finalize the block. +pub(crate) fn run_to_block(n: BlockNumber) { + Staking::on_finalize(System::block_number()); + for b in (System::block_number() + 1)..=n { + System::set_block_number(b); + Session::on_initialize(b); + >::on_initialize(b); + Timestamp::set_timestamp(System::block_number() * BLOCK_TIME + INIT_TIMESTAMP); + if b != n { + Staking::on_finalize(System::block_number()); + } + } +} diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 4017519e583d0..202e9a55c617c 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,6 +1,6 @@ use super::*; use frame_support::assert_err; -use mock::{new_test_ext, Origin, RootOffences, Test}; +use mock::{new_test_ext, start_session, Origin, RootOffences, Test}; #[test] fn create_offence_fails_given_signed_origin() { @@ -14,7 +14,8 @@ fn create_offence_fails_given_signed_origin() { #[test] fn create_offence_works_given_root_origin() { new_test_ext().execute_with(|| { - //let active_era = Staking::::active_era().unwrap(); + start_session(1); + let _active_era = Staking::::active_era().unwrap(); //assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); }) } From 99f7f3fd14d1d9e59b8727c3fb0591415ba2aa34 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Thu, 18 Aug 2022 21:06:11 +0300 Subject: [PATCH 28/54] passing tests --- frame/root-offences/src/tests.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 202e9a55c617c..f7a484e460359 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,6 +1,6 @@ use super::*; -use frame_support::assert_err; -use mock::{new_test_ext, start_session, Origin, RootOffences, Test}; +use frame_support::{assert_err, assert_ok}; +use mock::{new_test_ext, start_session, Origin, RootOffences}; #[test] fn create_offence_fails_given_signed_origin() { @@ -15,7 +15,8 @@ fn create_offence_fails_given_signed_origin() { fn create_offence_works_given_root_origin() { new_test_ext().execute_with(|| { start_session(1); - let _active_era = Staking::::active_era().unwrap(); - //assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); + start_session(2); + let offenders = (&[]).to_vec(); + assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); }) } From a7fd6153d4ff919af9311a6eeb58ba0bb58566b3 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Thu, 18 Aug 2022 21:47:14 +0300 Subject: [PATCH 29/54] impl GenesisConfig for pallet_session --- frame/root-offences/src/mock.rs | 40 +++++++++++++++++++++++++++++--- frame/root-offences/src/tests.rs | 11 ++++++--- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index 06cea16c48d99..992b0d9c7b7e1 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -4,14 +4,14 @@ use crate as root_offences; use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ parameter_types, - traits::{ConstU32, ConstU64, Hooks}, + traits::{ConstU32, ConstU64, Hooks, OneSessionHandler, GenesisBuild}, }; use pallet_session::TestSessionHandler; use pallet_staking::StakerStatus; use sp_core::H256; use sp_runtime::{ curve::PiecewiseLinear, - testing::Header, + testing::{Header, UintAuthorityId}, traits::{BlakeTwo256, IdentityLookup, Zero}, }; use sp_staking::SessionIndex; @@ -41,6 +41,32 @@ frame_support::construct_runtime!( } ); +/// Another session handler struct to test on_disabled. +pub struct OtherSessionHandler; +impl OneSessionHandler for OtherSessionHandler { + type Key = UintAuthorityId; + + fn on_genesis_session<'a, I: 'a>(_: I) + where + I: Iterator, + AccountId: 'a, + { + } + + fn on_new_session<'a, I: 'a>(_: bool, _: I, _: I) + where + I: Iterator, + AccountId: 'a, + { + } + + fn on_disabled(_validator_index: u32) {} +} + +impl sp_runtime::BoundToRuntimeAppPublic for OtherSessionHandler { + type Public = UintAuthorityId; +} + parameter_types! { pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights::simple_max(1024); @@ -144,7 +170,7 @@ impl pallet_session::historical::Config for Test { sp_runtime::impl_opaque_keys! { pub struct SessionKeys { - pub foo: sp_runtime::testing::UintAuthorityId, + pub other: OtherSessionHandler, } } @@ -187,6 +213,14 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let _ = pallet_staking::GenesisConfig:: { stakers: stakers.clone(), ..Default::default() }; + let _ = pallet_session::GenesisConfig:: { + keys: stakers + .into_iter() + .map(|(id, ..)| (id, id, SessionKeys { other: id.into() })) + .collect() + } + .assimilate_storage(&mut storage); + storage.into() } diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index f7a484e460359..28c8a84eed60e 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,6 +1,6 @@ use super::*; use frame_support::{assert_err, assert_ok}; -use mock::{new_test_ext, start_session, Origin, RootOffences}; +use mock::{new_test_ext, start_session, Origin, RootOffences, Balances}; #[test] fn create_offence_fails_given_signed_origin() { @@ -15,8 +15,13 @@ fn create_offence_fails_given_signed_origin() { fn create_offence_works_given_root_origin() { new_test_ext().execute_with(|| { start_session(1); - start_session(2); - let offenders = (&[]).to_vec(); + + assert_eq!(Balances::free_balance(11), 550); + + let offenders = [(11, Perbill::from_percent(50))].to_vec(); assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); + + start_session(2); + assert_eq!(Balances::free_balance(11), 550); }) } From 9ec53c8bae5355423a86e619169c27e48b770af4 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 19 Aug 2022 14:07:28 +0300 Subject: [PATCH 30/54] updated event --- Cargo.lock | 1 + frame/root-offences/Cargo.toml | 2 ++ frame/root-offences/src/lib.rs | 17 +++++++++++------ frame/root-offences/src/mock.rs | 23 +++++++++++++++++------ frame/root-offences/src/tests.rs | 14 +++++++++----- 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57d2e51b31474..23e713b6442fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6151,6 +6151,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-staking", + "sp-std", ] [[package]] diff --git a/frame/root-offences/Cargo.toml b/frame/root-offences/Cargo.toml index ff856505adeb7..367360e7535d6 100644 --- a/frame/root-offences/Cargo.toml +++ b/frame/root-offences/Cargo.toml @@ -31,6 +31,8 @@ pallet-staking-reward-curve = { version = "4.0.0-dev", path = "../staking/reward sp-core = { version = "6.0.0", path = "../../primitives/core" } sp-io = { version = "6.0.0", default-features = false, path = "../../primitives/io" } +sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" } + frame-election-provider-support = { version = "4.0.0-dev", path = "../election-provider-support" } [features] diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 734c8216ddcfa..237a21db42363 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -52,7 +52,7 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - RootCreatedOffence { offenders: Vec<(T::AccountId, Perbill)> }, + CreatedOffence { offenders: Vec<(T::AccountId, Perbill)>, unapplied_slash: Weight }, } #[pallet::error] @@ -93,9 +93,9 @@ pub mod pallet { let offence_details = Self::get_offence_details(offenders.clone())?; - Self::submit_offence(&offence_details, &slash_fraction); + let unapplied_slash = Self::submit_offence(&offence_details, &slash_fraction)?; - Self::deposit_event(Event::RootCreatedOffence { offenders }); + Self::deposit_event(Event::CreatedOffence { offenders, unapplied_slash }); Ok(()) } } @@ -109,14 +109,19 @@ pub mod pallet { >, { /// Submits the offence by calling the `on_offence` function. - fn submit_offence(offenders: &[OffenceDetails], slash_fraction: &[Perbill]) { + fn submit_offence( + offenders: &[OffenceDetails], + slash_fraction: &[Perbill], + ) -> Result { let session_index = as frame_support::traits::ValidatorSet>::session_index(); - as OnOffenceHandler< + Ok( as OnOffenceHandler< T::AccountId, IdentificationTuple, Weight, - >>::on_offence(&offenders, &slash_fraction, session_index, DisableStrategy::WhenSlashed); + >>::on_offence( + &offenders, &slash_fraction, session_index, DisableStrategy::WhenSlashed + )) } /// Returns a vector of offenders that are going to be slashed. diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index 992b0d9c7b7e1..e54249b6c9c4d 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -4,7 +4,7 @@ use crate as root_offences; use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ parameter_types, - traits::{ConstU32, ConstU64, Hooks, OneSessionHandler, GenesisBuild}, + traits::{ConstU32, ConstU64, GenesisBuild, Hooks, OneSessionHandler}, }; use pallet_session::TestSessionHandler; use pallet_staking::StakerStatus; @@ -14,7 +14,7 @@ use sp_runtime::{ testing::{Header, UintAuthorityId}, traits::{BlakeTwo256, IdentityLookup, Zero}, }; -use sp_staking::SessionIndex; +use sp_staking::{EraIndex, SessionIndex}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -133,6 +133,9 @@ parameter_types! { pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; pub static Offset: BlockNumber = 0; pub const Period: BlockNumber = 1; + pub static SessionsPerEra: SessionIndex = 3; + pub static SlashDeferDuration: EraIndex = 0; + pub const BondingDuration: EraIndex = 3; } impl pallet_staking::Config for Test { @@ -145,10 +148,10 @@ impl pallet_staking::Config for Test { type Event = Event; type Slash = (); type Reward = (); - type SessionsPerEra = (); - type SlashDeferDuration = (); + type SessionsPerEra = SessionsPerEra; + type SlashDeferDuration = SlashDeferDuration; type SlashCancelOrigin = frame_system::EnsureRoot; - type BondingDuration = (); + type BondingDuration = BondingDuration; type SessionInterface = Self; type EraPayout = pallet_staking::ConvertCurve; type NextNewSession = Session; @@ -217,7 +220,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { keys: stakers .into_iter() .map(|(id, ..)| (id, id, SessionKeys { other: id.into() })) - .collect() + .collect(), } .assimilate_storage(&mut storage); @@ -259,3 +262,11 @@ pub(crate) fn run_to_block(n: BlockNumber) { } } } + +pub(crate) fn active_era() -> EraIndex { + Staking::active_era().unwrap().index +} + +pub(crate) fn current_era() -> EraIndex { + Staking::current_era().unwrap() +} diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 28c8a84eed60e..5acb080634666 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,6 +1,8 @@ use super::*; use frame_support::{assert_err, assert_ok}; -use mock::{new_test_ext, start_session, Origin, RootOffences, Balances}; +use mock::{ + active_era, current_era, new_test_ext, start_session, Balances, Origin, RootOffences, System, +}; #[test] fn create_offence_fails_given_signed_origin() { @@ -16,12 +18,14 @@ fn create_offence_works_given_root_origin() { new_test_ext().execute_with(|| { start_session(1); + assert_eq!(active_era(), 0); + assert_eq!(current_era(), 0); + assert_eq!(Balances::free_balance(11), 550); - + let offenders = [(11, Perbill::from_percent(50))].to_vec(); - assert_ok!(RootOffences::create_offence(Origin::root(), offenders)); + assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); - start_session(2); - assert_eq!(Balances::free_balance(11), 550); + System::assert_last_event(Event::CreatedOffence { offenders, unapplied_slash: 0 }.into()); }) } From aa6ab8d7b514ee3b442b1a2168cf2873962bb87b Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Fri, 19 Aug 2022 14:13:57 +0300 Subject: [PATCH 31/54] Update frame/root-offences/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/root-offences/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 237a21db42363..3cc4c4b758e94 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -128,8 +128,7 @@ pub mod pallet { fn get_offence_details( offenders: Vec<(T::AccountId, Perbill)>, ) -> Result>, DispatchError> { - let active_era = Staking::::active_era().ok_or(Error::::FailedToGetActiveEra)?; - let now = active_era.index; + let now = Staking::::active_era().map(|e| e.index).ok_or(Error::::FailedToGetActiveEra)?; Ok(offenders .clone() From ee47b0198af181c59273e683f83e9acefdc830f3 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Fri, 19 Aug 2022 14:14:14 +0300 Subject: [PATCH 32/54] Update frame/root-offences/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/root-offences/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 3cc4c4b758e94..ef26cbed75e07 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -89,7 +89,7 @@ pub mod pallet { .clone() .into_iter() .map(|(_, fraction)| fraction) - .collect::>(); + .collect::>(); let offence_details = Self::get_offence_details(offenders.clone())?; From 160aa40fa17fbb7529a41fc5bde16fe00f3edcce Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 19 Aug 2022 15:03:26 +0300 Subject: [PATCH 33/54] remove = - sp_staking::offence::OffenceDetails>; - + type OffenceDetails = sp_staking::offence::OffenceDetails< + ::AccountId, + IdentificationTuple, + >; #[pallet::call] impl Pallet where @@ -85,11 +85,8 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - let slash_fraction = offenders - .clone() - .into_iter() - .map(|(_, fraction)| fraction) - .collect::>(); + let slash_fraction = + offenders.clone().into_iter().map(|(_, fraction)| fraction).collect::>(); let offence_details = Self::get_offence_details(offenders.clone())?; @@ -128,7 +125,9 @@ pub mod pallet { fn get_offence_details( offenders: Vec<(T::AccountId, Perbill)>, ) -> Result>, DispatchError> { - let now = Staking::::active_era().map(|e| e.index).ok_or(Error::::FailedToGetActiveEra)?; + let now = Staking::::active_era() + .map(|e| e.index) + .ok_or(Error::::FailedToGetActiveEra)?; Ok(offenders .clone() From ca78672bd64d9876b397abc7676bd8d0a7e21414 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Fri, 19 Aug 2022 16:24:11 +0300 Subject: [PATCH 34/54] specifying trait bounds inside Config --- frame/root-offences/src/lib.rs | 37 ++++++++++++++-------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index f3eec6888bb48..6ec724b6148e6 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -29,7 +29,7 @@ mod tests; use pallet_session::historical::IdentificationTuple; use pallet_staking::{BalanceOf, Exposure, ExposureOf, Pallet as Staking}; -use sp_runtime::{traits::Convert, Perbill}; +use sp_runtime::Perbill; use sp_staking::offence::{DisableStrategy, OnOffenceHandler}; pub use pallet::*; @@ -41,7 +41,18 @@ pub mod pallet { use frame_system::pallet_prelude::*; #[pallet::config] - pub trait Config: frame_system::Config + pallet_staking::Config { + pub trait Config: + frame_system::Config + + pallet_staking::Config + + pallet_session::Config::AccountId> + + pallet_session::historical::Config< + FullIdentification = Exposure< + ::AccountId, + BalanceOf, + >, + FullIdentificationOf = ExposureOf, + > + { type Event: From> + IsType<::Event>; } @@ -65,18 +76,7 @@ pub mod pallet { IdentificationTuple, >; #[pallet::call] - impl Pallet - where - T: pallet_session::Config::AccountId>, - T: pallet_session::historical::Config< - FullIdentification = Exposure<::AccountId, BalanceOf>, - FullIdentificationOf = ExposureOf, - >, - T::ValidatorIdOf: Convert< - ::AccountId, - Option<::AccountId>, - >, - { + impl Pallet { /// Allows the `root`, for example sudo to create an offence. #[pallet::weight(10_000)] pub fn create_offence( @@ -97,14 +97,7 @@ pub mod pallet { } } - impl Pallet - where - T: pallet_session::Config::AccountId>, - T: pallet_session::historical::Config< - FullIdentification = Exposure<::AccountId, BalanceOf>, - FullIdentificationOf = ExposureOf, - >, - { + impl Pallet { /// Submits the offence by calling the `on_offence` function. fn submit_offence( offenders: &[OffenceDetails], From 0ff7a3ed963ab96cbf1eed20b0ef35f014cd4ad0 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 11:24:02 +0300 Subject: [PATCH 35/54] commit --- frame/root-offences/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index e54249b6c9c4d..cb8af1ebb15c6 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -36,7 +36,7 @@ frame_support::construct_runtime!( Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - RootOffences: root_offences, + RootOffences: root_offences::{Pallet, Call, Storage, Event}, Historical: pallet_session::historical::{Pallet, Storage}, } ); From 29a0bdc8534e053fcca9a9969803fde46b8a6967 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 11:51:39 +0300 Subject: [PATCH 36/54] active era increases correctly :) --- frame/root-offences/src/mock.rs | 42 ++++++++++++++++++++++++++------ frame/root-offences/src/tests.rs | 9 ++++--- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index cb8af1ebb15c6..b6857a09d44b0 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -6,7 +6,6 @@ use frame_support::{ parameter_types, traits::{ConstU32, ConstU64, GenesisBuild, Hooks, OneSessionHandler}, }; -use pallet_session::TestSessionHandler; use pallet_staking::StakerStatus; use sp_core::H256; use sp_runtime::{ @@ -181,11 +180,11 @@ impl pallet_session::Config for Test { type SessionManager = pallet_session::historical::NoteHistoricalRoot; type Keys = SessionKeys; type ShouldEndSession = pallet_session::PeriodicSessions; - type NextSessionRotation = pallet_session::PeriodicSessions; - type SessionHandler = TestSessionHandler; + type SessionHandler = (OtherSessionHandler,); type Event = Event; type ValidatorId = AccountId; type ValidatorIdOf = pallet_staking::StashOf; + type NextSessionRotation = pallet_session::PeriodicSessions; type WeightInfo = (); } @@ -203,19 +202,48 @@ impl Config for Test { pub fn new_test_ext() -> sp_io::TestExternalities { let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(11, 550), (21, 1100)] } - .assimilate_storage(&mut storage) - .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![ + //controllers + (10, 50), + (20, 50), + (30, 50), + (40, 50), + // stashes + (11, 1000), + (21, 1000), + (31, 500), + (41, 1000), + ], + } + .assimilate_storage(&mut storage) + .unwrap(); let stakers = vec![ // (stash, ctrl, stake, status) - (11, 10, 500, StakerStatus::::Validator), + (11, 10, 1000, StakerStatus::::Validator), (21, 20, 1000, StakerStatus::::Validator), + // a loser validator + (31, 30, 500, StakerStatus::::Validator), + // an idle validator + (41, 40, 1000, StakerStatus::::Idle), ]; let _ = pallet_staking::GenesisConfig:: { stakers: stakers.clone(), ..Default::default() }; + let _ = pallet_staking::GenesisConfig:: { + stakers: stakers.clone(), + validator_count: 2, + minimum_validator_count: 0, + invulnerables: vec![], + slash_reward_fraction: Perbill::from_percent(10), + min_nominator_bond: 1, + min_validator_bond: 1, + ..Default::default() + } + .assimilate_storage(&mut storage); + let _ = pallet_session::GenesisConfig:: { keys: stakers .into_iter() diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 5acb080634666..3766b81369bd4 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -16,12 +16,15 @@ fn create_offence_fails_given_signed_origin() { #[test] fn create_offence_works_given_root_origin() { new_test_ext().execute_with(|| { + // NOTE: this test is still WIP. start_session(1); + start_session(2); + start_session(3); - assert_eq!(active_era(), 0); - assert_eq!(current_era(), 0); + assert_eq!(active_era(), 1); + assert_eq!(current_era(), 1); - assert_eq!(Balances::free_balance(11), 550); + assert_eq!(Balances::free_balance(11), 1000); let offenders = [(11, Perbill::from_percent(50))].to_vec(); assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); From 04f7c2d14c6f5933bbec6b67fdc06c92173afae7 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 12:17:08 +0300 Subject: [PATCH 37/54] ExtBuilder --- frame/root-offences/src/mock.rs | 125 ++++++++++++++++++------------- frame/root-offences/src/tests.rs | 6 +- 2 files changed, 78 insertions(+), 53 deletions(-) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index b6857a09d44b0..5f3d388009e3d 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -199,60 +199,85 @@ impl Config for Test { type Event = Event; } -pub fn new_test_ext() -> sp_io::TestExternalities { - let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); - - pallet_balances::GenesisConfig:: { - balances: vec![ - //controllers - (10, 50), - (20, 50), - (30, 50), - (40, 50), - // stashes - (11, 1000), - (21, 1000), - (31, 500), - (41, 1000), - ], - } - .assimilate_storage(&mut storage) - .unwrap(); - - let stakers = vec![ - // (stash, ctrl, stake, status) - (11, 10, 1000, StakerStatus::::Validator), - (21, 20, 1000, StakerStatus::::Validator), - // a loser validator - (31, 30, 500, StakerStatus::::Validator), - // an idle validator - (41, 40, 1000, StakerStatus::::Idle), - ]; - - let _ = - pallet_staking::GenesisConfig:: { stakers: stakers.clone(), ..Default::default() }; - - let _ = pallet_staking::GenesisConfig:: { - stakers: stakers.clone(), - validator_count: 2, - minimum_validator_count: 0, - invulnerables: vec![], - slash_reward_fraction: Perbill::from_percent(10), - min_nominator_bond: 1, - min_validator_bond: 1, - ..Default::default() +pub struct ExtBuilder { + validator_count: u32, + minimum_validator_count: u32, + invulnerables: Vec, + balance_factor: Balance, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { + validator_count: 2, + minimum_validator_count: 0, + invulnerables: vec![], + balance_factor: 1, + } } - .assimilate_storage(&mut storage); +} + +impl ExtBuilder { + fn build(self) -> sp_io::TestExternalities { + let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![ + //controllers + (10, self.balance_factor * 50), + (20, self.balance_factor * 50), + (30, self.balance_factor * 50), + (40, self.balance_factor * 50), + // stashes + (11, self.balance_factor * 1000), + (21, self.balance_factor * 1000), + (31, self.balance_factor * 500), + (41, self.balance_factor * 1000), + ], + } + .assimilate_storage(&mut storage) + .unwrap(); - let _ = pallet_session::GenesisConfig:: { - keys: stakers - .into_iter() - .map(|(id, ..)| (id, id, SessionKeys { other: id.into() })) - .collect(), + let stakers = vec![ + // (stash, ctrl, stake, status) + (11, 10, 1000, StakerStatus::::Validator), + (21, 20, 1000, StakerStatus::::Validator), + // a loser validator + (31, 30, 500, StakerStatus::::Validator), + // an idle validator + (41, 40, 1000, StakerStatus::::Idle), + ]; + + let _ = pallet_staking::GenesisConfig:: { + stakers: stakers.clone(), + ..Default::default() + }; + + let _ = pallet_staking::GenesisConfig:: { + stakers: stakers.clone(), + validator_count: self.validator_count, + minimum_validator_count: self.minimum_validator_count, + invulnerables: self.invulnerables, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + } + .assimilate_storage(&mut storage); + + let _ = pallet_session::GenesisConfig:: { + keys: stakers + .into_iter() + .map(|(id, ..)| (id, id, SessionKeys { other: id.into() })) + .collect(), + } + .assimilate_storage(&mut storage); + + storage.into() } - .assimilate_storage(&mut storage); - storage.into() + pub fn build_and_execute(self, test: impl FnOnce() -> ()) { + let mut ext = self.build(); + ext.execute_with(test); + } } /// Progresses from the current block number (whatever that may be) to the `P * session_index + 1`. diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 3766b81369bd4..4c22feeb60c00 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,13 +1,13 @@ use super::*; use frame_support::{assert_err, assert_ok}; use mock::{ - active_era, current_era, new_test_ext, start_session, Balances, Origin, RootOffences, System, + active_era, current_era, start_session, Balances, ExtBuilder, Origin, RootOffences, System, }; #[test] fn create_offence_fails_given_signed_origin() { use sp_runtime::traits::BadOrigin; - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let offenders = (&[]).to_vec(); assert_err!(RootOffences::create_offence(Origin::signed(1), offenders), BadOrigin); }) @@ -15,7 +15,7 @@ fn create_offence_fails_given_signed_origin() { #[test] fn create_offence_works_given_root_origin() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { // NOTE: this test is still WIP. start_session(1); start_session(2); From 444da1688b7708b93207355bccc67ec17a22b205 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 14:46:42 +0300 Subject: [PATCH 38/54] slashing works --- frame/root-offences/src/mock.rs | 21 ++++++++++++++++++--- frame/root-offences/src/tests.rs | 13 ++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index 5f3d388009e3d..591f565493af7 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -14,6 +14,7 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup, Zero}, }; use sp_staking::{EraIndex, SessionIndex}; +use sp_std::collections::btree_map::BTreeMap; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -128,6 +129,18 @@ impl onchain::Config for OnChainSeqPhragmen { type DataProvider = Staking; type WeightInfo = (); } + +pub struct OnStakerSlashMock(core::marker::PhantomData); +impl sp_staking::OnStakerSlash for OnStakerSlashMock { + fn on_slash( + _pool_account: &AccountId, + slashed_bonded: Balance, + slashed_chunks: &BTreeMap, + ) { + LedgerSlashPerEra::set((slashed_bonded, slashed_chunks.clone())); + } +} + parameter_types! { pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; pub static Offset: BlockNumber = 0; @@ -135,13 +148,15 @@ parameter_types! { pub static SessionsPerEra: SessionIndex = 3; pub static SlashDeferDuration: EraIndex = 0; pub const BondingDuration: EraIndex = 3; + pub static LedgerSlashPerEra: (BalanceOf, BTreeMap>) = (Zero::zero(), BTreeMap::new()); + pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(75); } impl pallet_staking::Config for Test { type MaxNominations = ConstU32<16>; type Currency = Balances; type CurrencyBalance = ::Balance; - type UnixTime = pallet_timestamp::Pallet; + type UnixTime = Timestamp; type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; type RewardRemainder = (); type Event = Event; @@ -155,12 +170,12 @@ impl pallet_staking::Config for Test { type EraPayout = pallet_staking::ConvertCurve; type NextNewSession = Session; type MaxNominatorRewardedPerValidator = ConstU32<64>; - type OffendingValidatorsThreshold = (); + type OffendingValidatorsThreshold = OffendingValidatorsThreshold; type ElectionProvider = onchain::UnboundedExecution; type GenesisElectionProvider = Self::ElectionProvider; type MaxUnlockingChunks = ConstU32<32>; type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; - type OnStakerSlash = (); + type OnStakerSlash = OnStakerSlashMock; type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; type WeightInfo = (); } diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 4c22feeb60c00..36fd9d167d824 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -16,19 +16,22 @@ fn create_offence_fails_given_signed_origin() { #[test] fn create_offence_works_given_root_origin() { ExtBuilder::default().build_and_execute(|| { - // NOTE: this test is still WIP. start_session(1); - start_session(2); - start_session(3); - assert_eq!(active_era(), 1); - assert_eq!(current_era(), 1); + assert_eq!(active_era(), 0); + assert_eq!(current_era(), 0); assert_eq!(Balances::free_balance(11), 1000); let offenders = [(11, Perbill::from_percent(50))].to_vec(); assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); + // the slash should be applied, so the unapplied slash is zero. System::assert_last_event(Event::CreatedOffence { offenders, unapplied_slash: 0 }.into()); + assert_eq!(Balances::free_balance(11), 500); + + // the other validator should keep his balance, because we only created + // an offences for the first validator. + assert_eq!(Balances::free_balance(21), 1000); }) } From e0bf7c7c653910509448b5a5ddf99dd5993434b1 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 16:42:53 +0300 Subject: [PATCH 39/54] new test --- frame/root-offences/src/tests.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 36fd9d167d824..d510d04f520e2 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -35,3 +35,27 @@ fn create_offence_works_given_root_origin() { assert_eq!(Balances::free_balance(21), 1000); }) } + +#[test] +fn create_offence_wont_slash_non_active_validators() { + ExtBuilder::default().build_and_execute(|| { + start_session(1); + + assert_eq!(active_era(), 0); + assert_eq!(current_era(), 0); + + // 31 is not an active validator. + assert_eq!(Balances::free_balance(31), 500); + + let offenders = [(31, Perbill::from_percent(20)), (11, Perbill::from_percent(20))].to_vec(); + assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); + + System::assert_last_event(Event::CreatedOffence { offenders, unapplied_slash: 0 }.into()); + + // so 31 didn't get slashed. + assert_eq!(Balances::free_balance(31), 500); + + // but 11 is an active validator so he got slashed. + assert_eq!(Balances::free_balance(11), 800); + }) +} From d941494d2f8d9eb7a8482ba0996868b0432edb65 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 17:12:09 +0300 Subject: [PATCH 40/54] additional test --- frame/root-offences/src/tests.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index d510d04f520e2..fc74546fe96f0 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -59,3 +59,24 @@ fn create_offence_wont_slash_non_active_validators() { assert_eq!(Balances::free_balance(11), 800); }) } + +#[test] +fn create_offence_wont_slash_idle() { + ExtBuilder::default().build_and_execute(|| { + start_session(1); + + assert_eq!(active_era(), 0); + assert_eq!(current_era(), 0); + + // 41 is idle. + assert_eq!(Balances::free_balance(41), 1000); + + let offenders = [(41, Perbill::from_percent(50))].to_vec(); + assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); + + System::assert_last_event(Event::CreatedOffence { offenders, unapplied_slash: 0 }.into()); + + // 41 didn't get slashed. + assert_eq!(Balances::free_balance(41), 1000); + }) +} From 7627641d29e4929fd6e879d17d3b4e31b13f59dc Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 19:43:21 +0200 Subject: [PATCH 41/54] commit --- frame/root-offences/Cargo.toml | 4 ++-- frame/root-offences/src/mock.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frame/root-offences/Cargo.toml b/frame/root-offences/Cargo.toml index 367360e7535d6..db01174d0f591 100644 --- a/frame/root-offences/Cargo.toml +++ b/frame/root-offences/Cargo.toml @@ -36,8 +36,8 @@ sp-std = { version = "4.0.0", default-features = false, path = "../../primitives frame-election-provider-support = { version = "4.0.0-dev", path = "../election-provider-support" } [features] -runtime-benchmarks = [] -try-runtime = [] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +try-runtime = ["frame-support/try-runtime"] default = ["std"] std = [ "codec/std", diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index 591f565493af7..1d5ef60223a1a 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -255,6 +255,7 @@ impl ExtBuilder { let stakers = vec![ // (stash, ctrl, stake, status) + // these two will be elected in the default test where we elect 2. (11, 10, 1000, StakerStatus::::Validator), (21, 20, 1000, StakerStatus::::Validator), // a loser validator From 84737f0552d2f82d9384fa8e79e5a476ac29f673 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 19:46:48 +0200 Subject: [PATCH 42/54] order --- frame/root-offences/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/root-offences/Cargo.toml b/frame/root-offences/Cargo.toml index db01174d0f591..6118a72c25af2 100644 --- a/frame/root-offences/Cargo.toml +++ b/frame/root-offences/Cargo.toml @@ -41,11 +41,11 @@ try-runtime = ["frame-support/try-runtime"] default = ["std"] std = [ "codec/std", - "scale-info/std", + "frame-support/std", + "frame-system/std", "pallet-session/std", "pallet-staking/std", "pallet-offences/std", - "frame-support/std", - "frame-system/std", + "scale-info/std", "sp-runtime/std", ] From bae19c046873235ee20bb63bfecf19a781117e19 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 19:48:02 +0200 Subject: [PATCH 43/54] fix? --- frame/root-offences/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/root-offences/Cargo.toml b/frame/root-offences/Cargo.toml index 6118a72c25af2..1c5cb4203bbb0 100644 --- a/frame/root-offences/Cargo.toml +++ b/frame/root-offences/Cargo.toml @@ -36,7 +36,7 @@ sp-std = { version = "4.0.0", default-features = false, path = "../../primitives frame-election-provider-support = { version = "4.0.0-dev", path = "../election-provider-support" } [features] -runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +runtime-benchmarks = [] try-runtime = ["frame-support/try-runtime"] default = ["std"] std = [ From 4cc7538edf2e03ab974f9bbaf03ab4175993465d Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 20 Aug 2022 20:15:05 +0200 Subject: [PATCH 44/54] fix in logic --- frame/root-offences/src/lib.rs | 35 ++++++++++++++------------------ frame/root-offences/src/tests.rs | 8 ++++---- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 6ec724b6148e6..f3f1618687b55 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -63,7 +63,7 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - CreatedOffence { offenders: Vec<(T::AccountId, Perbill)>, unapplied_slash: Weight }, + CreatedOffence { offenders: Vec<(T::AccountId, Perbill)> }, } #[pallet::error] @@ -78,7 +78,7 @@ pub mod pallet { #[pallet::call] impl Pallet { /// Allows the `root`, for example sudo to create an offence. - #[pallet::weight(10_000)] + #[pallet::weight(T::DbWeight::get().reads(2))] pub fn create_offence( origin: OriginFor, offenders: Vec<(T::AccountId, Perbill)>, @@ -90,30 +90,14 @@ pub mod pallet { let offence_details = Self::get_offence_details(offenders.clone())?; - let unapplied_slash = Self::submit_offence(&offence_details, &slash_fraction)?; + Self::submit_offence(&offence_details, &slash_fraction); - Self::deposit_event(Event::CreatedOffence { offenders, unapplied_slash }); + Self::deposit_event(Event::CreatedOffence { offenders }); Ok(()) } } impl Pallet { - /// Submits the offence by calling the `on_offence` function. - fn submit_offence( - offenders: &[OffenceDetails], - slash_fraction: &[Perbill], - ) -> Result { - let session_index = as frame_support::traits::ValidatorSet>::session_index(); - - Ok( as OnOffenceHandler< - T::AccountId, - IdentificationTuple, - Weight, - >>::on_offence( - &offenders, &slash_fraction, session_index, DisableStrategy::WhenSlashed - )) - } - /// Returns a vector of offenders that are going to be slashed. fn get_offence_details( offenders: Vec<(T::AccountId, Perbill)>, @@ -131,5 +115,16 @@ pub mod pallet { }) .collect()) } + + /// Submits the offence by calling the `on_offence` function. + fn submit_offence(offenders: &[OffenceDetails], slash_fraction: &[Perbill]) { + let session_index = as frame_support::traits::ValidatorSet>::session_index(); + + as OnOffenceHandler< + T::AccountId, + IdentificationTuple, + Weight, + >>::on_offence(&offenders, &slash_fraction, session_index, DisableStrategy::WhenSlashed); + } } } diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index fc74546fe96f0..a0510a69b9b59 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -26,8 +26,8 @@ fn create_offence_works_given_root_origin() { let offenders = [(11, Perbill::from_percent(50))].to_vec(); assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); - // the slash should be applied, so the unapplied slash is zero. - System::assert_last_event(Event::CreatedOffence { offenders, unapplied_slash: 0 }.into()); + System::assert_last_event(Event::CreatedOffence { offenders }.into()); + // the slash should be applied right away. assert_eq!(Balances::free_balance(11), 500); // the other validator should keep his balance, because we only created @@ -50,7 +50,7 @@ fn create_offence_wont_slash_non_active_validators() { let offenders = [(31, Perbill::from_percent(20)), (11, Perbill::from_percent(20))].to_vec(); assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); - System::assert_last_event(Event::CreatedOffence { offenders, unapplied_slash: 0 }.into()); + System::assert_last_event(Event::CreatedOffence { offenders }.into()); // so 31 didn't get slashed. assert_eq!(Balances::free_balance(31), 500); @@ -74,7 +74,7 @@ fn create_offence_wont_slash_idle() { let offenders = [(41, Perbill::from_percent(50))].to_vec(); assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); - System::assert_last_event(Event::CreatedOffence { offenders, unapplied_slash: 0 }.into()); + System::assert_last_event(Event::CreatedOffence { offenders }.into()); // 41 didn't get slashed. assert_eq!(Balances::free_balance(41), 1000); From e2b602963202ef37de64eea91908e118bb4d1bd6 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sun, 21 Aug 2022 10:37:09 +0200 Subject: [PATCH 45/54] remove unnecessary --- frame/root-offences/src/mock.rs | 4 ---- frame/root-offences/src/tests.rs | 7 +------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index 1d5ef60223a1a..ce200473e3201 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -335,7 +335,3 @@ pub(crate) fn run_to_block(n: BlockNumber) { pub(crate) fn active_era() -> EraIndex { Staking::active_era().unwrap().index } - -pub(crate) fn current_era() -> EraIndex { - Staking::current_era().unwrap() -} diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index a0510a69b9b59..09f1bd9821654 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,8 +1,6 @@ use super::*; use frame_support::{assert_err, assert_ok}; -use mock::{ - active_era, current_era, start_session, Balances, ExtBuilder, Origin, RootOffences, System, -}; +use mock::{active_era, start_session, Balances, ExtBuilder, Origin, RootOffences, System}; #[test] fn create_offence_fails_given_signed_origin() { @@ -19,7 +17,6 @@ fn create_offence_works_given_root_origin() { start_session(1); assert_eq!(active_era(), 0); - assert_eq!(current_era(), 0); assert_eq!(Balances::free_balance(11), 1000); @@ -42,7 +39,6 @@ fn create_offence_wont_slash_non_active_validators() { start_session(1); assert_eq!(active_era(), 0); - assert_eq!(current_era(), 0); // 31 is not an active validator. assert_eq!(Balances::free_balance(31), 500); @@ -66,7 +62,6 @@ fn create_offence_wont_slash_idle() { start_session(1); assert_eq!(active_era(), 0); - assert_eq!(current_era(), 0); // 41 is idle. assert_eq!(Balances::free_balance(41), 1000); From c944db1c75bc6c346928a79172466ec4ddf5568c Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 29 Aug 2022 14:23:27 +0200 Subject: [PATCH 46/54] wrap comment at 100 --- frame/nomination-pools/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/nomination-pools/src/lib.rs b/frame/nomination-pools/src/lib.rs index 7e02281582012..3e53cd729e3dd 100644 --- a/frame/nomination-pools/src/lib.rs +++ b/frame/nomination-pools/src/lib.rs @@ -2483,8 +2483,8 @@ impl Pallet { impl OnStakerSlash> for Pallet { fn on_slash( pool_account: &T::AccountId, - // Bonded balance is always read directly from staking, therefore we - // don't need to update anything here. + // Bonded balance is always read directly from staking, therefore we don't need to update + // anything here. slashed_bonded: BalanceOf, slashed_unlocking: &BTreeMap>, ) { From 4b2526e46491212f20f567681d3aed8aeebab073 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 29 Aug 2022 14:25:45 +0200 Subject: [PATCH 47/54] fmt --- frame/nomination-pools/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/nomination-pools/src/lib.rs b/frame/nomination-pools/src/lib.rs index 3e53cd729e3dd..a40a4cd46e13f 100644 --- a/frame/nomination-pools/src/lib.rs +++ b/frame/nomination-pools/src/lib.rs @@ -2483,7 +2483,7 @@ impl Pallet { impl OnStakerSlash> for Pallet { fn on_slash( pool_account: &T::AccountId, - // Bonded balance is always read directly from staking, therefore we don't need to update + // Bonded balance is always read directly from staking, therefore we don't need to update // anything here. slashed_bonded: BalanceOf, slashed_unlocking: &BTreeMap>, From 33f07e917f04b6a46bf2048ae0230c2b10c3007b Mon Sep 17 00:00:00 2001 From: Szegoo Date: Sat, 24 Sep 2022 10:29:13 +0200 Subject: [PATCH 48/54] merge fixes --- frame/root-offences/src/lib.rs | 2 +- frame/root-offences/src/mock.rs | 18 ++++++++++-------- frame/root-offences/src/tests.rs | 10 +++++----- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index f3f1618687b55..94874ddaf3b2b 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -53,7 +53,7 @@ pub mod pallet { FullIdentificationOf = ExposureOf, > { - type Event: From> + IsType<::Event>; + type RuntimeEvent: From> + IsType<::RuntimeEvent>; } #[pallet::pallet] diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index ce200473e3201..645c03463cc31 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -69,7 +69,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for OtherSessionHandler { parameter_types! { pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); + frame_system::limits::BlockWeights::simple_max(frame_support::weights::Weight::from_ref_time(1024)); } impl frame_system::Config for Test { @@ -77,16 +77,16 @@ impl frame_system::Config for Test { type BlockWeights = (); type BlockLength = (); type DbWeight = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; type BlockNumber = u64; type Hash = H256; - type Call = Call; + type RuntimeCall = RuntimeCall; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = ConstU64<250>; type Version = (); type PalletInfo = PalletInfo; @@ -104,7 +104,7 @@ impl pallet_balances::Config for Test { type MaxReserves = (); type ReserveIdentifier = [u8; 8]; type Balance = Balance; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ConstU64<1>; type AccountStore = System; @@ -159,7 +159,7 @@ impl pallet_staking::Config for Test { type UnixTime = Timestamp; type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; type RewardRemainder = (); - type Event = Event; + type RuntimeEvent = RuntimeEvent; type Slash = (); type Reward = (); type SessionsPerEra = SessionsPerEra; @@ -173,7 +173,9 @@ impl pallet_staking::Config for Test { type OffendingValidatorsThreshold = OffendingValidatorsThreshold; type ElectionProvider = onchain::UnboundedExecution; type GenesisElectionProvider = Self::ElectionProvider; + type TargetList = pallet_staking::UseValidatorsMap; type MaxUnlockingChunks = ConstU32<32>; + type HistoryDepth = ConstU32<84>; type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; type OnStakerSlash = OnStakerSlashMock; type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; @@ -196,7 +198,7 @@ impl pallet_session::Config for Test { type Keys = SessionKeys; type ShouldEndSession = pallet_session::PeriodicSessions; type SessionHandler = (OtherSessionHandler,); - type Event = Event; + type RuntimeEvent = RuntimeEvent; type ValidatorId = AccountId; type ValidatorIdOf = pallet_staking::StashOf; type NextSessionRotation = pallet_session::PeriodicSessions; @@ -211,7 +213,7 @@ impl pallet_timestamp::Config for Test { } impl Config for Test { - type Event = Event; + type RuntimeEvent = RuntimeEvent; } pub struct ExtBuilder { diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 09f1bd9821654..f0c519c5b20d4 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,13 +1,13 @@ use super::*; use frame_support::{assert_err, assert_ok}; -use mock::{active_era, start_session, Balances, ExtBuilder, Origin, RootOffences, System}; +use mock::{active_era, start_session, Balances, ExtBuilder, RootOffences, RuntimeOrigin, System}; #[test] fn create_offence_fails_given_signed_origin() { use sp_runtime::traits::BadOrigin; ExtBuilder::default().build_and_execute(|| { let offenders = (&[]).to_vec(); - assert_err!(RootOffences::create_offence(Origin::signed(1), offenders), BadOrigin); + assert_err!(RootOffences::create_offence(RuntimeOrigin::signed(1), offenders), BadOrigin); }) } @@ -21,7 +21,7 @@ fn create_offence_works_given_root_origin() { assert_eq!(Balances::free_balance(11), 1000); let offenders = [(11, Perbill::from_percent(50))].to_vec(); - assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); + assert_ok!(RootOffences::create_offence(RuntimeOrigin::root(), offenders.clone())); System::assert_last_event(Event::CreatedOffence { offenders }.into()); // the slash should be applied right away. @@ -44,7 +44,7 @@ fn create_offence_wont_slash_non_active_validators() { assert_eq!(Balances::free_balance(31), 500); let offenders = [(31, Perbill::from_percent(20)), (11, Perbill::from_percent(20))].to_vec(); - assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); + assert_ok!(RootOffences::create_offence(RuntimeOrigin::root(), offenders.clone())); System::assert_last_event(Event::CreatedOffence { offenders }.into()); @@ -67,7 +67,7 @@ fn create_offence_wont_slash_idle() { assert_eq!(Balances::free_balance(41), 1000); let offenders = [(41, Perbill::from_percent(50))].to_vec(); - assert_ok!(RootOffences::create_offence(Origin::root(), offenders.clone())); + assert_ok!(RootOffences::create_offence(RuntimeOrigin::root(), offenders.clone())); System::assert_last_event(Event::CreatedOffence { offenders }.into()); From 7b6d8ef57864c35ec0d889c443c69a7fa087e7a9 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Mon, 26 Sep 2022 16:17:51 +0200 Subject: [PATCH 49/54] Update frame/root-offences/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/root-offences/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 94874ddaf3b2b..f902d1fd0a261 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -75,6 +75,7 @@ pub mod pallet { ::AccountId, IdentificationTuple, >; + #[pallet::call] impl Pallet { /// Allows the `root`, for example sudo to create an offence. From 7a797857354a485238c358ed974661406c264181 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Mon, 26 Sep 2022 16:18:42 +0200 Subject: [PATCH 50/54] Update frame/root-offences/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/root-offences/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index f902d1fd0a261..1759e55fc7590 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -88,11 +88,9 @@ pub mod pallet { let slash_fraction = offenders.clone().into_iter().map(|(_, fraction)| fraction).collect::>(); - let offence_details = Self::get_offence_details(offenders.clone())?; Self::submit_offence(&offence_details, &slash_fraction); - Self::deposit_event(Event::CreatedOffence { offenders }); Ok(()) } From 4838575bd353e3517153b08baa1f12cb3815f909 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Mon, 26 Sep 2022 16:24:56 +0200 Subject: [PATCH 51/54] docs --- frame/root-offences/src/lib.rs | 6 ++++-- frame/root-offences/src/tests.rs | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/frame/root-offences/src/lib.rs b/frame/root-offences/src/lib.rs index 1759e55fc7590..b4b549627f3fa 100644 --- a/frame/root-offences/src/lib.rs +++ b/frame/root-offences/src/lib.rs @@ -63,11 +63,13 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - CreatedOffence { offenders: Vec<(T::AccountId, Perbill)> }, + /// An offence was created by root. + OffenceCreated { offenders: Vec<(T::AccountId, Perbill)> }, } #[pallet::error] pub enum Error { + /// Failed to get the active era from the staking pallet. FailedToGetActiveEra, } @@ -91,7 +93,7 @@ pub mod pallet { let offence_details = Self::get_offence_details(offenders.clone())?; Self::submit_offence(&offence_details, &slash_fraction); - Self::deposit_event(Event::CreatedOffence { offenders }); + Self::deposit_event(Event::OffenceCreated { offenders }); Ok(()) } } diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index f0c519c5b20d4..4a28ffd363678 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -23,7 +23,7 @@ fn create_offence_works_given_root_origin() { let offenders = [(11, Perbill::from_percent(50))].to_vec(); assert_ok!(RootOffences::create_offence(RuntimeOrigin::root(), offenders.clone())); - System::assert_last_event(Event::CreatedOffence { offenders }.into()); + System::assert_last_event(Event::OffenceCreated { offenders }.into()); // the slash should be applied right away. assert_eq!(Balances::free_balance(11), 500); @@ -46,7 +46,7 @@ fn create_offence_wont_slash_non_active_validators() { let offenders = [(31, Perbill::from_percent(20)), (11, Perbill::from_percent(20))].to_vec(); assert_ok!(RootOffences::create_offence(RuntimeOrigin::root(), offenders.clone())); - System::assert_last_event(Event::CreatedOffence { offenders }.into()); + System::assert_last_event(Event::OffenceCreated { offenders }.into()); // so 31 didn't get slashed. assert_eq!(Balances::free_balance(31), 500); @@ -69,7 +69,7 @@ fn create_offence_wont_slash_idle() { let offenders = [(41, Perbill::from_percent(50))].to_vec(); assert_ok!(RootOffences::create_offence(RuntimeOrigin::root(), offenders.clone())); - System::assert_last_event(Event::CreatedOffence { offenders }.into()); + System::assert_last_event(Event::OffenceCreated { offenders }.into()); // 41 didn't get slashed. assert_eq!(Balances::free_balance(41), 1000); From 6de5482a969dbbfce47368eb9086ef537a407591 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Tue, 27 Sep 2022 15:15:15 +0200 Subject: [PATCH 52/54] Update frame/root-offences/README.md Co-authored-by: Andronik --- frame/root-offences/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/root-offences/README.md b/frame/root-offences/README.md index 248559e4e398f..a2c5261b6985a 100644 --- a/frame/root-offences/README.md +++ b/frame/root-offences/README.md @@ -2,4 +2,4 @@ Pallet that allows the root to create an offence. -NOTE: This pallet should be used for testing purposes. \ No newline at end of file +NOTE: This pallet should only be used for testing purposes. \ No newline at end of file From 64ab68328d233b05950672361fc2b65859082e7c Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Tue, 27 Sep 2022 15:15:29 +0200 Subject: [PATCH 53/54] Update frame/root-offences/Cargo.toml Co-authored-by: Andronik --- frame/root-offences/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/root-offences/Cargo.toml b/frame/root-offences/Cargo.toml index 1c5cb4203bbb0..ea6a6527848aa 100644 --- a/frame/root-offences/Cargo.toml +++ b/frame/root-offences/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" license = "Apache-2.0" homepage = "https://substrate.io" repository = "https://github.com/paritytech/substrate/" -description = "FRAME sudo offences pallet" +description = "FRAME root offences pallet" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] From 83ff69074d655a9cc82a396cdb9fa9117a7e3bb8 Mon Sep 17 00:00:00 2001 From: Szegoo Date: Tue, 27 Sep 2022 15:16:26 +0200 Subject: [PATCH 54/54] license header --- frame/root-offences/src/mock.rs | 17 +++++++++++++++++ frame/root-offences/src/tests.rs | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/frame/root-offences/src/mock.rs b/frame/root-offences/src/mock.rs index 645c03463cc31..3f0a26afc1358 100644 --- a/frame/root-offences/src/mock.rs +++ b/frame/root-offences/src/mock.rs @@ -1,3 +1,20 @@ +// 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. + use super::*; use crate as root_offences; diff --git a/frame/root-offences/src/tests.rs b/frame/root-offences/src/tests.rs index 4a28ffd363678..a8b7d0a6d6aca 100644 --- a/frame/root-offences/src/tests.rs +++ b/frame/root-offences/src/tests.rs @@ -1,3 +1,20 @@ +// 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. + use super::*; use frame_support::{assert_err, assert_ok}; use mock::{active_era, start_session, Balances, ExtBuilder, RootOffences, RuntimeOrigin, System};