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

runtime: past session slashing runtime API #6667

Merged
merged 23 commits into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8dbeae7
runtime/vstaging: unapplied_slashes runtime API
ordian Feb 1, 2023
d3273d7
runtime/vstaging: key_ownership_proof runtime API
ordian Feb 2, 2023
8394592
runtime/ParachainHost: submit_report_dispute_lost
ordian Feb 2, 2023
d31edbb
fix key_ownership_proof API
ordian Feb 2, 2023
5808d0b
runtime: submit_report_dispute_lost runtime API
ordian Feb 3, 2023
78d9da0
nits
ordian Feb 3, 2023
7caf651
Update node/subsystem-types/src/messages.rs
ordian Feb 5, 2023
ab08d67
merge master and resolve ExecutorParams conflicts
ordian Feb 27, 2023
62e3831
revert unrelated fmt changes
ordian Feb 27, 2023
f2119e4
Merge branch 'master' into ao-past-session-slashing-runtime
ordian Mar 7, 2023
35d76d3
merge master, resolve conflicts, bump to v5
ordian Mar 16, 2023
a150569
Merge branch 'master' into ao-past-session-slashing-runtime
ordian Mar 21, 2023
fbc0e9d
Merge branch 'master' into ao-past-session-slashing-runtime
ordian Mar 23, 2023
2ba635b
Merge branch 'master' into ao-past-session-slashing-runtime
ordian Mar 29, 2023
ef78e51
post merge fixes
ordian Mar 29, 2023
4f660d1
Merge branch 'master' into ao-past-session-slashing-runtime
ordian Apr 12, 2023
a58b144
Merge branch 'master' into ao-past-session-slashing-runtime
ordian Apr 26, 2023
bce0379
fix compilation
ordian Apr 24, 2023
f45594d
Merge branch 'master' into ao-past-session-slashing-runtime
ordian May 23, 2023
9cb0723
Merge branch 'master' into ao-past-session-slashing-runtime
ordian May 24, 2023
1ae22c5
Merge branch 'master' into ao-past-session-slashing-runtime
ordian May 24, 2023
f2bcd9b
Merge branch 'master' into ao-past-session-slashing-runtime
ordian May 25, 2023
f621e4a
Merge branch 'master' into ao-past-session-slashing-runtime
ordian May 25, 2023
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
63 changes: 58 additions & 5 deletions node/core/runtime-api/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -62,6 +62,10 @@ pub(crate) struct RequestResultCache {
LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option<ValidationCodeHash>>,
version: LruCache<Hash, u32>,
disputes: LruCache<Hash, Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>>,
unapplied_slashes:
LruCache<Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>>,
key_ownership_proof:
LruCache<(Hash, ValidatorId), Option<vstaging::slashing::OpaqueKeyOwnershipProof>>,
}

impl Default for RequestResultCache {
Expand All @@ -88,6 +92,8 @@ 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),
key_ownership_proof: LruCache::new(DEFAULT_CACHE_CAP),
}
}
}
Expand Down Expand Up @@ -368,6 +374,44 @@ 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) fn key_ownership_proof(
&mut self,
key: (Hash, ValidatorId),
) -> Option<&Option<vstaging::slashing::OpaqueKeyOwnershipProof>> {
self.key_ownership_proof.get(&key)
}

pub(crate) fn cache_key_ownership_proof(
&mut self,
key: (Hash, ValidatorId),
value: Option<vstaging::slashing::OpaqueKeyOwnershipProof>,
) {
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 {
Expand Down Expand Up @@ -404,4 +448,13 @@ pub(crate) enum RequestResult {
ValidationCodeHash(Hash, ParaId, OccupiedCoreAssumption, Option<ValidationCodeHash>),
Version(Hash, u32),
Disputes(Hash, Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>),
UnappliedSlashes(Hash, Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>),
KeyOwnershipProof(Hash, ValidatorId, Option<vstaging::slashing::OpaqueKeyOwnershipProof>),
// This is a request with side-effects.
SubmitReportDisputeLost(
Hash,
vstaging::slashing::DisputeProof,
vstaging::slashing::OpaqueKeyOwnershipProof,
Option<()>,
),
}
35 changes: 35 additions & 0 deletions node/core/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ 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),
KeyOwnershipProof(relay_parent, validator_id, key_ownership_proof) => self
.requests_cache
.cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof),
SubmitReportDisputeLost(_, _, _, _) => {},
}
}

