mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 15:07:59 +00:00
add NodeFeatures field to HostConfiguration and runtime API (#2177)
Adds a `NodeFeatures` bitfield value to the runtime `HostConfiguration`, with the purpose of coordinating the enabling of node-side features, such as: https://github.com/paritytech/polkadot-sdk/issues/628 and https://github.com/paritytech/polkadot-sdk/issues/598. These are features that require all validators enable them at the same time, assuming all/most nodes have upgraded their node versions. This PR doesn't add any feature yet. These are coming in future PRs. Also adds a runtime API for querying the state of the client features and an extrinsic for setting/unsetting a feature by its index in the bitfield. Note: originally part of: https://github.com/paritytech/polkadot-sdk/pull/1644, but posted as standalone to be reused by other PRs until the initial PR is merged
This commit is contained in:
@@ -20,7 +20,7 @@ use schnellru::{ByLength, LruMap};
|
||||
use sp_consensus_babe::Epoch;
|
||||
|
||||
use polkadot_primitives::{
|
||||
async_backing, slashing, AuthorityDiscoveryId, BlockNumber, CandidateCommitments,
|
||||
async_backing, slashing, vstaging, AuthorityDiscoveryId, BlockNumber, CandidateCommitments,
|
||||
CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState,
|
||||
ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage,
|
||||
InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement,
|
||||
@@ -67,6 +67,7 @@ pub(crate) struct RequestResultCache {
|
||||
disabled_validators: LruMap<Hash, Vec<ValidatorIndex>>,
|
||||
para_backing_state: LruMap<(Hash, ParaId), Option<async_backing::BackingState>>,
|
||||
async_backing_params: LruMap<Hash, async_backing::AsyncBackingParams>,
|
||||
node_features: LruMap<SessionIndex, vstaging::NodeFeatures>,
|
||||
}
|
||||
|
||||
impl Default for RequestResultCache {
|
||||
@@ -100,6 +101,7 @@ impl Default for RequestResultCache {
|
||||
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)),
|
||||
node_features: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,6 +448,21 @@ impl RequestResultCache {
|
||||
self.minimum_backing_votes.insert(session_index, minimum_backing_votes);
|
||||
}
|
||||
|
||||
pub(crate) fn node_features(
|
||||
&mut self,
|
||||
session_index: SessionIndex,
|
||||
) -> Option<&vstaging::NodeFeatures> {
|
||||
self.node_features.get(&session_index).map(|f| &*f)
|
||||
}
|
||||
|
||||
pub(crate) fn cache_node_features(
|
||||
&mut self,
|
||||
session_index: SessionIndex,
|
||||
features: vstaging::NodeFeatures,
|
||||
) {
|
||||
self.node_features.insert(session_index, features);
|
||||
}
|
||||
|
||||
pub(crate) fn disabled_validators(
|
||||
&mut self,
|
||||
relay_parent: &Hash,
|
||||
@@ -540,4 +557,5 @@ pub(crate) enum RequestResult {
|
||||
DisabledValidators(Hash, Vec<ValidatorIndex>),
|
||||
ParaBackingState(Hash, ParaId, Option<async_backing::BackingState>),
|
||||
AsyncBackingParams(Hash, async_backing::AsyncBackingParams),
|
||||
NodeFeatures(SessionIndex, vstaging::NodeFeatures),
|
||||
}
|
||||
|
||||
@@ -173,6 +173,8 @@ where
|
||||
.cache_para_backing_state((relay_parent, para_id), constraints),
|
||||
AsyncBackingParams(relay_parent, params) =>
|
||||
self.requests_cache.cache_async_backing_params(relay_parent, params),
|
||||
NodeFeatures(session_index, params) =>
|
||||
self.requests_cache.cache_node_features(session_index, params),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +315,15 @@ where
|
||||
Some(Request::MinimumBackingVotes(index, sender))
|
||||
}
|
||||
},
|
||||
Request::NodeFeatures(index, sender) => {
|
||||
if let Some(value) = self.requests_cache.node_features(index) {
|
||||
self.metrics.on_cached_request();
|
||||
let _ = sender.send(Ok(value.clone()));
|
||||
None
|
||||
} else {
|
||||
Some(Request::NodeFeatures(index, sender))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,6 +419,9 @@ where
|
||||
|
||||
macro_rules! query {
|
||||
($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:expr, $sender:expr) => {{
|
||||
query!($req_variant, $api_name($($param),*), ver = $version, $sender, result = ( relay_parent $(, $param )* ) )
|
||||
}};
|
||||
($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:expr, $sender:expr, result = ( $($results:expr),* ) ) => {{
|
||||
let sender = $sender;
|
||||
let version: u32 = $version; // enforce type for the version expression
|
||||
let runtime_version = client.api_version_parachain_host(relay_parent).await
|
||||
@@ -441,7 +455,7 @@ where
|
||||
metrics.on_request(res.is_ok());
|
||||
let _ = sender.send(res.clone());
|
||||
|
||||
res.ok().map(|res| RequestResult::$req_variant(relay_parent, $( $param, )* res))
|
||||
res.ok().map(|res| RequestResult::$req_variant($( $results, )* res))
|
||||
}}
|
||||
}
|
||||
|
||||
@@ -591,5 +605,12 @@ where
|
||||
sender
|
||||
)
|
||||
},
|
||||
Request::NodeFeatures(index, sender) => query!(
|
||||
NodeFeatures,
|
||||
node_features(),
|
||||
ver = Request::NODE_FEATURES_RUNTIME_REQUIREMENT,
|
||||
sender,
|
||||
result = (index)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ use polkadot_node_primitives::{BabeAllowedSlots, BabeEpoch, BabeEpochConfigurati
|
||||
use polkadot_node_subsystem::SpawnGlue;
|
||||
use polkadot_node_subsystem_test_helpers::make_subsystem_context;
|
||||
use polkadot_primitives::{
|
||||
async_backing, slashing, AuthorityDiscoveryId, BlockNumber, CandidateCommitments,
|
||||
CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState,
|
||||
ExecutorParams, GroupRotationInfo, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage,
|
||||
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes,
|
||||
SessionIndex, SessionInfo, Slot, ValidationCode, ValidationCodeHash, ValidatorId,
|
||||
ValidatorIndex, ValidatorSignature,
|
||||
async_backing, slashing, vstaging::NodeFeatures, AuthorityDiscoveryId, BlockNumber,
|
||||
CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState,
|
||||
DisputeState, ExecutorParams, GroupRotationInfo, Id as ParaId, InboundDownwardMessage,
|
||||
InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement,
|
||||
ScrapedOnChainVotes, SessionIndex, SessionInfo, Slot, ValidationCode, ValidationCodeHash,
|
||||
ValidatorId, ValidatorIndex, ValidatorSignature,
|
||||
};
|
||||
use sp_api::ApiError;
|
||||
use sp_core::testing::TaskExecutor;
|
||||
@@ -269,6 +269,10 @@ impl RuntimeApiSubsystemClient for MockSubsystemClient {
|
||||
todo!("Not required for tests")
|
||||
}
|
||||
|
||||
async fn node_features(&self, _: Hash) -> Result<NodeFeatures, ApiError> {
|
||||
todo!("Not required for tests")
|
||||
}
|
||||
|
||||
async fn disabled_validators(&self, _: Hash) -> Result<Vec<ValidatorIndex>, ApiError> {
|
||||
todo!("Not required for tests")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user