Skip to content

Commit

Permalink
New Pallet: Root offences (paritytech#11943)
Browse files Browse the repository at this point in the history
* root-offences pallet

* fix errors

* cleaned up a bit

* remove unwrap()

* new pallet is getting compiled

* remove unnecessary type annotations

* remove more unnecessary type annotations

* addidtional cleaning

* commit

* cleaned up

* fix in logic

* add event

* removed Clone trait from AccountId

* test module

* remove unused imports

* fmt

* fix

* separate into functions, still messy

* test

* first test

* fmt

* cleaned up a bit

* separate into mock.rs and tests.rs

* basic docs for now

* pallet_staking GenesisiConfig

* fix

* added start_session

* passing tests

* impl GenesisConfig for pallet_session

* updated event

* Update frame/root-offences/src/lib.rs

Co-authored-by: Kian Paimani <[email protected]>

* Update frame/root-offences/src/lib.rs

Co-authored-by: Kian Paimani <[email protected]>

* remove <T: Config

* specifying trait bounds inside Config

* commit

* active era increases correctly :)

* ExtBuilder

* slashing works

* new test

* additional test

* commit

* order

* fix?

* fix in logic

* remove unnecessary

* wrap comment at 100

* fmt

* merge fixes

* Update frame/root-offences/src/lib.rs

Co-authored-by: Kian Paimani <[email protected]>

* Update frame/root-offences/src/lib.rs

Co-authored-by: Kian Paimani <[email protected]>

* docs

* Update frame/root-offences/README.md

Co-authored-by: Andronik <[email protected]>

* Update frame/root-offences/Cargo.toml

Co-authored-by: Andronik <[email protected]>

* license header

Co-authored-by: Kian Paimani <[email protected]>
Co-authored-by: Andronik <[email protected]>
  • Loading branch information
3 people authored and ark0f committed Feb 27, 2023
1 parent 42f320b commit 94c6c0f
Show file tree
Hide file tree
Showing 8 changed files with 661 additions and 1 deletion.
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ members = [
"frame/staking/reward-fn",
"frame/state-trie-migration",
"frame/sudo",
"frame/root-offences",
"frame/support",
"frame/support/procedural",
"frame/support/procedural/tools",
Expand Down
2 changes: 1 addition & 1 deletion frame/nomination-pools/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2523,7 +2523,7 @@ impl<T: Config> Pallet<T> {
impl<T: Config> OnStakerSlash<T::AccountId, BalanceOf<T>> for Pallet<T> {
fn on_slash(
pool_account: &T::AccountId,
// Bonded balance is always read directly from staking, therefore we need not update
// Bonded balance is always read directly from staking, therefore we don't need to update
// anything here.
slashed_bonded: BalanceOf<T>,
slashed_unlocking: &BTreeMap<EraIndex, BalanceOf<T>>,
Expand Down
51 changes: 51 additions & 0 deletions frame/root-offences/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[package]
name = "pallet-root-offences"
version = "1.0.0"
authors = ["Parity Technologies <[email protected]>"]
edition = "2021"
license = "Apache-2.0"
homepage = "https://substrate.io"
repository = "https://github.com/paritytech/substrate/"
description = "FRAME root 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" }

[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" }
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]
runtime-benchmarks = []
try-runtime = ["frame-support/try-runtime"]
default = ["std"]
std = [
"codec/std",
"frame-support/std",
"frame-system/std",
"pallet-session/std",
"pallet-staking/std",
"pallet-offences/std",
"scale-info/std",
"sp-runtime/std",
]
5 changes: 5 additions & 0 deletions frame/root-offences/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Sudo Offences Pallet

Pallet that allows the root to create an offence.

NOTE: This pallet should only be used for testing purposes.
131 changes: 131 additions & 0 deletions frame/root-offences/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// 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.
//!
//! NOTE: This pallet should be used for testing purposes.

#![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::Perbill;
use sp_staking::offence::{DisableStrategy, 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_staking::Config
+ pallet_session::Config<ValidatorId = <Self as frame_system::Config>::AccountId>
+ pallet_session::historical::Config<
FullIdentification = Exposure<
<Self as frame_system::Config>::AccountId,
BalanceOf<Self>,
>,
FullIdentificationOf = ExposureOf<Self>,
>
{
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// An offence was created by root.
OffenceCreated { offenders: Vec<(T::AccountId, Perbill)> },
}

#[pallet::error]
pub enum Error<T> {
/// Failed to get the active era from the staking pallet.
FailedToGetActiveEra,
}

type OffenceDetails<T> = sp_staking::offence::OffenceDetails<
<T as frame_system::Config>::AccountId,
IdentificationTuple<T>,
>;

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Allows the `root`, for example sudo to create an offence.
#[pallet::weight(T::DbWeight::get().reads(2))]
pub fn create_offence(
origin: OriginFor<T>,
offenders: Vec<(T::AccountId, Perbill)>,
) -> DispatchResult {
ensure_root(origin)?;

let slash_fraction =
offenders.clone().into_iter().map(|(_, fraction)| fraction).collect::<Vec<_>>();
let offence_details = Self::get_offence_details(offenders.clone())?;

Self::submit_offence(&offence_details, &slash_fraction);
Self::deposit_event(Event::OffenceCreated { offenders });
Ok(())
}
}

impl<T: Config> Pallet<T> {
/// Returns a vector of offenders that are going to be slashed.
fn get_offence_details(
offenders: Vec<(T::AccountId, Perbill)>,
) -> Result<Vec<OffenceDetails<T>>, DispatchError> {
let now = Staking::<T>::active_era()
.map(|e| e.index)
.ok_or(Error::<T>::FailedToGetActiveEra)?;

Ok(offenders
.clone()
.into_iter()
.map(|(o, _)| OffenceDetails::<T> {
offender: (o.clone(), Staking::<T>::eras_stakers(now, o)),
reporters: vec![],
})
.collect())
}

/// Submits the offence by calling the `on_offence` function.
fn submit_offence(offenders: &[OffenceDetails<T>], slash_fraction: &[Perbill]) {
let session_index = <pallet_session::Pallet<T> as frame_support::traits::ValidatorSet<T::AccountId>>::session_index();

<pallet_staking::Pallet<T> as OnOffenceHandler<
T::AccountId,
IdentificationTuple<T>,
Weight,
>>::on_offence(&offenders, &slash_fraction, session_index, DisableStrategy::WhenSlashed);
}
}
}
Loading

0 comments on commit 94c6c0f

Please sign in to comment.