Expand Down Expand Up @@ -258,6 +264,17 @@ 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)),
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)
},
),
}
}

Expand Down Expand Up @@ -502,5 +519,23 @@ 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
),
Request::KeyOwnershipProof(validator_id, sender) => query!(
KeyOwnershipProof,
key_ownership_proof(validator_id),
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
),
}
}
29 changes: 28 additions & 1 deletion node/subsystem-types/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -601,13 +601,40 @@ pub enum RuntimeApiRequest {
),
/// Returns all on-chain disputes at given block number. Available in `v3`.
Disputes(RuntimeApiSender<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>>),
/// Returns a list of validators that lost a past session dispute and need to be slashed.
/// `VStaging`
UnappliedSlashes(
RuntimeApiSender<Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>>,
),
/// Returns a merkle proof of a validator session key.
/// `VStaging`
KeyOwnershipProof(
ValidatorId,
RuntimeApiSender<Option<vstaging::slashing::OpaqueKeyOwnershipProof>>,
),
/// Submits an unsigned extrinsic to slash validator who lost a past session dispute.
/// `VStaging`
SubmitReportDisputeLost(
vstaging::slashing::DisputeProof,
vstaging::slashing::OpaqueKeyOwnershipProof,
RuntimeApiSender<Option<()>>,
),
}

impl RuntimeApiRequest {
/// Runtime version requirements for each message

/// `Disputes`
pub const DISPUTES_RUNTIME_REQUIREMENT: u32 = 3;

/// `UnappliedSlashes`
pub const UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT: u32 = 4;

/// `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.
Expand Down
67 changes: 62 additions & 5 deletions node/subsystem-types/src/runtime_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -188,6 +189,34 @@ pub trait RuntimeApiSubsystemClient {
at: Hash,
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, 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<Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>, 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,
validator_id: ValidatorId,
) -> Result<Option<vstaging::slashing::OpaqueKeyOwnershipProof>, 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<Option<()>, ApiError>;

// === BABE API ===

/// Returns information regarding the current epoch.
Expand Down Expand Up @@ -378,4 +407,32 @@ where
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError> {
self.runtime_api().disputes(&BlockId::Hash(at))
}

async fn unapplied_slashes(
&self,
at: Hash,
) -> Result<Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>, ApiError> {
self.runtime_api().unapplied_slashes(&BlockId::Hash(at))
}

async fn key_ownership_proof(
&self,
at: Hash,
validator_id: ValidatorId,
) -> Result<Option<vstaging::slashing::OpaqueKeyOwnershipProof>, 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<Option<()>, ApiError> {
self.runtime_api().submit_report_dispute_lost(
&BlockId::Hash(at),
dispute_proof,
key_ownership_proof,
)
}
}
20 changes: 19 additions & 1 deletion primitives/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -221,5 +221,23 @@ sp_api::decl_runtime_apis! {
/// Returns all onchain disputes.
#[api_version(3)]
fn disputes() -> Vec<(v2::SessionIndex, v2::CandidateHash, v2::DisputeState<v2::BlockNumber>)>;

/// Returns a list of validators that lost a past session dispute and need to be slashed.
#[api_version(4)]
fn unapplied_slashes() -> Vec<(v2::SessionIndex, v2::CandidateHash, vstaging::slashing::PendingSlashes)>;

/// Returns a merkle proof of a validator session key.
#[api_version(4)]
fn key_ownership_proof(
validator_id: v2::ValidatorId,
) -> Option<vstaging::slashing::OpaqueKeyOwnershipProof>;

/// Submit an unsigned extrinsic to slash validators who lost a dispute about
/// a candidate of a past session.
#[api_version(4)]
fn submit_report_dispute_lost(
dispute_proof: vstaging::slashing::DisputeProof,
key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof,
) -> Option<()>;
}
}
2 changes: 2 additions & 0 deletions primitives/src/vstaging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@
//! Staging Primitives.

// Put any primitives used by staging APIs functions here

pub mod slashing;
Loading