runtime: past session slashing runtime API (#6667)

* runtime/vstaging: unapplied_slashes runtime API

* runtime/vstaging: key_ownership_proof runtime API

* runtime/ParachainHost: submit_report_dispute_lost

* fix key_ownership_proof API

* runtime: submit_report_dispute_lost runtime API

* nits

* Update node/subsystem-types/src/messages.rs

Co-authored-by: Marcin S. <marcin@bytedude.com>

* revert unrelated fmt changes

* post merge fixes

* fix compilation

---------

Co-authored-by: Marcin S. <marcin@bytedude.com>
This commit is contained in:
ordian
2023-05-26 11:35:46 +02:00
committed by GitHub
parent 035b24866c
commit 9bc4f62eff
12 changed files with 441 additions and 96 deletions
@@ -49,8 +49,10 @@ use frame_support::{
weights::Weight,
};
use parity_scale_codec::{Decode, Encode};
use primitives::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex};
use primitives::{
vstaging::slashing::{DisputeProof, DisputesTimeSlot, PendingSlashes, SlashingOffenceKind},
CandidateHash, SessionIndex, ValidatorId, ValidatorIndex,
};
use scale_info::TypeInfo;
use sp_runtime::{
traits::Convert,
@@ -58,15 +60,12 @@ use sp_runtime::{
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
TransactionValidityError, ValidTransaction,
},
KeyTypeId, Perbill, RuntimeDebug,
KeyTypeId, Perbill,
};
use sp_session::{GetSessionNumber, GetValidatorCount};
use sp_staking::offence::{DisableStrategy, Kind, Offence, OffenceError, ReportOffence};
use sp_std::{
collections::{
btree_map::{BTreeMap, Entry},
btree_set::BTreeSet,
},
collections::{btree_map::Entry, btree_set::BTreeSet},
prelude::*,
};
@@ -92,23 +91,8 @@ impl<const M: u32> BenchmarkingConfiguration for BenchConfig<M> {
const MAX_VALIDATORS: u32 = M;
}
/// Timeslots should uniquely identify offences and are used for the offence
/// deduplication.
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
pub struct DisputesTimeSlot {
// The order of these matters for `derive(Ord)`.
session_index: SessionIndex,
candidate_hash: CandidateHash,
}
impl DisputesTimeSlot {
pub fn new(session_index: SessionIndex, candidate_hash: CandidateHash) -> Self {
Self { session_index, candidate_hash }
}
}
/// An offence that is filed when a series of validators lost a dispute.
#[derive(RuntimeDebug, TypeInfo)]
#[derive(TypeInfo)]
#[cfg_attr(feature = "std", derive(Clone, PartialEq, Eq))]
pub struct SlashingOffence<KeyOwnerIdentification> {
/// The size of the validator set in that session.
@@ -323,39 +307,6 @@ where
}
}
#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo)]
pub enum SlashingOffenceKind {
#[codec(index = 0)]
ForInvalid,
#[codec(index = 1)]
AgainstValid,
}
/// We store most of the information about a lost dispute on chain. This struct
/// is required to identify and verify it.
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
pub struct DisputeProof {
/// Time slot when the dispute occured.
pub time_slot: DisputesTimeSlot,
/// The dispute outcome.
pub kind: SlashingOffenceKind,
/// The index of the validator who lost a dispute.
pub validator_index: ValidatorIndex,
/// The parachain session key of the validator.
pub validator_id: ValidatorId,
}
/// Slashes that are waiting to be applied once we have validator key
/// identification.
#[derive(Encode, Decode, RuntimeDebug, TypeInfo)]
pub struct PendingSlashes {
/// Indices and keys of the validators who lost a dispute and are pending
/// slashes.
pub keys: BTreeMap<ValidatorIndex, ValidatorId>,
/// The dispute outcome.
pub kind: SlashingOffenceKind,
}
/// A trait that defines methods to report an offence (after the slashing report
/// has been validated) and for submitting a transaction to report a slash (from
/// an offchain context).
@@ -603,6 +554,17 @@ impl<T: Config> Pallet<T> {
let old_session = session_index - config.dispute_period - 1;
let _ = <UnappliedSlashes<T>>::clear_prefix(old_session, REMOVE_LIMIT, None);
}
pub(crate) fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, PendingSlashes)> {
<UnappliedSlashes<T>>::iter().collect()
}
pub(crate) fn submit_unsigned_slashing_report(
dispute_proof: DisputeProof,
key_ownership_proof: <T as Config>::KeyOwnerProof,
) -> Option<()> {
T::HandleReports::submit_unsigned_slashing_report(dispute_proof, key_ownership_proof).ok()
}
}
/// Methods for the `ValidateUnsigned` implementation:
@@ -21,6 +21,7 @@ use frame_benchmarking::{benchmarks, whitelist_account};
use frame_support::traits::{OnFinalize, OnInitialize};
use frame_system::RawOrigin;
use pallet_staking::testing_utils::create_validators;
use parity_scale_codec::Decode;
use primitives::{Hash, PARACHAIN_KEY_TYPE_ID};
use sp_runtime::traits::{One, StaticLookup};
use sp_session::MembershipProof;
@@ -15,3 +15,32 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Put implementations of functions from staging APIs here.
use crate::disputes;
use primitives::{vstaging, CandidateHash, DisputeState, SessionIndex};
use sp_std::prelude::*;
/// Implementation for `get_session_disputes` function from the runtime API
pub fn get_session_disputes<T: disputes::Config>(
) -> Vec<(SessionIndex, CandidateHash, DisputeState<T::BlockNumber>)> {
<disputes::Pallet<T>>::disputes()
}
/// Implementation of `unapplied_slashes` runtime API
pub fn unapplied_slashes<T: disputes::slashing::Config>(
) -> Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)> {
<disputes::slashing::Pallet<T>>::unapplied_slashes()
}
/// Implementation of `submit_report_dispute_lost` runtime API
pub fn submit_unsigned_slashing_report<T: disputes::slashing::Config>(
dispute_proof: vstaging::slashing::DisputeProof,
key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof,
) -> Option<()> {
let key_ownership_proof = key_ownership_proof.decode()?;
<disputes::slashing::Pallet<T>>::submit_unsigned_slashing_report(
dispute_proof,
key_ownership_proof,
)
}