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 all 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
64 changes: 59 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,12 @@ use lru::LruCache;
use sp_consensus_babe::Epoch;

use polkadot_primitives::{
AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash,
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, 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, ExecutorParams,
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 @@ -63,6 +64,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 Down Expand Up @@ -90,6 +95,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 @@ -385,6 +392,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 @@ -422,4 +467,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<()>,
),
}
95 changes: 71 additions & 24 deletions node/core/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,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 @@ -271,6 +277,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 @@ -419,33 +436,38 @@ where

Request::Authorities(sender) => query!(Authorities, authorities(), ver = 1, sender),
Request::Validators(sender) => query!(Validators, validators(), ver = 1, sender),
Request::ValidatorGroups(sender) =>
query!(ValidatorGroups, validator_groups(), ver = 1, sender),
Request::AvailabilityCores(sender) =>
query!(AvailabilityCores, availability_cores(), ver = 1, sender),
Request::ValidatorGroups(sender) => {
query!(ValidatorGroups, validator_groups(), ver = 1, sender)
},
Request::AvailabilityCores(sender) => {
query!(AvailabilityCores, availability_cores(), ver = 1, sender)
},
Request::PersistedValidationData(para, assumption, sender) => query!(
PersistedValidationData,
persisted_validation_data(para, assumption),
ver = 1,
sender
),
Request::AssumedValidationData(para, expected_persisted_validation_data_hash, sender) =>
Request::AssumedValidationData(para, expected_persisted_validation_data_hash, sender) => {
query!(
AssumedValidationData,
assumed_validation_data(para, expected_persisted_validation_data_hash),
ver = 1,
sender
),
)
},
Request::CheckValidationOutputs(para, commitments, sender) => query!(
CheckValidationOutputs,
check_validation_outputs(para, commitments),
ver = 1,
sender
),
Request::SessionIndexForChild(sender) =>
query!(SessionIndexForChild, session_index_for_child(), ver = 1, sender),
Request::ValidationCode(para, assumption, sender) =>
query!(ValidationCode, validation_code(para, assumption), ver = 1, sender),
Request::SessionIndexForChild(sender) => {
query!(SessionIndexForChild, session_index_for_child(), ver = 1, sender)
},
Request::ValidationCode(para, assumption, sender) => {
query!(ValidationCode, validation_code(para, assumption), ver = 1, sender)
},
Request::ValidationCodeByHash(validation_code_hash, sender) => query!(
ValidationCodeByHash,
validation_code_by_hash(validation_code_hash),
Expand All @@ -458,23 +480,28 @@ where
ver = 1,
sender
),
Request::CandidateEvents(sender) =>
query!(CandidateEvents, candidate_events(), ver = 1, sender),
Request::SessionInfo(index, sender) =>
query!(SessionInfo, session_info(index), ver = 2, sender),
Request::CandidateEvents(sender) => {
query!(CandidateEvents, candidate_events(), ver = 1, sender)
},
Request::SessionInfo(index, sender) => {
query!(SessionInfo, session_info(index), ver = 2, sender)
},
Request::SessionExecutorParams(session_index, sender) => query!(
SessionExecutorParams,
session_executor_params(session_index),
ver = Request::EXECUTOR_PARAMS_RUNTIME_REQUIREMENT,
sender
),
Request::DmqContents(id, sender) => query!(DmqContents, dmq_contents(id), ver = 1, sender),
Request::InboundHrmpChannelsContents(id, sender) =>
query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), ver = 1, sender),
Request::CurrentBabeEpoch(sender) =>
query!(CurrentBabeEpoch, current_epoch(), ver = 1, sender),
Request::FetchOnChainVotes(sender) =>
query!(FetchOnChainVotes, on_chain_votes(), ver = 1, sender),
Request::InboundHrmpChannelsContents(id, sender) => {
query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), ver = 1, sender)
},
Request::CurrentBabeEpoch(sender) => {
query!(CurrentBabeEpoch, current_epoch(), ver = 1, sender)
},
Request::FetchOnChainVotes(sender) => {
query!(FetchOnChainVotes, on_chain_votes(), ver = 1, sender)
},
Request::SubmitPvfCheckStatement(stmt, signature, sender) => {
query!(
SubmitPvfCheckStatement,
Expand All @@ -486,9 +513,29 @@ where
Request::PvfsRequirePrecheck(sender) => {
query!(PvfsRequirePrecheck, pvfs_require_precheck(), ver = 2, sender)
},
Request::ValidationCodeHash(para, assumption, sender) =>
query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender),
Request::Disputes(sender) =>
query!(Disputes, disputes(), ver = Request::DISPUTES_RUNTIME_REQUIREMENT, sender),
Request::ValidationCodeHash(para, assumption, sender) => {
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, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, Header as BlockHeader,
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet,
Expand Down Expand Up @@ -606,6 +606,24 @@ 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 {
Expand All @@ -614,8 +632,17 @@ impl RuntimeApiRequest {
/// `Disputes`
pub const DISPUTES_RUNTIME_REQUIREMENT: u32 = 3;

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

/// `ExecutorParams`
pub const EXECUTOR_PARAMS_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
55 changes: 54 additions & 1 deletion node/subsystem-types/src/runtime_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

use async_trait::async_trait;
use polkadot_primitives::{
runtime_api::ParachainHost, Block, BlockNumber, CandidateCommitments, CandidateEvent,
runtime_api::ParachainHost, vstaging, Block, BlockNumber, CandidateCommitments, CandidateEvent,
CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams,
GroupRotationInfo, Hash, Id, InboundDownwardMessage, InboundHrmpMessage,
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
Expand Down Expand Up @@ -182,6 +182,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>;

/// Get the execution environment parameter set by parent hash, if stored
async fn session_executor_params(
&self,
Expand Down Expand Up @@ -374,4 +402,29 @@ where
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError> {
self.runtime_api().disputes(at)
}

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

async fn key_ownership_proof(
&self,
at: Hash,
validator_id: ValidatorId,
) -> Result<Option<vstaging::slashing::OpaqueKeyOwnershipProof>, ApiError> {
self.runtime_api().key_ownership_proof(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(at, dispute_proof, key_ownership_proof)
}
}
Loading