diff --git a/polkadot/runtime/common/src/assigned_slots/benchmarking.rs b/polkadot/runtime/common/src/assigned_slots/benchmarking.rs index 61638fe6cabf..affe8ef41788 100644 --- a/polkadot/runtime/common/src/assigned_slots/benchmarking.rs +++ b/polkadot/runtime/common/src/assigned_slots/benchmarking.rs @@ -20,27 +20,27 @@ use super::*; use frame_benchmarking::v2::*; -use frame_support::assert_ok; use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; use primitives::Id as ParaId; use sp_runtime::traits::Bounded; type CurrencyOf = <::Leaser as Leaser>>::Currency; -type BalanceOf = <<::Leaser as Leaser>>::Currency as Currency< - ::AccountId, ->>::Balance; +type BalanceOf = + <<::Leaser as Leaser>>::Currency as FunInspect< + ::AccountId, + >>::Balance; #[benchmarks(where T: Config)] mod benchmarks { use super::*; - use crate::assigned_slots::Pallet as AssignedSlots; + use frame_support::{assert_ok, traits::fungible::Mutate}; fn register_parachain(para_id: ParaId) { let who: T::AccountId = whitelisted_caller(); let worst_validation_code = T::Registrar::worst_validation_code(); let worst_head_data = T::Registrar::worst_head_data(); - CurrencyOf::::make_free_balance_be(&who, BalanceOf::::max_value()); + CurrencyOf::::set_balance(&who, BalanceOf::::max_value()); assert_ok!(T::Registrar::register( who, diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index cc8ec339c118..f7c2889809e2 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -30,7 +30,7 @@ use crate::{ slots::{self, Pallet as Slots, WeightInfo as SlotsWeightInfo}, traits::{LeaseError, Leaser, Registrar}, }; -use frame_support::{pallet_prelude::*, traits::Currency}; +use frame_support::{pallet_prelude::*, traits::fungible::Inspect as FunInspect}; use frame_system::pallet_prelude::*; pub use pallet::*; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; @@ -98,9 +98,11 @@ impl WeightInfo for TestWeightInfo { } } -type BalanceOf = <<::Leaser as Leaser>>::Currency as Currency< - ::AccountId, ->>::Balance; +type BalanceOf = + <<::Leaser as Leaser>>::Currency as FunInspect< + ::AccountId, + >>::Balance; + type LeasePeriodOf = <::Leaser as Leaser>>::LeasePeriod; #[frame_support::pallet] @@ -663,7 +665,7 @@ mod tests { Configuration: parachains_configuration::{Pallet, Call, Storage, Config}, ParasShared: parachains_shared::{Pallet, Call, Storage}, Parachains: parachains_paras::{Pallet, Call, Storage, Config, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, + Slots: slots::{Pallet, Call, Storage, Event, HoldReason}, AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event}, } ); @@ -753,6 +755,7 @@ mod tests { impl slots::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; + type RuntimeHoldReason = RuntimeHoldReason; type Registrar = TestRegistrar; type LeasePeriod = LeasePeriod; type LeaseOffset = LeaseOffset; @@ -781,7 +784,7 @@ mod tests { pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { - balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], + balances: vec![(0, 5), (1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], } .assimilate_storage(&mut t) .unwrap(); diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs index e35303912fa1..49c499b74fac 100644 --- a/polkadot/runtime/common/src/auctions.rs +++ b/polkadot/runtime/common/src/auctions.rs @@ -25,7 +25,7 @@ use crate::{ use frame_support::{ dispatch::DispatchResult, ensure, - traits::{Currency, Get, Randomness, ReservableCurrency}, + traits::{fungible::Inspect as FunInspect, Currency, Get, Randomness, ReservableCurrency}, weights::Weight, }; use frame_system::pallet_prelude::BlockNumberFor; @@ -35,10 +35,9 @@ use primitives::Id as ParaId; use sp_runtime::traits::{CheckedSub, One, Saturating, Zero}; use sp_std::{mem::swap, prelude::*}; -type CurrencyOf = <::Leaser as Leaser>>::Currency; -type BalanceOf = <<::Leaser as Leaser>>::Currency as Currency< - ::AccountId, ->>::Balance; +type CurrencyOf = ::Currency; +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; pub trait WeightInfo { fn new_auction() -> Weight; @@ -98,6 +97,13 @@ pub mod pallet { LeasePeriod = BlockNumberFor, >; + type Currency: ReservableCurrency< + Self::AccountId, + Balance = <>>::Currency as FunInspect< + Self::AccountId, + >>::Balance, + >; + /// The parachain registrar type. type Registrar: Registrar; @@ -678,7 +684,7 @@ mod tests { use ::test_helpers::{dummy_hash, dummy_head_data, dummy_validation_code}; use frame_support::{ assert_noop, assert_ok, assert_storage_noop, ord_parameter_types, parameter_types, - traits::{ConstU32, EitherOfDiverse, OnFinalize, OnInitialize}, + traits::{ConstU32, Currency, EitherOfDiverse, OnFinalize, OnInitialize}, }; use frame_system::{EnsureRoot, EnsureSignedBy}; use pallet_balances; @@ -873,6 +879,7 @@ mod tests { impl Config for Test { type RuntimeEvent = RuntimeEvent; type Leaser = TestLeaser; + type Currency = Balances; type Registrar = TestRegistrar; type EndingPeriod = EndingPeriod; type SampleLength = SampleLength; diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index f14db68267d5..87d595a386ff 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -87,7 +87,7 @@ frame_support::construct_runtime!( Registrar: paras_registrar::{Pallet, Call, Storage, Event}, Auctions: auctions::{Pallet, Call, Storage, Event}, Crowdloan: crowdloan::{Pallet, Call, Storage, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, + Slots: slots::{Pallet, Call, Storage, Event, HoldReason}, } ); @@ -182,7 +182,7 @@ impl pallet_balances::Config for Test { type ReserveIdentifier = [u8; 8]; type RuntimeHoldReason = RuntimeHoldReason; type FreezeIdentifier = (); - type MaxHolds = ConstU32<0>; + type MaxHolds = ConstU32<1>; type MaxFreezes = ConstU32<0>; } @@ -230,6 +230,7 @@ parameter_types! { impl auctions::Config for Test { type RuntimeEvent = RuntimeEvent; type Leaser = Slots; + type Currency = Balances; type Registrar = Registrar; type EndingPeriod = EndingPeriod; type SampleLength = SampleLength; @@ -246,6 +247,7 @@ parameter_types! { impl slots::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; + type RuntimeHoldReason = RuntimeHoldReason; type Registrar = Registrar; type LeasePeriod = LeasePeriod; type LeaseOffset = LeaseOffset; diff --git a/polkadot/runtime/common/src/slots/migration.rs b/polkadot/runtime/common/src/slots/migration.rs index 4b499ca7c7bd..8d586df07a59 100644 --- a/polkadot/runtime/common/src/slots/migration.rs +++ b/polkadot/runtime/common/src/slots/migration.rs @@ -16,8 +16,132 @@ use super::*; use crate::crowdloan; +use frame_support::traits::OnRuntimeUpgrade; use sp_runtime::traits::AccountIdConversion; +#[cfg(feature = "try-runtime")] +use sp_runtime::TryRuntimeError; + +/// The current storage version. +pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + +pub mod versioned { + use super::*; + + /// Wrapper over `MigrateToV1` with convenience version checks. + /// + /// This migration would move lease reserves into named holds. + pub type ToV1 = frame_support::migrations::VersionedMigration< + 0, + 1, + v1::MigrateToV1, + Pallet, + ::DbWeight, + >; +} + +mod v1 { + use super::*; + use frame_support::traits::ReservableCurrency; + use sp_std::collections::btree_map::BTreeMap; + + #[cfg(feature = "try-runtime")] + use frame_support::traits::fungible::InspectHold; + + /// Balance type of OldCurrency. + pub type OldBalanceOf = ::AccountId, + >>::Balance; + + /// Alias to leases storage map with old currency. + #[frame_support::storage_alias] + pub type OldLeases = StorageMap< + Pallet, + Twox64Concat, + ParaId, + Vec::AccountId, OldBalanceOf)>>, + ValueQuery, + >; + + /// This migration would move funds for lease from reserved to hold. + pub struct MigrateToV1(sp_std::marker::PhantomData<(T, OldCurrency)>); + + impl OnRuntimeUpgrade for MigrateToV1 + where + T: Config, + OldCurrency: ReservableCurrency<::AccountId>, + BalanceOf: From, + { + fn on_runtime_upgrade() -> Weight { + // useful for calculating weights later + let mut migrated = 0u64; + let mut leases_count = 0u64; + + for (_, lease_periods) in OldLeases::::iter() { + leases_count += 1; + let mut deposit_held: BTreeMap> = + BTreeMap::new(); + + // go through each lease and find the lease deposit required for each leaser. + lease_periods.iter().for_each(|lease| { + if let Some((who, amount)) = lease { + deposit_held + .entry(who.clone()) + .and_modify(|deposit| *deposit = *amount.max(deposit)) + .or_insert(*amount); + } + }); + + deposit_held.iter().for_each(|(leaser, deposit)| { + OldCurrency::unreserve(leaser, *deposit); + let hold_result = Pallet::::hold(leaser, BalanceOf::::from(*deposit)); + defensive_assert!( + hold_result.is_ok(), + "hold should not fail, since we just unreserved the same amount" + ); + migrated += 1; + }) + } + + T::DbWeight::get().reads_writes( + // reads: leases_count + leases_count, + // writes = migrated * (unreserve + hold) + migrated.saturating_mul(2), + ) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_data: Vec) -> Result<(), TryRuntimeError> { + // Build a set of pairs of (para, who) that have a lease. + let mut para_leasers = + sp_std::collections::btree_set::BTreeSet::<(ParaId, T::AccountId)>::new(); + for (para, lease_periods) in Leases::::iter() { + lease_periods.into_iter().for_each(|maybe_lease| { + if let Some((who, _)) = maybe_lease { + para_leasers.insert((para, who)); + } + }); + } + + // for each pair assert hold amount is what we expect + para_leasers.iter().try_for_each(|(para, who)| -> Result<(), TryRuntimeError> { + // fixme(ank4n) there is a case where an account has a hold for multiple para-ids.. + let actual_hold = + T::Currency::balance_on_hold(&HoldReason::LeaseDeposit.into(), who); + let expected_hold = Pallet::::deposit_held(*para, who); + + ensure!( + actual_hold == expected_hold, + "ReservedAmount value not same as actual reserved balance" + ); + + Ok(()) + }) + } + } +} + /// Migrations for using fund index to create fund accounts instead of para ID. pub mod slots_crowdloan_index_migration { use super::*; diff --git a/polkadot/runtime/common/src/slots/mod.rs b/polkadot/runtime/common/src/slots/mod.rs index a3efd5bfa30a..3641cd5edfde 100644 --- a/polkadot/runtime/common/src/slots/mod.rs +++ b/polkadot/runtime/common/src/slots/mod.rs @@ -26,8 +26,9 @@ pub mod migration; use crate::traits::{LeaseError, Leaser, Registrar}; use frame_support::{ + defensive_assert, pallet_prelude::*, - traits::{Currency, ReservableCurrency}, + traits::fungible::{hold::Mutate as FunHoldMutate, Inspect as FunInspect, Mutate as FunMutate}, weights::Weight, }; use frame_system::pallet_prelude::*; @@ -37,7 +38,8 @@ use sp_runtime::traits::{CheckedConversion, CheckedSub, Saturating, Zero}; use sp_std::prelude::*; type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as FunInspect<::AccountId>>::Balance; + type LeasePeriodOf = BlockNumberFor; pub trait WeightInfo { @@ -68,6 +70,7 @@ pub mod pallet { use super::*; #[pallet::pallet] + #[pallet::storage_version(migration::STORAGE_VERSION)] #[pallet::without_storage_info] pub struct Pallet(_); @@ -77,7 +80,11 @@ pub mod pallet { type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// The currency type used for bidding. - type Currency: ReservableCurrency; + type Currency: FunHoldMutate + + FunMutate; + + /// The hold reason when reserving funds for the lease. + type RuntimeHoldReason: From; /// The parachain registrar type. type Registrar: Registrar; @@ -144,6 +151,14 @@ pub mod pallet { LeaseError, } + /// A reason for the pallet placing a hold on funds. + #[pallet::composite_enum] + pub enum HoldReason { + /// Funds are held for the current or upcoming leases. + #[codec(index = 0)] + LeaseDeposit, + } + #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(n: BlockNumberFor) -> Weight { @@ -192,8 +207,7 @@ pub mod pallet { // Refund any deposits for these leases for (who, deposit) in deposits { - let err_amount = T::Currency::unreserve(&who, deposit); - debug_assert!(err_amount.is_zero()); + Self::release(&who, deposit); } Leases::::remove(para); @@ -247,9 +261,9 @@ impl Pallet { // // `para` is now just an on-demand parachain. // - // Unreserve whatever is left. + // Release whatever is left. if let Some((who, value)) = &lease_periods[0] { - T::Currency::unreserve(&who, *value); + Self::release(&who, *value); } // Remove the now-empty lease list. @@ -270,9 +284,9 @@ impl Pallet { let now_held = Self::deposit_held(para, &ended_lease.0); // If this is less than what we were holding for this leaser's now-ended lease, - // then unreserve it. + // then release it. if let Some(rebate) = ended_lease.1.checked_sub(&now_held) { - T::Currency::unreserve(&ended_lease.0, rebate); + Self::release(&ended_lease.0, rebate); } } @@ -308,7 +322,7 @@ impl Pallet { // Return a vector of (user, balance) for all deposits for a parachain. // Useful when trying to clean up a parachain leases, as this would tell - // you all the balances you need to unreserve. + // you all the balances you need to release. fn all_deposits_held(para: ParaId) -> Vec<(T::AccountId, BalanceOf)> { let mut tracker = sp_std::collections::btree_map::BTreeMap::new(); Leases::::get(para).into_iter().for_each(|lease| match lease { @@ -326,6 +340,21 @@ impl Pallet { tracker.into_iter().collect() } + + fn hold(leaser: &T::AccountId, amount: BalanceOf) -> DispatchResult { + T::Currency::hold(&HoldReason::LeaseDeposit.into(), leaser, amount) + } + + fn release(leaser: &T::AccountId, amount: BalanceOf) { + let released_amount = T::Currency::release( + &HoldReason::LeaseDeposit.into(), + &leaser, + amount, + frame_support::traits::tokens::Precision::BestEffort, + ); + + defensive_assert!(released_amount.is_ok() && released_amount.unwrap() == amount); + } } impl crate::traits::OnSwap for Pallet { @@ -342,7 +371,7 @@ impl Leaser> for Pallet { fn lease_out( para: ParaId, leaser: &Self::AccountId, - amount: >::Balance, + amount: BalanceOf, period_begin: Self::LeasePeriod, period_count: Self::LeasePeriod, ) -> Result<(), LeaseError> { @@ -397,8 +426,7 @@ impl Leaser> for Pallet { // `para_id`. If so, then we can deduct those from the amount that we need to reserve. let maybe_additional = amount.checked_sub(&Self::deposit_held(para, &leaser)); if let Some(ref additional) = maybe_additional { - T::Currency::reserve(&leaser, *additional) - .map_err(|_| LeaseError::ReserveFailed)?; + Self::hold(&leaser, *additional).map_err(|_| LeaseError::ReserveFailed)?; } let reserved = maybe_additional.unwrap_or_default(); @@ -424,10 +452,7 @@ impl Leaser> for Pallet { }) } - fn deposit_held( - para: ParaId, - leaser: &Self::AccountId, - ) -> >::Balance { + fn deposit_held(para: ParaId, leaser: &Self::AccountId) -> BalanceOf { Leases::::get(para) .into_iter() .map(|lease| match lease { @@ -522,7 +547,7 @@ mod tests { { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, + Slots: slots::{Pallet, Call, Storage, Event, HoldReason}, } ); @@ -584,6 +609,7 @@ mod tests { impl Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; + type RuntimeHoldReason = RuntimeHoldReason; type Registrar = TestRegistrar; type LeasePeriod = LeasePeriod; type LeaseOffset = LeaseOffset; @@ -987,7 +1013,7 @@ mod tests { #[cfg(feature = "runtime-benchmarks")] mod benchmarking { use super::*; - use frame_support::assert_ok; + use frame_support::{assert_ok, traits::fungible::hold::Inspect}; use frame_system::RawOrigin; use runtime_parachains::paras; use sp_runtime::traits::{Bounded, One}; @@ -1008,7 +1034,7 @@ mod benchmarking { fn register_a_parathread(i: u32) -> (ParaId, T::AccountId) { let para = ParaId::from(i); let leaser: T::AccountId = account("leaser", i, 0); - T::Currency::make_free_balance_be(&leaser, BalanceOf::::max_value()); + T::Currency::set_balance(&leaser, BalanceOf::::max_value()); let worst_head_data = T::Registrar::worst_head_data(); let worst_validation_code = T::Registrar::worst_validation_code(); @@ -1036,7 +1062,7 @@ mod benchmarking { frame_system::Pallet::::set_block_number(T::LeaseOffset::get() + One::one()); let para = ParaId::from(1337); let leaser: T::AccountId = account("leaser", 0, 0); - T::Currency::make_free_balance_be(&leaser, BalanceOf::::max_value()); + T::Currency::set_balance(&leaser, BalanceOf::::max_value()); let amount = T::Currency::minimum_balance(); let period_begin = 69u32.into(); let period_count = 3u32.into(); @@ -1122,7 +1148,7 @@ mod benchmarking { for i in 0 .. max_people { let leaser = account("lease_deposit", i, 0); let amount = T::Currency::minimum_balance(); - T::Currency::make_free_balance_be(&leaser, BalanceOf::::max_value()); + T::Currency::set_balance(&leaser, BalanceOf::::max_value()); // Average slot has 4 lease periods. let period_count: LeasePeriodOf = 4u32.into(); @@ -1134,7 +1160,7 @@ mod benchmarking { for i in 0 .. max_people { let leaser = account("lease_deposit", i, 0); - assert_eq!(T::Currency::reserved_balance(&leaser), T::Currency::minimum_balance()); + assert_eq!(T::Currency::balance_on_hold(&HoldReason::LeaseDeposit.into(), &leaser), T::Currency::minimum_balance()); } let origin = @@ -1143,7 +1169,7 @@ mod benchmarking { verify { for i in 0 .. max_people { let leaser = account("lease_deposit", i, 0); - assert_eq!(T::Currency::reserved_balance(&leaser), 0u32.into()); + assert_eq!(T::Currency::balance_on_hold(&HoldReason::LeaseDeposit.into(), &leaser), 0u32.into()); } } diff --git a/polkadot/runtime/common/src/traits.rs b/polkadot/runtime/common/src/traits.rs index 8f75bf5c2fd8..759b8c027c6e 100644 --- a/polkadot/runtime/common/src/traits.rs +++ b/polkadot/runtime/common/src/traits.rs @@ -18,7 +18,10 @@ use frame_support::{ dispatch::DispatchResult, - traits::{Currency, ReservableCurrency}, + traits::{ + fungible::{hold::Mutate as FunHoldMutate, Inspect as FunInspect, Mutate as FunMutate}, + Currency, ReservableCurrency, + }, }; use primitives::{HeadData, Id as ParaId, ValidationCode}; use sp_std::vec::*; @@ -109,7 +112,7 @@ pub trait Leaser { type LeasePeriod; /// The currency type in which the lease is taken. - type Currency: ReservableCurrency; + type Currency: FunHoldMutate + FunMutate; /// Lease a new parachain slot for `para`. /// @@ -126,7 +129,7 @@ pub trait Leaser { fn lease_out( para: ParaId, leaser: &Self::AccountId, - amount: >::Balance, + amount: >::Balance, period_begin: Self::LeasePeriod, period_count: Self::LeasePeriod, ) -> Result<(), LeaseError>; @@ -136,7 +139,7 @@ pub trait Leaser { fn deposit_held( para: ParaId, leaser: &Self::AccountId, - ) -> >::Balance; + ) -> >::Balance; /// The length of a lease period, and any offset which may be introduced. /// This is only used in benchmarking to automate certain calls. diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index f4264ea35336..eb1f4658a11a 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1029,6 +1029,7 @@ parameter_types! { impl slots::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; + type RuntimeHoldReason = RuntimeHoldReason; type Registrar = Registrar; type LeasePeriod = LeasePeriod; type LeaseOffset = (); @@ -1068,6 +1069,7 @@ parameter_types! { impl auctions::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Leaser = Slots; + type Currency = Balances; type Registrar = Registrar; type EndingPeriod = EndingPeriod; type SampleLength = SampleLength; @@ -1093,7 +1095,7 @@ impl pallet_balances::Config for Runtime { type WeightInfo = weights::pallet_balances_nis_counterpart_balances::WeightInfo; type RuntimeHoldReason = RuntimeHoldReason; type FreezeIdentifier = (); - type MaxHolds = ConstU32<0>; + type MaxHolds = ConstU32<1>; type MaxFreezes = ConstU32<0>; } @@ -1356,7 +1358,7 @@ construct_runtime! { // Parachain Onboarding Pallets. Start indices at 70 to leave room. Registrar: paras_registrar::{Pallet, Call, Storage, Event, Config} = 70, - Slots: slots::{Pallet, Call, Storage, Event} = 71, + Slots: slots::{Pallet, Call, Storage, Event, HoldReason} = 71, Auctions: auctions::{Pallet, Call, Storage, Event} = 72, Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 73, diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index a7ddfc52ce6c..7a69f9311d3b 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1288,6 +1288,7 @@ parameter_types! { impl slots::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; + type RuntimeHoldReason = RuntimeHoldReason; type Registrar = Registrar; type LeasePeriod = LeasePeriod; type LeaseOffset = (); @@ -1327,6 +1328,7 @@ parameter_types! { impl auctions::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Leaser = Slots; + type Currency = Balances; type Registrar = Registrar; type EndingPeriod = EndingPeriod; type SampleLength = SampleLength; @@ -1477,7 +1479,7 @@ construct_runtime! { // Parachain Onboarding Pallets. Start indices at 60 to leave room. Registrar: paras_registrar::{Pallet, Call, Storage, Event, Config} = 60, - Slots: slots::{Pallet, Call, Storage, Event} = 61, + Slots: slots::{Pallet, Call, Storage, Event, HoldReason} = 61, ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 62, Auctions: auctions::{Pallet, Call, Storage, Event} = 63, Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 64, @@ -1557,6 +1559,7 @@ pub mod migrations { pallet_nomination_pools::migration::versioned_migrations::V5toV6, pallet_referenda::migration::v1::MigrateV0ToV1, pallet_nomination_pools::migration::versioned_migrations::V6ToV7, + slots::migration::versioned::ToV1, ); }