From 800d8e5a8bc93288abf3a307b9889fdde5a60ef8 Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Thu, 10 Aug 2023 11:55:32 +0300 Subject: [PATCH 1/7] Add `disabled_validators` in staging runtime api --- polkadot/node/core/runtime-api/src/cache.rs | 18 ++++++++++++++++++ polkadot/node/core/runtime-api/src/lib.rs | 10 ++++++++++ polkadot/node/subsystem-types/src/messages.rs | 6 ++++++ .../node/subsystem-types/src/runtime_client.rs | 7 +++++++ polkadot/node/subsystem-util/src/lib.rs | 1 + polkadot/primitives/src/runtime_api.rs | 6 ++++++ .../src/runtime_api_impl/vstaging.rs | 11 ++++++++++- polkadot/runtime/rococo/src/lib.rs | 9 ++++++++- 8 files changed, 66 insertions(+), 2 deletions(-) diff --git a/polkadot/node/core/runtime-api/src/cache.rs b/polkadot/node/core/runtime-api/src/cache.rs index cd22f37ddee4..896ef3f8e0d8 100644 --- a/polkadot/node/core/runtime-api/src/cache.rs +++ b/polkadot/node/core/runtime-api/src/cache.rs @@ -65,6 +65,7 @@ pub(crate) struct RequestResultCache { LruMap>, key_ownership_proof: LruMap<(Hash, ValidatorId), Option>, + disabled_validators: LruMap>, staging_para_backing_state: LruMap<(Hash, ParaId), Option>, staging_async_backing_params: LruMap, @@ -97,6 +98,7 @@ impl Default for RequestResultCache { disputes: 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)), + disabled_validators: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)), staging_para_backing_state: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)), staging_async_backing_params: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)), @@ -434,6 +436,21 @@ impl RequestResultCache { None } + pub(crate) fn disabled_validators( + &mut self, + relay_parent: &Hash, + ) -> Option<&Vec> { + self.disabled_validators.get(relay_parent).map(|v| &*v) + } + + pub(crate) fn cache_disabled_validators( + &mut self, + relay_parent: Hash, + disabled_validators: Vec, + ) { + self.disabled_validators.insert(relay_parent, disabled_validators); + } + pub(crate) fn staging_para_backing_state( &mut self, key: (Hash, ParaId), @@ -509,6 +526,7 @@ pub(crate) enum RequestResult { vstaging::slashing::OpaqueKeyOwnershipProof, Option<()>, ), + DisabledValidators(Hash, Vec), StagingParaBackingState(Hash, ParaId, Option), StagingAsyncBackingParams(Hash, vstaging::AsyncBackingParams), diff --git a/polkadot/node/core/runtime-api/src/lib.rs b/polkadot/node/core/runtime-api/src/lib.rs index 78531d41272b..04f5bb3fd706 100644 --- a/polkadot/node/core/runtime-api/src/lib.rs +++ b/polkadot/node/core/runtime-api/src/lib.rs @@ -163,6 +163,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), StagingParaBackingState(relay_parent, para_id, constraints) => self .requests_cache @@ -294,6 +296,8 @@ where Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) }, ), + Request::DisabledValidators(sender) => query!(disabled_validators(), sender) + .map(|sender| Request::DisabledValidators(sender)), Request::StagingParaBackingState(para, sender) => query!(staging_para_backing_state(para), sender) @@ -551,6 +555,12 @@ where ver = Request::SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT, sender ), + Request::DisabledValidators(sender) => query!( + DisabledValidators, + disabled_validators(), + ver = Request::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT, + sender + ), Request::StagingParaBackingState(para, sender) => { query!( diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index 8adc39eed56d..0d85034103d0 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -691,6 +691,9 @@ pub enum RuntimeApiRequest { slashing::OpaqueKeyOwnershipProof, RuntimeApiSender>, ), + /// Returns all disabled validators at a given block height. + /// `V6` + DisabledValidators(RuntimeApiSender>), /// Get the backing state of the given para. /// This is a staging API that will not be available on production runtimes. @@ -719,6 +722,9 @@ impl RuntimeApiRequest { /// `SubmitReportDisputeLost` pub const SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT: u32 = 5; + /// `DisabledValidators` + pub const DISABLED_VALIDATORS_RUNTIME_REQUIREMENT: u32 = 6; + /// Minimum version for backing state, required for async backing. /// /// 99 for now, should be adjusted to VSTAGING/actual runtime version once released. diff --git a/polkadot/node/subsystem-types/src/runtime_client.rs b/polkadot/node/subsystem-types/src/runtime_client.rs index 312cc4eec6ce..77ef358b9b0e 100644 --- a/polkadot/node/subsystem-types/src/runtime_client.rs +++ b/polkadot/node/subsystem-types/src/runtime_client.rs @@ -232,6 +232,9 @@ pub trait RuntimeApiSubsystemClient { session_index: SessionIndex, ) -> Result, ApiError>; + /// Gets the disabled validators at a specific block height + async fn disabled_validators(&self, at: Hash) -> Result, ApiError>; + // === Asynchronous backing API === /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent. @@ -473,6 +476,10 @@ where runtime_api.submit_report_dispute_lost(at, dispute_proof, key_ownership_proof) } + async fn disabled_validators(&self, at: Hash) -> Result, ApiError> { + self.client.runtime_api().disabled_validators(at) + } + async fn staging_para_backing_state( &self, at: Hash, diff --git a/polkadot/node/subsystem-util/src/lib.rs b/polkadot/node/subsystem-util/src/lib.rs index daee4a8350e5..71d2cd335850 100644 --- a/polkadot/node/subsystem-util/src/lib.rs +++ b/polkadot/node/subsystem-util/src/lib.rs @@ -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; KeyOwnershipProof; fn request_submit_report_dispute_lost(dp: slashing::DisputeProof, okop: slashing::OpaqueKeyOwnershipProof) -> Option<()>; SubmitReportDisputeLost; + fn request_disabled_validators() -> Vec; DisabledValidators; fn request_staging_async_backing_params() -> vstaging_primitives::AsyncBackingParams; StagingAsyncBackingParams; } diff --git a/polkadot/primitives/src/runtime_api.rs b/polkadot/primitives/src/runtime_api.rs index 483256fe20f3..463bb789b1ed 100644 --- a/polkadot/primitives/src/runtime_api.rs +++ b/polkadot/primitives/src/runtime_api.rs @@ -240,6 +240,12 @@ sp_api::decl_runtime_apis! { key_ownership_proof: vstaging::slashing::OpaqueKeyOwnershipProof, ) -> Option<()>; + /* Staging APIs */ + + /// Returns a sorted Vec with the `ValidatorIndex` of all disabled validators. + #[api_version(6)] + fn disabled_validators() -> Vec; + /***** Asynchronous backing *****/ /// Returns the state of parachain backing for a given para. diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs index 5406428377d0..af1f3b17b7c5 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -23,7 +23,7 @@ use primitives::{ AsyncBackingParams, BackingState, CandidatePendingAvailability, Constraints, InboundHrmpLimitations, OutboundHrmpChannelLimitations, }, - Id as ParaId, + Id as ParaId, ValidatorIndex, }; use sp_std::prelude::*; @@ -118,3 +118,12 @@ pub fn backing_state( pub fn async_backing_params() -> AsyncBackingParams { >::config().async_backing_params } + +/// Implementation for `DisabledValidators` +pub fn disabled_validators() -> Vec { + >::disabled_validators() + .iter() + .cloned() + .map(|v| ValidatorIndex(v)) + .collect() +} diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 6894bd7bbf44..940db21c66a8 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -46,7 +46,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::v5 as parachains_runtime_api_impl, + runtime_api_impl::{ + v5 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, }; @@ -1714,6 +1716,7 @@ sp_api::impl_runtime_apis! { } } + #[api_version(6)] impl primitives::runtime_api::ParachainHost for Runtime { fn validators() -> Vec { parachains_runtime_api_impl::validators::() @@ -1844,6 +1847,10 @@ sp_api::impl_runtime_apis! { key_ownership_proof, ) } + + fn disabled_validators() -> Vec { + parachains_staging_runtime_api_impl::disabled_validators::() + } } #[api_version(3)] From 936216d206821df7f9701c0181f99f8e646a10cc Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Mon, 4 Sep 2023 14:13:32 +0300 Subject: [PATCH 2/7] Cumulus changes --- .../relay-chain-minimal-node/src/blockchain_rpc_client.rs | 7 +++++++ .../client/relay-chain-rpc-interface/src/rpc_client.rs | 8 ++++++++ .../integration-tests/emulated/common/src/lib.rs | 1 + 3 files changed, 16 insertions(+) diff --git a/cumulus/client/relay-chain-minimal-node/src/blockchain_rpc_client.rs b/cumulus/client/relay-chain-minimal-node/src/blockchain_rpc_client.rs index fc4d803002cb..9e0ba05b2a83 100644 --- a/cumulus/client/relay-chain-minimal-node/src/blockchain_rpc_client.rs +++ b/cumulus/client/relay-chain-minimal-node/src/blockchain_rpc_client.rs @@ -338,6 +338,13 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient { .await?) } + async fn disabled_validators( + &self, + at: Hash, + ) -> Result, ApiError> { + Ok(self.rpc_client.parachain_host_disabled_validators(at).await?) + } + async fn staging_async_backing_params(&self, at: Hash) -> Result { Ok(self.rpc_client.parachain_host_staging_async_backing_params(at).await?) } diff --git a/cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs b/cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs index b079294b7842..b73b718e3e83 100644 --- a/cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs +++ b/cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs @@ -588,6 +588,14 @@ impl RelayChainRpcClient { .await } + pub async fn parachain_host_disabled_validators( + &self, + at: RelayHash, + ) -> Result, RelayChainError> { + self.call_remote_runtime_function("ParachainHost_disabled_validators", at, None::<()>) + .await + } + #[allow(missing_docs)] pub async fn parachain_host_staging_async_backing_params( &self, diff --git a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs index f6d589700360..f0f7aee1fb4f 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs @@ -19,6 +19,7 @@ pub use impls::{RococoWococoMessageHandler, WococoRococoMessageHandler}; pub use parachains_common::{AccountId, Balance}; pub use paste; use polkadot_parachain::primitives::HrmpChannelId; +use polkadot_primitives::runtime_api::runtime_decl_for_parachain_host::ParachainHostV6; pub use polkadot_runtime_parachains::inclusion::{AggregateMessageOrigin, UmpQueueId}; pub use sp_core::{sr25519, storage::Storage, Get}; use sp_tracing; From e4dee17aeea8ee66dad4b7f5ae7ad2a82b187da0 Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Mon, 4 Sep 2023 15:46:15 +0300 Subject: [PATCH 3/7] Fix compilation errors --- .../parachains/integration-tests/emulated/common/src/lib.rs | 1 + polkadot/runtime/rococo/src/lib.rs | 4 ++++ polkadot/runtime/westend/src/lib.rs | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs index 49751136f7ba..e5ec3c245778 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs @@ -24,6 +24,7 @@ use constants::{ bridge_hub_polkadot, bridge_hub_rococo, collectives, kusama, penpal, polkadot, rococo, westend, }; use impls::{RococoWococoMessageHandler, WococoRococoMessageHandler}; +use polkadot_primitives::runtime_api::runtime_decl_for_parachain_host::ParachainHostV6; // Substrate use frame_support::traits::OnInitialize; diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 8284d6e0d360..71ddf0985521 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1845,6 +1845,10 @@ sp_api::impl_runtime_apis! { ) } + fn minimum_backing_votes() -> u32 { + parachains_staging_runtime_api_impl::minimum_backing_votes::() + } + fn disabled_validators() -> Vec { parachains_staging_runtime_api_impl::disabled_validators::() } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 73aa4980151e..a368699fa1de 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1695,6 +1695,10 @@ sp_api::impl_runtime_apis! { fn minimum_backing_votes() -> u32 { parachains_staging_runtime_api_impl::minimum_backing_votes::() } + + fn disabled_validators() -> Vec { + parachains_staging_runtime_api_impl::disabled_validators::() + } } impl beefy_primitives::BeefyApi for Runtime { From 70dc6b62d8c98691ea5055702ebb334d510cc4d0 Mon Sep 17 00:00:00 2001 From: ordian Date: Wed, 27 Sep 2023 18:07:56 +0200 Subject: [PATCH 4/7] implement disabled_validators correctly --- .../subsystem-types/src/runtime_client.rs | 1 - .../src/runtime_api_impl/vstaging.rs | 34 ++++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/polkadot/node/subsystem-types/src/runtime_client.rs b/polkadot/node/subsystem-types/src/runtime_client.rs index 1c56bebb7060..f7adcf9862b5 100644 --- a/polkadot/node/subsystem-types/src/runtime_client.rs +++ b/polkadot/node/subsystem-types/src/runtime_client.rs @@ -240,7 +240,6 @@ pub trait RuntimeApiSubsystemClient { session_index: SessionIndex, ) -> Result; - // === v7: Asynchronous backing API === /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent. diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs index 5c9f2a8d6400..dba4fc7b3cc6 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -16,18 +16,28 @@ //! Put implementations of functions from staging APIs here. -use primitives::{ - ValidatorIndex, -}; -use sp_std::prelude::*; +use crate::shared; +use primitives::ValidatorIndex; +use sp_std::prelude::Vec; +use sp_std::collections::btree_map::BTreeMap; /// Implementation for `DisabledValidators` -pub fn disabled_validators() -> Vec { - // >::disabled_validators() - // .iter() - // .cloned() - // .map(|v| ValidatorIndex(v)) - // .collect() - // TODO - Vec::new() +pub fn disabled_validators() -> Vec +where + T: pallet_session::Config + shared::Config, +{ + let shuffled_indices = >::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::>(); + + // we might have disabled validators who are not parachain validators + >::disabled_validators() + .iter() + .filter_map(|v| reverse_index.get(v).cloned()) + .collect() } From bca3c83b34d88b403de471b878ebc8c1077de2df Mon Sep 17 00:00:00 2001 From: ordian Date: Wed, 27 Sep 2023 18:09:38 +0200 Subject: [PATCH 5/7] add a CAVEAT comment --- polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs index dba4fc7b3cc6..4214f25cee54 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -22,6 +22,8 @@ use sp_std::prelude::Vec; use sp_std::collections::btree_map::BTreeMap; /// 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() -> Vec where T: pallet_session::Config + shared::Config, From f717d0b74ac362a68cc251655ce6bdf39f76d51d Mon Sep 17 00:00:00 2001 From: ordian Date: Wed, 27 Sep 2023 18:13:25 +0200 Subject: [PATCH 6/7] cargo fmt --- polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs index 4214f25cee54..24a076f3a443 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -18,8 +18,7 @@ use crate::shared; use primitives::ValidatorIndex; -use sp_std::prelude::Vec; -use sp_std::collections::btree_map::BTreeMap; +use sp_std::{collections::btree_map::BTreeMap, prelude::Vec}; /// Implementation for `DisabledValidators` // CAVEAT: this should only be called on the node side From 2a5af8963d6f8a142644e98158de96ceac4822f9 Mon Sep 17 00:00:00 2001 From: ordian Date: Wed, 27 Sep 2023 18:32:39 +0200 Subject: [PATCH 7/7] Clarify docs --- polkadot/primitives/src/runtime_api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/primitives/src/runtime_api.rs b/polkadot/primitives/src/runtime_api.rs index ac5a3b054de2..5ec897c8cbb4 100644 --- a/polkadot/primitives/src/runtime_api.rs +++ b/polkadot/primitives/src/runtime_api.rs @@ -261,7 +261,7 @@ sp_api::decl_runtime_apis! { /***** Added in v8 *****/ - /// Returns a sorted Vec with the `ValidatorIndex` of all disabled validators. + /// Returns a list of all disabled validators at the given block. #[api_version(8)] fn disabled_validators() -> Vec; }