mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 00:31:02 +00:00
paras.rs to FRAME V2 (#3403)
* to v2 macro * line width * fix mock * actually compile moxk * compile tests * add hooks * origin back in mocks * assimilate_storage * add generic * maybe mock compiles now * origin between parachain and system causing problem * change origin * type alias as origin * keep origin * add aliases to tests * remove unnecessary imports * Parachain -> Paras * paras test * nvm * use genesis build in mock
This commit is contained in:
@@ -14,29 +14,23 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! The paras module is responsible for storing data on parachains and parathreads.
|
||||
//! The paras pallet is responsible for storing data on parachains and parathreads.
|
||||
//!
|
||||
//! It tracks which paras are parachains, what their current head data is in
|
||||
//! this fork of the relay chain, what their validation code is, and what their past and upcoming
|
||||
//! validation code is.
|
||||
//!
|
||||
//! A para is not considered live until it is registered and activated in this module. Activation can
|
||||
//! A para is not considered live until it is registered and activated in this pallet. Activation can
|
||||
//! only occur at session boundaries.
|
||||
|
||||
use sp_std::prelude::*;
|
||||
use sp_std::result;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_std::marker::PhantomData;
|
||||
use primitives::v1::{
|
||||
Id as ParaId, ValidationCode, ValidationCodeHash, HeadData, SessionIndex, ConsensusLog,
|
||||
};
|
||||
use sp_runtime::{traits::One, DispatchResult, SaturatedConversion};
|
||||
use frame_system::ensure_root;
|
||||
use frame_support::{
|
||||
decl_storage, decl_module, decl_error, decl_event, ensure,
|
||||
traits::Get,
|
||||
weights::Weight,
|
||||
};
|
||||
use frame_system::pallet_prelude::*;
|
||||
use frame_support::pallet_prelude::*;
|
||||
use parity_scale_codec::{Encode, Decode};
|
||||
use crate::{configuration, shared, initializer::SessionChangeNotification};
|
||||
use sp_core::RuntimeDebug;
|
||||
@@ -44,20 +38,9 @@ use sp_core::RuntimeDebug;
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
pub use crate::Origin;
|
||||
pub use crate::Origin as ParachainOrigin;
|
||||
|
||||
pub trait Config:
|
||||
frame_system::Config +
|
||||
configuration::Config +
|
||||
shared::Config
|
||||
{
|
||||
/// The outer origin type.
|
||||
type Origin: From<Origin>
|
||||
+ From<<Self as frame_system::Config>::Origin>
|
||||
+ Into<result::Result<Origin, <Self as Config>::Origin>>;
|
||||
|
||||
type Event: From<Event> + Into<<Self as frame_system::Config>::Event>;
|
||||
}
|
||||
pub use pallet::*;
|
||||
|
||||
// the two key times necessary to track for every code replacement.
|
||||
#[derive(Default, Encode, Decode)]
|
||||
@@ -279,105 +262,30 @@ pub struct ParaGenesisArgs {
|
||||
pub parachain: bool,
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Config> as Paras {
|
||||
/// All parachains. Ordered ascending by ParaId. Parathreads are not included.
|
||||
Parachains get(fn parachains): Vec<ParaId>;
|
||||
/// The current lifecycle of a all known Para IDs.
|
||||
ParaLifecycles: map hasher(twox_64_concat) ParaId => Option<ParaLifecycle>;
|
||||
/// The head-data of every registered para.
|
||||
Heads get(fn para_head): map hasher(twox_64_concat) ParaId => Option<HeadData>;
|
||||
/// The validation code hash of every live para.
|
||||
///
|
||||
/// Corresponding code can be retrieved with [`CodeByHash`].
|
||||
CurrentCodeHash: map hasher(twox_64_concat) ParaId => Option<ValidationCodeHash>;
|
||||
/// Actual past code hash, indicated by the para id as well as the block number at which it
|
||||
/// became outdated.
|
||||
///
|
||||
/// Corresponding code can be retrieved with [`CodeByHash`].
|
||||
PastCodeHash: map hasher(twox_64_concat) (ParaId, T::BlockNumber) => Option<ValidationCodeHash>;
|
||||
/// Past code of parachains. The parachains themselves may not be registered anymore,
|
||||
/// but we also keep their code on-chain for the same amount of time as outdated code
|
||||
/// to keep it available for secondary checkers.
|
||||
PastCodeMeta get(fn past_code_meta):
|
||||
map hasher(twox_64_concat) ParaId => ParaPastCodeMeta<T::BlockNumber>;
|
||||
/// Which paras have past code that needs pruning and the relay-chain block at which the code was replaced.
|
||||
/// Note that this is the actual height of the included block, not the expected height at which the
|
||||
/// code upgrade would be applied, although they may be equal.
|
||||
/// This is to ensure the entire acceptance period is covered, not an offset acceptance period starting
|
||||
/// from the time at which the parachain perceives a code upgrade as having occurred.
|
||||
/// Multiple entries for a single para are permitted. Ordered ascending by block number.
|
||||
PastCodePruning: Vec<(ParaId, T::BlockNumber)>;
|
||||
/// The block number at which the planned code change is expected for a para.
|
||||
/// The change will be applied after the first parablock for this ID included which executes
|
||||
/// in the context of a relay chain block with a number >= `expected_at`.
|
||||
FutureCodeUpgrades get(fn future_code_upgrade_at): map hasher(twox_64_concat) ParaId => Option<T::BlockNumber>;
|
||||
/// The actual future code hash of a para.
|
||||
///
|
||||
/// Corresponding code can be retrieved with [`CodeByHash`].
|
||||
FutureCodeHash: map hasher(twox_64_concat) ParaId => Option<ValidationCodeHash>;
|
||||
/// The actions to perform during the start of a specific session index.
|
||||
ActionsQueue get(fn actions_queue): map hasher(twox_64_concat) SessionIndex => Vec<ParaId>;
|
||||
/// Upcoming paras instantiation arguments.
|
||||
UpcomingParasGenesis: map hasher(twox_64_concat) ParaId => Option<ParaGenesisArgs>;
|
||||
/// The number of reference on the validation code in [`CodeByHash`] storage.
|
||||
CodeByHashRefs: map hasher(identity) ValidationCodeHash => u32;
|
||||
/// Validation code stored by its hash.
|
||||
///
|
||||
/// This storage is consistent with [`FutureCodeHash`], [`CurrentCodeHash`] and
|
||||
/// [`PastCodeHash`].
|
||||
CodeByHash get(fn code_by_hash): map hasher(identity) ValidationCodeHash => Option<ValidationCode>;
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(super) trait Store)]
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config:
|
||||
frame_system::Config +
|
||||
configuration::Config +
|
||||
shared::Config
|
||||
{
|
||||
/// The outer origin type.
|
||||
type Origin: From<Origin>
|
||||
+ From<<Self as frame_system::Config>::Origin>
|
||||
+ Into<result::Result<Origin, <Self as Config>::Origin>>;
|
||||
|
||||
type Event: From<Event> + IsType<<Self as frame_system::Config>::Event>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(paras): Vec<(ParaId, ParaGenesisArgs)>;
|
||||
config(_phdata): PhantomData<T>;
|
||||
build(build::<T>);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
fn build<T: Config>(config: &GenesisConfig<T>) {
|
||||
let mut parachains: Vec<_> = config.paras
|
||||
.iter()
|
||||
.filter(|(_, args)| args.parachain)
|
||||
.map(|&(ref id, _)| id)
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
parachains.sort();
|
||||
parachains.dedup();
|
||||
|
||||
Parachains::put(¶chains);
|
||||
|
||||
for (id, genesis_args) in &config.paras {
|
||||
let code_hash = genesis_args.validation_code.hash();
|
||||
<Module<T>>::increase_code_ref(&code_hash, &genesis_args.validation_code);
|
||||
<Module<T> as Store>::CurrentCodeHash::insert(&id, &code_hash);
|
||||
<Module<T> as Store>::Heads::insert(&id, &genesis_args.genesis_head);
|
||||
if genesis_args.parachain {
|
||||
ParaLifecycles::insert(&id, ParaLifecycle::Parachain);
|
||||
} else {
|
||||
ParaLifecycles::insert(&id, ParaLifecycle::Parathread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decl_error! {
|
||||
pub enum Error for Module<T: Config> {
|
||||
/// Para is not registered in our system.
|
||||
NotRegistered,
|
||||
/// Para cannot be onboarded because it is already tracked by our system.
|
||||
CannotOnboard,
|
||||
/// Para cannot be offboarded at this time.
|
||||
CannotOffboard,
|
||||
/// Para cannot be upgraded to a parachain.
|
||||
CannotUpgrade,
|
||||
/// Para cannot be downgraded to a parathread.
|
||||
CannotDowngrade,
|
||||
}
|
||||
}
|
||||
|
||||
decl_event! {
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||
pub enum Event {
|
||||
/// Current code has been updated for a Para. \[para_id\]
|
||||
CurrentCodeUpdated(ParaId),
|
||||
@@ -390,18 +298,160 @@ decl_event! {
|
||||
/// A para has been queued to execute pending actions. \[para_id\]
|
||||
ActionQueued(ParaId, SessionIndex),
|
||||
}
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
/// The parachains configuration module.
|
||||
pub struct Module<T: Config> for enum Call where origin: <T as frame_system::Config>::Origin {
|
||||
type Error = Error<T>;
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
/// Para is not registered in our system.
|
||||
NotRegistered,
|
||||
/// Para cannot be onboarded because it is already tracked by our system.
|
||||
CannotOnboard,
|
||||
/// Para cannot be offboarded at this time.
|
||||
CannotOffboard,
|
||||
/// Para cannot be upgraded to a parachain.
|
||||
CannotUpgrade,
|
||||
/// Para cannot be downgraded to a parathread.
|
||||
CannotDowngrade,
|
||||
}
|
||||
|
||||
fn deposit_event() = default;
|
||||
/// All parachains. Ordered ascending by ParaId. Parathreads are not included.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn parachains)]
|
||||
pub(super) type Parachains<T: Config> = StorageValue<_, Vec<ParaId>, ValueQuery>;
|
||||
|
||||
/// The current lifecycle of a all known Para IDs.
|
||||
#[pallet::storage]
|
||||
pub(super) type ParaLifecycles<T: Config> = StorageMap<_, Twox64Concat, ParaId, ParaLifecycle>;
|
||||
|
||||
/// The head-data of every registered para.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn para_head)]
|
||||
pub(super) type Heads<T: Config> = StorageMap<_, Twox64Concat, ParaId, HeadData>;
|
||||
|
||||
/// The validation code hash of every live para.
|
||||
///
|
||||
/// Corresponding code can be retrieved with [`CodeByHash`].
|
||||
#[pallet::storage]
|
||||
pub(super) type CurrentCodeHash<T: Config> = StorageMap<_, Twox64Concat, ParaId, ValidationCodeHash>;
|
||||
|
||||
/// Actual past code hash, indicated by the para id as well as the block number at which it
|
||||
/// became outdated.
|
||||
///
|
||||
/// Corresponding code can be retrieved with [`CodeByHash`].
|
||||
#[pallet::storage]
|
||||
pub(super) type PastCodeHash<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat,
|
||||
(ParaId, T::BlockNumber),
|
||||
ValidationCodeHash
|
||||
>;
|
||||
|
||||
/// Past code of parachains. The parachains themselves may not be registered anymore,
|
||||
/// but we also keep their code on-chain for the same amount of time as outdated code
|
||||
/// to keep it available for secondary checkers.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn past_code_meta)]
|
||||
pub(super) type PastCodeMeta<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat,
|
||||
ParaId,
|
||||
ParaPastCodeMeta<T::BlockNumber>,
|
||||
ValueQuery
|
||||
>;
|
||||
|
||||
/// Which paras have past code that needs pruning and the relay-chain block at which the code was replaced.
|
||||
/// Note that this is the actual height of the included block, not the expected height at which the
|
||||
/// code upgrade would be applied, although they may be equal.
|
||||
/// This is to ensure the entire acceptance period is covered, not an offset acceptance period starting
|
||||
/// from the time at which the parachain perceives a code upgrade as having occurred.
|
||||
/// Multiple entries for a single para are permitted. Ordered ascending by block number.
|
||||
#[pallet::storage]
|
||||
pub(super) type PastCodePruning<T: Config> = StorageValue<_, Vec<(ParaId, T::BlockNumber)>, ValueQuery>;
|
||||
|
||||
/// The block number at which the planned code change is expected for a para.
|
||||
/// The change will be applied after the first parablock for this ID included which executes
|
||||
/// in the context of a relay chain block with a number >= `expected_at`.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn future_code_upgrade_at)]
|
||||
pub(super) type FutureCodeUpgrades<T: Config> = StorageMap<_, Twox64Concat, ParaId, T::BlockNumber>;
|
||||
|
||||
/// The actual future code hash of a para.
|
||||
///
|
||||
/// Corresponding code can be retrieved with [`CodeByHash`].
|
||||
#[pallet::storage]
|
||||
pub(super) type FutureCodeHash<T: Config> = StorageMap<_, Twox64Concat, ParaId, ValidationCodeHash>;
|
||||
|
||||
/// The actions to perform during the start of a specific session index.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn actions_queue)]
|
||||
pub(super) type ActionsQueue<T: Config> = StorageMap<_, Twox64Concat, SessionIndex, Vec<ParaId>, ValueQuery>;
|
||||
|
||||
/// Upcoming paras instantiation arguments.
|
||||
#[pallet::storage]
|
||||
pub(super) type UpcomingParasGenesis<T: Config> = StorageMap<_, Twox64Concat, ParaId, ParaGenesisArgs>;
|
||||
|
||||
/// The number of reference on the validation code in [`CodeByHash`] storage.
|
||||
#[pallet::storage]
|
||||
pub(super) type CodeByHashRefs<T: Config> = StorageMap<_, Identity, ValidationCodeHash, u32, ValueQuery>;
|
||||
|
||||
/// Validation code stored by its hash.
|
||||
///
|
||||
/// This storage is consistent with [`FutureCodeHash`], [`CurrentCodeHash`] and
|
||||
/// [`PastCodeHash`].
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn code_by_hash)]
|
||||
pub(super) type CodeByHash<T: Config> = StorageMap<_, Identity, ValidationCodeHash, ValidationCode>;
|
||||
|
||||
#[pallet::genesis_config]
|
||||
pub struct GenesisConfig {
|
||||
pub paras: Vec<(ParaId, ParaGenesisArgs)>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Default for GenesisConfig {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
paras: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::genesis_build]
|
||||
impl<T: Config> GenesisBuild<T> for GenesisConfig {
|
||||
fn build(&self) {
|
||||
let mut parachains: Vec<_> = self.paras
|
||||
.iter()
|
||||
.filter(|(_, args)| args.parachain)
|
||||
.map(|&(ref id, _)| id)
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
parachains.sort();
|
||||
parachains.dedup();
|
||||
|
||||
Parachains::<T>::put(¶chains);
|
||||
|
||||
for (id, genesis_args) in &self.paras {
|
||||
let code_hash = genesis_args.validation_code.hash();
|
||||
<Pallet<T>>::increase_code_ref(&code_hash, &genesis_args.validation_code);
|
||||
<Pallet<T> as Store>::CurrentCodeHash::insert(&id, &code_hash);
|
||||
<Pallet<T> as Store>::Heads::insert(&id, &genesis_args.genesis_head);
|
||||
if genesis_args.parachain {
|
||||
ParaLifecycles::<T>::insert(&id, ParaLifecycle::Parachain);
|
||||
} else {
|
||||
ParaLifecycles::<T>::insert(&id, ParaLifecycle::Parathread);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::origin]
|
||||
pub type Origin = ParachainOrigin;
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Set the storage for the parachain validation code immediately.
|
||||
#[weight = 0]
|
||||
fn force_set_current_code(origin, para: ParaId, new_code: ValidationCode) {
|
||||
#[pallet::weight(0)]
|
||||
pub fn force_set_current_code(origin: OriginFor<T>, para: ParaId, new_code: ValidationCode) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
let prior_code_hash = <Self as Store>::CurrentCodeHash::get(¶).unwrap_or_default();
|
||||
let new_code_hash = new_code.hash();
|
||||
@@ -411,57 +461,67 @@ decl_module! {
|
||||
let now = frame_system::Pallet::<T>::block_number();
|
||||
Self::note_past_code(para, now, now, prior_code_hash);
|
||||
Self::deposit_event(Event::CurrentCodeUpdated(para));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the storage for the current parachain head data immediately.
|
||||
#[weight = 0]
|
||||
fn force_set_current_head(origin, para: ParaId, new_head: HeadData) {
|
||||
#[pallet::weight(0)]
|
||||
pub fn force_set_current_head(origin: OriginFor<T>, para: ParaId, new_head: HeadData) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
<Self as Store>::Heads::insert(¶, new_head);
|
||||
Self::deposit_event(Event::CurrentHeadUpdated(para));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Schedule a code upgrade for block `expected_at`.
|
||||
#[weight = 0]
|
||||
fn force_schedule_code_upgrade(origin, para: ParaId, new_code: ValidationCode, expected_at: T::BlockNumber) {
|
||||
#[pallet::weight(0)]
|
||||
pub fn force_schedule_code_upgrade(
|
||||
origin: OriginFor<T>,
|
||||
para: ParaId,
|
||||
new_code: ValidationCode,
|
||||
expected_at: T::BlockNumber
|
||||
) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
Self::schedule_code_upgrade(para, new_code, expected_at);
|
||||
Self::deposit_event(Event::CodeUpgradeScheduled(para));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Note a new block head for para within the context of the current block.
|
||||
#[weight = 0]
|
||||
fn force_note_new_head(origin, para: ParaId, new_head: HeadData) {
|
||||
#[pallet::weight(0)]
|
||||
pub fn force_note_new_head(origin: OriginFor<T>, para: ParaId, new_head: HeadData) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
let now = frame_system::Pallet::<T>::block_number();
|
||||
Self::note_new_head(para, new_head, now);
|
||||
Self::deposit_event(Event::NewHeadNoted(para));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Put a parachain directly into the next session's action queue.
|
||||
/// We can't queue it any sooner than this without going into the
|
||||
/// initializer...
|
||||
#[weight = 0]
|
||||
fn force_queue_action(origin, para: ParaId) {
|
||||
#[pallet::weight(0)]
|
||||
pub fn force_queue_action(origin: OriginFor<T>, para: ParaId) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
let next_session = shared::Module::<T>::session_index().saturating_add(One::one());
|
||||
ActionsQueue::mutate(next_session, |v| {
|
||||
let next_session = shared::Pallet::<T>::session_index().saturating_add(One::one());
|
||||
ActionsQueue::<T>::mutate(next_session, |v| {
|
||||
if let Err(i) = v.binary_search(¶) {
|
||||
v.insert(i, para);
|
||||
}
|
||||
});
|
||||
Self::deposit_event(Event::ActionQueued(para, next_session));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> Module<T> {
|
||||
/// Called by the initializer to initialize the configuration module.
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Called by the initializer to initialize the configuration pallet.
|
||||
pub(crate) fn initializer_initialize(now: T::BlockNumber) -> Weight {
|
||||
Self::prune_old_code(now)
|
||||
}
|
||||
|
||||
/// Called by the initializer to finalize the configuration module.
|
||||
/// Called by the initializer to finalize the configuration pallet.
|
||||
pub(crate) fn initializer_finalize() { }
|
||||
|
||||
/// Called by the initializer to note that a new session has started.
|
||||
@@ -474,8 +534,8 @@ impl<T: Config> Module<T> {
|
||||
|
||||
/// The validation code of live para.
|
||||
pub(crate) fn current_code(para_id: &ParaId) -> Option<ValidationCode> {
|
||||
CurrentCodeHash::get(para_id).and_then(|code_hash| {
|
||||
let code = CodeByHash::get(&code_hash);
|
||||
CurrentCodeHash::<T>::get(para_id).and_then(|code_hash| {
|
||||
let code = CodeByHash::<T>::get(&code_hash);
|
||||
if code.is_none() {
|
||||
log::error!(
|
||||
"Pallet paras storage is inconsistent, code not found for hash {}",
|
||||
@@ -496,13 +556,13 @@ impl<T: Config> Module<T> {
|
||||
//
|
||||
// Returns the list of outgoing paras from the actions queue.
|
||||
fn apply_actions_queue(session: SessionIndex) -> Vec<ParaId> {
|
||||
let actions = ActionsQueue::take(session);
|
||||
let actions = ActionsQueue::<T>::take(session);
|
||||
let mut parachains = <Self as Store>::Parachains::get();
|
||||
let now = <frame_system::Pallet<T>>::block_number();
|
||||
let mut outgoing = Vec::new();
|
||||
|
||||
for para in actions {
|
||||
let lifecycle = ParaLifecycles::get(¶);
|
||||
let lifecycle = ParaLifecycles::<T>::get(¶);
|
||||
match lifecycle {
|
||||
None | Some(ParaLifecycle::Parathread) | Some(ParaLifecycle::Parachain) => { /* Nothing to do... */ },
|
||||
// Onboard a new parathread or parachain.
|
||||
@@ -512,9 +572,9 @@ impl<T: Config> Module<T> {
|
||||
if let Err(i) = parachains.binary_search(¶) {
|
||||
parachains.insert(i, para);
|
||||
}
|
||||
ParaLifecycles::insert(¶, ParaLifecycle::Parachain);
|
||||
ParaLifecycles::<T>::insert(¶, ParaLifecycle::Parachain);
|
||||
} else {
|
||||
ParaLifecycles::insert(¶, ParaLifecycle::Parathread);
|
||||
ParaLifecycles::<T>::insert(¶, ParaLifecycle::Parathread);
|
||||
}
|
||||
|
||||
let code_hash = genesis_data.validation_code.hash();
|
||||
@@ -528,14 +588,14 @@ impl<T: Config> Module<T> {
|
||||
if let Err(i) = parachains.binary_search(¶) {
|
||||
parachains.insert(i, para);
|
||||
}
|
||||
ParaLifecycles::insert(¶, ParaLifecycle::Parachain);
|
||||
ParaLifecycles::<T>::insert(¶, ParaLifecycle::Parachain);
|
||||
},
|
||||
// Downgrade a parachain to a parathread
|
||||
Some(ParaLifecycle::DowngradingParachain) => {
|
||||
if let Ok(i) = parachains.binary_search(¶) {
|
||||
parachains.remove(i);
|
||||
}
|
||||
ParaLifecycles::insert(¶, ParaLifecycle::Parathread);
|
||||
ParaLifecycles::<T>::insert(¶, ParaLifecycle::Parathread);
|
||||
},
|
||||
// Offboard a parathread or parachain from the system
|
||||
Some(ParaLifecycle::OffboardingParachain) | Some(ParaLifecycle::OffboardingParathread) => {
|
||||
@@ -545,7 +605,7 @@ impl<T: Config> Module<T> {
|
||||
|
||||
<Self as Store>::Heads::remove(¶);
|
||||
<Self as Store>::FutureCodeUpgrades::remove(¶);
|
||||
ParaLifecycles::remove(¶);
|
||||
ParaLifecycles::<T>::remove(¶);
|
||||
let removed_future_code_hash = <Self as Store>::FutureCodeHash::take(¶);
|
||||
if let Some(removed_future_code_hash) = removed_future_code_hash {
|
||||
Self::decrease_code_ref(&removed_future_code_hash);
|
||||
@@ -599,7 +659,7 @@ impl<T: Config> Module<T> {
|
||||
// looks at old code metadata, compares them to the current acceptance window, and prunes those
|
||||
// that are too old.
|
||||
fn prune_old_code(now: T::BlockNumber) -> Weight {
|
||||
let config = configuration::Module::<T>::config();
|
||||
let config = configuration::Pallet::<T>::config();
|
||||
let code_retention_period = config.code_retention_period;
|
||||
if now <= code_retention_period {
|
||||
let weight = T::DbWeight::get().reads_writes(1, 0);
|
||||
@@ -658,7 +718,7 @@ impl<T: Config> Module<T> {
|
||||
///
|
||||
/// Returns false if para is already registered in the system.
|
||||
pub fn can_schedule_para_initialize(id: &ParaId, _: &ParaGenesisArgs) -> bool {
|
||||
let lifecycle = ParaLifecycles::get(id);
|
||||
let lifecycle = ParaLifecycles::<T>::get(id);
|
||||
lifecycle.is_none()
|
||||
}
|
||||
|
||||
@@ -671,9 +731,9 @@ impl<T: Config> Module<T> {
|
||||
// Make sure parachain isn't already in our system.
|
||||
ensure!(Self::can_schedule_para_initialize(&id, &genesis), Error::<T>::CannotOnboard);
|
||||
|
||||
ParaLifecycles::insert(&id, ParaLifecycle::Onboarding);
|
||||
UpcomingParasGenesis::insert(&id, genesis);
|
||||
ActionsQueue::mutate(scheduled_session, |v| {
|
||||
ParaLifecycles::<T>::insert(&id, ParaLifecycle::Onboarding);
|
||||
UpcomingParasGenesis::<T>::insert(&id, genesis);
|
||||
ActionsQueue::<T>::mutate(scheduled_session, |v| {
|
||||
if let Err(i) = v.binary_search(&id) {
|
||||
v.insert(i, id);
|
||||
}
|
||||
@@ -688,23 +748,23 @@ impl<T: Config> Module<T> {
|
||||
///
|
||||
/// No-op if para is not registered at all.
|
||||
pub(crate) fn schedule_para_cleanup(id: ParaId) -> DispatchResult {
|
||||
let lifecycle = ParaLifecycles::get(&id);
|
||||
let lifecycle = ParaLifecycles::<T>::get(&id);
|
||||
match lifecycle {
|
||||
// If para is not registered, nothing to do!
|
||||
None => {
|
||||
return Ok(())
|
||||
},
|
||||
Some(ParaLifecycle::Parathread) => {
|
||||
ParaLifecycles::insert(&id, ParaLifecycle::OffboardingParathread);
|
||||
ParaLifecycles::<T>::insert(&id, ParaLifecycle::OffboardingParathread);
|
||||
},
|
||||
Some(ParaLifecycle::Parachain) => {
|
||||
ParaLifecycles::insert(&id, ParaLifecycle::OffboardingParachain);
|
||||
ParaLifecycles::<T>::insert(&id, ParaLifecycle::OffboardingParachain);
|
||||
},
|
||||
_ => return Err(Error::<T>::CannotOffboard)?,
|
||||
}
|
||||
|
||||
let scheduled_session = Self::scheduled_session();
|
||||
ActionsQueue::mutate(scheduled_session, |v| {
|
||||
ActionsQueue::<T>::mutate(scheduled_session, |v| {
|
||||
if let Err(i) = v.binary_search(&id) {
|
||||
v.insert(i, id);
|
||||
}
|
||||
@@ -718,12 +778,12 @@ impl<T: Config> Module<T> {
|
||||
/// Will return error if `ParaLifecycle` is not `Parathread`.
|
||||
pub(crate) fn schedule_parathread_upgrade(id: ParaId) -> DispatchResult {
|
||||
let scheduled_session = Self::scheduled_session();
|
||||
let lifecycle = ParaLifecycles::get(&id).ok_or(Error::<T>::NotRegistered)?;
|
||||
let lifecycle = ParaLifecycles::<T>::get(&id).ok_or(Error::<T>::NotRegistered)?;
|
||||
|
||||
ensure!(lifecycle == ParaLifecycle::Parathread, Error::<T>::CannotUpgrade);
|
||||
|
||||
ParaLifecycles::insert(&id, ParaLifecycle::UpgradingParathread);
|
||||
ActionsQueue::mutate(scheduled_session, |v| {
|
||||
ParaLifecycles::<T>::insert(&id, ParaLifecycle::UpgradingParathread);
|
||||
ActionsQueue::<T>::mutate(scheduled_session, |v| {
|
||||
if let Err(i) = v.binary_search(&id) {
|
||||
v.insert(i, id);
|
||||
}
|
||||
@@ -737,12 +797,12 @@ impl<T: Config> Module<T> {
|
||||
/// Noop if `ParaLifecycle` is not `Parachain`.
|
||||
pub(crate) fn schedule_parachain_downgrade(id: ParaId) -> DispatchResult {
|
||||
let scheduled_session = Self::scheduled_session();
|
||||
let lifecycle = ParaLifecycles::get(&id).ok_or(Error::<T>::NotRegistered)?;
|
||||
let lifecycle = ParaLifecycles::<T>::get(&id).ok_or(Error::<T>::NotRegistered)?;
|
||||
|
||||
ensure!(lifecycle == ParaLifecycle::Parachain, Error::<T>::CannotDowngrade);
|
||||
|
||||
ParaLifecycles::insert(&id, ParaLifecycle::DowngradingParachain);
|
||||
ActionsQueue::mutate(scheduled_session, |v| {
|
||||
ParaLifecycles::<T>::insert(&id, ParaLifecycle::DowngradingParachain);
|
||||
ActionsQueue::<T>::mutate(scheduled_session, |v| {
|
||||
if let Err(i) = v.binary_search(&id) {
|
||||
v.insert(i, id);
|
||||
}
|
||||
@@ -773,7 +833,7 @@ impl<T: Config> Module<T> {
|
||||
<frame_system::Pallet<T>>::deposit_log(log.into());
|
||||
|
||||
let (reads, writes) = Self::increase_code_ref(&new_code_hash, &new_code);
|
||||
FutureCodeHash::insert(&id, new_code_hash);
|
||||
FutureCodeHash::<T>::insert(&id, new_code_hash);
|
||||
T::DbWeight::get().reads_writes(1 + reads, 2 + writes)
|
||||
}
|
||||
})
|
||||
@@ -787,16 +847,16 @@ impl<T: Config> Module<T> {
|
||||
new_head: HeadData,
|
||||
execution_context: T::BlockNumber,
|
||||
) -> Weight {
|
||||
Heads::insert(&id, new_head);
|
||||
Heads::<T>::insert(&id, new_head);
|
||||
|
||||
if let Some(expected_at) = <Self as Store>::FutureCodeUpgrades::get(&id) {
|
||||
if expected_at <= execution_context {
|
||||
<Self as Store>::FutureCodeUpgrades::remove(&id);
|
||||
|
||||
// Both should always be `Some` in this case, since a code upgrade is scheduled.
|
||||
let new_code_hash = FutureCodeHash::take(&id).unwrap_or_default();
|
||||
let prior_code_hash = CurrentCodeHash::get(&id).unwrap_or_default();
|
||||
CurrentCodeHash::insert(&id, &new_code_hash);
|
||||
let new_code_hash = FutureCodeHash::<T>::take(&id).unwrap_or_default();
|
||||
let prior_code_hash = CurrentCodeHash::<T>::get(&id).unwrap_or_default();
|
||||
CurrentCodeHash::<T>::insert(&id, &new_code_hash);
|
||||
|
||||
let log = ConsensusLog::ParaUpgradeCode(id, new_code_hash);
|
||||
<frame_system::Pallet<T>>::deposit_log(log.into());
|
||||
@@ -847,11 +907,11 @@ impl<T: Config> Module<T> {
|
||||
};
|
||||
|
||||
if upgrade_applied_intermediate {
|
||||
FutureCodeHash::get(&id)
|
||||
FutureCodeHash::<T>::get(&id)
|
||||
} else {
|
||||
match Self::past_code_meta(&id).code_at(at) {
|
||||
None => None,
|
||||
Some(UseCodeAt::Current) => CurrentCodeHash::get(&id),
|
||||
Some(UseCodeAt::Current) => CurrentCodeHash::<T>::get(&id),
|
||||
Some(UseCodeAt::ReplacedAt(replaced)) => <Self as Store>::PastCodeHash::get(&(id, replaced)),
|
||||
}
|
||||
}
|
||||
@@ -859,14 +919,14 @@ impl<T: Config> Module<T> {
|
||||
|
||||
/// Returns the current lifecycle state of the para.
|
||||
pub fn lifecycle(id: ParaId) -> Option<ParaLifecycle> {
|
||||
ParaLifecycles::get(&id)
|
||||
ParaLifecycles::<T>::get(&id)
|
||||
}
|
||||
|
||||
/// Returns whether the given ID refers to a valid para.
|
||||
///
|
||||
/// Paras that are onboarding or offboarding are not included.
|
||||
pub fn is_valid_para(id: ParaId) -> bool {
|
||||
if let Some(state) = ParaLifecycles::get(&id) {
|
||||
if let Some(state) = ParaLifecycles::<T>::get(&id) {
|
||||
!state.is_onboarding() && !state.is_offboarding()
|
||||
} else {
|
||||
false
|
||||
@@ -877,7 +937,7 @@ impl<T: Config> Module<T> {
|
||||
///
|
||||
/// Includes parachains which will downgrade to a parathread in the future.
|
||||
pub fn is_parachain(id: ParaId) -> bool {
|
||||
if let Some(state) = ParaLifecycles::get(&id) {
|
||||
if let Some(state) = ParaLifecycles::<T>::get(&id) {
|
||||
state.is_parachain()
|
||||
} else {
|
||||
false
|
||||
@@ -888,7 +948,7 @@ impl<T: Config> Module<T> {
|
||||
///
|
||||
/// Includes parathreads which will upgrade to parachains in the future.
|
||||
pub fn is_parathread(id: ParaId) -> bool {
|
||||
if let Some(state) = ParaLifecycles::get(&id) {
|
||||
if let Some(state) = ParaLifecycles::<T>::get(&id) {
|
||||
state.is_parathread()
|
||||
} else {
|
||||
false
|
||||
@@ -909,7 +969,7 @@ impl<T: Config> Module<T> {
|
||||
|
||||
/// Return the session index that should be used for any future scheduled changes.
|
||||
fn scheduled_session() -> SessionIndex {
|
||||
shared::Module::<T>::scheduled_session()
|
||||
shared::Pallet::<T>::scheduled_session()
|
||||
}
|
||||
|
||||
/// Store the validation code if not already stored, and increase the number of reference.
|
||||
@@ -944,7 +1004,7 @@ impl<T: Config> Module<T> {
|
||||
#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
|
||||
pub fn test_on_new_session() {
|
||||
Self::initializer_on_new_session(&SessionChangeNotification {
|
||||
session_index: shared::Module::<T>::session_index(),
|
||||
session_index: shared::Pallet::<T>::session_index(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
@@ -954,10 +1014,7 @@ impl<T: Config> Module<T> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use primitives::v1::BlockNumber;
|
||||
use frame_support::{
|
||||
assert_ok,
|
||||
traits::{OnFinalize, OnInitialize}
|
||||
};
|
||||
use frame_support::assert_ok;
|
||||
|
||||
use crate::mock::{new_test_ext, Paras, Shared, System, MockGenesisConfig};
|
||||
use crate::configuration::HostConfiguration;
|
||||
@@ -1613,9 +1670,9 @@ mod tests {
|
||||
);
|
||||
|
||||
// Lifecycle is tracked correctly
|
||||
assert_eq!(ParaLifecycles::get(&a), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(ParaLifecycles::get(&b), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(ParaLifecycles::get(&c), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&a), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&b), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&c), Some(ParaLifecycle::Onboarding));
|
||||
|
||||
// run to block without session change.
|
||||
run_to_block(2, None);
|
||||
@@ -1627,9 +1684,9 @@ mod tests {
|
||||
);
|
||||
|
||||
// Lifecycle is tracked correctly
|
||||
assert_eq!(ParaLifecycles::get(&a), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(ParaLifecycles::get(&b), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(ParaLifecycles::get(&c), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&a), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&b), Some(ParaLifecycle::Onboarding));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&c), Some(ParaLifecycle::Onboarding));
|
||||
|
||||
|
||||
// Two sessions pass, so action queue is triggered
|
||||
@@ -1639,9 +1696,9 @@ mod tests {
|
||||
assert_eq!(<Paras as Store>::ActionsQueue::get(Paras::scheduled_session()), Vec::new());
|
||||
|
||||
// Lifecycle is tracked correctly
|
||||
assert_eq!(ParaLifecycles::get(&a), Some(ParaLifecycle::Parathread));
|
||||
assert_eq!(ParaLifecycles::get(&b), Some(ParaLifecycle::Parachain));
|
||||
assert_eq!(ParaLifecycles::get(&c), Some(ParaLifecycle::Parachain));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&a), Some(ParaLifecycle::Parathread));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&b), Some(ParaLifecycle::Parachain));
|
||||
assert_eq!(<Paras as Store>::ParaLifecycles::get(&c), Some(ParaLifecycle::Parachain));
|
||||
|
||||
assert_eq!(Paras::current_code(&a), Some(vec![2].into()));
|
||||
assert_eq!(Paras::current_code(&b), Some(vec![1].into()));
|
||||
@@ -1777,18 +1834,18 @@ mod tests {
|
||||
Paras::increase_code_ref(&code.hash(), &code);
|
||||
Paras::increase_code_ref(&code.hash(), &code);
|
||||
|
||||
assert!(CodeByHash::contains_key(code.hash()));
|
||||
assert_eq!(CodeByHashRefs::get(code.hash()), 2);
|
||||
assert!(<Paras as Store>::CodeByHash::contains_key(code.hash()));
|
||||
assert_eq!(<Paras as Store>::CodeByHashRefs::get(code.hash()), 2);
|
||||
|
||||
Paras::decrease_code_ref(&code.hash());
|
||||
|
||||
assert!(CodeByHash::contains_key(code.hash()));
|
||||
assert_eq!(CodeByHashRefs::get(code.hash()), 1);
|
||||
assert!(<Paras as Store>::CodeByHash::contains_key(code.hash()));
|
||||
assert_eq!(<Paras as Store>::CodeByHashRefs::get(code.hash()), 1);
|
||||
|
||||
Paras::decrease_code_ref(&code.hash());
|
||||
|
||||
assert!(!CodeByHash::contains_key(code.hash()));
|
||||
assert!(!CodeByHashRefs::contains_key(code.hash()));
|
||||
assert!(!<Paras as Store>::CodeByHash::contains_key(code.hash()));
|
||||
assert!(!<Paras as Store>::CodeByHashRefs::contains_key(code.hash()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user