Skip to content

Commit

Permalink
Disabled validators runtime API (#1257)
Browse files Browse the repository at this point in the history
Exposes disabled validators list via a runtime API.

---------

Co-authored-by: ordian <noreply@reusable.software>
Co-authored-by: ordian <write@reusable.software>
  • Loading branch information
3 people authored Oct 12, 2023
1 parent f0e6d2a commit 7aace06
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,13 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient {
Ok(self.rpc_client.parachain_host_minimum_backing_votes(at, session_index).await?)
}

async fn disabled_validators(
&self,
at: Hash,
) -> Result<Vec<polkadot_primitives::ValidatorIndex>, ApiError> {
Ok(self.rpc_client.parachain_host_disabled_validators(at).await?)
}

async fn async_backing_params(&self, at: Hash) -> Result<AsyncBackingParams, ApiError> {
Ok(self.rpc_client.parachain_host_async_backing_params(at).await?)
}
Expand Down
8 changes: 8 additions & 0 deletions cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,14 @@ impl RelayChainRpcClient {
.await
}

pub async fn parachain_host_disabled_validators(
&self,
at: RelayHash,
) -> Result<Vec<ValidatorIndex>, RelayChainError> {
self.call_remote_runtime_function("ParachainHost_disabled_validators", at, None::<()>)
.await
}

#[allow(missing_docs)]
pub async fn parachain_host_async_backing_params(
&self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use xcm_emulator::{
};

decl_test_relay_chains! {
#[api_version(7)]
#[api_version(8)]
pub struct Westend {
genesis = westend::genesis(),
on_init = (),
Expand All @@ -50,7 +50,7 @@ decl_test_relay_chains! {
AssetRate: westend_runtime::AssetRate,
}
},
#[api_version(7)]
#[api_version(8)]
pub struct Rococo {
genesis = rococo::genesis(),
on_init = (),
Expand All @@ -65,7 +65,7 @@ decl_test_relay_chains! {
Balances: rococo_runtime::Balances,
}
},
#[api_version(7)]
#[api_version(8)]
pub struct Wococo {
genesis = rococo::genesis(),
on_init = (),
Expand Down
18 changes: 18 additions & 0 deletions polkadot/node/core/runtime-api/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub(crate) struct RequestResultCache {
unapplied_slashes: LruMap<Hash, Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>>,
key_ownership_proof: LruMap<(Hash, ValidatorId), Option<slashing::OpaqueKeyOwnershipProof>>,
minimum_backing_votes: LruMap<SessionIndex, u32>,
disabled_validators: LruMap<Hash, Vec<ValidatorIndex>>,
para_backing_state: LruMap<(Hash, ParaId), Option<async_backing::BackingState>>,
async_backing_params: LruMap<Hash, async_backing::AsyncBackingParams>,
}
Expand Down Expand Up @@ -96,6 +97,7 @@ impl Default for RequestResultCache {
unapplied_slashes: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
key_ownership_proof: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
minimum_backing_votes: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
disabled_validators: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
para_backing_state: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
async_backing_params: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
}
Expand Down Expand Up @@ -444,6 +446,21 @@ impl RequestResultCache {
self.minimum_backing_votes.insert(session_index, minimum_backing_votes);
}

pub(crate) fn disabled_validators(
&mut self,
relay_parent: &Hash,
) -> Option<&Vec<ValidatorIndex>> {
self.disabled_validators.get(relay_parent).map(|v| &*v)
}

pub(crate) fn cache_disabled_validators(
&mut self,
relay_parent: Hash,
disabled_validators: Vec<ValidatorIndex>,
) {
self.disabled_validators.insert(relay_parent, disabled_validators);
}

pub(crate) fn para_backing_state(
&mut self,
key: (Hash, ParaId),
Expand Down Expand Up @@ -520,6 +537,7 @@ pub(crate) enum RequestResult {
slashing::OpaqueKeyOwnershipProof,
Option<()>,
),
DisabledValidators(Hash, Vec<ValidatorIndex>),
ParaBackingState(Hash, ParaId, Option<async_backing::BackingState>),
AsyncBackingParams(Hash, async_backing::AsyncBackingParams),
}
10 changes: 10 additions & 0 deletions polkadot/node/core/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ where
.requests_cache
.cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof),
SubmitReportDisputeLost(_, _, _, _) => {},
DisabledValidators(relay_parent, disabled_validators) =>
self.requests_cache.cache_disabled_validators(relay_parent, disabled_validators),
ParaBackingState(relay_parent, para_id, constraints) => self
.requests_cache
.cache_para_backing_state((relay_parent, para_id), constraints),
Expand Down Expand Up @@ -296,6 +298,8 @@ where
Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender)
},
),
Request::DisabledValidators(sender) => query!(disabled_validators(), sender)
.map(|sender| Request::DisabledValidators(sender)),
Request::ParaBackingState(para, sender) => query!(para_backing_state(para), sender)
.map(|sender| Request::ParaBackingState(para, sender)),
Request::AsyncBackingParams(sender) => query!(async_backing_params(), sender)
Expand Down Expand Up @@ -565,6 +569,12 @@ where
ver = Request::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT,
sender
),
Request::DisabledValidators(sender) => query!(
DisabledValidators,
disabled_validators(),
ver = Request::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT,
sender
),
Request::ParaBackingState(para, sender) => {
query!(
ParaBackingState,
Expand Down
4 changes: 4 additions & 0 deletions polkadot/node/core/runtime-api/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ impl RuntimeApiSubsystemClient for MockSubsystemClient {
async fn minimum_backing_votes(&self, _: Hash, _: SessionIndex) -> Result<u32, ApiError> {
todo!("Not required for tests")
}

async fn disabled_validators(&self, _: Hash) -> Result<Vec<ValidatorIndex>, ApiError> {
todo!("Not required for tests")
}
}

#[test]
Expand Down
5 changes: 5 additions & 0 deletions polkadot/node/subsystem-types/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,8 @@ pub enum RuntimeApiRequest {
),
/// Get the minimum required backing votes.
MinimumBackingVotes(SessionIndex, RuntimeApiSender<u32>),
/// Returns all disabled validators at a given block height.
DisabledValidators(RuntimeApiSender<Vec<ValidatorIndex>>),
/// Get the backing state of the given para.
ParaBackingState(ParaId, RuntimeApiSender<Option<async_backing::BackingState>>),
/// Get candidate's acceptance limitations for asynchronous backing for a relay parent.
Expand Down Expand Up @@ -726,6 +728,9 @@ impl RuntimeApiRequest {

/// Minimum version to enable asynchronous backing: `AsyncBackingParams` and `ParaBackingState`.
pub const ASYNC_BACKING_STATE_RUNTIME_REQUIREMENT: u32 = 7;

/// `DisabledValidators`
pub const DISABLED_VALIDATORS_RUNTIME_REQUIREMENT: u32 = 8;
}

/// A message to the Runtime API subsystem.
Expand Down
9 changes: 8 additions & 1 deletion polkadot/node/subsystem-types/src/runtime_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ pub trait RuntimeApiSubsystemClient {
at: Hash,
para_id: Id,
) -> Result<Option<async_backing::BackingState>, ApiError>;

// === v8 ===
/// Gets the disabled validators at a specific block height
async fn disabled_validators(&self, at: Hash) -> Result<Vec<ValidatorIndex>, ApiError>;
}

/// Default implementation of [`RuntimeApiSubsystemClient`] using the client.
Expand Down Expand Up @@ -497,11 +501,14 @@ where
self.client.runtime_api().para_backing_state(at, para_id)
}

/// Returns candidate's acceptance limitations for asynchronous backing for a relay parent.
async fn async_backing_params(
&self,
at: Hash,
) -> Result<async_backing::AsyncBackingParams, ApiError> {
self.client.runtime_api().async_backing_params(at)
}

async fn disabled_validators(&self, at: Hash) -> Result<Vec<ValidatorIndex>, ApiError> {
self.client.runtime_api().disabled_validators(at)
}
}
1 change: 1 addition & 0 deletions polkadot/node/subsystem-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ specialize_requests! {
fn request_unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>; UnappliedSlashes;
fn request_key_ownership_proof(validator_id: ValidatorId) -> Option<slashing::OpaqueKeyOwnershipProof>; KeyOwnershipProof;
fn request_submit_report_dispute_lost(dp: slashing::DisputeProof, okop: slashing::OpaqueKeyOwnershipProof) -> Option<()>; SubmitReportDisputeLost;
fn request_disabled_validators() -> Vec<ValidatorIndex>; DisabledValidators;
fn request_async_backing_params() -> AsyncBackingParams; AsyncBackingParams;
}

Expand Down
7 changes: 7 additions & 0 deletions polkadot/primitives/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ sp_api::decl_runtime_apis! {
#[api_version(6)]
fn minimum_backing_votes() -> u32;


/***** Added in v7: Asynchronous backing *****/

/// Returns the state of parachain backing for a given para.
Expand All @@ -257,5 +258,11 @@ sp_api::decl_runtime_apis! {
/// Returns candidate's acceptance limitations for asynchronous backing for a relay parent.
#[api_version(7)]
fn async_backing_params() -> AsyncBackingParams;

/***** Added in v8 *****/

/// Returns a list of all disabled validators at the given block.
#[api_version(8)]
fn disabled_validators() -> Vec<ValidatorIndex>;
}
}
27 changes: 27 additions & 0 deletions polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,30 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! Put implementations of functions from staging APIs here.

