Disabled validators runtime API (#1257)

Exposes disabled validators list via a runtime API.

---------

Co-authored-by: ordian <noreply@reusable.software>
Co-authored-by: ordian <write@reusable.software>
This commit is contained in:
Tsvetomir Dimitrov
2023-10-12 16:01:07 +03:00
committed by GitHub
parent f0e6d2ad52
commit 7aace06b3d
13 changed files with 115 additions and 8 deletions
@@ -346,6 +346,13 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient {
Ok(self.rpc_client.parachain_host_minimum_backing_votes(at, session_index).await?) 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> { async fn async_backing_params(&self, at: Hash) -> Result<AsyncBackingParams, ApiError> {
Ok(self.rpc_client.parachain_host_async_backing_params(at).await?) Ok(self.rpc_client.parachain_host_async_backing_params(at).await?)
} }
@@ -597,6 +597,14 @@ impl RelayChainRpcClient {
.await .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)] #[allow(missing_docs)]
pub async fn parachain_host_async_backing_params( pub async fn parachain_host_async_backing_params(
&self, &self,
@@ -33,7 +33,7 @@ use xcm_emulator::{
}; };
decl_test_relay_chains! { decl_test_relay_chains! {
#[api_version(7)] #[api_version(8)]
pub struct Westend { pub struct Westend {
genesis = westend::genesis(), genesis = westend::genesis(),
on_init = (), on_init = (),
@@ -50,7 +50,7 @@ decl_test_relay_chains! {
AssetRate: westend_runtime::AssetRate, AssetRate: westend_runtime::AssetRate,
} }
}, },
#[api_version(7)] #[api_version(8)]
pub struct Rococo { pub struct Rococo {
genesis = rococo::genesis(), genesis = rococo::genesis(),
on_init = (), on_init = (),
@@ -65,7 +65,7 @@ decl_test_relay_chains! {
Balances: rococo_runtime::Balances, Balances: rococo_runtime::Balances,
} }
}, },
#[api_version(7)] #[api_version(8)]
pub struct Wococo { pub struct Wococo {
genesis = rococo::genesis(), genesis = rococo::genesis(),
on_init = (), on_init = (),
@@ -64,6 +64,7 @@ pub(crate) struct RequestResultCache {
unapplied_slashes: LruMap<Hash, Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>>, unapplied_slashes: LruMap<Hash, Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>>,
key_ownership_proof: LruMap<(Hash, ValidatorId), Option<slashing::OpaqueKeyOwnershipProof>>, key_ownership_proof: LruMap<(Hash, ValidatorId), Option<slashing::OpaqueKeyOwnershipProof>>,
minimum_backing_votes: LruMap<SessionIndex, u32>, minimum_backing_votes: LruMap<SessionIndex, u32>,
disabled_validators: LruMap<Hash, Vec<ValidatorIndex>>,
para_backing_state: LruMap<(Hash, ParaId), Option<async_backing::BackingState>>, para_backing_state: LruMap<(Hash, ParaId), Option<async_backing::BackingState>>,
async_backing_params: LruMap<Hash, async_backing::AsyncBackingParams>, async_backing_params: LruMap<Hash, async_backing::AsyncBackingParams>,
} }
@@ -96,6 +97,7 @@ impl Default for RequestResultCache {
unapplied_slashes: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)), unapplied_slashes: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
key_ownership_proof: 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)), 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)), para_backing_state: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
async_backing_params: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)), async_backing_params: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
} }
@@ -444,6 +446,21 @@ impl RequestResultCache {
self.minimum_backing_votes.insert(session_index, minimum_backing_votes); 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( pub(crate) fn para_backing_state(
&mut self, &mut self,
key: (Hash, ParaId), key: (Hash, ParaId),
@@ -520,6 +537,7 @@ pub(crate) enum RequestResult {
slashing::OpaqueKeyOwnershipProof, slashing::OpaqueKeyOwnershipProof,
Option<()>, Option<()>,
), ),
DisabledValidators(Hash, Vec<ValidatorIndex>),
ParaBackingState(Hash, ParaId, Option<async_backing::BackingState>), ParaBackingState(Hash, ParaId, Option<async_backing::BackingState>),
AsyncBackingParams(Hash, async_backing::AsyncBackingParams), AsyncBackingParams(Hash, async_backing::AsyncBackingParams),
} }
+10
View File
@@ -166,6 +166,8 @@ where
.requests_cache .requests_cache
.cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof), .cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof),
SubmitReportDisputeLost(_, _, _, _) => {}, SubmitReportDisputeLost(_, _, _, _) => {},
DisabledValidators(relay_parent, disabled_validators) =>
self.requests_cache.cache_disabled_validators(relay_parent, disabled_validators),
ParaBackingState(relay_parent, para_id, constraints) => self ParaBackingState(relay_parent, para_id, constraints) => self
.requests_cache .requests_cache
.cache_para_backing_state((relay_parent, para_id), constraints), .cache_para_backing_state((relay_parent, para_id), constraints),
@@ -296,6 +298,8 @@ where
Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) 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) Request::ParaBackingState(para, sender) => query!(para_backing_state(para), sender)
.map(|sender| Request::ParaBackingState(para, sender)), .map(|sender| Request::ParaBackingState(para, sender)),
Request::AsyncBackingParams(sender) => query!(async_backing_params(), sender) Request::AsyncBackingParams(sender) => query!(async_backing_params(), sender)
@@ -565,6 +569,12 @@ where
ver = Request::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT, ver = Request::MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT,
sender sender
), ),
Request::DisabledValidators(sender) => query!(
DisabledValidators,
disabled_validators(),
ver = Request::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT,
sender
),
Request::ParaBackingState(para, sender) => { Request::ParaBackingState(para, sender) => {
query!( query!(
ParaBackingState, ParaBackingState,
@@ -268,6 +268,10 @@ impl RuntimeApiSubsystemClient for MockSubsystemClient {
async fn minimum_backing_votes(&self, _: Hash, _: SessionIndex) -> Result<u32, ApiError> { async fn minimum_backing_votes(&self, _: Hash, _: SessionIndex) -> Result<u32, ApiError> {
todo!("Not required for tests") todo!("Not required for tests")
} }
async fn disabled_validators(&self, _: Hash) -> Result<Vec<ValidatorIndex>, ApiError> {
todo!("Not required for tests")
}
} }
#[test] #[test]
@@ -695,6 +695,8 @@ pub enum RuntimeApiRequest {
), ),
/// Get the minimum required backing votes. /// Get the minimum required backing votes.
MinimumBackingVotes(SessionIndex, RuntimeApiSender<u32>), 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. /// Get the backing state of the given para.
ParaBackingState(ParaId, RuntimeApiSender<Option<async_backing::BackingState>>), ParaBackingState(ParaId, RuntimeApiSender<Option<async_backing::BackingState>>),
/// Get candidate's acceptance limitations for asynchronous backing for a relay parent. /// Get candidate's acceptance limitations for asynchronous backing for a relay parent.
@@ -726,6 +728,9 @@ impl RuntimeApiRequest {
/// Minimum version to enable asynchronous backing: `AsyncBackingParams` and `ParaBackingState`. /// Minimum version to enable asynchronous backing: `AsyncBackingParams` and `ParaBackingState`.
pub const ASYNC_BACKING_STATE_RUNTIME_REQUIREMENT: u32 = 7; 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. /// A message to the Runtime API subsystem.
@@ -255,6 +255,10 @@ pub trait RuntimeApiSubsystemClient {
at: Hash, at: Hash,
para_id: Id, para_id: Id,
) -> Result<Option<async_backing::BackingState>, ApiError>; ) -> 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. /// Default implementation of [`RuntimeApiSubsystemClient`] using the client.
@@ -497,11 +501,14 @@ where
self.client.runtime_api().para_backing_state(at, para_id) 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( async fn async_backing_params(
&self, &self,
at: Hash, at: Hash,
) -> Result<async_backing::AsyncBackingParams, ApiError> { ) -> Result<async_backing::AsyncBackingParams, ApiError> {
self.client.runtime_api().async_backing_params(at) 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
View File
@@ -226,6 +226,7 @@ specialize_requests! {
fn request_unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>; UnappliedSlashes; fn request_unapplied_slashes() -> Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>; UnappliedSlashes;
fn request_key_ownership_proof(validator_id: ValidatorId) -> Option<slashing::OpaqueKeyOwnershipProof>; KeyOwnershipProof; 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_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; fn request_async_backing_params() -> AsyncBackingParams; AsyncBackingParams;
} }
+7
View File
@@ -248,6 +248,7 @@ sp_api::decl_runtime_apis! {
#[api_version(6)] #[api_version(6)]
fn minimum_backing_votes() -> u32; fn minimum_backing_votes() -> u32;
/***** Added in v7: Asynchronous backing *****/ /***** Added in v7: Asynchronous backing *****/
/// Returns the state of parachain backing for a given para. /// Returns the state of parachain backing for a given para.
@@ -257,5 +258,11 @@ sp_api::decl_runtime_apis! {
/// Returns candidate's acceptance limitations for asynchronous backing for a relay parent. /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent.
#[api_version(7)] #[api_version(7)]
fn async_backing_params() -> AsyncBackingParams; 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>;
} }
} }
@@ -15,3 +15,30 @@
// 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::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()
}
+9 -2
View File
@@ -49,7 +49,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, 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, scheduler as parachains_scheduler, session_info as parachains_session_info,
shared as parachains_shared, shared as parachains_shared,
}; };
@@ -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 { 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>()
@@ -1728,6 +1730,11 @@ sp_api::impl_runtime_apis! {
fn async_backing_params() -> primitives::AsyncBackingParams { fn async_backing_params() -> primitives::AsyncBackingParams {
parachains_runtime_api_impl::async_backing_params::<Runtime>() parachains_runtime_api_impl::async_backing_params::<Runtime>()
} }
fn disabled_validators() -> Vec<ValidatorIndex> {
parachains_staging_runtime_api_impl::disabled_validators::<Runtime>()
}
} }
#[api_version(3)] #[api_version(3)]
+8 -2
View File
@@ -70,7 +70,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::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, scheduler as parachains_scheduler, session_info as parachains_session_info,
shared as parachains_shared, shared as parachains_shared,
}; };
@@ -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 { 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>()
@@ -1838,6 +1840,10 @@ sp_api::impl_runtime_apis! {
fn async_backing_params() -> primitives::AsyncBackingParams { fn async_backing_params() -> primitives::AsyncBackingParams {
parachains_runtime_api_impl::async_backing_params::<Runtime>() 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 { impl beefy_primitives::BeefyApi<Block, BeefyId> for Runtime {