polkadot_primitives/v8/slashing.rs
1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
16
17//! Primitives types used for dispute slashing.
18
19use crate::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex};
20use alloc::{collections::btree_map::BTreeMap, vec::Vec};
21use codec::{Decode, DecodeWithMemTracking, Encode};
22use scale_info::TypeInfo;
23
24/// The kind of the dispute offence.
25#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, DecodeWithMemTracking, TypeInfo, Debug)]
26pub enum SlashingOffenceKind {
27 /// A severe offence when a validator backed an invalid block.
28 #[codec(index = 0)]
29 ForInvalid,
30 /// A minor offence when a validator disputed a valid block.
31 #[codec(index = 1)]
32 AgainstValid,
33}
34
35/// Timeslots should uniquely identify offences and are used for the offence
36/// deduplication.
37#[derive(
38 Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo, Debug,
39)]
40pub struct DisputesTimeSlot {
41 // The order of the fields matters for `derive(Ord)`.
42 /// Session index when the candidate was backed/included.
43 pub session_index: SessionIndex,
44 /// Candidate hash of the disputed candidate.
45 pub candidate_hash: CandidateHash,
46}
47
48impl DisputesTimeSlot {
49 /// Create a new instance of `Self`.
50 pub fn new(session_index: SessionIndex, candidate_hash: CandidateHash) -> Self {
51 Self { session_index, candidate_hash }
52 }
53}
54
55/// We store most of the information about a lost dispute on chain. This struct
56/// is required to identify and verify it.
57#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo, Debug)]
58pub struct DisputeProof {
59 /// Time slot when the dispute occurred.
60 pub time_slot: DisputesTimeSlot,
61 /// The dispute outcome.
62 pub kind: SlashingOffenceKind,
63 /// The index of the validator who lost a dispute.
64 pub validator_index: ValidatorIndex,
65 /// The parachain session key of the validator.
66 pub validator_id: ValidatorId,
67}
68
69/// Slashes that are waiting to be applied once we have validator key
70/// identification.
71#[derive(Encode, Decode, TypeInfo, Debug, Clone)]
72pub struct PendingSlashes {
73 /// Indices and keys of the validators who lost a dispute and are pending
74 /// slashes.
75 pub keys: BTreeMap<ValidatorIndex, ValidatorId>,
76 /// The dispute outcome.
77 pub kind: SlashingOffenceKind,
78}
79
80// TODO: can we reuse this type between BABE, GRANDPA and disputes?
81/// An opaque type used to represent the key ownership proof at the runtime API
82/// boundary. The inner value is an encoded representation of the actual key
83/// ownership proof which will be parameterized when defining the runtime. At
84/// the runtime API boundary this type is unknown and as such we keep this
85/// opaque representation, implementors of the runtime API will have to make
86/// sure that all usages of `OpaqueKeyOwnershipProof` refer to the same type.
87#[derive(Decode, Encode, PartialEq, Eq, Debug, Clone, TypeInfo)]
88pub struct OpaqueKeyOwnershipProof(Vec<u8>);
89impl OpaqueKeyOwnershipProof {
90 /// Create a new `OpaqueKeyOwnershipProof` using the given encoded
91 /// representation.
92 pub fn new(inner: Vec<u8>) -> OpaqueKeyOwnershipProof {
93 OpaqueKeyOwnershipProof(inner)
94 }
95
96 /// Try to decode this `OpaqueKeyOwnershipProof` into the given concrete key
97 /// ownership proof type.
98 pub fn decode<T: Decode>(self) -> Option<T> {
99 Decode::decode(&mut &self.0[..]).ok()
100 }
101
102 /// Length of the encoded proof.
103 pub fn len(&self) -> usize {
104 self.0.len()
105 }
106}