use crate::shared;
use primitives::ValidatorIndex;
use sp_std::{collections::btree_map::BTreeMap, prelude::Vec};

/// Implementation for `DisabledValidators`
// CAVEAT: this should only be called on the node side
// as it might produce incorrect results on session boundaries
pub fn disabled_validators<T>() -> Vec<ValidatorIndex>
where
T: pallet_session::Config + shared::Config,
{
let shuffled_indices = <shared::Pallet<T>>::active_validator_indices();
// mapping from raw validator index to `ValidatorIndex`
// this computation is the same within a session, but should be cheap
let reverse_index = shuffled_indices
.iter()
.enumerate()
.map(|(i, v)| (v.0, ValidatorIndex(i as u32)))
.collect::<BTreeMap<u32, ValidatorIndex>>();

// we might have disabled validators who are not parachain validators
<pallet_session::Pallet<T>>::disabled_validators()
.iter()
.filter_map(|v| reverse_index.get(v).cloned())
.collect()
}
11 changes: 9 additions & 2 deletions polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ use runtime_parachains::{
inclusion::{AggregateMessageOrigin, UmpQueueId},
initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras,
paras_inherent as parachains_paras_inherent,
runtime_api_impl::v7 as parachains_runtime_api_impl,
runtime_api_impl::{
v7 as parachains_runtime_api_impl, vstaging as parachains_staging_runtime_api_impl,
},
scheduler as parachains_scheduler, session_info as parachains_session_info,
shared as parachains_shared,
};
Expand Down Expand Up @@ -1585,7 +1587,7 @@ sp_api::impl_runtime_apis! {
}
}

#[api_version(7)]
#[api_version(8)]
impl primitives::runtime_api::ParachainHost<Block, Hash, BlockNumber> for Runtime {
fn validators() -> Vec<ValidatorId> {
parachains_runtime_api_impl::validators::<Runtime>()
Expand Down Expand Up @@ -1728,6 +1730,11 @@ sp_api::impl_runtime_apis! {
fn async_backing_params() -> primitives::AsyncBackingParams {
parachains_runtime_api_impl::async_backing_params::<Runtime>()
}

fn disabled_validators() -> Vec<ValidatorIndex> {
parachains_staging_runtime_api_impl::disabled_validators::<Runtime>()
}

}

#[api_version(3)]
Expand Down
10 changes: 8 additions & 2 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ use runtime_parachains::{
inclusion::{AggregateMessageOrigin, UmpQueueId},
initializer as parachains_initializer, origin as parachains_origin, paras as parachains_paras,
paras_inherent as parachains_paras_inherent, reward_points as parachains_reward_points,
runtime_api_impl::v7 as parachains_runtime_api_impl,
runtime_api_impl::{
v7 as parachains_runtime_api_impl, vstaging as parachains_staging_runtime_api_impl,
},
scheduler as parachains_scheduler, session_info as parachains_session_info,
shared as parachains_shared,
};
Expand Down Expand Up @@ -1695,7 +1697,7 @@ sp_api::impl_runtime_apis! {
}
}

#[api_version(7)]
#[api_version(8)]
impl primitives::runtime_api::ParachainHost<Block, Hash, BlockNumber> for Runtime {
fn validators() -> Vec<ValidatorId> {
parachains_runtime_api_impl::validators::<Runtime>()
Expand Down Expand Up @@ -1838,6 +1840,10 @@ sp_api::impl_runtime_apis! {
fn async_backing_params() -> primitives::AsyncBackingParams {
parachains_runtime_api_impl::async_backing_params::<Runtime>()
}

fn disabled_validators() -> Vec<ValidatorIndex> {
parachains_staging_runtime_api_impl::disabled_validators::<Runtime>()
}
}

impl beefy_primitives::BeefyApi<Block, BeefyId> for Runtime {
Expand Down

0 comments on commit 7aace06

Please sign in to comment.