From 198835592041e021138f67e2fa4965652bc1af14 Mon Sep 17 00:00:00 2001 From: Dmitry Sinyavin Date: Sun, 4 Dec 2022 20:48:21 +0100 Subject: [PATCH] Move executor params to `SessionInfo`: primitives and runtime --- primitives/src/runtime_api.rs | 4 +- primitives/src/vstaging/mod.rs | 125 ++++++++++++++++++ runtime/parachains/src/runtime_api_impl/v2.rs | 10 +- .../src/runtime_api_impl/vstaging.rs | 12 +- runtime/parachains/src/session_info.rs | 16 +-- .../parachains/src/session_info/migration.rs | 38 +++--- runtime/rococo/src/lib.rs | 14 +- runtime/westend/src/lib.rs | 16 +-- 8 files changed, 178 insertions(+), 57 deletions(-) diff --git a/primitives/src/runtime_api.rs b/primitives/src/runtime_api.rs index 0c4c5db823d6..35f73337100c 100644 --- a/primitives/src/runtime_api.rs +++ b/primitives/src/runtime_api.rs @@ -221,8 +221,8 @@ sp_api::decl_runtime_apis! { #[api_version(3)] fn disputes() -> Vec<(v2::SessionIndex, v2::CandidateHash, v2::DisputeState)>; - /// Returns execution environment parameter set for the session. + /// Get the session info for the given session, if stored. #[api_version(3)] - fn session_executor_params(session_index: sp_staking::SessionIndex) -> Option; + fn session_info_staging(index: sp_staking::SessionIndex) -> Option; } } diff --git a/primitives/src/vstaging/mod.rs b/primitives/src/vstaging/mod.rs index b4040ce05021..0053dd997bc6 100644 --- a/primitives/src/vstaging/mod.rs +++ b/primitives/src/vstaging/mod.rs @@ -23,3 +23,128 @@ pub use executor_params::{ ExecInstantiationStrategy, ExecutionEnvironment, ExecutorParam, ExecutorParams, ExecutorParamsHash, }; + +use crate::v2::{ + self, AssignmentId, AuthorityDiscoveryId, GroupIndex, IndexedVec, SessionIndex, ValidatorId, + ValidatorIndex, +}; +use parity_scale_codec::{Decode, Encode}; +#[cfg(feature = "std")] +use parity_util_mem::MallocSizeOf; +use primitives::RuntimeDebug; +use scale_info::TypeInfo; +use sp_std::vec::Vec; + +/// Information about validator sets of a session. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq, MallocSizeOf))] +pub struct SessionInfo { + /****** New in vstaging *******/ + /// Executor parameter set for the session. + pub executor_params: ExecutorParams, + + /****** New in v2 *******/ + /// All the validators actively participating in parachain consensus. + /// Indices are into the broader validator set. + pub active_validator_indices: Vec, + /// A secure random seed for the session, gathered from BABE. + pub random_seed: [u8; 32], + /// The amount of sessions to keep for disputes. + pub dispute_period: SessionIndex, + + /****** Old fields ******/ + /// Validators in canonical ordering. + /// + /// NOTE: There might be more authorities in the current session, than `validators` participating + /// in parachain consensus. See + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148). + /// + /// `SessionInfo::validators` will be limited to to `max_validators` when set. + pub validators: IndexedVec, + /// Validators' authority discovery keys for the session in canonical ordering. + /// + /// NOTE: The first `validators.len()` entries will match the corresponding validators in + /// `validators`, afterwards any remaining authorities can be found. This is any authorities not + /// participating in parachain consensus - see + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148) + #[cfg_attr(feature = "std", ignore_malloc_size_of = "outside type")] + pub discovery_keys: Vec, + /// The assignment keys for validators. + /// + /// NOTE: There might be more authorities in the current session, than validators participating + /// in parachain consensus. See + /// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148). + /// + /// Therefore: + /// ```ignore + /// assignment_keys.len() == validators.len() && validators.len() <= discovery_keys.len() + /// ``` + pub assignment_keys: Vec, + /// Validators in shuffled ordering - these are the validator groups as produced + /// by the `Scheduler` module for the session and are typically referred to by + /// `GroupIndex`. + pub validator_groups: IndexedVec>, + /// The number of availability cores used by the protocol during this session. + pub n_cores: u32, + /// The zeroth delay tranche width. + pub zeroth_delay_tranche_width: u32, + /// The number of samples we do of `relay_vrf_modulo`. + pub relay_vrf_modulo_samples: u32, + /// The number of delay tranches in total. + pub n_delay_tranches: u32, + /// How many slots (BABE / SASSAFRAS) must pass before an assignment is considered a + /// no-show. + pub no_show_slots: u32, + /// The number of validators needed to approve a block. + pub needed_approvals: u32, +} + +// Structure downgrade for backward compatibility +impl From for v2::SessionInfo { + fn from(new: SessionInfo) -> Self { + Self { + active_validator_indices: new.active_validator_indices, + random_seed: new.random_seed, + dispute_period: new.dispute_period, + validators: new.validators, + discovery_keys: new.discovery_keys, + assignment_keys: new.assignment_keys, + validator_groups: new.validator_groups, + n_cores: new.n_cores, + zeroth_delay_tranche_width: new.zeroth_delay_tranche_width, + relay_vrf_modulo_samples: new.relay_vrf_modulo_samples, + n_delay_tranches: new.n_delay_tranches, + no_show_slots: new.no_show_slots, + needed_approvals: new.needed_approvals, + } + } +} + +// Structure upgrade for storage translation +impl From for SessionInfo { + fn from(old: v2::SessionInfo) -> Self { + Self { + executor_params: ExecutorParams::default(), + active_validator_indices: old.active_validator_indices, + random_seed: old.random_seed, + dispute_period: old.dispute_period, + validators: old.validators, + discovery_keys: old.discovery_keys, + assignment_keys: old.assignment_keys, + validator_groups: old.validator_groups, + n_cores: old.n_cores, + zeroth_delay_tranche_width: old.zeroth_delay_tranche_width, + relay_vrf_modulo_samples: old.relay_vrf_modulo_samples, + n_delay_tranches: old.n_delay_tranches, + no_show_slots: old.no_show_slots, + needed_approvals: old.needed_approvals, + } + } +} + +// Old V1 session support +impl From for SessionInfo { + fn from(old: v2::OldV1SessionInfo) -> Self { + v2::SessionInfo::from(old).into() + } +} diff --git a/runtime/parachains/src/runtime_api_impl/v2.rs b/runtime/parachains/src/runtime_api_impl/v2.rs index 57345a819de0..aeeb72c57c2f 100644 --- a/runtime/parachains/src/runtime_api_impl/v2.rs +++ b/runtime/parachains/src/runtime_api_impl/v2.rs @@ -22,11 +22,11 @@ use crate::{ session_info, shared, }; use primitives::v2::{ - AuthorityDiscoveryId, CandidateEvent, CommittedCandidateReceipt, CoreIndex, CoreOccupied, + self, AuthorityDiscoveryId, CandidateEvent, CommittedCandidateReceipt, CoreIndex, CoreOccupied, CoreState, GroupIndex, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, OccupiedCore, OccupiedCoreAssumption, PersistedValidationData, - PvfCheckStatement, ScheduledCore, ScrapedOnChainVotes, SessionIndex, SessionInfo, - ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, + PvfCheckStatement, ScheduledCore, ScrapedOnChainVotes, SessionIndex, ValidationCode, + ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; use sp_runtime::traits::One; use sp_std::{collections::btree_map::BTreeMap, prelude::*}; @@ -343,8 +343,8 @@ where } /// Get the session info for the given session, if stored. -pub fn session_info(index: SessionIndex) -> Option { - >::session_info(index) +pub fn session_info(index: SessionIndex) -> Option { + >::session_info(index).map(|s| s.into()) } /// Implementation for the `dmq_contents` function of the runtime API. diff --git a/runtime/parachains/src/runtime_api_impl/vstaging.rs b/runtime/parachains/src/runtime_api_impl/vstaging.rs index 3ae6e9154b3a..19d4ed408d6f 100644 --- a/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -19,7 +19,7 @@ use crate::{disputes, session_info}; use primitives::{ v2::{CandidateHash, DisputeState, SessionIndex}, - vstaging::ExecutorParams, + vstaging, }; use sp_std::prelude::*; @@ -29,9 +29,9 @@ pub fn get_session_disputes( >::disputes() } -/// Get session executor parameter set -pub fn session_executor_params( - session_index: SessionIndex, -) -> Option { - >::session_executor_params(session_index) +/// Get the session info for the given session, if stored. +pub fn session_info_staging( + index: SessionIndex, +) -> Option { + >::session_info(index) } diff --git a/runtime/parachains/src/session_info.rs b/runtime/parachains/src/session_info.rs index 17deb7a93afa..87bc94ca4866 100644 --- a/runtime/parachains/src/session_info.rs +++ b/runtime/parachains/src/session_info.rs @@ -28,8 +28,8 @@ use frame_support::{ traits::{OneSessionHandler, ValidatorSet, ValidatorSetWithIdentification}, }; use primitives::{ - v2::{AssignmentId, AuthorityDiscoveryId, SessionIndex, SessionInfo}, - vstaging::{ExecutionEnvironment, ExecutorParam, ExecutorParams}, + v2::{AssignmentId, AuthorityDiscoveryId, SessionIndex}, + vstaging::{ExecutionEnvironment, ExecutorParam, ExecutorParams, SessionInfo}, }; use sp_std::vec::Vec; @@ -111,12 +111,6 @@ pub mod pallet { #[pallet::getter(fn account_keys)] pub(crate) type AccountKeys = StorageMap<_, Identity, SessionIndex, Vec>>; - - /// Executor parameter set for a given session index - #[pallet::storage] - #[pallet::getter(fn session_executor_params)] - pub(crate) type SessionExecutorParams = - StorageMap<_, Identity, SessionIndex, ExecutorParams>; } /// An abstraction for the authority discovery pallet @@ -168,7 +162,6 @@ impl Pallet { // Idx will be missing for a few sessions after the runtime upgrade. // But it shouldn'be be a problem. AccountKeys::::remove(&idx); - SessionExecutorParams::::remove(&idx); } // update `EarliestStoredSession` based on `config.dispute_period` EarliestStoredSession::::set(new_earliest_stored_session); @@ -185,6 +178,7 @@ impl Pallet { // create a new entry in `Sessions` with information about the current session let new_session_info = SessionInfo { + executor_params: ExecutorParams::from(&EXECUTOR_PARAMS[..]), validators, // these are from the notification and are thus already correct. discovery_keys: take_active_subset_and_inactive(&active_set, &discovery_keys), assignment_keys: take_active_subset(&active_set, &assignment_keys), @@ -200,10 +194,6 @@ impl Pallet { dispute_period, }; Sessions::::insert(&new_session_index, &new_session_info); - SessionExecutorParams::::insert( - &new_session_index, - ExecutorParams::from(&EXECUTOR_PARAMS[..]), - ); } /// Called by the initializer to initialize the session info pallet. diff --git a/runtime/parachains/src/session_info/migration.rs b/runtime/parachains/src/session_info/migration.rs index 4f290d7e54f3..a8afc3556521 100644 --- a/runtime/parachains/src/session_info/migration.rs +++ b/runtime/parachains/src/session_info/migration.rs @@ -23,40 +23,48 @@ pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); pub mod v2 { use super::STORAGE_VERSION; - use crate::{session_info, session_info::Pallet, shared}; + use crate::{ + session_info, + session_info::{Pallet, Store}, + }; use frame_support::{ pallet_prelude::Weight, traits::{OnRuntimeUpgrade, StorageVersion}, }; use frame_system::Config; - use primitives::vstaging::ExecutorParams; use sp_core::Get; + #[cfg(feature = "try-runtime")] + use primitives::vstaging::ExecutorParams; + #[cfg(feature = "try-runtime")] use crate::session_info::Vec; + #[cfg(feature = "try-runtime")] + use crate::shared; + /// The log target. const TARGET: &'static str = "runtime::session_info::migration::v2"; pub struct MigrateToV2(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV2 { fn on_runtime_upgrade() -> Weight { - // Bootstrap session executor params with the default ones if no parameters for the - // current session are in storage. `ExecutorParams::default()` is supposed to generate - // EXACTLY the same set of parameters the previous implementation used in a hard-coded - // form. This supposed to only run once, when upgrading from pre-parametrized executor - // code. let db_weight = T::DbWeight::get(); let mut weight = db_weight.reads(1); if StorageVersion::get::>() == 1 { log::info!(target: TARGET, "Upgrading storage v1 -> v2"); - let session_index = >::session_index(); - session_info::pallet::SessionExecutorParams::::insert( - &session_index, - ExecutorParams::default(), + let mut vs = 0; + + as Store>::Sessions::translate_values( + |old: primitives::v2::SessionInfo| { + vs += 1; + Some(primitives::vstaging::SessionInfo::from(old)) + }, ); + weight += db_weight.reads_writes(vs, vs); + STORAGE_VERSION.put::>(); - weight += db_weight.reads(1) + db_weight.writes(2); + weight += db_weight.writes(1); } else { log::warn!(target: TARGET, "Can only upgrade from version 1"); } @@ -67,8 +75,6 @@ pub mod v2 { fn pre_upgrade() -> Result, &'static str> { log::info!(target: TARGET, "Performing pre-upgrade checks"); assert_eq!(StorageVersion::get::>(), 1); - let session_index = >::session_index(); - assert!(Pallet::::session_executor_params(session_index).is_none()); Ok(Default::default()) } @@ -77,8 +83,8 @@ pub mod v2 { log::info!(target: TARGET, "Performing post-upgrade checks"); assert_eq!(StorageVersion::get::>(), 2); let session_index = >::session_index(); - let executor_params = Pallet::::session_executor_params(session_index); - assert_eq!(executor_params, Some(ExecutorParams::default())); + let session_info = Pallet::::session_info(session_index); + assert_eq!(session_info.unwrap().executor_params, ExecutorParams::default()); Ok(()) } } diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index 487ad10fabfe..f2d80bf407b1 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -23,13 +23,13 @@ use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use primitives::{ v2::{ - AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, + self, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, OccupiedCoreAssumption, - PersistedValidationData, ScrapedOnChainVotes, SessionInfo, Signature, ValidationCode, + PersistedValidationData, ScrapedOnChainVotes, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, }, - vstaging::ExecutorParams, + vstaging, }; use runtime_common::{ assigned_slots, auctions, claims, crowdloan, impl_runtime_weights, impls::ToAuthor, @@ -1666,12 +1666,12 @@ sp_api::impl_runtime_apis! { }) } - fn session_executor_params(session_index: SessionIndex) -> Option { - parachains_runtime_api_impl_staging::session_executor_params::(session_index) + fn session_info(index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_info::(index) } - fn session_info(index: SessionIndex) -> Option { - parachains_runtime_api_impl::session_info::(index) + fn session_info_staging(index: SessionIndex) -> Option { + parachains_runtime_api_impl_staging::session_info_staging::(index) } fn dmq_contents(recipient: ParaId) -> Vec> { diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index 0247b9a1d824..1bd3fac4792d 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -37,13 +37,13 @@ use pallet_transaction_payment::{CurrencyAdapter, FeeDetails, RuntimeDispatchInf use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use primitives::{ v2::{ - AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, + self, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, DisputeState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, Nonce, OccupiedCoreAssumption, - PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionInfo, Signature, - ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, + PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, Signature, ValidationCode, + ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }, - vstaging::ExecutorParams, + vstaging, }; use runtime_common::{ assigned_slots, auctions, crowdloan, elections::OnChainAccuracy, impl_runtime_weights, @@ -1403,12 +1403,12 @@ sp_api::impl_runtime_apis! { }) } - fn session_executor_params(session_index: SessionIndex) -> Option { - parachains_runtime_api_impl_staging::session_executor_params::(session_index) + fn session_info(index: SessionIndex) -> Option { + parachains_runtime_api_impl::session_info::(index) } - fn session_info(index: SessionIndex) -> Option { - parachains_runtime_api_impl::session_info::(index) + fn session_info_staging(index: SessionIndex) -> Option { + parachains_runtime_api_impl_staging::session_info_staging::(index) } fn dmq_contents(recipient: ParaId) -> Vec> {