mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 04:01:10 +00:00
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:
@@ -20,11 +20,12 @@ use lru::LruCache;
|
|||||||
use sp_consensus_babe::Epoch;
|
use sp_consensus_babe::Epoch;
|
||||||
|
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash,
|
vstaging, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateEvent,
|
||||||
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash,
|
CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams,
|
||||||
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption,
|
GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage,
|
||||||
PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo,
|
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
|
||||||
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature,
|
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
|
/// For consistency we have the same capacity for all caches. We use 128 as we'll only need that
|
||||||
@@ -63,6 +64,10 @@ pub(crate) struct RequestResultCache {
|
|||||||
LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option<ValidationCodeHash>>,
|
LruCache<(Hash, ParaId, OccupiedCoreAssumption), Option<ValidationCodeHash>>,
|
||||||
version: LruCache<Hash, u32>,
|
version: LruCache<Hash, u32>,
|
||||||
disputes: LruCache<Hash, Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>>,
|
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 {
|
impl Default for RequestResultCache {
|
||||||
@@ -90,6 +95,8 @@ impl Default for RequestResultCache {
|
|||||||
validation_code_hash: LruCache::new(DEFAULT_CACHE_CAP),
|
validation_code_hash: LruCache::new(DEFAULT_CACHE_CAP),
|
||||||
version: LruCache::new(DEFAULT_CACHE_CAP),
|
version: LruCache::new(DEFAULT_CACHE_CAP),
|
||||||
disputes: 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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,6 +392,44 @@ impl RequestResultCache {
|
|||||||
) {
|
) {
|
||||||
self.disputes.put(relay_parent, value);
|
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 {
|
pub(crate) enum RequestResult {
|
||||||
@@ -422,4 +467,13 @@ pub(crate) enum RequestResult {
|
|||||||
ValidationCodeHash(Hash, ParaId, OccupiedCoreAssumption, Option<ValidationCodeHash>),
|
ValidationCodeHash(Hash, ParaId, OccupiedCoreAssumption, Option<ValidationCodeHash>),
|
||||||
Version(Hash, u32),
|
Version(Hash, u32),
|
||||||
Disputes(Hash, Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>),
|
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<()>,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,6 +157,12 @@ where
|
|||||||
self.requests_cache.cache_version(relay_parent, version),
|
self.requests_cache.cache_version(relay_parent, version),
|
||||||
Disputes(relay_parent, disputes) =>
|
Disputes(relay_parent, disputes) =>
|
||||||
self.requests_cache.cache_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(_, _, _, _) => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,6 +277,17 @@ where
|
|||||||
.map(|sender| Request::ValidationCodeHash(para, assumption, sender)),
|
.map(|sender| Request::ValidationCodeHash(para, assumption, sender)),
|
||||||
Request::Disputes(sender) =>
|
Request::Disputes(sender) =>
|
||||||
query!(disputes(), sender).map(|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)
|
||||||
|
},
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,33 +436,38 @@ where
|
|||||||
|
|
||||||
Request::Authorities(sender) => query!(Authorities, authorities(), ver = 1, sender),
|
Request::Authorities(sender) => query!(Authorities, authorities(), ver = 1, sender),
|
||||||
Request::Validators(sender) => query!(Validators, validators(), ver = 1, sender),
|
Request::Validators(sender) => query!(Validators, validators(), ver = 1, sender),
|
||||||
Request::ValidatorGroups(sender) =>
|
Request::ValidatorGroups(sender) => {
|
||||||
query!(ValidatorGroups, validator_groups(), ver = 1, sender),
|
query!(ValidatorGroups, validator_groups(), ver = 1, sender)
|
||||||
Request::AvailabilityCores(sender) =>
|
},
|
||||||
query!(AvailabilityCores, availability_cores(), ver = 1, sender),
|
Request::AvailabilityCores(sender) => {
|
||||||
|
query!(AvailabilityCores, availability_cores(), ver = 1, sender)
|
||||||
|
},
|
||||||
Request::PersistedValidationData(para, assumption, sender) => query!(
|
Request::PersistedValidationData(para, assumption, sender) => query!(
|
||||||
PersistedValidationData,
|
PersistedValidationData,
|
||||||
persisted_validation_data(para, assumption),
|
persisted_validation_data(para, assumption),
|
||||||
ver = 1,
|
ver = 1,
|
||||||
sender
|
sender
|
||||||
),
|
),
|
||||||
Request::AssumedValidationData(para, expected_persisted_validation_data_hash, sender) =>
|
Request::AssumedValidationData(para, expected_persisted_validation_data_hash, sender) => {
|
||||||
query!(
|
query!(
|
||||||
AssumedValidationData,
|
AssumedValidationData,
|
||||||
assumed_validation_data(para, expected_persisted_validation_data_hash),
|
assumed_validation_data(para, expected_persisted_validation_data_hash),
|
||||||
ver = 1,
|
ver = 1,
|
||||||
sender
|
sender
|
||||||
),
|
)
|
||||||
|
},
|
||||||
Request::CheckValidationOutputs(para, commitments, sender) => query!(
|
Request::CheckValidationOutputs(para, commitments, sender) => query!(
|
||||||
CheckValidationOutputs,
|
CheckValidationOutputs,
|
||||||
check_validation_outputs(para, commitments),
|
check_validation_outputs(para, commitments),
|
||||||
ver = 1,
|
ver = 1,
|
||||||
sender
|
sender
|
||||||
),
|
),
|
||||||
Request::SessionIndexForChild(sender) =>
|
Request::SessionIndexForChild(sender) => {
|
||||||
query!(SessionIndexForChild, session_index_for_child(), ver = 1, 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::ValidationCode(para, assumption, sender) => {
|
||||||
|
query!(ValidationCode, validation_code(para, assumption), ver = 1, sender)
|
||||||
|
},
|
||||||
Request::ValidationCodeByHash(validation_code_hash, sender) => query!(
|
Request::ValidationCodeByHash(validation_code_hash, sender) => query!(
|
||||||
ValidationCodeByHash,
|
ValidationCodeByHash,
|
||||||
validation_code_by_hash(validation_code_hash),
|
validation_code_by_hash(validation_code_hash),
|
||||||
@@ -458,10 +480,12 @@ where
|
|||||||
ver = 1,
|
ver = 1,
|
||||||
sender
|
sender
|
||||||
),
|
),
|
||||||
Request::CandidateEvents(sender) =>
|
Request::CandidateEvents(sender) => {
|
||||||
query!(CandidateEvents, candidate_events(), ver = 1, sender),
|
query!(CandidateEvents, candidate_events(), ver = 1, sender)
|
||||||
Request::SessionInfo(index, sender) =>
|
},
|
||||||
query!(SessionInfo, session_info(index), ver = 2, sender),
|
Request::SessionInfo(index, sender) => {
|
||||||
|
query!(SessionInfo, session_info(index), ver = 2, sender)
|
||||||
|
},
|
||||||
Request::SessionExecutorParams(session_index, sender) => query!(
|
Request::SessionExecutorParams(session_index, sender) => query!(
|
||||||
SessionExecutorParams,
|
SessionExecutorParams,
|
||||||
session_executor_params(session_index),
|
session_executor_params(session_index),
|
||||||
@@ -469,12 +493,15 @@ where
|
|||||||
sender
|
sender
|
||||||
),
|
),
|
||||||
Request::DmqContents(id, sender) => query!(DmqContents, dmq_contents(id), ver = 1, sender),
|
Request::DmqContents(id, sender) => query!(DmqContents, dmq_contents(id), ver = 1, sender),
|
||||||
Request::InboundHrmpChannelsContents(id, sender) =>
|
Request::InboundHrmpChannelsContents(id, sender) => {
|
||||||
query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), ver = 1, sender),
|
query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), ver = 1, sender)
|
||||||
Request::CurrentBabeEpoch(sender) =>
|
},
|
||||||
query!(CurrentBabeEpoch, current_epoch(), ver = 1, sender),
|
Request::CurrentBabeEpoch(sender) => {
|
||||||
Request::FetchOnChainVotes(sender) =>
|
query!(CurrentBabeEpoch, current_epoch(), ver = 1, sender)
|
||||||
query!(FetchOnChainVotes, on_chain_votes(), ver = 1, sender),
|
},
|
||||||
|
Request::FetchOnChainVotes(sender) => {
|
||||||
|
query!(FetchOnChainVotes, on_chain_votes(), ver = 1, sender)
|
||||||
|
},
|
||||||
Request::SubmitPvfCheckStatement(stmt, signature, sender) => {
|
Request::SubmitPvfCheckStatement(stmt, signature, sender) => {
|
||||||
query!(
|
query!(
|
||||||
SubmitPvfCheckStatement,
|
SubmitPvfCheckStatement,
|
||||||
@@ -486,9 +513,29 @@ where
|
|||||||
Request::PvfsRequirePrecheck(sender) => {
|
Request::PvfsRequirePrecheck(sender) => {
|
||||||
query!(PvfsRequirePrecheck, pvfs_require_precheck(), ver = 2, sender)
|
query!(PvfsRequirePrecheck, pvfs_require_precheck(), ver = 2, sender)
|
||||||
},
|
},
|
||||||
Request::ValidationCodeHash(para, assumption, sender) =>
|
Request::ValidationCodeHash(para, assumption, sender) => {
|
||||||
query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender),
|
query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender)
|
||||||
Request::Disputes(sender) =>
|
},
|
||||||
query!(Disputes, disputes(), ver = Request::DISPUTES_RUNTIME_REQUIREMENT, 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
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ use polkadot_node_primitives::{
|
|||||||
SignedDisputeStatement, SignedFullStatement, ValidationResult,
|
SignedDisputeStatement, SignedFullStatement, ValidationResult,
|
||||||
};
|
};
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
AuthorityDiscoveryId, BackedCandidate, BlockNumber, CandidateEvent, CandidateHash,
|
vstaging, AuthorityDiscoveryId, BackedCandidate, BlockNumber, CandidateEvent, CandidateHash,
|
||||||
CandidateIndex, CandidateReceipt, CollatorId, CommittedCandidateReceipt, CoreState,
|
CandidateIndex, CandidateReceipt, CollatorId, CommittedCandidateReceipt, CoreState,
|
||||||
DisputeState, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, Header as BlockHeader,
|
DisputeState, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, Header as BlockHeader,
|
||||||
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet,
|
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet,
|
||||||
@@ -606,6 +606,24 @@ pub enum RuntimeApiRequest {
|
|||||||
),
|
),
|
||||||
/// Returns all on-chain disputes at given block number. Available in `v3`.
|
/// Returns all on-chain disputes at given block number. Available in `v3`.
|
||||||
Disputes(RuntimeApiSender<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>>),
|
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 {
|
impl RuntimeApiRequest {
|
||||||
@@ -614,8 +632,17 @@ impl RuntimeApiRequest {
|
|||||||
/// `Disputes`
|
/// `Disputes`
|
||||||
pub const DISPUTES_RUNTIME_REQUIREMENT: u32 = 3;
|
pub const DISPUTES_RUNTIME_REQUIREMENT: u32 = 3;
|
||||||
|
|
||||||
|
/// `UnappliedSlashes`
|
||||||
|
pub const UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT: u32 = 4;
|
||||||
|
|
||||||
/// `ExecutorParams`
|
/// `ExecutorParams`
|
||||||
pub const EXECUTOR_PARAMS_RUNTIME_REQUIREMENT: u32 = 4;
|
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.
|
/// A message to the Runtime API subsystem.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use polkadot_primitives::{
|
use polkadot_primitives::{
|
||||||
runtime_api::ParachainHost, Block, BlockNumber, CandidateCommitments, CandidateEvent,
|
runtime_api::ParachainHost, vstaging, Block, BlockNumber, CandidateCommitments, CandidateEvent,
|
||||||
CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams,
|
CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams,
|
||||||
GroupRotationInfo, Hash, Id, InboundDownwardMessage, InboundHrmpMessage,
|
GroupRotationInfo, Hash, Id, InboundDownwardMessage, InboundHrmpMessage,
|
||||||
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
|
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
|
||||||
@@ -182,6 +182,34 @@ pub trait RuntimeApiSubsystemClient {
|
|||||||
at: Hash,
|
at: Hash,
|
||||||
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError>;
|
) -> 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
|
/// Get the execution environment parameter set by parent hash, if stored
|
||||||
async fn session_executor_params(
|
async fn session_executor_params(
|
||||||
&self,
|
&self,
|
||||||
@@ -374,4 +402,29 @@ where
|
|||||||
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError> {
|
) -> Result<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>, ApiError> {
|
||||||
self.runtime_api().disputes(at)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,10 +111,10 @@
|
|||||||
//! from the stable primitives.
|
//! from the stable primitives.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt,
|
vstaging, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash,
|
||||||
CoreState, DisputeState, ExecutorParams, GroupRotationInfo, OccupiedCoreAssumption,
|
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo,
|
||||||
PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo,
|
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
|
||||||
ValidatorId, ValidatorIndex, ValidatorSignature,
|
SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, ValidatorSignature,
|
||||||
};
|
};
|
||||||
use parity_scale_codec::{Decode, Encode};
|
use parity_scale_codec::{Decode, Encode};
|
||||||
use polkadot_core_primitives as pcp;
|
use polkadot_core_primitives as pcp;
|
||||||
@@ -218,5 +218,23 @@ sp_api::decl_runtime_apis! {
|
|||||||
|
|
||||||
/// Returns execution parameters for the session.
|
/// Returns execution parameters for the session.
|
||||||
fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams>;
|
fn session_executor_params(session_index: SessionIndex) -> Option<ExecutorParams>;
|
||||||
|
|
||||||
|
/// Returns a list of validators that lost a past session dispute and need to be slashed.
|
||||||
|
#[api_version(5)]
|
||||||
|
fn unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)>;
|
||||||
|
|
||||||
|
/// Returns a merkle proof of a validator session key.
|
||||||
|
#[api_version(5)]
|
||||||
|
fn key_ownership_proof(
|
||||||
|
validator_id: 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(5)]
|
||||||
|
fn submit_report_dispute_lost(
|
||||||
|
dispute_proof: vstaging::slashing::DisputeProof,
|
||||||
|
key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof,
|
||||||
|
) -> Option<()>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
// Put any primitives used by staging APIs functions here
|
// Put any primitives used by staging APIs functions here
|
||||||
pub use crate::v4::*;
|
pub use crate::v4::*;
|
||||||
|
pub mod slashing;
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
|
|
||||||
use parity_scale_codec::{Decode, Encode};
|
use parity_scale_codec::{Decode, Encode};
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
// Copyright 2017-2023 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Primitives types used for dispute slashing.
|
||||||
|
|
||||||
|
use crate::v4::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex};
|
||||||
|
use parity_scale_codec::{Decode, Encode};
|
||||||
|
use scale_info::TypeInfo;
|
||||||
|
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};
|
||||||
|
|
||||||
|
/// 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<ValidatorIndex, ValidatorId>,
|
||||||
|
/// 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, TypeInfo)]
|
||||||
|
pub struct OpaqueKeyOwnershipProof(Vec<u8>);
|
||||||
|
impl OpaqueKeyOwnershipProof {
|
||||||
|
/// Create a new `OpaqueKeyOwnershipProof` using the given encoded
|
||||||
|
/// representation.
|
||||||
|
pub fn new(inner: Vec<u8>) -> OpaqueKeyOwnershipProof {
|
||||||
|
OpaqueKeyOwnershipProof(inner)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to decode this `OpaqueKeyOwnershipProof` into the given concrete key
|
||||||
|
/// ownership proof type.
|
||||||
|
pub fn decode<T: Decode>(self) -> Option<T> {
|
||||||
|
Decode::decode(&mut &self.0[..]).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,8 +49,10 @@ use frame_support::{
|
|||||||
weights::Weight,
|
weights::Weight,
|
||||||
};
|
};
|
||||||
|
|
||||||
use parity_scale_codec::{Decode, Encode};
|
use primitives::{
|
||||||
use primitives::{CandidateHash, SessionIndex, ValidatorId, ValidatorIndex};
|
vstaging::slashing::{DisputeProof, DisputesTimeSlot, PendingSlashes, SlashingOffenceKind},
|
||||||
|
CandidateHash, SessionIndex, ValidatorId, ValidatorIndex,
|
||||||
|
};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::Convert,
|
traits::Convert,
|
||||||
@@ -58,15 +60,12 @@ use sp_runtime::{
|
|||||||
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
|
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
|
||||||
TransactionValidityError, ValidTransaction,
|
TransactionValidityError, ValidTransaction,
|
||||||
},
|
},
|
||||||
KeyTypeId, Perbill, RuntimeDebug,
|
KeyTypeId, Perbill,
|
||||||
};
|
};
|
||||||
use sp_session::{GetSessionNumber, GetValidatorCount};
|
use sp_session::{GetSessionNumber, GetValidatorCount};
|
||||||
use sp_staking::offence::{DisableStrategy, Kind, Offence, OffenceError, ReportOffence};
|
use sp_staking::offence::{DisableStrategy, Kind, Offence, OffenceError, ReportOffence};
|
||||||
use sp_std::{
|
use sp_std::{
|
||||||
collections::{
|
collections::{btree_map::Entry, btree_set::BTreeSet},
|
||||||
btree_map::{BTreeMap, Entry},
|
|
||||||
btree_set::BTreeSet,
|
|
||||||
},
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,23 +91,8 @@ impl<const M: u32> BenchmarkingConfiguration for BenchConfig<M> {
|
|||||||
const MAX_VALIDATORS: u32 = 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.
|
/// 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))]
|
#[cfg_attr(feature = "std", derive(Clone, PartialEq, Eq))]
|
||||||
pub struct SlashingOffence<KeyOwnerIdentification> {
|
pub struct SlashingOffence<KeyOwnerIdentification> {
|
||||||
/// The size of the validator set in that session.
|
/// 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
|
/// 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
|
/// has been validated) and for submitting a transaction to report a slash (from
|
||||||
/// an offchain context).
|
/// an offchain context).
|
||||||
@@ -603,6 +554,17 @@ impl<T: Config> Pallet<T> {
|
|||||||
let old_session = session_index - config.dispute_period - 1;
|
let old_session = session_index - config.dispute_period - 1;
|
||||||
let _ = <UnappliedSlashes<T>>::clear_prefix(old_session, REMOVE_LIMIT, None);
|
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:
|
/// Methods for the `ValidateUnsigned` implementation:
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use frame_benchmarking::{benchmarks, whitelist_account};
|
|||||||
use frame_support::traits::{OnFinalize, OnInitialize};
|
use frame_support::traits::{OnFinalize, OnInitialize};
|
||||||
use frame_system::RawOrigin;
|
use frame_system::RawOrigin;
|
||||||
use pallet_staking::testing_utils::create_validators;
|
use pallet_staking::testing_utils::create_validators;
|
||||||
|
use parity_scale_codec::Decode;
|
||||||
use primitives::{Hash, PARACHAIN_KEY_TYPE_ID};
|
use primitives::{Hash, PARACHAIN_KEY_TYPE_ID};
|
||||||
use sp_runtime::traits::{One, StaticLookup};
|
use sp_runtime::traits::{One, StaticLookup};
|
||||||
use sp_session::MembershipProof;
|
use sp_session::MembershipProof;
|
||||||
|
|||||||
@@ -15,3 +15,32 @@
|
|||||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Put implementations of functions from staging APIs here.
|
//! 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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,11 +23,11 @@
|
|||||||
use pallet_nis::WithMaximumOf;
|
use pallet_nis::WithMaximumOf;
|
||||||
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
|
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
|
||||||
use primitives::{
|
use primitives::{
|
||||||
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash,
|
vstaging, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash,
|
||||||
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash,
|
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash,
|
||||||
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce,
|
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce,
|
||||||
OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature,
|
OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature,
|
||||||
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID,
|
||||||
};
|
};
|
||||||
use runtime_common::{
|
use runtime_common::{
|
||||||
assigned_slots, auctions, claims, crowdloan, impl_runtime_weights, impls::ToAuthor,
|
assigned_slots, auctions, claims, crowdloan, impl_runtime_weights, impls::ToAuthor,
|
||||||
@@ -1800,6 +1800,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api_version(5)]
|
||||||
impl primitives::runtime_api::ParachainHost<Block, Hash, BlockNumber> for Runtime {
|
impl primitives::runtime_api::ParachainHost<Block, Hash, BlockNumber> for Runtime {
|
||||||
fn validators() -> Vec<ValidatorId> {
|
fn validators() -> Vec<ValidatorId> {
|
||||||
parachains_runtime_api_impl::validators::<Runtime>()
|
parachains_runtime_api_impl::validators::<Runtime>()
|
||||||
@@ -1905,6 +1906,31 @@ sp_api::impl_runtime_apis! {
|
|||||||
fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
|
fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
|
||||||
parachains_runtime_api_impl::get_session_disputes::<Runtime>()
|
parachains_runtime_api_impl::get_session_disputes::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unapplied_slashes(
|
||||||
|
) -> Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)> {
|
||||||
|
runtime_parachains::runtime_api_impl::vstaging::unapplied_slashes::<Runtime>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_ownership_proof(
|
||||||
|
validator_id: ValidatorId,
|
||||||
|
) -> Option<vstaging::slashing::OpaqueKeyOwnershipProof> {
|
||||||
|
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_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof,
|
||||||
|
) -> Option<()> {
|
||||||
|
runtime_parachains::runtime_api_impl::vstaging::submit_unsigned_slashing_report::<Runtime>(
|
||||||
|
dispute_proof,
|
||||||
|
key_ownership_proof,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[api_version(2)]
|
#[api_version(2)]
|
||||||
|
|||||||
@@ -39,12 +39,12 @@ use pallet_session::historical as session_historical;
|
|||||||
use pallet_transaction_payment::{CurrencyAdapter, FeeDetails, RuntimeDispatchInfo};
|
use pallet_transaction_payment::{CurrencyAdapter, FeeDetails, RuntimeDispatchInfo};
|
||||||
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
|
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
|
||||||
use primitives::{
|
use primitives::{
|
||||||
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash,
|
vstaging, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash,
|
||||||
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash,
|
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash,
|
||||||
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce,
|
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce,
|
||||||
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
|
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
|
||||||
SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
||||||
ValidatorSignature,
|
ValidatorSignature, PARACHAIN_KEY_TYPE_ID,
|
||||||
};
|
};
|
||||||
use runtime_common::{
|
use runtime_common::{
|
||||||
assigned_slots, auctions, crowdloan, elections::OnChainAccuracy, impl_runtime_weights,
|
assigned_slots, auctions, crowdloan, elections::OnChainAccuracy, impl_runtime_weights,
|
||||||
@@ -58,7 +58,9 @@ use runtime_parachains::{
|
|||||||
inclusion::{AggregateMessageOrigin, UmpQueueId},
|
inclusion::{AggregateMessageOrigin, UmpQueueId},
|
||||||
initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras,
|
initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras,
|
||||||
paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points,
|
paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points,
|
||||||
runtime_api_impl::v4 as parachains_runtime_api_impl,
|
runtime_api_impl::{
|
||||||
|
v4 as parachains_runtime_api_impl, vstaging as parachains_runtime_api_impl_staging,
|
||||||
|
},
|
||||||
scheduler as parachains_scheduler, session_info as parachains_session_info,
|
scheduler as parachains_scheduler, session_info as parachains_session_info,
|
||||||
shared as parachains_shared,
|
shared as parachains_shared,
|
||||||
};
|
};
|
||||||
@@ -1472,6 +1474,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api_version(5)]
|
||||||
impl primitives::runtime_api::ParachainHost<Block, Hash, BlockNumber> for Runtime {
|
impl primitives::runtime_api::ParachainHost<Block, Hash, BlockNumber> for Runtime {
|
||||||
fn validators() -> Vec<ValidatorId> {
|
fn validators() -> Vec<ValidatorId> {
|
||||||
parachains_runtime_api_impl::validators::<Runtime>()
|
parachains_runtime_api_impl::validators::<Runtime>()
|
||||||
@@ -1577,6 +1580,31 @@ sp_api::impl_runtime_apis! {
|
|||||||
fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
|
fn disputes() -> Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)> {
|
||||||
parachains_runtime_api_impl::get_session_disputes::<Runtime>()
|
parachains_runtime_api_impl::get_session_disputes::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unapplied_slashes(
|
||||||
|
) -> Vec<(SessionIndex, CandidateHash, vstaging::slashing::PendingSlashes)> {
|
||||||
|
parachains_runtime_api_impl_staging::unapplied_slashes::<Runtime>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_ownership_proof(
|
||||||
|
validator_id: ValidatorId,
|
||||||
|
) -> Option<vstaging::slashing::OpaqueKeyOwnershipProof> {
|
||||||
|
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_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof,
|
||||||
|
) -> Option<()> {
|
||||||
|
parachains_runtime_api_impl_staging::submit_unsigned_slashing_report::<Runtime>(
|
||||||
|
dispute_proof,
|
||||||
|
key_ownership_proof,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
||||||
|
|||||||
Reference in New Issue
Block a user