Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Offences reporting and slashing #3322

Merged
merged 119 commits into from
Aug 16, 2019
Merged
Show file tree
Hide file tree
Changes from 113 commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
4f24928
Remove offline slashing logic from staking.
tomusdrw Aug 6, 2019
9f1cad1
Initial version of reworked offence module, can report offences
folsen Aug 6, 2019
3fc6eaa
Merge branch 'retreat-slashing' of github.com:paritytech/substrate in…
tomusdrw Aug 6, 2019
89e623b
Clean up staking example.
tomusdrw Aug 6, 2019
0e1d398
Commit SlashingOffence
pepyakin Aug 6, 2019
d5c9cd1
Force new era on slash.
tomusdrw Aug 6, 2019
45e5907
Add offenders in the SlashingOffence trait.
pepyakin Aug 6, 2019
b93118f
Introduce the ReportOffence trait.
pepyakin Aug 6, 2019
051001a
Rename `Offence`.
pepyakin Aug 6, 2019
2dae936
Add on_before_session_ending handler.
tomusdrw Aug 6, 2019
5c3a249
Move offence related stuff under sr-primitives.
pepyakin Aug 6, 2019
aaa8159
Fix cargo check.
tomusdrw Aug 6, 2019
06ee813
Import new im-online implementation.
tomusdrw Aug 6, 2019
a807dae
Adding validator count to historical session storage as it's needed f…
folsen Aug 6, 2019
32cba20
Add a comment about offence.
pepyakin Aug 6, 2019
39f7ed0
Add BabeEquivocationOffence
pepyakin Aug 6, 2019
c5579b3
GrandpaEquivocationOffence
pepyakin Aug 6, 2019
ecd8d81
slash_fraction and fix
pepyakin Aug 6, 2019
cfe194d
current_era_start_session_index
pepyakin Aug 6, 2019
4cb0bfe
UnresponsivnessOffence
pepyakin Aug 7, 2019
7ede025
Finalise OnOffenceHandler traits, and stub impl for staking.
tomusdrw Aug 7, 2019
a56a7b4
slash_fraction doesn't really need &self
pepyakin Aug 7, 2019
da2cc83
Note that offenders count is greater than 0
pepyakin Aug 7, 2019
0e2047a
Merge branch 'master' into retreat-slashing
tomusdrw Aug 7, 2019
61c6c22
Add a test to ensure that I got the math right
pepyakin Aug 7, 2019
c94f253
Merge remote-tracking branch 'origin/retreat-slashing' into retreat-s…
tomusdrw Aug 7, 2019
f7a8711
Use FullIdentification in offences.
tomusdrw Aug 7, 2019
7b14a37
Use FullIndentification.
tomusdrw Aug 7, 2019
cea7edc
Hook up the offences module.
pepyakin Aug 7, 2019
da01b46
Report unresponsive validators
pepyakin Aug 7, 2019
e25b43a
Make sure eras have the same length.
tomusdrw Aug 7, 2019
55aeff5
Slashing and rewards.
tomusdrw Aug 7, 2019
0c8b03f
Fix compilation.
tomusdrw Aug 7, 2019
382ffa3
Distribute rewards.
tomusdrw Aug 7, 2019
ac05b4f
Merge branch 'master' into retreat-slashing
tomusdrw Aug 7, 2019
ea68a83
Supply validators_count
pepyakin Aug 7, 2019
fae60b9
Use identificationTuple in Unresponsivness report
pepyakin Aug 7, 2019
6af9ffc
Fix merge.
pepyakin Aug 7, 2019
f2f91ab
Make sure we don't slash if amount is zero.
tomusdrw Aug 7, 2019
9c91502
We don't return an error from report_offence anymo
pepyakin Aug 7, 2019
fdbc3bd
We actually can use vec!
pepyakin Aug 7, 2019
c101666
Prevent division by zero if the reporters is empty
pepyakin Aug 7, 2019
2d1d103
offence_forces_new_era/nominators_also_get_slashed
pepyakin Aug 7, 2019
b7989c9
advance_session
pepyakin Aug 7, 2019
21c1131
Fix tests.
pepyakin Aug 7, 2019
a60252e
Merge branch 'master' into retreat-slashing
tomusdrw Aug 7, 2019
0db09ad
Merge remote-tracking branch 'origin/retreat-slashing' into retreat-s…
tomusdrw Aug 7, 2019
e9029f8
Update srml/staking/src/lib.rs
tomusdrw Aug 7, 2019
e40e448
slashing_performed_according_exposure
pepyakin Aug 7, 2019
63f08a0
Check that reporters receive their slice.
pepyakin Aug 7, 2019
fdb9d15
Small clean-up.
tomusdrw Aug 7, 2019
108869c
Merge branch 'retreat-slashing' of github.com:paritytech/substrate in…
tomusdrw Aug 7, 2019
39cdeb6
invulnerables_are_not_slashed
pepyakin Aug 7, 2019
67b0a50
Minor clean ups.
pepyakin Aug 7, 2019
763d32d
Improve docs.
pepyakin Aug 7, 2019
9c43140
dont_slash_if_fraction_is_zero
pepyakin Aug 7, 2019
c65854c
Remove session dependency from offences.
tomusdrw Aug 7, 2019
77c23dc
Introduce sr-staking-primitives
pepyakin Aug 7, 2019
4384e6c
Move offence under sr_staking_primitives
pepyakin Aug 7, 2019
7d94eaf
rename session_index
pepyakin Aug 7, 2019
97d4f5c
Resolves todos re using SessionIndex
pepyakin Aug 7, 2019
b8f65a8
Fix staking tests.
pepyakin Aug 7, 2019
fe75ebe
Properly scale denominator.
pepyakin Aug 7, 2019
2ff220b
Fix UnresponsivnessOffence
pepyakin Aug 7, 2019
00a8506
Fix compilation.
tomusdrw Aug 8, 2019
eb790f2
Tests for offences.
tomusdrw Aug 8, 2019
bdf5177
Merge branch 'master' into retreat-slashing
tomusdrw Aug 8, 2019
2d0881a
Clean offences tests.
pepyakin Aug 8, 2019
8b4cd8e
Fix staking doc test.
tomusdrw Aug 8, 2019
b90e397
Merge branch 'retreat-slashing' of github.com:paritytech/substrate in…
tomusdrw Aug 8, 2019
b9fa71b
Bump spec version
tomusdrw Aug 8, 2019
6eb6cab
Fix aura tests.
tomusdrw Aug 8, 2019
9e7e8ce
Fix node_executor
pepyakin Aug 8, 2019
f23b2f3
Deposit an event on offence.
pepyakin Aug 8, 2019
2de1c86
Fix compilation of node-runtime
pepyakin Aug 8, 2019
6420e80
Remove aura slashing logic.
tomusdrw Aug 8, 2019
591fa51
Remove HandleReport
pepyakin Aug 8, 2019
0c4760f
Update docs for timeslot.
pepyakin Aug 8, 2019
48a3366
rename with_on_offence_fractions
pepyakin Aug 8, 2019
4bc4e6c
Add should_properly_count_offences
pepyakin Aug 8, 2019
eb1de19
Replace ValidatorIdByIndex with CurrentElectedSet
pepyakin Aug 9, 2019
b015094
Clarify babe equivocation
pepyakin Aug 12, 2019
04ac719
Merge master
pepyakin Aug 12, 2019
1facbf8
Fix offences.
pepyakin Aug 12, 2019
57bc7a2
Rename validators_count to validator_set_count
tomusdrw Aug 13, 2019
0b57b0d
Fix squaring.
pepyakin Aug 14, 2019
12baeda
Update core/sr-staking-primitives/src/offence.rs
tomusdrw Aug 14, 2019
a88c5ac
Docs for CurrentElectedSet.
pepyakin Aug 14, 2019
53b2c64
Don't punish only invulnerables
pepyakin Aug 14, 2019
2b81cc2
Merge 'origin/master' into retreat-slashing
pepyakin Aug 14, 2019
2c30785
Use `get/insert` instead of `mutate`.
pepyakin Aug 14, 2019
fa1d88e
Fix compilation
pepyakin Aug 14, 2019
192e811
Update core/sr-staking-primitives/src/offence.rs
tomusdrw Aug 14, 2019
455dcac
Update srml/offences/src/lib.rs
tomusdrw Aug 14, 2019
3c46391
Update srml/im-online/src/lib.rs
tomusdrw Aug 14, 2019
7257ca9
Update srml/im-online/src/lib.rs
tomusdrw Aug 14, 2019
542de32
Update srml/im-online/src/lib.rs
tomusdrw Aug 14, 2019
e02ef2f
Update srml/babe/src/lib.rs
tomusdrw Aug 14, 2019
08366c0
Update core/sr-staking-primitives/src/offence.rs
tomusdrw Aug 14, 2019
3f398c4
Update core/sr-staking-primitives/src/offence.rs
tomusdrw Aug 14, 2019
fe3094c
Update core/sr-staking-primitives/src/offence.rs
tomusdrw Aug 14, 2019
9b4263c
Update core/sr-staking-primitives/src/offence.rs
tomusdrw Aug 14, 2019
ce5e8ed
Update core/sr-staking-primitives/src/offence.rs
tomusdrw Aug 14, 2019
758a1ec
Add aura todo.
tomusdrw Aug 14, 2019
d58208b
Allow multiple reports for single offence report.
tomusdrw Aug 14, 2019
4feb6e3
Fix slash_fraction calculation.
tomusdrw Aug 14, 2019
dd58c06
Fix typos.
tomusdrw Aug 14, 2019
0c65697
Fix compilation and tests.
tomusdrw Aug 14, 2019
fc927d1
Fix staking tests.
tomusdrw Aug 14, 2019
f3a2d68
Update srml/im-online/src/lib.rs
tomusdrw Aug 14, 2019
b7f44fc
Fix doc on time_slot
pepyakin Aug 15, 2019
2d0fe68
Allow slashing only on current era (#3411)
rphmeier Aug 16, 2019
6d2b7f8
Pave the way for pruning
pepyakin Aug 15, 2019
03734e8
Merge 'origin/master' into retreat-slashing
pepyakin Aug 16, 2019
7781bc9
Address issues.
pepyakin Aug 16, 2019
967ca96
Try to refactor collect_offence_reports
pepyakin Aug 16, 2019
6bc58a8
Other fixes.
pepyakin Aug 16, 2019
bbc837b
More fixes.
pepyakin Aug 16, 2019
9430a2d
Merge 'origin/master' into retreat-slashing
pepyakin Aug 16, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ members = [
"core/sr-api-macros",
"core/sr-io",
"core/sr-primitives",
"core/sr-staking-primitives",
"core/sr-sandbox",
"core/sr-std",
"core/sr-version",
Expand Down Expand Up @@ -84,6 +85,7 @@ members = [
"srml/indices",
"srml/membership",
"srml/metadata",
"srml/offences",
"srml/session",
"srml/staking",
"srml/sudo",
Expand Down
1 change: 1 addition & 0 deletions core/cli/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ pub struct NetworkConfigurationParams {
}

arg_enum! {
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum NodeKeyType {
Secp256k1,
Expand Down
1 change: 1 addition & 0 deletions core/sr-io/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ export_api! {
/// Even if this function returns `true`, it does not mean that any keys are configured
/// and that the validator is registered in the chain.
fn is_validator() -> bool;

/// Submit transaction to the pool.
///
/// The transaction will end up in the pool.
Expand Down
31 changes: 31 additions & 0 deletions core/sr-primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,18 @@ impl Perbill {

Perbill(part as u32)
}

/// Return the product of multiplication of this value by itself.
pub fn square(self) -> Self {
let p: u64 = self.0 as u64 * self.0 as u64;
let q: u64 = 1_000_000_000 * 1_000_000_000;
Self::from_rational_approximation(p, q)
}

/// Take out the raw parts-per-billions.
pub fn into_parts(self) -> u32 {
self.0
}
}

impl<N> ops::Mul<N> for Perbill
Expand Down Expand Up @@ -959,4 +971,23 @@ mod tests {
((Into::<U256>::into(std::u128::MAX) * 999_999u32) / 1_000_000u32).as_u128()
);
}

#[test]
fn per_bill_square() {
const FIXTURES: &[(u32, u32)] = &[
(0, 0),
(1250000, 1562), // (0.00125, 0.000001562)
(255300000, 65178090), // (0.2553, 0.06517809)
(500000000, 250000000), // (0.5, 0.25)
(999995000, 999990000), // (0.999995, 0.999990000, but ideally 0.99999000002)
(1000000000, 1000000000),
];

for &(x, r) in FIXTURES {
assert_eq!(
Perbill::from_parts(x).square(),
Perbill::from_parts(r),
);
}
}
}
18 changes: 18 additions & 0 deletions core/sr-staking-primitives/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "sr-staking-primitives"
version = "2.0.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"

[dependencies]
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
sr-primitives = { path = "../sr-primitives", default-features = false }
rstd = { package = "sr-std", path = "../sr-std", default-features = false }

[features]
default = ["std"]
std = [
"codec/std",
"sr-primitives/std",
"rstd/std",
]
32 changes: 32 additions & 0 deletions core/sr-staking-primitives/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.

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

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

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

//! A crate which contains primitives that are useful for implementation that uses staking
//! approaches in general. Definitions related to sessions, slashing, etc go here.

use rstd::vec::Vec;

pub mod offence;

/// Simple index type with which we can count sessions.
pub type SessionIndex = u32;

/// A trait for getting the currently elected validator set without coupling to the module that
/// provides this information.
pub trait CurrentElectedSet<ValidatorId> {
pepyakin marked this conversation as resolved.
Show resolved Hide resolved
/// Returns the validator ids for the currently elected validator set.
fn current_elected_set() -> Vec<ValidatorId>;
}
142 changes: 142 additions & 0 deletions core/sr-staking-primitives/src/offence.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.

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

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

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

//! Common traits and types that are useful for describing offences for usage in environments
//! that use staking.

use rstd::vec::Vec;

use codec::{Encode, Decode};
use sr_primitives::Perbill;

use crate::SessionIndex;

/// The kind of an offence, is a byte string representing some kind identifier
/// e.g. `b"im-online:offlin"`, `b"babe:equivocatio"`
// TODO [slashing]: Is there something better we can have here that is more natural but still
// flexible? as you see in examples, they get cut off with long names.
pub type Kind = [u8; 16];

/// Number of times the offence of this authority was already reported in the past.
///
/// Note that we don't buffer offence reporting, so every time we see a new offence
/// of the same kind, we will report past authorities again.
/// This counter keeps track of how many times the authority was already reported in the past,
/// so that we can slash it accordingly.
pub type OffenceCount = u32;

/// A trait implemented by an offence report.
///
/// This trait assumes that the offence is legitimate and was validated already.
///
/// Examples of offences include: a BABE equivocation or a GRANDPA unjustified vote.
pub trait Offence<Offender> {
/// Identifier which is unique for this kind of an offence.
const ID: Kind;

/// A type that represents a point in time on an abstract timescale.
///
/// See `Offence::time_slot` for details. The only requirement is that such timescale could be
/// represented by a single `u128` value.
type TimeSlot: Clone + codec::Codec + Ord;

/// The list of all offenders involved in this incident.
///
/// The list has no duplicates, so it is rather a set.
fn offenders(&self) -> Vec<Offender>;

/// The session index that is used for querying the validator set for the `slash_fraction`
/// function.
///
/// This is used for filtering historical sessions.
fn session_index(&self) -> SessionIndex;

/// Return a validator set count at the time when the offence took place.
fn validator_set_count(&self) -> u32;

/// A point in time when this offence happened.
///
/// This is used for looking up offences that happened at the "same time".
///
/// The timescale is abstract and doesn't have to be the same across different implementations
/// of this trait. The value doesn't represent absolute timescale though since it is interpreted
/// along with the `session_index`. Two offences are considered to happen at the same time iff
/// both `session_index` and `time_slot` are equal.
///
/// As an example, for GRANDPA timescale could be a round number and for BABE it could be a slot
/// number. Note that for GRANDPA the round number is reset each epoch.
fn time_slot(&self) -> Self::TimeSlot;

/// A slash fraction of the total exposure that should be slashed for this
/// particular offence kind for the given parameters that happened at a singular `TimeSlot`.
///
/// `offenders_count` - the count of unique offending authorities. It is >0.
/// `validator_set_count` - the cardinality of the validator set at the time of offence.
fn slash_fraction(
offenders_count: u32,
validator_set_count: u32,
) -> Perbill;
}

/// A trait for decoupling offence reporters from the actual handling of offence reports.
pub trait ReportOffence<Reporter, Offender, O: Offence<Offender>> {
/// Report an `offence` and reward given `reporters`.
fn report_offence(reporters: Vec<Reporter>, offence: O);
}

impl<Reporter, Offender, O: Offence<Offender>> ReportOffence<Reporter, Offender, O> for () {
fn report_offence(_reporters: Vec<Reporter>, _offence: O) {}
}

/// A trait to take action on an offence.
///
/// Used to decouple the module that handles offences and
/// the one that should punish for those offences.
pub trait OnOffenceHandler<Reporter, Offender> {
/// A handler for an offence of a particular kind.
///
/// Note that this contains a list of all previous offenders
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, initially we don't implement pruning. We should be able to add it in the future though when we switch to rolling window.

/// as well. The implementer should cater for a case, where
/// the same authorities were reported for the same offence
/// in the past (see `OffenceCount`).
///
/// The vector of `slash_fraction` contains `Perbill`s
/// the authorities should be slashed and is computed
/// according to the `OffenceCount` already. This is of the same length as `offenders.`
/// Zero is a valid value for a fraction.
fn on_offence(
offenders: &[OffenceDetails<Reporter, Offender>],
slash_fraction: &[Perbill],
);
}

impl<Reporter, Offender> OnOffenceHandler<Reporter, Offender> for () {
fn on_offence(
_offenders: &[OffenceDetails<Reporter, Offender>],
_slash_fraction: &[Perbill],
) {}
}

/// A details about an offending authority for a particular kind of offence.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct OffenceDetails<Reporter, Offender> {
/// The offending authority id
pub offender: Offender,
/// A list of reporters of offences of this authority ID. Possibly empty where there are no
/// particular reporters.
pub reporters: Vec<Reporter>,
}
1 change: 0 additions & 1 deletion node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ impl system::Trait for Runtime {
}

impl aura::Trait for Runtime {
type HandleReport = ();
type AuthorityId = AuraId;
}

Expand Down
Loading