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:
Alin Dima
2023-11-14 20:48:32 +02:00
committed by GitHub
parent 31c38cea3d
commit fc12f435e3
25 changed files with 709 additions and 131 deletions
Generated
+1
View File
@@ -1527,6 +1527,7 @@ checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [ dependencies = [
"funty", "funty",
"radium", "radium",
"serde",
"tap", "tap",
"wyz", "wyz",
] ]
@@ -24,6 +24,7 @@ use polkadot_overseer::RuntimeApiSubsystemClient;
use polkadot_primitives::{ use polkadot_primitives::{
async_backing::{AsyncBackingParams, BackingState}, async_backing::{AsyncBackingParams, BackingState},
slashing, slashing,
vstaging::NodeFeatures,
}; };
use sc_authority_discovery::{AuthorityDiscovery, Error as AuthorityDiscoveryError}; use sc_authority_discovery::{AuthorityDiscovery, Error as AuthorityDiscoveryError};
use sp_api::{ApiError, RuntimeApiInfo}; use sp_api::{ApiError, RuntimeApiInfo};
@@ -364,6 +365,10 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient {
) -> Result<Option<BackingState>, ApiError> { ) -> Result<Option<BackingState>, ApiError> {
Ok(self.rpc_client.parachain_host_para_backing_state(at, para_id).await?) Ok(self.rpc_client.parachain_host_para_backing_state(at, para_id).await?)
} }
async fn node_features(&self, at: Hash) -> Result<NodeFeatures, ApiError> {
Ok(self.rpc_client.parachain_host_node_features(at).await?)
}
} }
#[async_trait::async_trait] #[async_trait::async_trait]
@@ -31,7 +31,9 @@ use parity_scale_codec::{Decode, Encode};
use cumulus_primitives_core::{ use cumulus_primitives_core::{
relay_chain::{ relay_chain::{
async_backing::{AsyncBackingParams, BackingState}, async_backing::{AsyncBackingParams, BackingState},
slashing, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash, slashing,
vstaging::NodeFeatures,
BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash,
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo,
Hash as RelayHash, Header as RelayHeader, InboundHrmpMessage, OccupiedCoreAssumption, Hash as RelayHash, Header as RelayHeader, InboundHrmpMessage, OccupiedCoreAssumption,
PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode,
@@ -597,6 +599,14 @@ impl RelayChainRpcClient {
.await .await
} }
pub async fn parachain_host_node_features(
&self,
at: RelayHash,
) -> Result<NodeFeatures, RelayChainError> {
self.call_remote_runtime_function("ParachainHost_node_features", at, None::<()>)
.await
}
pub async fn parachain_host_disabled_validators( pub async fn parachain_host_disabled_validators(
&self, &self,
at: RelayHash, at: RelayHash,
@@ -24,7 +24,7 @@ use emulated_integration_tests_common::{
// Rococo declaration // Rococo declaration
decl_test_relay_chains! { decl_test_relay_chains! {
#[api_version(8)] #[api_version(9)]
pub struct Rococo { pub struct Rococo {
genesis = genesis::genesis(), genesis = genesis::genesis(),
on_init = (), on_init = (),
@@ -24,7 +24,7 @@ use emulated_integration_tests_common::{
// Westend declaration // Westend declaration
decl_test_relay_chains! { decl_test_relay_chains! {
#[api_version(8)] #[api_version(9)]
pub struct Westend { pub struct Westend {
genesis = genesis::genesis(), genesis = genesis::genesis(),
on_init = (), on_init = (),
+19 -1
View File
@@ -20,7 +20,7 @@ use schnellru::{ByLength, LruMap};
use sp_consensus_babe::Epoch; use sp_consensus_babe::Epoch;
use polkadot_primitives::{ use polkadot_primitives::{
async_backing, slashing, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, async_backing, slashing, vstaging, AuthorityDiscoveryId, BlockNumber, CandidateCommitments,
CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState,
ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage,
InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement,
@@ -67,6 +67,7 @@ pub(crate) struct RequestResultCache {
disabled_validators: LruMap<Hash, Vec<ValidatorIndex>>, 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>,
node_features: LruMap<SessionIndex, vstaging::NodeFeatures>,
} }
impl Default for RequestResultCache { impl Default for RequestResultCache {
@@ -100,6 +101,7 @@ impl Default for RequestResultCache {
disabled_validators: 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)),
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); 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( pub(crate) fn disabled_validators(
&mut self, &mut self,
relay_parent: &Hash, relay_parent: &Hash,
@@ -540,4 +557,5 @@ pub(crate) enum RequestResult {
DisabledValidators(Hash, Vec<ValidatorIndex>), 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),
NodeFeatures(SessionIndex, vstaging::NodeFeatures),
} }
+22 -1
View File
@@ -173,6 +173,8 @@ where
.cache_para_backing_state((relay_parent, para_id), constraints), .cache_para_backing_state((relay_parent, para_id), constraints),
AsyncBackingParams(relay_parent, params) => AsyncBackingParams(relay_parent, params) =>
self.requests_cache.cache_async_backing_params(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)) 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 { macro_rules! query {
($req_variant:ident, $api_name:ident ($($param:expr),*), ver = $version:expr, $sender:expr) => {{ ($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 sender = $sender;
let version: u32 = $version; // enforce type for the version expression let version: u32 = $version; // enforce type for the version expression
let runtime_version = client.api_version_parachain_host(relay_parent).await let runtime_version = client.api_version_parachain_host(relay_parent).await
@@ -441,7 +455,7 @@ where
metrics.on_request(res.is_ok()); metrics.on_request(res.is_ok());
let _ = sender.send(res.clone()); 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 sender
) )
}, },
Request::NodeFeatures(index, sender) => query!(
NodeFeatures,
node_features(),
ver = Request::NODE_FEATURES_RUNTIME_REQUIREMENT,
sender,
result = (index)
),
} }
} }
+10 -6
View File
@@ -20,12 +20,12 @@ use polkadot_node_primitives::{BabeAllowedSlots, BabeEpoch, BabeEpochConfigurati
use polkadot_node_subsystem::SpawnGlue; use polkadot_node_subsystem::SpawnGlue;
use polkadot_node_subsystem_test_helpers::make_subsystem_context; use polkadot_node_subsystem_test_helpers::make_subsystem_context;
use polkadot_primitives::{ use polkadot_primitives::{
async_backing, slashing, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, async_backing, slashing, vstaging::NodeFeatures, AuthorityDiscoveryId, BlockNumber,
CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState,
ExecutorParams, GroupRotationInfo, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, DisputeState, ExecutorParams, GroupRotationInfo, Id as ParaId, InboundDownwardMessage,
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement,
SessionIndex, SessionInfo, Slot, ValidationCode, ValidationCodeHash, ValidatorId, ScrapedOnChainVotes, SessionIndex, SessionInfo, Slot, ValidationCode, ValidationCodeHash,
ValidatorIndex, ValidatorSignature, ValidatorId, ValidatorIndex, ValidatorSignature,
}; };
use sp_api::ApiError; use sp_api::ApiError;
use sp_core::testing::TaskExecutor; use sp_core::testing::TaskExecutor;
@@ -269,6 +269,10 @@ impl RuntimeApiSubsystemClient for MockSubsystemClient {
todo!("Not required for tests") 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> { async fn disabled_validators(&self, _: Hash) -> Result<Vec<ValidatorIndex>, ApiError> {
todo!("Not required for tests") todo!("Not required for tests")
} }
+11 -6
View File
@@ -42,12 +42,12 @@ use polkadot_node_primitives::{
ValidationResult, ValidationResult,
}; };
use polkadot_primitives::{ use polkadot_primitives::{
async_backing, slashing, AuthorityDiscoveryId, BackedCandidate, BlockNumber, CandidateEvent, async_backing, slashing, vstaging::NodeFeatures, AuthorityDiscoveryId, BackedCandidate,
CandidateHash, CandidateIndex, CandidateReceipt, CollatorId, CommittedCandidateReceipt, BlockNumber, CandidateEvent, CandidateHash, CandidateIndex, CandidateReceipt, CollatorId,
CoreState, DisputeState, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupIndex,
Header as BlockHeader, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, GroupRotationInfo, Hash, Header as BlockHeader, Id as ParaId, InboundDownwardMessage,
MultiDisputeStatementSet, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, InboundHrmpMessage, MultiDisputeStatementSet, OccupiedCoreAssumption, PersistedValidationData,
PvfExecTimeoutKind, SessionIndex, SessionInfo, SignedAvailabilityBitfield, PvfCheckStatement, PvfExecTimeoutKind, SessionIndex, SessionInfo, SignedAvailabilityBitfield,
SignedAvailabilityBitfields, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, SignedAvailabilityBitfields, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
ValidatorSignature, ValidatorSignature,
}; };
@@ -718,6 +718,8 @@ pub enum RuntimeApiRequest {
/// ///
/// If it's not supported by the Runtime, the async backing is said to be disabled. /// If it's not supported by the Runtime, the async backing is said to be disabled.
AsyncBackingParams(RuntimeApiSender<async_backing::AsyncBackingParams>), AsyncBackingParams(RuntimeApiSender<async_backing::AsyncBackingParams>),
/// Get the node features.
NodeFeatures(SessionIndex, RuntimeApiSender<NodeFeatures>),
} }
impl RuntimeApiRequest { impl RuntimeApiRequest {
@@ -746,6 +748,9 @@ impl RuntimeApiRequest {
/// `DisabledValidators` /// `DisabledValidators`
pub const DISABLED_VALIDATORS_RUNTIME_REQUIREMENT: u32 = 8; pub const DISABLED_VALIDATORS_RUNTIME_REQUIREMENT: u32 = 8;
/// `Node features`
pub const NODE_FEATURES_RUNTIME_REQUIREMENT: u32 = 9;
} }
/// A message to the Runtime API subsystem. /// A message to the Runtime API subsystem.
@@ -16,12 +16,12 @@
use async_trait::async_trait; use async_trait::async_trait;
use polkadot_primitives::{ use polkadot_primitives::{
async_backing, runtime_api::ParachainHost, slashing, Block, BlockNumber, CandidateCommitments, async_backing, runtime_api::ParachainHost, slashing, vstaging, Block, BlockNumber,
CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState,
ExecutorParams, GroupRotationInfo, Hash, Id, InboundDownwardMessage, InboundHrmpMessage, DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id, InboundDownwardMessage,
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement,
SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash,
ValidatorSignature, ValidatorId, ValidatorIndex, ValidatorSignature,
}; };
use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sc_transaction_pool_api::OffchainTransactionPoolFactory;
use sp_api::{ApiError, ApiExt, ProvideRuntimeApi}; use sp_api::{ApiError, ApiExt, ProvideRuntimeApi};
@@ -257,8 +257,14 @@ pub trait RuntimeApiSubsystemClient {
) -> Result<Option<async_backing::BackingState>, ApiError>; ) -> Result<Option<async_backing::BackingState>, ApiError>;
// === v8 === // === v8 ===
/// Gets the disabled validators at a specific block height /// Gets the disabled validators at a specific block height
async fn disabled_validators(&self, at: Hash) -> Result<Vec<ValidatorIndex>, ApiError>; async fn disabled_validators(&self, at: Hash) -> Result<Vec<ValidatorIndex>, ApiError>;
// === v9 ===
/// Get the node features.
async fn node_features(&self, at: Hash) -> Result<vstaging::NodeFeatures, ApiError>;
} }
/// Default implementation of [`RuntimeApiSubsystemClient`] using the client. /// Default implementation of [`RuntimeApiSubsystemClient`] using the client.
@@ -508,6 +514,10 @@ where
self.client.runtime_api().async_backing_params(at) self.client.runtime_api().async_backing_params(at)
} }
async fn node_features(&self, at: Hash) -> Result<vstaging::NodeFeatures, ApiError> {
self.client.runtime_api().node_features(at)
}
async fn disabled_validators(&self, at: Hash) -> Result<Vec<ValidatorIndex>, ApiError> { async fn disabled_validators(&self, at: Hash) -> Result<Vec<ValidatorIndex>, ApiError> {
self.client.runtime_api().disabled_validators(at) self.client.runtime_api().disabled_validators(at)
} }
@@ -30,8 +30,8 @@ use polkadot_node_subsystem::{
}; };
use polkadot_node_subsystem_types::UnpinHandle; use polkadot_node_subsystem_types::UnpinHandle;
use polkadot_primitives::{ use polkadot_primitives::{
slashing, AsyncBackingParams, CandidateEvent, CandidateHash, CoreState, EncodeAs, slashing, vstaging::NodeFeatures, AsyncBackingParams, CandidateEvent, CandidateHash, CoreState,
ExecutorParams, GroupIndex, GroupRotationInfo, Hash, IndexedVec, OccupiedCore, EncodeAs, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, IndexedVec, OccupiedCore,
ScrapedOnChainVotes, SessionIndex, SessionInfo, Signed, SigningContext, UncheckedSigned, ScrapedOnChainVotes, SessionIndex, SessionInfo, Signed, SigningContext, UncheckedSigned,
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, LEGACY_MIN_BACKING_VOTES, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, LEGACY_MIN_BACKING_VOTES,
}; };
@@ -507,3 +507,32 @@ pub async fn request_min_backing_votes(
min_backing_votes_res min_backing_votes_res
} }
} }
/// Request the node features enabled in the runtime.
/// Pass in the session index for caching purposes, as it should only change on session boundaries.
/// Prior to runtime API version 9, just return `None`.
pub async fn request_node_features(
parent: Hash,
session_index: SessionIndex,
sender: &mut impl overseer::SubsystemSender<RuntimeApiMessage>,
) -> Result<Option<NodeFeatures>> {
let res = recv_runtime(
request_from_runtime(parent, sender, |tx| {
RuntimeApiRequest::NodeFeatures(session_index, tx)
})
.await,
)
.await;
if let Err(Error::RuntimeRequest(RuntimeApiError::NotSupported { .. })) = res {
gum::trace!(
target: LOG_TARGET,
?parent,
"Querying the node features from the runtime is not supported by the current Runtime API",
);
Ok(None)
} else {
res.map(Some)
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ license.workspace = true
description = "Shared primitives used by Polkadot runtime" description = "Shared primitives used by Polkadot runtime"
[dependencies] [dependencies]
bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } bitvec = { version = "1.0.0", default-features = false, features = ["alloc", "serde"] }
hex-literal = "0.4.1" hex-literal = "0.4.1"
parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] } parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] }
scale-info = { version = "2.10.0", default-features = false, features = ["bit-vec", "derive", "serde"] } scale-info = { version = "2.10.0", default-features = false, features = ["bit-vec", "derive", "serde"] }
+11 -4
View File
@@ -114,10 +114,10 @@
//! separated from the stable primitives. //! separated from the stable primitives.
use crate::{ use crate::{
async_backing, slashing, AsyncBackingParams, BlockNumber, CandidateCommitments, CandidateEvent, async_backing, slashing, vstaging, AsyncBackingParams, BlockNumber, CandidateCommitments,
CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState,
GroupRotationInfo, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ExecutorParams, GroupRotationInfo, OccupiedCoreAssumption, PersistedValidationData,
ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex,
ValidatorSignature, ValidatorSignature,
}; };
use parity_scale_codec::{Decode, Encode}; use parity_scale_codec::{Decode, Encode};
@@ -264,5 +264,12 @@ sp_api::decl_runtime_apis! {
/// Returns a list of all disabled validators at the given block. /// Returns a list of all disabled validators at the given block.
#[api_version(8)] #[api_version(8)]
fn disabled_validators() -> Vec<ValidatorIndex>; fn disabled_validators() -> Vec<ValidatorIndex>;
/***** Added in v9 *****/
/// Get node features.
/// This is a staging method! Do not use on production runtimes!
#[api_version(9)]
fn node_features() -> vstaging::NodeFeatures;
} }
} }
+5
View File
@@ -17,3 +17,8 @@
//! Staging Primitives. //! Staging Primitives.
// Put any primitives used by staging APIs functions here // Put any primitives used by staging APIs functions here
use bitvec::vec::BitVec;
/// Bit indices in the `HostConfiguration.node_features` that correspond to different node features.
pub type NodeFeatures = BitVec<u8, bitvec::order::Lsb0>;
@@ -26,8 +26,8 @@ use polkadot_parachain_primitives::primitives::{
MAX_HORIZONTAL_MESSAGE_NUM, MAX_UPWARD_MESSAGE_NUM, MAX_HORIZONTAL_MESSAGE_NUM, MAX_UPWARD_MESSAGE_NUM,
}; };
use primitives::{ use primitives::{
AsyncBackingParams, Balance, ExecutorParamError, ExecutorParams, SessionIndex, vstaging::NodeFeatures, AsyncBackingParams, Balance, ExecutorParamError, ExecutorParams,
LEGACY_MIN_BACKING_VOTES, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MAX_POV_SIZE, SessionIndex, LEGACY_MIN_BACKING_VOTES, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MAX_POV_SIZE,
ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE,
}; };
use sp_runtime::{traits::Zero, Perbill}; use sp_runtime::{traits::Zero, Perbill};
@@ -261,6 +261,8 @@ pub struct HostConfiguration<BlockNumber> {
/// The minimum number of valid backing statements required to consider a parachain candidate /// The minimum number of valid backing statements required to consider a parachain candidate
/// backable. /// backable.
pub minimum_backing_votes: u32, pub minimum_backing_votes: u32,
/// Node features enablement.
pub node_features: NodeFeatures,
} }
impl<BlockNumber: Default + From<u32>> Default for HostConfiguration<BlockNumber> { impl<BlockNumber: Default + From<u32>> Default for HostConfiguration<BlockNumber> {
@@ -312,6 +314,7 @@ impl<BlockNumber: Default + From<u32>> Default for HostConfiguration<BlockNumber
on_demand_target_queue_utilization: Perbill::from_percent(25), on_demand_target_queue_utilization: Perbill::from_percent(25),
on_demand_ttl: 5u32.into(), on_demand_ttl: 5u32.into(),
minimum_backing_votes: LEGACY_MIN_BACKING_VOTES, minimum_backing_votes: LEGACY_MIN_BACKING_VOTES,
node_features: NodeFeatures::EMPTY,
} }
} }
} }
@@ -463,6 +466,7 @@ pub trait WeightInfo {
fn set_hrmp_open_request_ttl() -> Weight; fn set_hrmp_open_request_ttl() -> Weight;
fn set_config_with_executor_params() -> Weight; fn set_config_with_executor_params() -> Weight;
fn set_config_with_perbill() -> Weight; fn set_config_with_perbill() -> Weight;
fn set_node_feature() -> Weight;
} }
pub struct TestWeightInfo; pub struct TestWeightInfo;
@@ -488,6 +492,9 @@ impl WeightInfo for TestWeightInfo {
fn set_config_with_perbill() -> Weight { fn set_config_with_perbill() -> Weight {
Weight::MAX Weight::MAX
} }
fn set_node_feature() -> Weight {
Weight::MAX
}
} }
#[frame_support::pallet] #[frame_support::pallet]
@@ -496,18 +503,19 @@ pub mod pallet {
/// The current storage version. /// The current storage version.
/// ///
/// v0-v1: <https://github.com/paritytech/polkadot/pull/3575> /// v0-v1: <https://github.com/paritytech/polkadot/pull/3575>
/// v1-v2: <https://github.com/paritytech/polkadot/pull/4420> /// v1-v2: <https://github.com/paritytech/polkadot/pull/4420>
/// v2-v3: <https://github.com/paritytech/polkadot/pull/6091> /// v2-v3: <https://github.com/paritytech/polkadot/pull/6091>
/// v3-v4: <https://github.com/paritytech/polkadot/pull/6345> /// v3-v4: <https://github.com/paritytech/polkadot/pull/6345>
/// v4-v5: <https://github.com/paritytech/polkadot/pull/6937> /// v4-v5: <https://github.com/paritytech/polkadot/pull/6937>
/// + <https://github.com/paritytech/polkadot/pull/6961> /// + <https://github.com/paritytech/polkadot/pull/6961>
/// + <https://github.com/paritytech/polkadot/pull/6934> /// + <https://github.com/paritytech/polkadot/pull/6934>
/// v5-v6: <https://github.com/paritytech/polkadot/pull/6271> (remove UMP dispatch queue) /// v5-v6: <https://github.com/paritytech/polkadot/pull/6271> (remove UMP dispatch queue)
/// v6-v7: <https://github.com/paritytech/polkadot/pull/7396> /// v6-v7: <https://github.com/paritytech/polkadot/pull/7396>
/// v7-v8: <https://github.com/paritytech/polkadot/pull/6969> /// v7-v8: <https://github.com/paritytech/polkadot/pull/6969>
/// v8-v9: <https://github.com/paritytech/polkadot/pull/7577> /// v8-v9: <https://github.com/paritytech/polkadot/pull/7577>
const STORAGE_VERSION: StorageVersion = StorageVersion::new(9); /// v9-v10: <https://github.com/paritytech/polkadot-sdk/pull/2177>
const STORAGE_VERSION: StorageVersion = StorageVersion::new(10);
#[pallet::pallet] #[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)] #[pallet::storage_version(STORAGE_VERSION)]
@@ -1195,6 +1203,23 @@ pub mod pallet {
config.minimum_backing_votes = new; config.minimum_backing_votes = new;
}) })
} }
/// Set/Unset a node feature.
#[pallet::call_index(53)]
#[pallet::weight((
T::WeightInfo::set_node_feature(),
DispatchClass::Operational
))]
pub fn set_node_feature(origin: OriginFor<T>, index: u8, value: bool) -> DispatchResult {
ensure_root(origin)?;
Self::schedule_config_update(|config| {
let index = usize::from(index);
if config.node_features.len() <= index {
config.node_features.resize(index + 1, false);
}
config.node_features.set(index, value);
})
}
} }
#[pallet::hooks] #[pallet::hooks]
@@ -49,6 +49,8 @@ benchmarks! {
set_config_with_perbill {}: set_on_demand_fee_variability(RawOrigin::Root, Perbill::from_percent(100)) set_config_with_perbill {}: set_on_demand_fee_variability(RawOrigin::Root, Perbill::from_percent(100))
set_node_feature{}: set_node_feature(RawOrigin::Root, 255, true)
impl_benchmark_test_suite!( impl_benchmark_test_suite!(
Pallet, Pallet,
crate::mock::new_test_ext(Default::default()), crate::mock::new_test_ext(Default::default()),
@@ -16,6 +16,7 @@
//! A module that is responsible for migration of storage. //! A module that is responsible for migration of storage.
pub mod v10;
pub mod v6; pub mod v6;
pub mod v7; pub mod v7;
pub mod v8; pub mod v8;
@@ -0,0 +1,277 @@
// Copyright (C) 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/>.
//! A module that is responsible for migration of storage.
use crate::configuration::{self, Config, Pallet};
use frame_support::{pallet_prelude::*, traits::Defensive, weights::Weight};
use frame_system::pallet_prelude::BlockNumberFor;
use primitives::{vstaging::NodeFeatures, SessionIndex};
use sp_std::vec::Vec;
use frame_support::traits::OnRuntimeUpgrade;
use super::v9::V9HostConfiguration;
type V10HostConfiguration<BlockNumber> = configuration::HostConfiguration<BlockNumber>;
mod v9 {
use super::*;
#[frame_support::storage_alias]
pub(crate) type ActiveConfig<T: Config> =
StorageValue<Pallet<T>, V9HostConfiguration<BlockNumberFor<T>>, OptionQuery>;
#[frame_support::storage_alias]
pub(crate) type PendingConfigs<T: Config> = StorageValue<
Pallet<T>,
Vec<(SessionIndex, V9HostConfiguration<BlockNumberFor<T>>)>,
OptionQuery,
>;
}
mod v10 {
use super::*;
#[frame_support::storage_alias]
pub(crate) type ActiveConfig<T: Config> =
StorageValue<Pallet<T>, V10HostConfiguration<BlockNumberFor<T>>, OptionQuery>;
#[frame_support::storage_alias]
pub(crate) type PendingConfigs<T: Config> = StorageValue<
Pallet<T>,
Vec<(SessionIndex, V10HostConfiguration<BlockNumberFor<T>>)>,
OptionQuery,
>;
}
pub struct VersionUncheckedMigrateToV10<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for VersionUncheckedMigrateToV10<T> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
log::trace!(target: crate::configuration::LOG_TARGET, "Running pre_upgrade() for HostConfiguration MigrateToV10");
Ok(Vec::new())
}
fn on_runtime_upgrade() -> Weight {
migrate_to_v10::<T>()
}
#[cfg(feature = "try-runtime")]
fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
log::trace!(target: crate::configuration::LOG_TARGET, "Running post_upgrade() for HostConfiguration MigrateToV10");
ensure!(
Pallet::<T>::on_chain_storage_version() >= StorageVersion::new(10),
"Storage version should be >= 10 after the migration"
);
Ok(())
}
}
pub type MigrateToV10<T> = frame_support::migrations::VersionedMigration<
9,
10,
VersionUncheckedMigrateToV10<T>,
Pallet<T>,
<T as frame_system::Config>::DbWeight,
>;
// Unusual formatting is justified:
// - make it easier to verify that fields assign what they supposed to assign.
// - this code is transient and will be removed after all migrations are done.
// - this code is important enough to optimize for legibility sacrificing consistency.
#[rustfmt::skip]
fn translate<T: Config>(pre: V9HostConfiguration<BlockNumberFor<T>>) -> V10HostConfiguration<BlockNumberFor<T>> {
V10HostConfiguration {
max_code_size : pre.max_code_size,
max_head_data_size : pre.max_head_data_size,
max_upward_queue_count : pre.max_upward_queue_count,
max_upward_queue_size : pre.max_upward_queue_size,
max_upward_message_size : pre.max_upward_message_size,
max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate,
hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate,
validation_upgrade_cooldown : pre.validation_upgrade_cooldown,
validation_upgrade_delay : pre.validation_upgrade_delay,
max_pov_size : pre.max_pov_size,
max_downward_message_size : pre.max_downward_message_size,
hrmp_sender_deposit : pre.hrmp_sender_deposit,
hrmp_recipient_deposit : pre.hrmp_recipient_deposit,
hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity,
hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size,
hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels,
hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels,
hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size,
code_retention_period : pre.code_retention_period,
on_demand_cores : pre.on_demand_cores,
on_demand_retries : pre.on_demand_retries,
group_rotation_frequency : pre.group_rotation_frequency,
paras_availability_period : pre.paras_availability_period,
scheduling_lookahead : pre.scheduling_lookahead,
max_validators_per_core : pre.max_validators_per_core,
max_validators : pre.max_validators,
dispute_period : pre.dispute_period,
dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period,
no_show_slots : pre.no_show_slots,
n_delay_tranches : pre.n_delay_tranches,
zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width,
needed_approvals : pre.needed_approvals,
relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples,
pvf_voting_ttl : pre.pvf_voting_ttl,
minimum_validation_upgrade_delay : pre.minimum_validation_upgrade_delay,
async_backing_params : pre.async_backing_params,
executor_params : pre.executor_params,
on_demand_queue_max_size : pre.on_demand_queue_max_size,
on_demand_base_fee : pre.on_demand_base_fee,
on_demand_fee_variability : pre.on_demand_fee_variability,
on_demand_target_queue_utilization : pre.on_demand_target_queue_utilization,
on_demand_ttl : pre.on_demand_ttl,
minimum_backing_votes : pre.minimum_backing_votes,
node_features : NodeFeatures::EMPTY
}
}
fn migrate_to_v10<T: Config>() -> Weight {
let v9 = v9::ActiveConfig::<T>::get()
.defensive_proof("Could not decode old config")
.unwrap_or_default();
let v10 = translate::<T>(v9);
v10::ActiveConfig::<T>::set(Some(v10));
// Allowed to be empty.
let pending_v9 = v9::PendingConfigs::<T>::get().unwrap_or_default();
let mut pending_v10 = Vec::new();
for (session, v9) in pending_v9.into_iter() {
let v10 = translate::<T>(v9);
pending_v10.push((session, v10));
}
v10::PendingConfigs::<T>::set(Some(pending_v10.clone()));
let num_configs = (pending_v10.len() + 1) as u64;
T::DbWeight::get().reads_writes(num_configs, num_configs)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{new_test_ext, Test};
use primitives::LEGACY_MIN_BACKING_VOTES;
#[test]
fn v10_deserialized_from_actual_data() {
// Example how to get new `raw_config`:
// We'll obtain the raw_config at a specified a block
// Steps:
// 1. Go to Polkadot.js -> Developer -> Chain state -> Storage: https://polkadot.js.org/apps/#/chainstate
// 2. Set these parameters:
// 2.1. selected state query: configuration; activeConfig():
// PolkadotRuntimeParachainsConfigurationHostConfiguration
// 2.2. blockhash to query at:
// 0xf89d3ab5312c5f70d396dc59612f0aa65806c798346f9db4b35278baed2e0e53 (the hash of
// the block)
// 2.3. Note the value of encoded storage key ->
// 0x06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385 for the
// referenced block.
// 2.4. You'll also need the decoded values to update the test.
// 3. Go to Polkadot.js -> Developer -> Chain state -> Raw storage
// 3.1 Enter the encoded storage key and you get the raw config.
// This exceeds the maximal line width length, but that's fine, since this is not code and
// doesn't need to be read and also leaving it as one line allows to easily copy it.
let raw_config =
hex_literal::hex!["
0000300000800000080000000000100000c8000005000000050000000200000002000000000000000000000000005000000010000400000000000000000000000000000000000000000000000000000000000000000000000800000000200000040000000000100000b004000000000000000000001027000080b2e60e80c3c90180969800000000000000000000000000050000001400000004000000010000000101000000000600000064000000020000001900000000000000020000000200000002000000050000000200000000"
];
let v10 =
V10HostConfiguration::<primitives::BlockNumber>::decode(&mut &raw_config[..]).unwrap();
// We check only a sample of the values here. If we missed any fields or messed up data
// types that would skew all the fields coming after.
assert_eq!(v10.max_code_size, 3_145_728);
assert_eq!(v10.validation_upgrade_cooldown, 2);
assert_eq!(v10.max_pov_size, 5_242_880);
assert_eq!(v10.hrmp_channel_max_message_size, 1_048_576);
assert_eq!(v10.n_delay_tranches, 25);
assert_eq!(v10.minimum_validation_upgrade_delay, 5);
assert_eq!(v10.group_rotation_frequency, 20);
assert_eq!(v10.on_demand_cores, 0);
assert_eq!(v10.on_demand_base_fee, 10_000_000);
assert_eq!(v10.minimum_backing_votes, LEGACY_MIN_BACKING_VOTES);
assert_eq!(v10.node_features, NodeFeatures::EMPTY);
}
// Test that `migrate_to_v10`` correctly applies the `translate` function to current and pending
// configs.
#[test]
fn test_migrate_to_v10() {
// Host configuration has lots of fields. However, in this migration we only add one
// field. The most important part to check are a couple of the last fields. We also pick
// extra fields to check arbitrarily, e.g. depending on their position (i.e. the middle) and
// also their type.
//
// We specify only the picked fields and the rest should be provided by the `Default`
// implementation. That implementation is copied over between the two types and should work
// fine.
let v9 = V9HostConfiguration::<primitives::BlockNumber> {
needed_approvals: 69,
paras_availability_period: 55,
hrmp_recipient_deposit: 1337,
max_pov_size: 1111,
minimum_validation_upgrade_delay: 20,
..Default::default()
};
let mut pending_configs = Vec::new();
pending_configs.push((100, v9.clone()));
pending_configs.push((300, v9.clone()));
new_test_ext(Default::default()).execute_with(|| {
// Implant the v9 version in the state.
v9::ActiveConfig::<Test>::set(Some(v9.clone()));
v9::PendingConfigs::<Test>::set(Some(pending_configs));
migrate_to_v10::<Test>();
let v10 = translate::<Test>(v9);
let mut configs_to_check = v10::PendingConfigs::<Test>::get().unwrap();
configs_to_check.push((0, v10::ActiveConfig::<Test>::get().unwrap()));
for (_, config) in configs_to_check {
assert_eq!(config, v10);
assert_eq!(config.node_features, NodeFeatures::EMPTY);
}
});
}
// Test that migration doesn't panic in case there're no pending configurations upgrades in
// pallet's storage.
#[test]
fn test_migrate_to_v10_no_pending() {
let v9 = V9HostConfiguration::<primitives::BlockNumber>::default();
new_test_ext(Default::default()).execute_with(|| {
// Implant the v9 version in the state.
v9::ActiveConfig::<Test>::set(Some(v9));
// Ensure there're no pending configs.
v9::PendingConfigs::<Test>::set(None);
// Shouldn't fail.
migrate_to_v10::<Test>();
});
}
}
@@ -23,13 +23,116 @@ use frame_support::{
weights::Weight, weights::Weight,
}; };
use frame_system::pallet_prelude::BlockNumberFor; use frame_system::pallet_prelude::BlockNumberFor;
use primitives::{SessionIndex, LEGACY_MIN_BACKING_VOTES}; use primitives::{
AsyncBackingParams, Balance, ExecutorParams, SessionIndex, LEGACY_MIN_BACKING_VOTES,
ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE,
};
use sp_runtime::Perbill;
use sp_std::vec::Vec; use sp_std::vec::Vec;
use frame_support::traits::OnRuntimeUpgrade; use frame_support::traits::OnRuntimeUpgrade;
use super::v8::V8HostConfiguration; use super::v8::V8HostConfiguration;
type V9HostConfiguration<BlockNumber> = configuration::HostConfiguration<BlockNumber>; /// All configuration of the runtime with respect to paras.
#[derive(Clone, Encode, Decode, Debug)]
pub struct V9HostConfiguration<BlockNumber> {
pub max_code_size: u32,
pub max_head_data_size: u32,
pub max_upward_queue_count: u32,
pub max_upward_queue_size: u32,
pub max_upward_message_size: u32,
pub max_upward_message_num_per_candidate: u32,
pub hrmp_max_message_num_per_candidate: u32,
pub validation_upgrade_cooldown: BlockNumber,
pub validation_upgrade_delay: BlockNumber,
pub async_backing_params: AsyncBackingParams,
pub max_pov_size: u32,
pub max_downward_message_size: u32,
pub hrmp_max_parachain_outbound_channels: u32,
pub hrmp_sender_deposit: Balance,
pub hrmp_recipient_deposit: Balance,
pub hrmp_channel_max_capacity: u32,
pub hrmp_channel_max_total_size: u32,
pub hrmp_max_parachain_inbound_channels: u32,
pub hrmp_channel_max_message_size: u32,
pub executor_params: ExecutorParams,
pub code_retention_period: BlockNumber,
pub on_demand_cores: u32,
pub on_demand_retries: u32,
pub on_demand_queue_max_size: u32,
pub on_demand_target_queue_utilization: Perbill,
pub on_demand_fee_variability: Perbill,
pub on_demand_base_fee: Balance,
pub on_demand_ttl: BlockNumber,
pub group_rotation_frequency: BlockNumber,
pub paras_availability_period: BlockNumber,
pub scheduling_lookahead: u32,
pub max_validators_per_core: Option<u32>,
pub max_validators: Option<u32>,
pub dispute_period: SessionIndex,
pub dispute_post_conclusion_acceptance_period: BlockNumber,
pub no_show_slots: u32,
pub n_delay_tranches: u32,
pub zeroth_delay_tranche_width: u32,
pub needed_approvals: u32,
pub relay_vrf_modulo_samples: u32,
pub pvf_voting_ttl: SessionIndex,
pub minimum_validation_upgrade_delay: BlockNumber,
pub minimum_backing_votes: u32,
}
impl<BlockNumber: Default + From<u32>> Default for V9HostConfiguration<BlockNumber> {
fn default() -> Self {
Self {
async_backing_params: AsyncBackingParams {
max_candidate_depth: 0,
allowed_ancestry_len: 0,
},
group_rotation_frequency: 1u32.into(),
paras_availability_period: 1u32.into(),
no_show_slots: 1u32.into(),
validation_upgrade_cooldown: Default::default(),
validation_upgrade_delay: 2u32.into(),
code_retention_period: Default::default(),
max_code_size: Default::default(),
max_pov_size: Default::default(),
max_head_data_size: Default::default(),
on_demand_cores: Default::default(),
on_demand_retries: Default::default(),
scheduling_lookahead: 1,
max_validators_per_core: Default::default(),
max_validators: None,
dispute_period: 6,
dispute_post_conclusion_acceptance_period: 100.into(),
n_delay_tranches: Default::default(),
zeroth_delay_tranche_width: Default::default(),
needed_approvals: Default::default(),
relay_vrf_modulo_samples: Default::default(),
max_upward_queue_count: Default::default(),
max_upward_queue_size: Default::default(),
max_downward_message_size: Default::default(),
max_upward_message_size: Default::default(),
max_upward_message_num_per_candidate: Default::default(),
hrmp_sender_deposit: Default::default(),
hrmp_recipient_deposit: Default::default(),
hrmp_channel_max_capacity: Default::default(),
hrmp_channel_max_total_size: Default::default(),
hrmp_max_parachain_inbound_channels: Default::default(),
hrmp_channel_max_message_size: Default::default(),
hrmp_max_parachain_outbound_channels: Default::default(),
hrmp_max_message_num_per_candidate: Default::default(),
pvf_voting_ttl: 2u32.into(),
minimum_validation_upgrade_delay: 2.into(),
executor_params: Default::default(),
on_demand_queue_max_size: ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE,
on_demand_base_fee: 10_000_000u128,
on_demand_fee_variability: Perbill::from_percent(3),
on_demand_target_queue_utilization: Perbill::from_percent(25),
on_demand_ttl: 5u32.into(),
minimum_backing_votes: LEGACY_MIN_BACKING_VOTES,
}
}
}
mod v8 { mod v8 {
use super::*; use super::*;
@@ -16,6 +16,7 @@
use super::*; use super::*;
use crate::mock::{new_test_ext, Configuration, ParasShared, RuntimeOrigin, Test}; use crate::mock::{new_test_ext, Configuration, ParasShared, RuntimeOrigin, Test};
use bitvec::{bitvec, prelude::Lsb0};
use frame_support::{assert_err, assert_noop, assert_ok}; use frame_support::{assert_err, assert_noop, assert_ok};
fn on_new_session(session_index: SessionIndex) -> (HostConfiguration<u32>, HostConfiguration<u32>) { fn on_new_session(session_index: SessionIndex) -> (HostConfiguration<u32>, HostConfiguration<u32>) {
@@ -318,6 +319,7 @@ fn setting_pending_config_members() {
on_demand_target_queue_utilization: Perbill::from_percent(25), on_demand_target_queue_utilization: Perbill::from_percent(25),
on_demand_ttl: 5u32, on_demand_ttl: 5u32,
minimum_backing_votes: 5, minimum_backing_votes: 5,
node_features: bitvec![u8, Lsb0; 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
}; };
Configuration::set_validation_upgrade_cooldown( Configuration::set_validation_upgrade_cooldown(
@@ -473,6 +475,12 @@ fn setting_pending_config_members() {
new_config.minimum_backing_votes, new_config.minimum_backing_votes,
) )
.unwrap(); .unwrap();
Configuration::set_node_feature(RuntimeOrigin::root(), 1, true).unwrap();
Configuration::set_node_feature(RuntimeOrigin::root(), 1, true).unwrap();
Configuration::set_node_feature(RuntimeOrigin::root(), 3, true).unwrap();
Configuration::set_node_feature(RuntimeOrigin::root(), 10, true).unwrap();
Configuration::set_node_feature(RuntimeOrigin::root(), 10, false).unwrap();
Configuration::set_node_feature(RuntimeOrigin::root(), 11, true).unwrap();
assert_eq!(PendingConfigs::<Test>::get(), vec![(shared::SESSION_DELAY, new_config)],); assert_eq!(PendingConfigs::<Test>::get(), vec![(shared::SESSION_DELAY, new_config)],);
}) })
@@ -16,8 +16,8 @@
//! Put implementations of functions from staging APIs here. //! Put implementations of functions from staging APIs here.
use crate::shared; use crate::{configuration, initializer, shared};
use primitives::ValidatorIndex; use primitives::{vstaging::NodeFeatures, ValidatorIndex};
use sp_std::{collections::btree_map::BTreeMap, prelude::Vec}; use sp_std::{collections::btree_map::BTreeMap, prelude::Vec};
/// Implementation for `DisabledValidators` /// Implementation for `DisabledValidators`
@@ -42,3 +42,8 @@ where
.filter_map(|v| reverse_index.get(v).cloned()) .filter_map(|v| reverse_index.get(v).cloned())
.collect() .collect()
} }
/// Returns the current state of the node features.
pub fn node_features<T: initializer::Config>() -> NodeFeatures {
<configuration::Pallet<T>>::config().node_features
}
+11 -6
View File
@@ -23,11 +23,12 @@
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::{
slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, slashing, vstaging::NodeFeatures, AccountId, AccountIndex, Balance, BlockNumber,
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState,
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage,
OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature, InboundHrmpMessage, Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData,
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, ScrapedOnChainVotes, SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId,
ValidatorIndex, PARACHAIN_KEY_TYPE_ID,
}; };
use runtime_common::{ use runtime_common::{
assigned_slots, auctions, claims, crowdloan, impl_runtime_weights, assigned_slots, auctions, claims, crowdloan, impl_runtime_weights,
@@ -1499,6 +1500,7 @@ pub mod migrations {
frame_support::migrations::RemovePallet<TipsPalletName, <Runtime as frame_system::Config>::DbWeight>, frame_support::migrations::RemovePallet<TipsPalletName, <Runtime as frame_system::Config>::DbWeight>,
pallet_grandpa::migrations::MigrateV4ToV5<Runtime>, pallet_grandpa::migrations::MigrateV4ToV5<Runtime>,
parachains_configuration::migration::v10::MigrateToV10<Runtime>,
); );
} }
@@ -1660,7 +1662,7 @@ sp_api::impl_runtime_apis! {
} }
} }
#[api_version(8)] #[api_version(9)]
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>()
@@ -1808,6 +1810,9 @@ sp_api::impl_runtime_apis! {
parachains_staging_runtime_api_impl::disabled_validators::<Runtime>() parachains_staging_runtime_api_impl::disabled_validators::<Runtime>()
} }
fn node_features() -> NodeFeatures {
parachains_staging_runtime_api_impl::node_features::<Runtime>()
}
} }
#[api_version(3)] #[api_version(3)]
@@ -17,9 +17,9 @@
//! Autogenerated weights for `runtime_parachains::configuration` //! Autogenerated weights for `runtime_parachains::configuration`
//! //!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! DATE: 2023-11-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000` //! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
// Executed Command: // Executed Command:
@@ -31,11 +31,11 @@
// --extrinsic=* // --extrinsic=*
// --wasm-execution=compiled // --wasm-execution=compiled
// --heap-pages=4096 // --heap-pages=4096
// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json // --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
// --pallet=runtime_parachains::configuration // --pallet=runtime_parachains::configuration
// --chain=rococo-dev // --chain=rococo-dev
// --header=./file_header.txt // --header=./polkadot/file_header.txt
// --output=./runtime/rococo/src/weights/ // --output=./polkadot/runtime/rococo/src/weights/
#![cfg_attr(rustfmt, rustfmt_skip)] #![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)] #![allow(unused_parens)]
@@ -56,11 +56,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_block_number() -> Weight { fn set_config_with_block_number() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_051_000 picoseconds. // Minimum execution time: 7_793_000 picoseconds.
Weight::from_parts(9_496_000, 0) Weight::from_parts(8_192_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -72,11 +72,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_u32() -> Weight { fn set_config_with_u32() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_104_000 picoseconds. // Minimum execution time: 7_819_000 picoseconds.
Weight::from_parts(9_403_000, 0) Weight::from_parts(8_004_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -88,11 +88,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_option_u32() -> Weight { fn set_config_with_option_u32() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_112_000 picoseconds. // Minimum execution time: 7_760_000 picoseconds.
Weight::from_parts(9_495_000, 0) Weight::from_parts(8_174_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -114,11 +114,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_balance() -> Weight { fn set_config_with_balance() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_011_000 picoseconds. // Minimum execution time: 7_814_000 picoseconds.
Weight::from_parts(9_460_000, 0) Weight::from_parts(8_098_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -130,11 +130,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_executor_params() -> Weight { fn set_config_with_executor_params() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_940_000 picoseconds. // Minimum execution time: 10_028_000 picoseconds.
Weight::from_parts(10_288_000, 0) Weight::from_parts(10_386_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -146,11 +146,27 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_perbill() -> Weight { fn set_config_with_perbill() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_192_000 picoseconds. // Minimum execution time: 7_867_000 picoseconds.
Weight::from_parts(9_595_000, 0) Weight::from_parts(8_191_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Configuration::PendingConfigs` (r:1 w:1)
/// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0)
/// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_node_feature() -> Weight {
// Proof Size summary in bytes:
// Measured: `151`
// Estimated: `1636`
// Minimum execution time: 10_158_000 picoseconds.
Weight::from_parts(10_430_000, 0)
.saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
+12 -7
View File
@@ -46,12 +46,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::{
slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, slashing, vstaging::NodeFeatures, AccountId, AccountIndex, Balance, BlockNumber,
CommittedCandidateReceipt, CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState,
Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage,
OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, InboundHrmpMessage, Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData,
SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, PvfCheckStatement, ScrapedOnChainVotes, SessionInfo, Signature, ValidationCode,
ValidatorSignature, PARACHAIN_KEY_TYPE_ID, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, PARACHAIN_KEY_TYPE_ID,
}; };
use runtime_common::{ use runtime_common::{
assigned_slots, auctions, crowdloan, assigned_slots, auctions, crowdloan,
@@ -1559,6 +1559,7 @@ pub mod migrations {
pallet_referenda::migration::v1::MigrateV0ToV1<Runtime, ()>, pallet_referenda::migration::v1::MigrateV0ToV1<Runtime, ()>,
pallet_nomination_pools::migration::versioned_migrations::V6ToV7<Runtime>, pallet_nomination_pools::migration::versioned_migrations::V6ToV7<Runtime>,
pallet_grandpa::migrations::MigrateV4ToV5<Runtime>, pallet_grandpa::migrations::MigrateV4ToV5<Runtime>,
parachains_configuration::migration::v10::MigrateToV10<Runtime>,
); );
} }
@@ -1699,7 +1700,7 @@ sp_api::impl_runtime_apis! {
} }
} }
#[api_version(8)] #[api_version(9)]
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>()
@@ -1846,6 +1847,10 @@ sp_api::impl_runtime_apis! {
fn disabled_validators() -> Vec<ValidatorIndex> { fn disabled_validators() -> Vec<ValidatorIndex> {
parachains_staging_runtime_api_impl::disabled_validators::<Runtime>() parachains_staging_runtime_api_impl::disabled_validators::<Runtime>()
} }
fn node_features() -> NodeFeatures {
parachains_staging_runtime_api_impl::node_features::<Runtime>()
}
} }
impl beefy_primitives::BeefyApi<Block, BeefyId> for Runtime { impl beefy_primitives::BeefyApi<Block, BeefyId> for Runtime {
@@ -17,9 +17,9 @@
//! Autogenerated weights for `runtime_parachains::configuration` //! Autogenerated weights for `runtime_parachains::configuration`
//! //!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! DATE: 2023-11-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000` //! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024
// Executed Command: // Executed Command:
@@ -31,11 +31,11 @@
// --extrinsic=* // --extrinsic=*
// --wasm-execution=compiled // --wasm-execution=compiled
// --heap-pages=4096 // --heap-pages=4096
// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json // --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
// --pallet=runtime_parachains::configuration // --pallet=runtime_parachains::configuration
// --chain=westend-dev // --chain=westend-dev
// --header=./file_header.txt // --header=./polkadot/file_header.txt
// --output=./runtime/westend/src/weights/ // --output=./polkadot/runtime/westend/src/weights/
#![cfg_attr(rustfmt, rustfmt_skip)] #![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)] #![allow(unused_parens)]
@@ -56,11 +56,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_block_number() -> Weight { fn set_config_with_block_number() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_616_000 picoseconds. // Minimum execution time: 8_065_000 picoseconds.
Weight::from_parts(9_961_000, 0) Weight::from_parts(8_389_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -72,11 +72,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_u32() -> Weight { fn set_config_with_u32() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_587_000 picoseconds. // Minimum execution time: 8_038_000 picoseconds.
Weight::from_parts(9_964_000, 0) Weight::from_parts(8_463_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -88,11 +88,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_option_u32() -> Weight { fn set_config_with_option_u32() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_650_000 picoseconds. // Minimum execution time: 7_843_000 picoseconds.
Weight::from_parts(9_960_000, 0) Weight::from_parts(8_216_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -114,11 +114,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_balance() -> Weight { fn set_config_with_balance() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_545_000 picoseconds. // Minimum execution time: 7_969_000 picoseconds.
Weight::from_parts(9_845_000, 0) Weight::from_parts(8_362_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -130,11 +130,11 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_executor_params() -> Weight { fn set_config_with_executor_params() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 10_258_000 picoseconds. // Minimum execution time: 10_084_000 picoseconds.
Weight::from_parts(10_607_000, 0) Weight::from_parts(10_451_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@@ -146,11 +146,27 @@ impl<T: frame_system::Config> runtime_parachains::configuration::WeightInfo for
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_config_with_perbill() -> Weight { fn set_config_with_perbill() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `127` // Measured: `151`
// Estimated: `1612` // Estimated: `1636`
// Minimum execution time: 9_502_000 picoseconds. // Minimum execution time: 7_948_000 picoseconds.
Weight::from_parts(9_902_000, 0) Weight::from_parts(8_268_000, 0)
.saturating_add(Weight::from_parts(0, 1612)) .saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Configuration::PendingConfigs` (r:1 w:1)
/// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0)
/// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
fn set_node_feature() -> Weight {
// Proof Size summary in bytes:
// Measured: `151`
// Estimated: `1636`
// Minimum execution time: 10_257_000 picoseconds.
Weight::from_parts(10_584_000, 0)
.saturating_add(Weight::from_parts(0, 1636))
.saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }