From 8dbeae7f8e13916d229da7a387ee6de02aeb0222 Mon Sep 17 00:00:00 2001 From: Andronik Date: Wed, 1 Feb 2023 18:11:22 -0300 Subject: [PATCH 01/10] runtime/vstaging: unapplied_slashes runtime API --- node/core/runtime-api/src/cache.rs | 29 +++++-- node/core/runtime-api/src/lib.rs | 10 +++ node/subsystem-types/src/messages.rs | 10 ++- node/subsystem-types/src/runtime_client.rs | 26 +++++-- primitives/src/runtime_api.rs | 6 +- primitives/src/vstaging/mod.rs | 2 + primitives/src/vstaging/slashing.rs | 76 +++++++++++++++++++ runtime/parachains/src/disputes/slashing.rs | 68 +++-------------- .../src/runtime_api_impl/vstaging.rs | 8 +- 9 files changed, 166 insertions(+), 69 deletions(-) create mode 100644 primitives/src/vstaging/slashing.rs diff --git a/node/core/runtime-api/src/cache.rs b/node/core/runtime-api/src/cache.rs index 9efc31328692..acf6bb604a44 100644 --- a/node/core/runtime-api/src/cache.rs +++ b/node/core/runtime-api/src/cache.rs @@ -20,11 +20,11 @@ use lru::LruCache; use sp_consensus_babe::Epoch; use polkadot_primitives::{ - AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash, - CommittedCandidateReceipt, CoreState, DisputeState, GroupRotationInfo, Hash, Id as ParaId, - InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, - PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, - ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, + vstaging, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateEvent, + CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, GroupRotationInfo, Hash, + Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption, + PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, + ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; /// For consistency we have the same capacity for all caches. We use 128 as we'll only need that @@ -62,6 +62,8 @@ pub(crate) struct RequestResultCache { LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option>, version: LruCache, disputes: LruCache)>>, + unapplied_slashes: + LruCache>, } impl Default for RequestResultCache { @@ -88,6 +90,7 @@ impl Default for RequestResultCache { validation_code_hash: LruCache::new(DEFAULT_CACHE_CAP), version: LruCache::new(DEFAULT_CACHE_CAP), disputes: LruCache::new(DEFAULT_CACHE_CAP), + unapplied_slashes: LruCache::new(DEFAULT_CACHE_CAP), } } } @@ -368,6 +371,21 @@ impl RequestResultCache { ) { self.disputes.put(relay_parent, value); } + + pub(crate) fn unapplied_slashes( + &mut self, + relay_parent: &Hash, + ) -> Option<&Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>> { + self.unapplied_slashes.get(relay_parent) + } + + pub(crate) fn cache_unapplied_slashes( + &mut self, + relay_parent: Hash, + value: Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>, + ) { + self.unapplied_slashes.put(relay_parent, value); + } } pub(crate) enum RequestResult { @@ -404,4 +422,5 @@ pub(crate) enum RequestResult { ValidationCodeHash(Hash, ParaId, OccupiedCoreAssumption, Option), Version(Hash, u32), Disputes(Hash, Vec<(SessionIndex, CandidateHash, DisputeState)>), + UnappliedSlashes(Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>), } diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index 3d016305bc64..88ae79a73b9f 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -155,6 +155,8 @@ where self.requests_cache.cache_version(relay_parent, version), Disputes(relay_parent, disputes) => self.requests_cache.cache_disputes(relay_parent, disputes), + UnappliedSlashes(relay_parent, unapplied_slashes) => + self.requests_cache.cache_unapplied_slashes(relay_parent, unapplied_slashes), } } @@ -258,6 +260,8 @@ where .map(|sender| Request::ValidationCodeHash(para, assumption, sender)), Request::Disputes(sender) => query!(disputes(), sender).map(|sender| Request::Disputes(sender)), + Request::UnappliedSlashes(sender) => + query!(unapplied_slashes(), sender).map(|sender| Request::UnappliedSlashes(sender)), } } @@ -502,5 +506,11 @@ where query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender), Request::Disputes(sender) => query!(Disputes, disputes(), ver = Request::DISPUTES_RUNTIME_REQUIREMENT, sender), + Request::UnappliedSlashes(sender) => query!( + UnappliedSlashes, + unapplied_slashes(), + ver = Request::UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT, + sender + ), } } diff --git a/node/subsystem-types/src/messages.rs b/node/subsystem-types/src/messages.rs index 506e37d2cc92..3ba39d8f9288 100644 --- a/node/subsystem-types/src/messages.rs +++ b/node/subsystem-types/src/messages.rs @@ -39,7 +39,7 @@ use polkadot_node_primitives::{ SignedDisputeStatement, SignedFullStatement, ValidationResult, }; use polkadot_primitives::{ - AuthorityDiscoveryId, BackedCandidate, BlockNumber, CandidateEvent, CandidateHash, + vstaging, AuthorityDiscoveryId, BackedCandidate, BlockNumber, CandidateEvent, CandidateHash, CandidateIndex, CandidateReceipt, CollatorId, CommittedCandidateReceipt, CoreState, DisputeState, GroupIndex, GroupRotationInfo, Hash, Header as BlockHeader, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet, OccupiedCoreAssumption, @@ -601,6 +601,11 @@ pub enum RuntimeApiRequest { ), /// Returns all on-chain disputes at given block number. Available in `v3`. Disputes(RuntimeApiSender)>>), + /// Returns a list of validators that lost a past session dispute and need to be slashed. + /// `VStaging` + UnappliedSlashes( + RuntimeApiSender>, + ), } impl RuntimeApiRequest { @@ -608,6 +613,9 @@ impl RuntimeApiRequest { /// `Disputes` pub const DISPUTES_RUNTIME_REQUIREMENT: u32 = 3; + + /// `UnappliedSlashes` + pub const UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT: u32 = 1000; } /// A message to the Runtime API subsystem. diff --git a/node/subsystem-types/src/runtime_client.rs b/node/subsystem-types/src/runtime_client.rs index 9a55462b8852..400576cbb7ea 100644 --- a/node/subsystem-types/src/runtime_client.rs +++ b/node/subsystem-types/src/runtime_client.rs @@ -16,11 +16,12 @@ use async_trait::async_trait; use polkadot_primitives::{ - runtime_api::ParachainHost, Block, BlockId, BlockNumber, CandidateCommitments, CandidateEvent, - CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, GroupRotationInfo, Hash, Id, - InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, - PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, - ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, + runtime_api::ParachainHost, vstaging, Block, BlockId, BlockNumber, CandidateCommitments, + CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, + GroupRotationInfo, Hash, Id, InboundDownwardMessage, InboundHrmpMessage, + OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, + SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, + ValidatorSignature, }; use sp_api::{ApiError, ApiExt, ProvideRuntimeApi}; use sp_authority_discovery::AuthorityDiscoveryApi; @@ -188,6 +189,14 @@ pub trait RuntimeApiSubsystemClient { at: Hash, ) -> Result)>, ApiError>; + /// Returns a list of validators that lost a past session dispute and need to be slashed. + /// + /// WARNING: This is a staging method! Do not use on production runtimes! + async fn unapplied_slashes( + &self, + at: Hash, + ) -> Result, ApiError>; + // === BABE API === /// Returns information regarding the current epoch. @@ -378,4 +387,11 @@ where ) -> Result)>, ApiError> { self.runtime_api().disputes(&BlockId::Hash(at)) } + + async fn unapplied_slashes( + &self, + at: Hash, + ) -> Result, ApiError> { + self.runtime_api().unapplied_slashes(&BlockId::Hash(at)) + } } diff --git a/primitives/src/runtime_api.rs b/primitives/src/runtime_api.rs index 2f6793d22032..4fb705d428be 100644 --- a/primitives/src/runtime_api.rs +++ b/primitives/src/runtime_api.rs @@ -110,7 +110,7 @@ //! All staging API functions should use primitives from `vstaging`. They should be clearly separated //! from the stable primitives. -use crate::v2; +use crate::{v2, vstaging}; use parity_scale_codec::{Decode, Encode}; use polkadot_core_primitives as pcp; use polkadot_parachain::primitives as ppp; @@ -221,5 +221,9 @@ sp_api::decl_runtime_apis! { /// Returns all onchain disputes. #[api_version(3)] fn disputes() -> Vec<(v2::SessionIndex, v2::CandidateHash, v2::DisputeState)>; + + /// Returns a list of validators that lost a past session dispute and need to be slashed. + #[api_version(1000)] + fn unapplied_slashes() -> Vec<(v2::SessionIndex, v2::CandidateHash, vstaging::slashing::PendingSlashes)>; } } diff --git a/primitives/src/vstaging/mod.rs b/primitives/src/vstaging/mod.rs index 64671bd48a60..a0c262bafff6 100644 --- a/primitives/src/vstaging/mod.rs +++ b/primitives/src/vstaging/mod.rs @@ -17,3 +17,5 @@ //! Staging Primitives. // Put any primitives used by staging APIs functions here + +pub mod slashing; diff --git a/primitives/src/vstaging/slashing.rs b/primitives/src/vstaging/slashing.rs new file mode 100644 index 000000000000..dfddf64aa008 --- /dev/null +++ b/primitives/src/vstaging/slashing.rs @@ -0,0 +1,76 @@ +// Copyright 2017-2021 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Primitives types used for dispute slashing. + +use crate::v2::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex}; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_std::collections::btree_map::BTreeMap; + +/// The kind of the dispute offence. +#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, TypeInfo, Debug)] +pub enum SlashingOffenceKind { + /// A severe offence when a validator backed an invalid block. + #[codec(index = 0)] + ForInvalid, + /// A minor offence when a validator disputed a valid block. + #[codec(index = 1)] + AgainstValid, +} + +/// Timeslots should uniquely identify offences and are used for the offence +/// deduplication. +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, TypeInfo, Debug)] +pub struct DisputesTimeSlot { + // The order of the fields matters for `derive(Ord)`. + /// Session index when the candidate was backed/included. + pub session_index: SessionIndex, + /// Candidate hash of the disputed candidate. + pub candidate_hash: CandidateHash, +} + +impl DisputesTimeSlot { + /// Create a new instance of `Self`. + pub fn new(session_index: SessionIndex, candidate_hash: CandidateHash) -> Self { + Self { session_index, candidate_hash } + } +} + +/// 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, TypeInfo, Debug)] +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, TypeInfo, Debug, Clone)] +pub struct PendingSlashes { + /// Indices and keys of the validators who lost a dispute and are pending + /// slashes. + pub keys: BTreeMap, + /// The dispute outcome. + pub kind: SlashingOffenceKind, +} diff --git a/runtime/parachains/src/disputes/slashing.rs b/runtime/parachains/src/disputes/slashing.rs index fd127d7f0789..29a887557c01 100644 --- a/runtime/parachains/src/disputes/slashing.rs +++ b/runtime/parachains/src/disputes/slashing.rs @@ -49,8 +49,11 @@ use frame_support::{ weights::Weight, }; -use parity_scale_codec::{Decode, Encode}; -use primitives::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex}; +use parity_scale_codec::Decode; +use primitives::{ + vstaging::slashing::{DisputeProof, DisputesTimeSlot, PendingSlashes, SlashingOffenceKind}, + CandidateHash, SessionIndex, ValidatorId, ValidatorIndex, +}; use scale_info::TypeInfo; use sp_runtime::{ traits::Convert, @@ -58,15 +61,12 @@ use sp_runtime::{ InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction, }, - DispatchResult, KeyTypeId, Perbill, RuntimeDebug, + DispatchResult, 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 +92,8 @@ impl BenchmarkingConfiguration for BenchConfig { 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 { /// The size of the validator set in that session. @@ -323,39 +308,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, - /// 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 +555,10 @@ impl Pallet { let old_session = session_index - config.dispute_period - 1; let _ = >::clear_prefix(old_session, REMOVE_LIMIT, None); } + + pub(crate) fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, PendingSlashes)> { + >::iter().collect() + } } /// Methods for the `ValidateUnsigned` implementation: diff --git a/runtime/parachains/src/runtime_api_impl/vstaging.rs b/runtime/parachains/src/runtime_api_impl/vstaging.rs index 2191fb304e1c..cc0a8d0eb23e 100644 --- a/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -17,7 +17,7 @@ //! Put implementations of functions from staging APIs here. use crate::disputes; -use primitives::{CandidateHash, DisputeState, SessionIndex}; +use primitives::{vstaging, CandidateHash, DisputeState, SessionIndex}; use sp_std::prelude::*; /// Implementation for `get_session_disputes` function from the runtime API @@ -25,3 +25,9 @@ pub fn get_session_disputes( ) -> Vec<(SessionIndex, CandidateHash, DisputeState)> { >::disputes() } + +/// Implementation of `unapplied_slashes` runtime API +pub fn unapplied_slashes( +) -> Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)> { + >::unapplied_slashes() +} From d3273d72a0376b6b63a293a6973b05145e8c65ec Mon Sep 17 00:00:00 2001 From: Andronik Date: Thu, 2 Feb 2023 16:08:22 -0300 Subject: [PATCH 02/10] runtime/vstaging: key_ownership_proof runtime API --- node/core/runtime-api/src/cache.rs | 19 ++++++++++++++ node/core/runtime-api/src/lib.rs | 14 +++++++++++ node/subsystem-types/src/messages.rs | 10 ++++++++ node/subsystem-types/src/runtime_client.rs | 20 +++++++++++++++ primitives/src/runtime_api.rs | 7 ++++++ primitives/src/vstaging/slashing.rs | 25 ++++++++++++++++++- runtime/parachains/src/disputes/slashing.rs | 1 - .../src/disputes/slashing/benchmarking.rs | 1 + 8 files changed, 95 insertions(+), 2 deletions(-) diff --git a/node/core/runtime-api/src/cache.rs b/node/core/runtime-api/src/cache.rs index acf6bb604a44..840102f67e92 100644 --- a/node/core/runtime-api/src/cache.rs +++ b/node/core/runtime-api/src/cache.rs @@ -64,6 +64,8 @@ pub(crate) struct RequestResultCache { disputes: LruCache)>>, unapplied_slashes: LruCache>, + key_ownership_proof: + LruCache<(Hash, SessionIndex, ValidatorId), vstaging::slashing::OpaqueKeyOwnershipProof>, } impl Default for RequestResultCache { @@ -91,6 +93,7 @@ impl Default for RequestResultCache { version: LruCache::new(DEFAULT_CACHE_CAP), disputes: LruCache::new(DEFAULT_CACHE_CAP), unapplied_slashes: LruCache::new(DEFAULT_CACHE_CAP), + key_ownership_proof: LruCache::new(DEFAULT_CACHE_CAP), } } } @@ -386,6 +389,21 @@ impl RequestResultCache { ) { self.unapplied_slashes.put(relay_parent, value); } + + pub(crate) fn key_ownership_proof( + &mut self, + key: (Hash, SessionIndex, ValidatorId), + ) -> Option<&vstaging::slashing::OpaqueKeyOwnershipProof> { + self.key_ownership_proof.get(&key) + } + + pub(crate) fn cache_key_ownership_proof( + &mut self, + key: (Hash, SessionIndex, ValidatorId), + value: vstaging::slashing::OpaqueKeyOwnershipProof, + ) { + self.key_ownership_proof.put(key, value); + } } pub(crate) enum RequestResult { @@ -423,4 +441,5 @@ pub(crate) enum RequestResult { Version(Hash, u32), Disputes(Hash, Vec<(SessionIndex, CandidateHash, DisputeState)>), UnappliedSlashes(Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>), + KeyOwnershipProof(Hash, SessionIndex, ValidatorId, vstaging::slashing::OpaqueKeyOwnershipProof), } diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index 88ae79a73b9f..64acc1492c27 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -157,6 +157,11 @@ where self.requests_cache.cache_disputes(relay_parent, disputes), UnappliedSlashes(relay_parent, unapplied_slashes) => self.requests_cache.cache_unapplied_slashes(relay_parent, unapplied_slashes), + KeyOwnershipProof(relay_parent, session_index, validator_id, key_ownership_proof) => + self.requests_cache.cache_key_ownership_proof( + (relay_parent, session_index, validator_id), + key_ownership_proof, + ), } } @@ -262,6 +267,9 @@ where query!(disputes(), sender).map(|sender| Request::Disputes(sender)), Request::UnappliedSlashes(sender) => query!(unapplied_slashes(), sender).map(|sender| Request::UnappliedSlashes(sender)), + Request::KeyOwnershipProof(session_index, validator_id, sender) => + query!(key_ownership_proof(session_index, validator_id), sender) + .map(|sender| Request::KeyOwnershipProof(session_index, validator_id, sender)), } } @@ -512,5 +520,11 @@ where ver = Request::UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT, sender ), + Request::KeyOwnershipProof(session_index, validator_id, sender) => query!( + KeyOwnershipProof, + key_ownership_proof(session_index, validator_id), + ver = Request::KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT, + sender + ), } } diff --git a/node/subsystem-types/src/messages.rs b/node/subsystem-types/src/messages.rs index 3ba39d8f9288..b28d292a51db 100644 --- a/node/subsystem-types/src/messages.rs +++ b/node/subsystem-types/src/messages.rs @@ -606,6 +606,13 @@ pub enum RuntimeApiRequest { UnappliedSlashes( RuntimeApiSender>, ), + /// Returns a merkle proof of a validator session key in a past session. + /// `VStaging` + KeyOwnershipProof( + SessionIndex, + ValidatorId, + RuntimeApiSender, + ), } impl RuntimeApiRequest { @@ -616,6 +623,9 @@ impl RuntimeApiRequest { /// `UnappliedSlashes` pub const UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT: u32 = 1000; + + /// `KeyOwnershipProof` + pub const KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT: u32 = 1000; } /// A message to the Runtime API subsystem. diff --git a/node/subsystem-types/src/runtime_client.rs b/node/subsystem-types/src/runtime_client.rs index 400576cbb7ea..6a29c3264f75 100644 --- a/node/subsystem-types/src/runtime_client.rs +++ b/node/subsystem-types/src/runtime_client.rs @@ -197,6 +197,16 @@ pub trait RuntimeApiSubsystemClient { at: Hash, ) -> Result, ApiError>; + /// Returns a merkle proof of a validator session key in a past session. + /// + /// WARNING: This is a staging method! Do not use on production runtimes! + async fn key_ownership_proof( + &self, + at: Hash, + session_index: SessionIndex, + validator_id: ValidatorId, + ) -> Result; + // === BABE API === /// Returns information regarding the current epoch. @@ -394,4 +404,14 @@ where ) -> Result, ApiError> { self.runtime_api().unapplied_slashes(&BlockId::Hash(at)) } + + async fn key_ownership_proof( + &self, + at: Hash, + session_index: SessionIndex, + validator_id: ValidatorId, + ) -> Result { + self.runtime_api() + .key_ownership_proof(&BlockId::Hash(at), session_index, validator_id) + } } diff --git a/primitives/src/runtime_api.rs b/primitives/src/runtime_api.rs index 4fb705d428be..63b27881d5a4 100644 --- a/primitives/src/runtime_api.rs +++ b/primitives/src/runtime_api.rs @@ -225,5 +225,12 @@ sp_api::decl_runtime_apis! { /// Returns a list of validators that lost a past session dispute and need to be slashed. #[api_version(1000)] fn unapplied_slashes() -> Vec<(v2::SessionIndex, v2::CandidateHash, vstaging::slashing::PendingSlashes)>; + + /// Returns a list of validators that lost a past session dispute and need to be slashed. + #[api_version(1000)] + fn key_ownership_proof( + session_index: v2::SessionIndex, + validator_id: v2::ValidatorId, + ) -> vstaging::slashing::OpaqueKeyOwnershipProof; } } diff --git a/primitives/src/vstaging/slashing.rs b/primitives/src/vstaging/slashing.rs index dfddf64aa008..8edcc202feea 100644 --- a/primitives/src/vstaging/slashing.rs +++ b/primitives/src/vstaging/slashing.rs @@ -19,7 +19,7 @@ use crate::v2::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex}; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_std::collections::btree_map::BTreeMap; +use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; /// The kind of the dispute offence. #[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, TypeInfo, Debug)] @@ -74,3 +74,26 @@ pub struct PendingSlashes { /// The dispute outcome. pub kind: SlashingOffenceKind, } + +// TODO: can we reuse this type between BABE, GRANDPA and disputes? +/// An opaque type used to represent the key ownership proof at the runtime API +/// boundary. The inner value is an encoded representation of the actual key +/// ownership proof which will be parameterized when defining the runtime. At +/// the runtime API boundary this type is unknown and as such we keep this +/// opaque representation, implementors of the runtime API will have to make +/// sure that all usages of `OpaqueKeyOwnershipProof` refer to the same type. +#[derive(Decode, Encode, PartialEq, Eq, Debug, Clone)] +pub struct OpaqueKeyOwnershipProof(Vec); +impl OpaqueKeyOwnershipProof { + /// Create a new `OpaqueKeyOwnershipProof` using the given encoded + /// representation. + pub fn new(inner: Vec) -> OpaqueKeyOwnershipProof { + OpaqueKeyOwnershipProof(inner) + } + + /// Try to decode this `OpaqueKeyOwnershipProof` into the given concrete key + /// ownership proof type. + pub fn decode(self) -> Option { + Decode::decode(&mut &self.0[..]).ok() + } +} diff --git a/runtime/parachains/src/disputes/slashing.rs b/runtime/parachains/src/disputes/slashing.rs index 29a887557c01..71abfa5b7688 100644 --- a/runtime/parachains/src/disputes/slashing.rs +++ b/runtime/parachains/src/disputes/slashing.rs @@ -49,7 +49,6 @@ use frame_support::{ weights::Weight, }; -use parity_scale_codec::Decode; use primitives::{ vstaging::slashing::{DisputeProof, DisputesTimeSlot, PendingSlashes, SlashingOffenceKind}, CandidateHash, SessionIndex, ValidatorId, ValidatorIndex, diff --git a/runtime/parachains/src/disputes/slashing/benchmarking.rs b/runtime/parachains/src/disputes/slashing/benchmarking.rs index 0b328e3e5797..91f2fefa77e0 100644 --- a/runtime/parachains/src/disputes/slashing/benchmarking.rs +++ b/runtime/parachains/src/disputes/slashing/benchmarking.rs @@ -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; From 8394592eac9d6a301b8b542af4358d66d721ebc5 Mon Sep 17 00:00:00 2001 From: Andronik Date: Thu, 2 Feb 2023 16:28:51 -0300 Subject: [PATCH 03/10] runtime/ParachainHost: submit_report_dispute_lost --- primitives/src/runtime_api.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/primitives/src/runtime_api.rs b/primitives/src/runtime_api.rs index 63b27881d5a4..3c07e909c15e 100644 --- a/primitives/src/runtime_api.rs +++ b/primitives/src/runtime_api.rs @@ -232,5 +232,13 @@ sp_api::decl_runtime_apis! { session_index: v2::SessionIndex, validator_id: v2::ValidatorId, ) -> vstaging::slashing::OpaqueKeyOwnershipProof; + + /// Submit an unsigned extrinsic to slash validators who lost a dispute about + /// a candidate of a past session. + #[api_version(1000)] + fn submit_report_dispute_lost( + dispute_prool: vstaging::slashing::DisputeProof, + key_owner_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + ) -> Option<()>; } } From d31edbb94283e6f10fa9879f55d609a1e6863748 Mon Sep 17 00:00:00 2001 From: Andronik Date: Thu, 2 Feb 2023 17:08:03 -0300 Subject: [PATCH 04/10] fix key_ownership_proof API --- node/core/runtime-api/src/cache.rs | 12 ++++---- node/core/runtime-api/src/lib.rs | 18 +++++------ node/subsystem-types/src/messages.rs | 9 +++--- node/subsystem-types/src/runtime_client.rs | 9 ++---- primitives/src/runtime_api.rs | 13 ++++---- runtime/parachains/src/disputes/slashing.rs | 7 +++++ runtime/rococo/src/lib.rs | 33 +++++++++++++++++++-- 7 files changed, 64 insertions(+), 37 deletions(-) diff --git a/node/core/runtime-api/src/cache.rs b/node/core/runtime-api/src/cache.rs index 840102f67e92..c2cd5e571be1 100644 --- a/node/core/runtime-api/src/cache.rs +++ b/node/core/runtime-api/src/cache.rs @@ -65,7 +65,7 @@ pub(crate) struct RequestResultCache { unapplied_slashes: LruCache>, key_ownership_proof: - LruCache<(Hash, SessionIndex, ValidatorId), vstaging::slashing::OpaqueKeyOwnershipProof>, + LruCache<(Hash, ValidatorId), Option>, } impl Default for RequestResultCache { @@ -392,15 +392,15 @@ impl RequestResultCache { pub(crate) fn key_ownership_proof( &mut self, - key: (Hash, SessionIndex, ValidatorId), - ) -> Option<&vstaging::slashing::OpaqueKeyOwnershipProof> { + key: (Hash, ValidatorId), + ) -> Option<&Option> { self.key_ownership_proof.get(&key) } pub(crate) fn cache_key_ownership_proof( &mut self, - key: (Hash, SessionIndex, ValidatorId), - value: vstaging::slashing::OpaqueKeyOwnershipProof, + key: (Hash, ValidatorId), + value: Option, ) { self.key_ownership_proof.put(key, value); } @@ -441,5 +441,5 @@ pub(crate) enum RequestResult { Version(Hash, u32), Disputes(Hash, Vec<(SessionIndex, CandidateHash, DisputeState)>), UnappliedSlashes(Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>), - KeyOwnershipProof(Hash, SessionIndex, ValidatorId, vstaging::slashing::OpaqueKeyOwnershipProof), + KeyOwnershipProof(Hash, ValidatorId, Option), } diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index 64acc1492c27..c084a1f791fa 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -157,11 +157,9 @@ where self.requests_cache.cache_disputes(relay_parent, disputes), UnappliedSlashes(relay_parent, unapplied_slashes) => self.requests_cache.cache_unapplied_slashes(relay_parent, unapplied_slashes), - KeyOwnershipProof(relay_parent, session_index, validator_id, key_ownership_proof) => - self.requests_cache.cache_key_ownership_proof( - (relay_parent, session_index, validator_id), - key_ownership_proof, - ), + KeyOwnershipProof(relay_parent, validator_id, key_ownership_proof) => self + .requests_cache + .cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof), } } @@ -267,9 +265,9 @@ where query!(disputes(), sender).map(|sender| Request::Disputes(sender)), Request::UnappliedSlashes(sender) => query!(unapplied_slashes(), sender).map(|sender| Request::UnappliedSlashes(sender)), - Request::KeyOwnershipProof(session_index, validator_id, sender) => - query!(key_ownership_proof(session_index, validator_id), sender) - .map(|sender| Request::KeyOwnershipProof(session_index, validator_id, sender)), + Request::KeyOwnershipProof(validator_id, sender) => + query!(key_ownership_proof(validator_id), sender) + .map(|sender| Request::KeyOwnershipProof(validator_id, sender)), } } @@ -520,9 +518,9 @@ where ver = Request::UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT, sender ), - Request::KeyOwnershipProof(session_index, validator_id, sender) => query!( + Request::KeyOwnershipProof(validator_id, sender) => query!( KeyOwnershipProof, - key_ownership_proof(session_index, validator_id), + key_ownership_proof(validator_id), ver = Request::KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT, sender ), diff --git a/node/subsystem-types/src/messages.rs b/node/subsystem-types/src/messages.rs index b28d292a51db..b556324fd752 100644 --- a/node/subsystem-types/src/messages.rs +++ b/node/subsystem-types/src/messages.rs @@ -606,12 +606,11 @@ pub enum RuntimeApiRequest { UnappliedSlashes( RuntimeApiSender>, ), - /// Returns a merkle proof of a validator session key in a past session. + /// Returns a merkle proof of a validator session key. /// `VStaging` KeyOwnershipProof( - SessionIndex, ValidatorId, - RuntimeApiSender, + RuntimeApiSender>, ), } @@ -622,10 +621,10 @@ impl RuntimeApiRequest { pub const DISPUTES_RUNTIME_REQUIREMENT: u32 = 3; /// `UnappliedSlashes` - pub const UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT: u32 = 1000; + pub const UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT: u32 = 4; /// `KeyOwnershipProof` - pub const KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT: u32 = 1000; + pub const KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT: u32 = 4; } /// A message to the Runtime API subsystem. diff --git a/node/subsystem-types/src/runtime_client.rs b/node/subsystem-types/src/runtime_client.rs index 6a29c3264f75..6718ccb2e50f 100644 --- a/node/subsystem-types/src/runtime_client.rs +++ b/node/subsystem-types/src/runtime_client.rs @@ -203,9 +203,8 @@ pub trait RuntimeApiSubsystemClient { async fn key_ownership_proof( &self, at: Hash, - session_index: SessionIndex, validator_id: ValidatorId, - ) -> Result; + ) -> Result, ApiError>; // === BABE API === @@ -408,10 +407,8 @@ where async fn key_ownership_proof( &self, at: Hash, - session_index: SessionIndex, validator_id: ValidatorId, - ) -> Result { - self.runtime_api() - .key_ownership_proof(&BlockId::Hash(at), session_index, validator_id) + ) -> Result, ApiError> { + self.runtime_api().key_ownership_proof(&BlockId::Hash(at), validator_id) } } diff --git a/primitives/src/runtime_api.rs b/primitives/src/runtime_api.rs index 3c07e909c15e..d2e5feaaf6ab 100644 --- a/primitives/src/runtime_api.rs +++ b/primitives/src/runtime_api.rs @@ -223,21 +223,20 @@ sp_api::decl_runtime_apis! { fn disputes() -> Vec<(v2::SessionIndex, v2::CandidateHash, v2::DisputeState)>; /// Returns a list of validators that lost a past session dispute and need to be slashed. - #[api_version(1000)] + #[api_version(4)] fn unapplied_slashes() -> Vec<(v2::SessionIndex, v2::CandidateHash, vstaging::slashing::PendingSlashes)>; - /// Returns a list of validators that lost a past session dispute and need to be slashed. - #[api_version(1000)] + /// Returns a merkle proof of a validator session key. + #[api_version(4)] fn key_ownership_proof( - session_index: v2::SessionIndex, validator_id: v2::ValidatorId, - ) -> vstaging::slashing::OpaqueKeyOwnershipProof; + ) -> Option; /// Submit an unsigned extrinsic to slash validators who lost a dispute about /// a candidate of a past session. - #[api_version(1000)] + #[api_version(4)] fn submit_report_dispute_lost( - dispute_prool: vstaging::slashing::DisputeProof, + dispute_proof: vstaging::slashing::DisputeProof, key_owner_proof: vstaging::slashing::OpaqueKeyOwnershipProof, ) -> Option<()>; } diff --git a/runtime/parachains/src/disputes/slashing.rs b/runtime/parachains/src/disputes/slashing.rs index 71abfa5b7688..50bf330f0443 100644 --- a/runtime/parachains/src/disputes/slashing.rs +++ b/runtime/parachains/src/disputes/slashing.rs @@ -558,6 +558,13 @@ impl Pallet { pub(crate) fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, PendingSlashes)> { >::iter().collect() } + + pub fn submit_unsigned_slashing_report( + dispute_proof: DisputeProof, + key_ownership_proof: ::KeyOwnerProof, + ) -> Option<()> { + T::HandleReports::submit_unsigned_slashing_report(dispute_proof, key_ownership_proof).ok() + } } /// Methods for the `ValidateUnsigned` implementation: diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index 36af2a251520..94f22f703aba 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -23,11 +23,11 @@ use pallet_nis::WithMaximumOf; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use primitives::{ - AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, + vstaging, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature, ValidationCode, - ValidationCodeHash, ValidatorId, ValidatorIndex, + ValidationCodeHash, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, }; use runtime_common::{ assigned_slots, auctions, claims, crowdloan, impl_runtime_weights, impls::ToAuthor, @@ -1645,7 +1645,7 @@ sp_api::impl_runtime_apis! { } } - #[api_version(3)] + #[api_version(4)] impl primitives::runtime_api::ParachainHost for Runtime { fn validators() -> Vec { parachains_runtime_api_impl::validators::() @@ -1747,6 +1747,33 @@ sp_api::impl_runtime_apis! { fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState)> { runtime_parachains::runtime_api_impl::vstaging::get_session_disputes::() } + + fn unapplied_slashes( + ) -> Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)> { + runtime_parachains::runtime_api_impl::vstaging::unapplied_slashes::() + } + + fn key_ownership_proof( + validator_id: ValidatorId, + ) -> Option { + use parity_scale_codec::Encode; + + Historical::prove((PARACHAIN_KEY_TYPE_ID, validator_id)) + .map(|p| p.encode()) + .map(vstaging::slashing::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_dispute_lost( + dispute_proof: vstaging::slashing::DisputeProof, + key_owner_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + ParasSlashing::submit_unsigned_slashing_report( + dispute_proof, + key_owner_proof, + ) + } } impl beefy_primitives::BeefyApi for Runtime { From 5808d0b9bd81bf3256944ce80c7f9b28d5165d1b Mon Sep 17 00:00:00 2001 From: Andronik Date: Fri, 3 Feb 2023 10:17:31 -0300 Subject: [PATCH 05/10] runtime: submit_report_dispute_lost runtime API --- node/core/runtime-api/src/cache.rs | 15 ++++++++++++++ node/core/runtime-api/src/lib.rs | 13 ++++++++++++ node/subsystem-types/src/messages.rs | 10 +++++++++ node/subsystem-types/src/runtime_client.rs | 24 ++++++++++++++++++++++ 4 files changed, 62 insertions(+) diff --git a/node/core/runtime-api/src/cache.rs b/node/core/runtime-api/src/cache.rs index c2cd5e571be1..ac8cbabbfe3f 100644 --- a/node/core/runtime-api/src/cache.rs +++ b/node/core/runtime-api/src/cache.rs @@ -404,6 +404,14 @@ impl RequestResultCache { ) { self.key_ownership_proof.put(key, value); } + + // This request is never cached, hence always returns `None`. + pub(crate) fn submit_report_dispute_lost( + &mut self, + _key: (Hash, vstaging::slashing::DisputeProof, vstaging::slashing::OpaqueKeyOwnershipProof), + ) -> Option<&Option<()>> { + None + } } pub(crate) enum RequestResult { @@ -442,4 +450,11 @@ pub(crate) enum RequestResult { Disputes(Hash, Vec<(SessionIndex, CandidateHash, DisputeState)>), UnappliedSlashes(Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>), KeyOwnershipProof(Hash, ValidatorId, Option), + // This is a request with side-effects. + SubmitReportDisputeLost( + Hash, + vstaging::slashing::DisputeProof, + vstaging::slashing::OpaqueKeyOwnershipProof, + Option<()>, + ), } diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index c084a1f791fa..692598f7fd93 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -160,6 +160,7 @@ where KeyOwnershipProof(relay_parent, validator_id, key_ownership_proof) => self .requests_cache .cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof), + SubmitReportDisputeLost(_, _, _, _) => {}, } } @@ -268,6 +269,12 @@ where Request::KeyOwnershipProof(validator_id, sender) => query!(key_ownership_proof(validator_id), sender) .map(|sender| Request::KeyOwnershipProof(validator_id, sender)), + Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) => + query!(submit_report_dispute_lost(dispute_proof, key_ownership_proof), sender).map( + |sender| { + Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) + }, + ), } } @@ -524,5 +531,11 @@ where ver = Request::KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT, sender ), + Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) => query!( + SubmitReportDisputeLost, + submit_report_dispute_lost(dispute_proof, key_ownership_proof), + ver = Request::SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT, + sender + ), } } diff --git a/node/subsystem-types/src/messages.rs b/node/subsystem-types/src/messages.rs index b556324fd752..5ab6dc6c06bf 100644 --- a/node/subsystem-types/src/messages.rs +++ b/node/subsystem-types/src/messages.rs @@ -612,6 +612,13 @@ pub enum RuntimeApiRequest { ValidatorId, RuntimeApiSender>, ), + /// Submits an unsigned extrinsic to slash validator who lost a past session dispute. + /// `VStaging`` + SubmitReportDisputeLost( + vstaging::slashing::DisputeProof, + vstaging::slashing::OpaqueKeyOwnershipProof, + RuntimeApiSender>, + ), } impl RuntimeApiRequest { @@ -625,6 +632,9 @@ impl RuntimeApiRequest { /// `KeyOwnershipProof` pub const KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT: u32 = 4; + + /// `SubmitReportDisputeLost` + pub const SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT: u32 = 4; } /// A message to the Runtime API subsystem. diff --git a/node/subsystem-types/src/runtime_client.rs b/node/subsystem-types/src/runtime_client.rs index 6718ccb2e50f..1ffb53c9832f 100644 --- a/node/subsystem-types/src/runtime_client.rs +++ b/node/subsystem-types/src/runtime_client.rs @@ -206,6 +206,17 @@ pub trait RuntimeApiSubsystemClient { validator_id: ValidatorId, ) -> Result, ApiError>; + /// Submits an unsigned extrinsic to slash validators who lost a dispute about + /// a candidate of a past session. + /// + /// WARNING: This is a staging method! Do not use on production runtimes! + async fn submit_report_dispute_lost( + &self, + at: Hash, + dispute_proof: vstaging::slashing::DisputeProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + ) -> Result, ApiError>; + // === BABE API === /// Returns information regarding the current epoch. @@ -411,4 +422,17 @@ where ) -> Result, ApiError> { self.runtime_api().key_ownership_proof(&BlockId::Hash(at), validator_id) } + + async fn submit_report_dispute_lost( + &self, + at: Hash, + dispute_proof: vstaging::slashing::DisputeProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + ) -> Result, ApiError> { + self.runtime_api().submit_report_dispute_lost( + &BlockId::Hash(at), + dispute_proof, + key_ownership_proof, + ) + } } From 78d9da04b7516b7350d344199f919ba4790f4efd Mon Sep 17 00:00:00 2001 From: Andronik Date: Fri, 3 Feb 2023 13:36:26 -0300 Subject: [PATCH 06/10] nits --- primitives/src/runtime_api.rs | 2 +- primitives/src/vstaging/slashing.rs | 2 +- runtime/parachains/src/disputes/slashing.rs | 2 +- .../parachains/src/runtime_api_impl/vstaging.rs | 15 ++++++++++++++- runtime/rococo/src/lib.rs | 8 +++----- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/primitives/src/runtime_api.rs b/primitives/src/runtime_api.rs index d2e5feaaf6ab..bb10c7d81618 100644 --- a/primitives/src/runtime_api.rs +++ b/primitives/src/runtime_api.rs @@ -237,7 +237,7 @@ sp_api::decl_runtime_apis! { #[api_version(4)] fn submit_report_dispute_lost( dispute_proof: vstaging::slashing::DisputeProof, - key_owner_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, ) -> Option<()>; } } diff --git a/primitives/src/vstaging/slashing.rs b/primitives/src/vstaging/slashing.rs index 8edcc202feea..3efaf213f059 100644 --- a/primitives/src/vstaging/slashing.rs +++ b/primitives/src/vstaging/slashing.rs @@ -1,4 +1,4 @@ -// Copyright 2017-2021 Parity Technologies (UK) Ltd. +// Copyright 2017-2023 Parity Technologies (UK) Ltd. // This file is part of Polkadot. // Polkadot is free software: you can redistribute it and/or modify diff --git a/runtime/parachains/src/disputes/slashing.rs b/runtime/parachains/src/disputes/slashing.rs index 50bf330f0443..23e31a826254 100644 --- a/runtime/parachains/src/disputes/slashing.rs +++ b/runtime/parachains/src/disputes/slashing.rs @@ -559,7 +559,7 @@ impl Pallet { >::iter().collect() } - pub fn submit_unsigned_slashing_report( + pub(crate) fn submit_unsigned_slashing_report( dispute_proof: DisputeProof, key_ownership_proof: ::KeyOwnerProof, ) -> Option<()> { diff --git a/runtime/parachains/src/runtime_api_impl/vstaging.rs b/runtime/parachains/src/runtime_api_impl/vstaging.rs index cc0a8d0eb23e..7c7c77d591ad 100644 --- a/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -1,4 +1,4 @@ -// Copyright 2017-2022 Parity Technologies (UK) Ltd. +// Copyright 2017-2023 Parity Technologies (UK) Ltd. // This file is part of Polkadot. // Polkadot is free software: you can redistribute it and/or modify @@ -31,3 +31,16 @@ pub fn unapplied_slashes( ) -> Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)> { >::unapplied_slashes() } + +/// Implementation of `submit_report_dispute_lost` runtime API +pub fn submit_unsigned_slashing_report( + dispute_proof: vstaging::slashing::DisputeProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, +) -> Option<()> { + let key_ownership_proof = key_ownership_proof.decode()?; + + >::submit_unsigned_slashing_report( + dispute_proof, + key_ownership_proof, + ) +} diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index 94f22f703aba..afa12431c606 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -1765,13 +1765,11 @@ sp_api::impl_runtime_apis! { fn submit_report_dispute_lost( dispute_proof: vstaging::slashing::DisputeProof, - key_owner_proof: vstaging::slashing::OpaqueKeyOwnershipProof, + key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, ) -> Option<()> { - let key_owner_proof = key_owner_proof.decode()?; - - ParasSlashing::submit_unsigned_slashing_report( + runtime_parachains::runtime_api_impl::vstaging::submit_unsigned_slashing_report::( dispute_proof, - key_owner_proof, + key_ownership_proof, ) } } From 7caf6514a158f6d99418d3d2148886c86a9dfc03 Mon Sep 17 00:00:00 2001 From: ordian Date: Sun, 5 Feb 2023 10:11:33 -0300 Subject: [PATCH 07/10] Update node/subsystem-types/src/messages.rs Co-authored-by: Marcin S. --- node/subsystem-types/src/messages.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/subsystem-types/src/messages.rs b/node/subsystem-types/src/messages.rs index 5ab6dc6c06bf..bc162dc2d068 100644 --- a/node/subsystem-types/src/messages.rs +++ b/node/subsystem-types/src/messages.rs @@ -613,7 +613,7 @@ pub enum RuntimeApiRequest { RuntimeApiSender>, ), /// Submits an unsigned extrinsic to slash validator who lost a past session dispute. - /// `VStaging`` + /// `VStaging` SubmitReportDisputeLost( vstaging::slashing::DisputeProof, vstaging::slashing::OpaqueKeyOwnershipProof, From 62e3831673a8a55a670e508a08428b68db6caed3 Mon Sep 17 00:00:00 2001 From: Andronik Date: Mon, 27 Feb 2023 14:53:11 +0100 Subject: [PATCH 08/10] revert unrelated fmt changes --- node/core/candidate-validation/src/lib.rs | 5 ++--- node/core/chain-selection/src/db_backend/v1.rs | 5 ++--- node/network/bridge/src/network.rs | 5 ++--- node/network/collator-protocol/src/validator_side/mod.rs | 5 ++--- node/network/statement-distribution/src/error.rs | 5 ++--- node/service/src/lib.rs | 5 ++--- 6 files changed, 12 insertions(+), 18 deletions(-) diff --git a/node/core/candidate-validation/src/lib.rs b/node/core/candidate-validation/src/lib.rs index 93e2563266c6..cf84486f322a 100644 --- a/node/core/candidate-validation/src/lib.rs +++ b/node/core/candidate-validation/src/lib.rs @@ -633,7 +633,7 @@ where // reasonably sure that this is some local problem on the current node. Err(ValidationFailed(e)) }, - Ok(res) => { + Ok(res) => if res.head_data.hash() != candidate_receipt.descriptor.para_head { gum::info!(target: LOG_TARGET, ?para_id, "Invalid candidate (para_head)"); Ok(ValidationResult::Invalid(InvalidCandidate::ParaHeadHashMismatch)) @@ -658,8 +658,7 @@ where } else { Ok(ValidationResult::Valid(outputs, persisted_validation_data)) } - } - }, + }, } } diff --git a/node/core/chain-selection/src/db_backend/v1.rs b/node/core/chain-selection/src/db_backend/v1.rs index 6d173527f357..64c4e37b1502 100644 --- a/node/core/chain-selection/src/db_backend/v1.rs +++ b/node/core/chain-selection/src/db_backend/v1.rs @@ -236,13 +236,12 @@ impl Backend for DbBackend { let val = stagnant_at_iter .filter_map(|r| match r { - Ok((k, v)) => { + Ok((k, v)) => match (decode_stagnant_at_key(&mut &k[..]), >::decode(&mut &v[..]).ok()) { (Some(at), Some(stagnant_at)) => Some(Ok((at, stagnant_at))), _ => None, - } - }, + }, Err(e) => Some(Err(e)), }) .enumerate() diff --git a/node/network/bridge/src/network.rs b/node/network/bridge/src/network.rs index 2947c0dd3fc1..28a84a19b321 100644 --- a/node/network/bridge/src/network.rs +++ b/node/network/bridge/src/network.rs @@ -193,9 +193,8 @@ impl Network for Arc> { match pending_response .send(Err(RequestFailure::Network(OutboundFailure::DialFailure))) { - Err(_) => { - gum::debug!(target: LOG_TARGET, "Sending failed request response failed.") - }, + Err(_) => + gum::debug!(target: LOG_TARGET, "Sending failed request response failed."), Ok(_) => {}, } return diff --git a/node/network/collator-protocol/src/validator_side/mod.rs b/node/network/collator-protocol/src/validator_side/mod.rs index 28c727ae0d27..5d5417fb3001 100644 --- a/node/network/collator-protocol/src/validator_side/mod.rs +++ b/node/network/collator-protocol/src/validator_side/mod.rs @@ -567,9 +567,8 @@ impl CollationsPerRelayParent { self.waiting_collation = next.as_ref().map(|(_, collator_id)| collator_id.clone()); next }, - CollationStatus::WaitingOnValidation | CollationStatus::Fetching => { - unreachable!("We have reset the status above!") - }, + CollationStatus::WaitingOnValidation | CollationStatus::Fetching => + unreachable!("We have reset the status above!"), } } } diff --git a/node/network/statement-distribution/src/error.rs b/node/network/statement-distribution/src/error.rs index d417a1fc45b7..86cbbc8a9877 100644 --- a/node/network/statement-distribution/src/error.rs +++ b/node/network/statement-distribution/src/error.rs @@ -86,9 +86,8 @@ pub fn log_error(result: Result<()>, ctx: &'static str) -> std::result::Result<( match result.into_nested()? { Err(jfyi) => { match jfyi { - JfyiError::RequestedUnannouncedCandidate(_, _) => { - gum::warn!(target: LOG_TARGET, error = %jfyi, ctx) - }, + JfyiError::RequestedUnannouncedCandidate(_, _) => + gum::warn!(target: LOG_TARGET, error = %jfyi, ctx), _ => gum::debug!(target: LOG_TARGET, error = %jfyi, ctx), } Ok(()) diff --git a/node/service/src/lib.rs b/node/service/src/lib.rs index ae9f499df4f2..97b78aaf2aee 100644 --- a/node/service/src/lib.rs +++ b/node/service/src/lib.rs @@ -301,7 +301,7 @@ pub fn open_database(db_source: &DatabaseSource) -> Result, Er path.parent().ok_or(Error::DatabasePathRequired)?.into(), parachains_db::CacheSizes::default(), )?, - DatabaseSource::Auto { paritydb_path, rocksdb_path, .. } => { + DatabaseSource::Auto { paritydb_path, rocksdb_path, .. } => if paritydb_path.is_dir() && paritydb_path.exists() { parachains_db::open_creating_paritydb( paritydb_path.parent().ok_or(Error::DatabasePathRequired)?.into(), @@ -312,8 +312,7 @@ pub fn open_database(db_source: &DatabaseSource) -> Result, Er rocksdb_path.clone(), parachains_db::CacheSizes::default(), )? - } - }, + }, DatabaseSource::Custom { .. } => { unimplemented!("No polkadot subsystem db for custom source."); }, From ef78e51a3e6482fd5e085ceaf6d9bbc6195845ae Mon Sep 17 00:00:00 2001 From: Andronik Date: Wed, 29 Mar 2023 16:56:58 +0200 Subject: [PATCH 09/10] post merge fixes --- primitives/src/vstaging/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/primitives/src/vstaging/mod.rs b/primitives/src/vstaging/mod.rs index 9f5a99852e37..bc62ec66eb6e 100644 --- a/primitives/src/vstaging/mod.rs +++ b/primitives/src/vstaging/mod.rs @@ -18,6 +18,7 @@ // Put any primitives used by staging APIs functions here pub use crate::v4::*; +pub mod slashing; use sp_std::prelude::*; use parity_scale_codec::{Decode, Encode}; From bce03797a1126837fde8cf90c2cf571ee2f1a2fb Mon Sep 17 00:00:00 2001 From: Andronik Date: Mon, 24 Apr 2023 16:23:08 +0200 Subject: [PATCH 10/10] fix compilation --- primitives/src/vstaging/slashing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/src/vstaging/slashing.rs b/primitives/src/vstaging/slashing.rs index 0dd81c783e4d..c5782c7c2ab4 100644 --- a/primitives/src/vstaging/slashing.rs +++ b/primitives/src/vstaging/slashing.rs @@ -82,7 +82,7 @@ pub struct PendingSlashes { /// the runtime API boundary this type is unknown and as such we keep this /// opaque representation, implementors of the runtime API will have to make /// sure that all usages of `OpaqueKeyOwnershipProof` refer to the same type. -#[derive(Decode, Encode, PartialEq, Eq, Debug, Clone)] +#[derive(Decode, Encode, PartialEq, Eq, Debug, Clone, TypeInfo)] pub struct OpaqueKeyOwnershipProof(Vec); impl OpaqueKeyOwnershipProof { /// Create a new `OpaqueKeyOwnershipProof` using the given encoded