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

            
19
use crate::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex};
20
use alloc::{collections::btree_map::BTreeMap, vec::Vec};
21
use codec::{Decode, Encode};
22
use scale_info::TypeInfo;
23

            
24
/// The kind of the dispute offence.
25
18
#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, TypeInfo, Debug)]
26
pub enum SlashingOffenceKind {
27
843
	/// A severe offence when a validator backed an invalid block.
28
843
	#[codec(index = 0)]
29
843
	ForInvalid,
30
159
	/// A minor offence when a validator disputed a valid block.
31
159
	#[codec(index = 1)]
32
159
	AgainstValid,
33
}
34

            
35
/// Timeslots should uniquely identify offences and are used for the offence
36
/// deduplication.
37
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, TypeInfo, Debug)]
38
pub struct DisputesTimeSlot {
39
	// The order of the fields matters for `derive(Ord)`.
40
	/// Session index when the candidate was backed/included.
41
	pub session_index: SessionIndex,
42
	/// Candidate hash of the disputed candidate.
43
	pub candidate_hash: CandidateHash,
44
}
45

            
46
impl DisputesTimeSlot {
47
	/// Create a new instance of `Self`.
48
	pub fn new(session_index: SessionIndex, candidate_hash: CandidateHash) -> Self {
49
		Self { session_index, candidate_hash }
50
	}
51
}
52

            
53
/// We store most of the information about a lost dispute on chain. This struct
54
/// is required to identify and verify it.
55
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug)]
56
pub struct DisputeProof {
57
	/// Time slot when the dispute occurred.
58
	pub time_slot: DisputesTimeSlot,
59
	/// The dispute outcome.
60
	pub kind: SlashingOffenceKind,
61
	/// The index of the validator who lost a dispute.
62
	pub validator_index: ValidatorIndex,
63
	/// The parachain session key of the validator.
64
	pub validator_id: ValidatorId,
65
}
66

            
67
/// Slashes that are waiting to be applied once we have validator key
68
/// identification.
69
#[derive(Encode, Decode, TypeInfo, Debug, Clone)]
70
pub struct PendingSlashes {
71
	/// Indices and keys of the validators who lost a dispute and are pending
72
	/// slashes.
73
	pub keys: BTreeMap<ValidatorIndex, ValidatorId>,
74
	/// The dispute outcome.
75
	pub kind: SlashingOffenceKind,
76
}
77

            
78
// TODO: can we reuse this type between BABE, GRANDPA and disputes?
79
/// An opaque type used to represent the key ownership proof at the runtime API
80
/// boundary. The inner value is an encoded representation of the actual key
81
/// ownership proof which will be parameterized when defining the runtime. At
82
/// the runtime API boundary this type is unknown and as such we keep this
83
/// opaque representation, implementors of the runtime API will have to make
84
/// sure that all usages of `OpaqueKeyOwnershipProof` refer to the same type.
85
#[derive(Decode, Encode, PartialEq, Eq, Debug, Clone, TypeInfo)]
86
pub struct OpaqueKeyOwnershipProof(Vec<u8>);
87
impl OpaqueKeyOwnershipProof {
88
	/// Create a new `OpaqueKeyOwnershipProof` using the given encoded
89
	/// representation.
90
	pub fn new(inner: Vec<u8>) -> OpaqueKeyOwnershipProof {
91
		OpaqueKeyOwnershipProof(inner)
92
	}
93

            
94
	/// Try to decode this `OpaqueKeyOwnershipProof` into the given concrete key
95
	/// ownership proof type.
96
	pub fn decode<T: Decode>(self) -> Option<T> {
97
		Decode::decode(&mut &self.0[..]).ok()
98
	}
99

            
100
	/// Length of the encoded proof.
101
	pub fn len(&self) -> usize {
102
		self.0.len()
103
	}
104
}