1pub mod benchmarking;
27pub mod migration;
28
29use crate::{
30 slots::{self, Pezpallet as Slots, WeightInfo as SlotsWeightInfo},
31 traits::{LeaseError, Leaser, Registrar},
32};
33use alloc::vec::Vec;
34use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
35use pezframe_support::{pezpallet_prelude::*, traits::Currency};
36use pezframe_system::pezpallet_prelude::*;
37use pezkuwi_primitives::Id as ParaId;
38use pezkuwi_runtime_teyrchains::{
39 configuration,
40 paras::{self},
41};
42pub use pezpallet::*;
43use pezsp_runtime::traits::{One, Saturating, Zero};
44use scale_info::TypeInfo;
45
46const LOG_TARGET: &str = "runtime::assigned_slots";
47
48#[derive(
50 Encode, Decode, DecodeWithMemTracking, Clone, Copy, Eq, PartialEq, RuntimeDebug, TypeInfo,
51)]
52pub enum SlotLeasePeriodStart {
53 Current,
54 Next,
55}
56
57#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, MaxEncodedLen, RuntimeDebug, TypeInfo)]
59pub struct TeyrchainTemporarySlot<AccountId, LeasePeriod> {
60 pub manager: AccountId,
62 pub period_begin: LeasePeriod,
66 pub period_count: LeasePeriod,
69 pub last_lease: Option<LeasePeriod>,
72 pub lease_count: u32,
74}
75
76pub trait WeightInfo {
77 fn assign_perm_teyrchain_slot() -> Weight;
78 fn assign_temp_teyrchain_slot() -> Weight;
79 fn unassign_teyrchain_slot() -> Weight;
80 fn set_max_permanent_slots() -> Weight;
81 fn set_max_temporary_slots() -> Weight;
82}
83
84pub struct TestWeightInfo;
85impl WeightInfo for TestWeightInfo {
86 fn assign_perm_teyrchain_slot() -> Weight {
87 Weight::zero()
88 }
89 fn assign_temp_teyrchain_slot() -> Weight {
90 Weight::zero()
91 }
92 fn unassign_teyrchain_slot() -> Weight {
93 Weight::zero()
94 }
95 fn set_max_permanent_slots() -> Weight {
96 Weight::zero()
97 }
98 fn set_max_temporary_slots() -> Weight {
99 Weight::zero()
100 }
101}
102
103type BalanceOf<T> = <<<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::Currency as Currency<
104 <T as pezframe_system::Config>::AccountId,
105>>::Balance;
106type LeasePeriodOf<T> = <<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::LeasePeriod;
107
108#[pezframe_support::pezpallet]
109pub mod pezpallet {
110 use super::*;
111
112 const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
114
115 #[pezpallet::pezpallet]
116 #[pezpallet::storage_version(STORAGE_VERSION)]
117 pub struct Pezpallet<T>(_);
118
119 #[pezpallet::config]
120 #[pezpallet::disable_pezframe_system_supertrait_check]
121 pub trait Config: configuration::Config + paras::Config + slots::Config {
122 #[allow(deprecated)]
124 type RuntimeEvent: From<Event<Self>>
125 + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
126
127 type AssignSlotOrigin: EnsureOrigin<<Self as pezframe_system::Config>::RuntimeOrigin>;
129
130 type Leaser: Leaser<
132 BlockNumberFor<Self>,
133 AccountId = Self::AccountId,
134 LeasePeriod = BlockNumberFor<Self>,
135 >;
136
137 #[pezpallet::constant]
139 type PermanentSlotLeasePeriodLength: Get<u32>;
140
141 #[pezpallet::constant]
143 type TemporarySlotLeasePeriodLength: Get<u32>;
144
145 #[pezpallet::constant]
147 type MaxTemporarySlotPerLeasePeriod: Get<u32>;
148
149 type WeightInfo: WeightInfo;
151 }
152
153 #[pezpallet::storage]
155 pub type PermanentSlots<T: Config> =
156 StorageMap<_, Twox64Concat, ParaId, (LeasePeriodOf<T>, LeasePeriodOf<T>), OptionQuery>;
157
158 #[pezpallet::storage]
160 pub type PermanentSlotCount<T: Config> = StorageValue<_, u32, ValueQuery>;
161
162 #[pezpallet::storage]
164 pub type TemporarySlots<T: Config> = StorageMap<
165 _,
166 Twox64Concat,
167 ParaId,
168 TeyrchainTemporarySlot<T::AccountId, LeasePeriodOf<T>>,
169 OptionQuery,
170 >;
171
172 #[pezpallet::storage]
174 pub type TemporarySlotCount<T: Config> = StorageValue<_, u32, ValueQuery>;
175
176 #[pezpallet::storage]
178 pub type ActiveTemporarySlotCount<T: Config> = StorageValue<_, u32, ValueQuery>;
179
180 #[pezpallet::storage]
182 pub type MaxTemporarySlots<T: Config> = StorageValue<_, u32, ValueQuery>;
183
184 #[pezpallet::storage]
186 pub type MaxPermanentSlots<T: Config> = StorageValue<_, u32, ValueQuery>;
187
188 #[pezpallet::genesis_config]
189 #[derive(pezframe_support::DefaultNoBound)]
190 pub struct GenesisConfig<T: Config> {
191 pub max_temporary_slots: u32,
192 pub max_permanent_slots: u32,
193 #[serde(skip)]
194 pub _config: PhantomData<T>,
195 }
196
197 #[pezpallet::genesis_build]
198 impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
199 fn build(&self) {
200 MaxPermanentSlots::<T>::put(&self.max_permanent_slots);
201 MaxTemporarySlots::<T>::put(&self.max_temporary_slots);
202 }
203 }
204
205 #[pezpallet::event]
206 #[pezpallet::generate_deposit(pub(super) fn deposit_event)]
207 pub enum Event<T: Config> {
208 PermanentSlotAssigned(ParaId),
210 TemporarySlotAssigned(ParaId),
212 MaxPermanentSlotsChanged { slots: u32 },
214 MaxTemporarySlotsChanged { slots: u32 },
216 }
217
218 #[pezpallet::error]
219 pub enum Error<T> {
220 ParaDoesntExist,
222 NotParathread,
224 CannotUpgrade,
227 CannotDowngrade,
230 SlotAlreadyAssigned,
232 SlotNotAssigned,
234 OngoingLeaseExists,
236 MaxPermanentSlotsExceeded,
238 MaxTemporarySlotsExceeded,
240 }
241
242 #[pezpallet::hooks]
243 impl<T: Config> Hooks<BlockNumberFor<T>> for Pezpallet<T> {
244 fn on_initialize(n: BlockNumberFor<T>) -> Weight {
245 if let Some((lease_period, first_block)) = Self::lease_period_index(n) {
246 if first_block {
248 return Self::manage_lease_period_start(lease_period);
249 }
250 }
251
252 Weight::zero()
254 }
255 }
256
257 #[pezpallet::call]
258 impl<T: Config> Pezpallet<T> {
259 #[pezpallet::call_index(0)]
261 #[pezpallet::weight((<T as Config>::WeightInfo::assign_perm_teyrchain_slot(), DispatchClass::Operational))]
262 pub fn assign_perm_teyrchain_slot(origin: OriginFor<T>, id: ParaId) -> DispatchResult {
263 T::AssignSlotOrigin::ensure_origin(origin)?;
264
265 let manager = T::Registrar::manager_of(id).ok_or(Error::<T>::ParaDoesntExist)?;
266
267 ensure!(T::Registrar::is_parathread(id), Error::<T>::NotParathread);
268
269 ensure!(
270 !Self::has_permanent_slot(id) && !Self::has_temporary_slot(id),
271 Error::<T>::SlotAlreadyAssigned
272 );
273
274 let current_lease_period: BlockNumberFor<T> = Self::current_lease_period_index();
275 ensure!(
276 !T::Leaser::already_leased(
277 id,
278 current_lease_period,
279 current_lease_period.saturating_add(
281 BlockNumberFor::<T>::from(2u32)
282 .saturating_mul(T::PermanentSlotLeasePeriodLength::get().into())
283 )
284 ),
285 Error::<T>::OngoingLeaseExists
286 );
287
288 ensure!(
289 PermanentSlotCount::<T>::get() < MaxPermanentSlots::<T>::get(),
290 Error::<T>::MaxPermanentSlotsExceeded
291 );
292
293 Self::configure_slot_lease(
295 id,
296 manager,
297 current_lease_period,
298 T::PermanentSlotLeasePeriodLength::get().into(),
299 )
300 .map_err(|_| Error::<T>::CannotUpgrade)?;
301
302 PermanentSlots::<T>::insert(
303 id,
304 (
305 current_lease_period,
306 LeasePeriodOf::<T>::from(T::PermanentSlotLeasePeriodLength::get()),
307 ),
308 );
309 PermanentSlotCount::<T>::mutate(|count| count.saturating_inc());
310
311 Self::deposit_event(Event::<T>::PermanentSlotAssigned(id));
312 Ok(())
313 }
314
315 #[pezpallet::call_index(1)]
319 #[pezpallet::weight((<T as Config>::WeightInfo::assign_temp_teyrchain_slot(), DispatchClass::Operational))]
320 pub fn assign_temp_teyrchain_slot(
321 origin: OriginFor<T>,
322 id: ParaId,
323 lease_period_start: SlotLeasePeriodStart,
324 ) -> DispatchResult {
325 T::AssignSlotOrigin::ensure_origin(origin)?;
326
327 let manager = T::Registrar::manager_of(id).ok_or(Error::<T>::ParaDoesntExist)?;
328
329 ensure!(T::Registrar::is_parathread(id), Error::<T>::NotParathread);
330
331 ensure!(
332 !Self::has_permanent_slot(id) && !Self::has_temporary_slot(id),
333 Error::<T>::SlotAlreadyAssigned
334 );
335
336 let current_lease_period: BlockNumberFor<T> = Self::current_lease_period_index();
337 ensure!(
338 !T::Leaser::already_leased(
339 id,
340 current_lease_period,
341 current_lease_period.saturating_add(
343 BlockNumberFor::<T>::from(2u32)
344 .saturating_mul(T::TemporarySlotLeasePeriodLength::get().into())
345 )
346 ),
347 Error::<T>::OngoingLeaseExists
348 );
349
350 ensure!(
351 TemporarySlotCount::<T>::get() < MaxTemporarySlots::<T>::get(),
352 Error::<T>::MaxTemporarySlotsExceeded
353 );
354
355 let mut temp_slot = TeyrchainTemporarySlot {
356 manager: manager.clone(),
357 period_begin: match lease_period_start {
358 SlotLeasePeriodStart::Current => current_lease_period,
359 SlotLeasePeriodStart::Next => current_lease_period + One::one(),
360 },
361 period_count: T::TemporarySlotLeasePeriodLength::get().into(),
362 last_lease: None,
363 lease_count: 0,
364 };
365
366 if lease_period_start == SlotLeasePeriodStart::Current
367 && ActiveTemporarySlotCount::<T>::get() < T::MaxTemporarySlotPerLeasePeriod::get()
368 {
369 match Self::configure_slot_lease(
371 id,
372 manager,
373 temp_slot.period_begin,
374 temp_slot.period_count,
375 ) {
376 Ok(_) => {
377 ActiveTemporarySlotCount::<T>::mutate(|count| count.saturating_inc());
378 temp_slot.last_lease = Some(temp_slot.period_begin);
379 temp_slot.lease_count += 1;
380 },
381 Err(err) => {
382 log::warn!(
386 target: LOG_TARGET,
387 "Failed to allocate a temp slot for para {:?} at period {:?}: {:?}",
388 id,
389 current_lease_period,
390 err
391 );
392 },
393 }
394 }
395
396 TemporarySlots::<T>::insert(id, temp_slot);
397 TemporarySlotCount::<T>::mutate(|count| count.saturating_inc());
398
399 Self::deposit_event(Event::<T>::TemporarySlotAssigned(id));
400
401 Ok(())
402 }
403
404 #[pezpallet::call_index(2)]
406 #[pezpallet::weight((<T as Config>::WeightInfo::unassign_teyrchain_slot(), DispatchClass::Operational))]
407 pub fn unassign_teyrchain_slot(origin: OriginFor<T>, id: ParaId) -> DispatchResult {
408 T::AssignSlotOrigin::ensure_origin(origin.clone())?;
409
410 ensure!(
411 Self::has_permanent_slot(id) || Self::has_temporary_slot(id),
412 Error::<T>::SlotNotAssigned
413 );
414
415 let is_teyrchain = Self::is_teyrchain(id);
417
418 Self::clear_slot_leases(origin.clone(), id)?;
420
421 if PermanentSlots::<T>::contains_key(id) {
422 PermanentSlots::<T>::remove(id);
423 PermanentSlotCount::<T>::mutate(|count| *count = count.saturating_sub(One::one()));
424 } else if TemporarySlots::<T>::contains_key(id) {
425 TemporarySlots::<T>::remove(id);
426 TemporarySlotCount::<T>::mutate(|count| *count = count.saturating_sub(One::one()));
427 if is_teyrchain {
428 ActiveTemporarySlotCount::<T>::mutate(|active_count| {
429 *active_count = active_count.saturating_sub(One::one())
430 });
431 }
432 }
433
434 if is_teyrchain {
436 if let Err(err) = pezkuwi_runtime_teyrchains::schedule_teyrchain_downgrade::<T>(id)
437 {
438 log::warn!(
442 target: LOG_TARGET,
443 "Failed to downgrade teyrchain {:?} at period {:?}: {:?}",
444 id,
445 Self::current_lease_period_index(),
446 err
447 );
448 }
449 }
450
451 Ok(())
452 }
453
454 #[pezpallet::call_index(3)]
456 #[pezpallet::weight((<T as Config>::WeightInfo::set_max_permanent_slots(), DispatchClass::Operational))]
457 pub fn set_max_permanent_slots(origin: OriginFor<T>, slots: u32) -> DispatchResult {
458 ensure_root(origin)?;
459
460 MaxPermanentSlots::<T>::put(slots);
461
462 Self::deposit_event(Event::<T>::MaxPermanentSlotsChanged { slots });
463 Ok(())
464 }
465
466 #[pezpallet::call_index(4)]
468 #[pezpallet::weight((<T as Config>::WeightInfo::set_max_temporary_slots(), DispatchClass::Operational))]
469 pub fn set_max_temporary_slots(origin: OriginFor<T>, slots: u32) -> DispatchResult {
470 ensure_root(origin)?;
471
472 MaxTemporarySlots::<T>::put(slots);
473
474 Self::deposit_event(Event::<T>::MaxTemporarySlotsChanged { slots });
475 Ok(())
476 }
477 }
478}
479
480impl<T: Config> Pezpallet<T> {
481 fn allocate_temporary_slot_leases(lease_period_index: LeasePeriodOf<T>) -> DispatchResult {
495 let mut active_temp_slots = 0u32;
496 let mut pending_temp_slots = Vec::new();
497 TemporarySlots::<T>::iter().for_each(|(para, slot)| {
498 match slot.last_lease {
499 Some(last_lease)
500 if last_lease <= lease_period_index &&
501 lease_period_index <
502 (last_lease.saturating_add(slot.period_count)) =>
503 {
504 active_temp_slots += 1;
506 }
507 Some(last_lease)
508 if last_lease.saturating_add(slot.period_count.saturating_mul(2u32.into())) <= lease_period_index => {
510 pending_temp_slots.push((para, slot));
511 },
512 None if slot.period_begin <= lease_period_index => {
513 pending_temp_slots.insert(0, (para, slot));
515 },
516 _ => {
517 },
519 }
520 });
521
522 let mut newly_created_lease = 0u32;
523 if active_temp_slots < T::MaxTemporarySlotPerLeasePeriod::get()
524 && !pending_temp_slots.is_empty()
525 {
526 pending_temp_slots.sort_by(|a, b| {
529 a.1.lease_count
530 .cmp(&b.1.lease_count)
531 .then_with(|| a.1.last_lease.cmp(&b.1.last_lease))
532 .then_with(|| a.0.cmp(&b.0))
533 });
534
535 let slots_to_be_upgraded = pending_temp_slots.iter().take(
536 (T::MaxTemporarySlotPerLeasePeriod::get().saturating_sub(active_temp_slots))
537 as usize,
538 );
539
540 for (id, temp_slot) in slots_to_be_upgraded {
541 TemporarySlots::<T>::try_mutate::<_, _, Error<T>, _>(id, |s| {
542 Self::configure_slot_lease(
544 *id,
545 temp_slot.manager.clone(),
546 lease_period_index,
547 temp_slot.period_count,
548 )
549 .map_err(|_| Error::<T>::CannotUpgrade)?;
550
551 *s = Some(TeyrchainTemporarySlot {
553 manager: temp_slot.manager.clone(),
554 period_begin: temp_slot.period_begin,
555 period_count: temp_slot.period_count,
556 last_lease: Some(lease_period_index),
557 lease_count: temp_slot.lease_count + 1,
558 });
559
560 newly_created_lease += 1;
561
562 Ok(())
563 })?;
564 }
565 }
566
567 ActiveTemporarySlotCount::<T>::set(active_temp_slots + newly_created_lease);
568
569 Ok(())
570 }
571
572 fn clear_slot_leases(origin: OriginFor<T>, id: ParaId) -> DispatchResult {
575 Slots::<T>::clear_all_leases(origin, id)
576 }
577
578 fn configure_slot_lease(
581 para: ParaId,
582 manager: T::AccountId,
583 lease_period: LeasePeriodOf<T>,
584 lease_duration: LeasePeriodOf<T>,
585 ) -> Result<(), LeaseError> {
586 T::Leaser::lease_out(para, &manager, BalanceOf::<T>::zero(), lease_period, lease_duration)
587 }
588
589 fn has_permanent_slot(id: ParaId) -> bool {
591 PermanentSlots::<T>::contains_key(id)
592 }
593
594 fn has_temporary_slot(id: ParaId) -> bool {
596 TemporarySlots::<T>::contains_key(id)
597 }
598
599 fn is_teyrchain(id: ParaId) -> bool {
601 T::Registrar::is_teyrchain(id)
602 }
603
604 fn current_lease_period_index() -> LeasePeriodOf<T> {
606 T::Leaser::lease_period_index(pezframe_system::Pezpallet::<T>::block_number())
607 .and_then(|x| Some(x.0))
608 .unwrap()
609 }
610
611 fn lease_period_index(block: BlockNumberFor<T>) -> Option<(LeasePeriodOf<T>, bool)> {
613 T::Leaser::lease_period_index(block)
614 }
615
616 fn manage_lease_period_start(lease_period_index: LeasePeriodOf<T>) -> Weight {
618 if let Err(err) = Self::allocate_temporary_slot_leases(lease_period_index) {
621 log::error!(
622 target: LOG_TARGET,
623 "Allocating slots failed for lease period {:?}, with: {:?}",
624 lease_period_index,
625 err
626 );
627 }
628 <T as slots::Config>::WeightInfo::force_lease()
629 * (T::MaxTemporarySlotPerLeasePeriod::get() as u64)
630 }
631}
632
633#[cfg(test)]
635mod tests {
636 use super::*;
637
638 use crate::{assigned_slots, mock::TestRegistrar, slots};
639 use pezframe_support::{assert_noop, assert_ok, derive_impl, parameter_types};
640 use pezframe_system::EnsureRoot;
641 use pezkuwi_primitives::BlockNumber;
642 use pezkuwi_primitives_test_helpers::{dummy_head_data, dummy_validation_code};
643 use pezkuwi_runtime_teyrchains::{
644 configuration as teyrchains_configuration, paras as teyrchains_paras,
645 shared as teyrchains_shared,
646 };
647 use pezpallet_balances;
648 use pezsp_core::H256;
649 use pezsp_runtime::{
650 traits::{BlakeTwo256, IdentityLookup},
651 transaction_validity::TransactionPriority,
652 BuildStorage,
653 DispatchError::BadOrigin,
654 };
655
656 type UncheckedExtrinsic = pezframe_system::mocking::MockUncheckedExtrinsic<Test>;
657 type Block = pezframe_system::mocking::MockBlockU32<Test>;
658
659 pezframe_support::construct_runtime!(
660 pub enum Test
661 {
662 System: pezframe_system,
663 Balances: pezpallet_balances,
664 Configuration: teyrchains_configuration,
665 ParasShared: teyrchains_shared,
666 Teyrchains: teyrchains_paras,
667 Slots: slots,
668 AssignedSlots: assigned_slots,
669 }
670 );
671
672 impl<C> pezframe_system::offchain::CreateTransactionBase<C> for Test
673 where
674 RuntimeCall: From<C>,
675 {
676 type Extrinsic = UncheckedExtrinsic;
677 type RuntimeCall = RuntimeCall;
678 }
679
680 impl<C> pezframe_system::offchain::CreateBare<C> for Test
681 where
682 RuntimeCall: From<C>,
683 {
684 fn create_bare(call: Self::RuntimeCall) -> Self::Extrinsic {
685 UncheckedExtrinsic::new_bare(call)
686 }
687 }
688
689 #[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
690 impl pezframe_system::Config for Test {
691 type BaseCallFilter = pezframe_support::traits::Everything;
692 type BlockWeights = ();
693 type BlockLength = ();
694 type RuntimeOrigin = RuntimeOrigin;
695 type RuntimeCall = RuntimeCall;
696 type Nonce = u64;
697 type Hash = H256;
698 type Hashing = BlakeTwo256;
699 type AccountId = u64;
700 type Lookup = IdentityLookup<Self::AccountId>;
701 type Block = Block;
702 type RuntimeEvent = RuntimeEvent;
703 type DbWeight = ();
704 type Version = ();
705 type PalletInfo = PalletInfo;
706 type AccountData = pezpallet_balances::AccountData<u64>;
707 type OnNewAccount = ();
708 type OnKilledAccount = ();
709 type SystemWeightInfo = ();
710 type SS58Prefix = ();
711 type OnSetCode = ();
712 type MaxConsumers = pezframe_support::traits::ConstU32<16>;
713 }
714
715 #[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
716 impl pezpallet_balances::Config for Test {
717 type AccountStore = System;
718 }
719
720 impl teyrchains_configuration::Config for Test {
721 type WeightInfo = teyrchains_configuration::TestWeightInfo;
722 }
723
724 parameter_types! {
725 pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
726 }
727
728 impl teyrchains_paras::Config for Test {
729 type RuntimeEvent = RuntimeEvent;
730 type WeightInfo = teyrchains_paras::TestWeightInfo;
731 type UnsignedPriority = ParasUnsignedPriority;
732 type QueueFootprinter = ();
733 type NextSessionRotation = crate::mock::TestNextSessionRotation;
734 type OnNewHead = ();
735 type AssignCoretime = ();
736 type Fungible = Balances;
737 type CooldownRemovalMultiplier = ConstUint<1>;
738 type AuthorizeCurrentCodeOrigin = EnsureRoot<Self::AccountId>;
739 }
740
741 impl teyrchains_shared::Config for Test {
742 type DisabledValidators = ();
743 }
744
745 parameter_types! {
746 pub const LeasePeriod: BlockNumber = 3;
747 pub static LeaseOffset: BlockNumber = 0;
748 pub const ParaDeposit: u64 = 1;
749 }
750
751 impl slots::Config for Test {
752 type RuntimeEvent = RuntimeEvent;
753 type Currency = Balances;
754 type Registrar = TestRegistrar<Test>;
755 type LeasePeriod = LeasePeriod;
756 type LeaseOffset = LeaseOffset;
757 type ForceOrigin = EnsureRoot<Self::AccountId>;
758 type WeightInfo = crate::slots::TestWeightInfo;
759 }
760
761 parameter_types! {
762 pub const PermanentSlotLeasePeriodLength: u32 = 3;
763 pub const TemporarySlotLeasePeriodLength: u32 = 2;
764 pub const MaxTemporarySlotPerLeasePeriod: u32 = 2;
765 }
766
767 impl assigned_slots::Config for Test {
768 type RuntimeEvent = RuntimeEvent;
769 type AssignSlotOrigin = EnsureRoot<Self::AccountId>;
770 type Leaser = Slots;
771 type PermanentSlotLeasePeriodLength = PermanentSlotLeasePeriodLength;
772 type TemporarySlotLeasePeriodLength = TemporarySlotLeasePeriodLength;
773 type MaxTemporarySlotPerLeasePeriod = MaxTemporarySlotPerLeasePeriod;
774 type WeightInfo = crate::assigned_slots::TestWeightInfo;
775 }
776
777 pub fn new_test_ext() -> pezsp_io::TestExternalities {
780 let mut t = pezframe_system::GenesisConfig::<Test>::default().build_storage().unwrap();
781 pezpallet_balances::GenesisConfig::<Test> {
782 balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
783 ..Default::default()
784 }
785 .assimilate_storage(&mut t)
786 .unwrap();
787
788 crate::assigned_slots::GenesisConfig::<Test> {
789 max_temporary_slots: 6,
790 max_permanent_slots: 2,
791 _config: Default::default(),
792 }
793 .assimilate_storage(&mut t)
794 .unwrap();
795
796 t.into()
797 }
798
799 #[test]
800 fn basic_setup_works() {
801 new_test_ext().execute_with(|| {
802 System::run_to_block::<AllPalletsWithSystem>(1);
803 assert_eq!(AssignedSlots::current_lease_period_index(), 0);
804 assert_eq!(Slots::deposit_held(1.into(), &1), 0);
805
806 System::run_to_block::<AllPalletsWithSystem>(3);
807 assert_eq!(AssignedSlots::current_lease_period_index(), 1);
808 });
809 }
810
811 #[test]
812 fn assign_perm_slot_fails_for_unknown_para() {
813 new_test_ext().execute_with(|| {
814 System::run_to_block::<AllPalletsWithSystem>(1);
815
816 assert_noop!(
817 AssignedSlots::assign_perm_teyrchain_slot(
818 RuntimeOrigin::root(),
819 ParaId::from(1_u32),
820 ),
821 Error::<Test>::ParaDoesntExist
822 );
823 });
824 }
825
826 #[test]
827 fn assign_perm_slot_fails_for_invalid_origin() {
828 new_test_ext().execute_with(|| {
829 System::run_to_block::<AllPalletsWithSystem>(1);
830
831 assert_noop!(
832 AssignedSlots::assign_perm_teyrchain_slot(
833 RuntimeOrigin::signed(1),
834 ParaId::from(1_u32),
835 ),
836 BadOrigin
837 );
838 });
839 }
840
841 #[test]
842 fn assign_perm_slot_fails_when_not_parathread() {
843 new_test_ext().execute_with(|| {
844 System::run_to_block::<AllPalletsWithSystem>(1);
845
846 assert_ok!(TestRegistrar::<Test>::register(
847 1,
848 ParaId::from(1_u32),
849 dummy_head_data(),
850 dummy_validation_code(),
851 ));
852 assert_ok!(TestRegistrar::<Test>::make_teyrchain(ParaId::from(1_u32)));
853
854 assert_noop!(
855 AssignedSlots::assign_perm_teyrchain_slot(
856 RuntimeOrigin::root(),
857 ParaId::from(1_u32),
858 ),
859 Error::<Test>::NotParathread
860 );
861 });
862 }
863
864 #[test]
865 fn assign_perm_slot_fails_when_existing_lease() {
866 new_test_ext().execute_with(|| {
867 System::run_to_block::<AllPalletsWithSystem>(1);
868
869 assert_ok!(TestRegistrar::<Test>::register(
870 1,
871 ParaId::from(1_u32),
872 dummy_head_data(),
873 dummy_validation_code(),
874 ));
875
876 assert_ok!(Slots::lease_out(ParaId::from(1_u32), &1, 1, 1, 1));
878 assert_noop!(
880 AssignedSlots::assign_perm_teyrchain_slot(
881 RuntimeOrigin::root(),
882 ParaId::from(1_u32),
883 ),
884 Error::<Test>::OngoingLeaseExists
885 );
886
887 assert_ok!(Slots::clear_all_leases(RuntimeOrigin::root(), 1.into()));
889
890 assert_ok!(Slots::lease_out(ParaId::from(1_u32), &1, 1, 2, 1));
892 assert_noop!(
894 AssignedSlots::assign_perm_teyrchain_slot(
895 RuntimeOrigin::root(),
896 ParaId::from(1_u32),
897 ),
898 Error::<Test>::OngoingLeaseExists
899 );
900 });
901 }
902
903 #[test]
904 fn assign_perm_slot_fails_when_max_perm_slots_exceeded() {
905 new_test_ext().execute_with(|| {
906 System::run_to_block::<AllPalletsWithSystem>(1);
907
908 assert_ok!(TestRegistrar::<Test>::register(
909 1,
910 ParaId::from(1_u32),
911 dummy_head_data(),
912 dummy_validation_code(),
913 ));
914
915 assert_ok!(TestRegistrar::<Test>::register(
916 2,
917 ParaId::from(2_u32),
918 dummy_head_data(),
919 dummy_validation_code(),
920 ));
921
922 assert_ok!(TestRegistrar::<Test>::register(
923 3,
924 ParaId::from(3_u32),
925 dummy_head_data(),
926 dummy_validation_code(),
927 ));
928
929 assert_ok!(AssignedSlots::assign_perm_teyrchain_slot(
930 RuntimeOrigin::root(),
931 ParaId::from(1_u32),
932 ));
933 assert_ok!(AssignedSlots::assign_perm_teyrchain_slot(
934 RuntimeOrigin::root(),
935 ParaId::from(2_u32),
936 ));
937 assert_eq!(assigned_slots::PermanentSlotCount::<Test>::get(), 2);
938
939 assert_noop!(
940 AssignedSlots::assign_perm_teyrchain_slot(
941 RuntimeOrigin::root(),
942 ParaId::from(3_u32),
943 ),
944 Error::<Test>::MaxPermanentSlotsExceeded
945 );
946 });
947 }
948
949 #[test]
950 fn assign_perm_slot_succeeds_for_parathread() {
951 new_test_ext().execute_with(|| {
952 let mut block = 1;
953 System::run_to_block::<AllPalletsWithSystem>(block);
954 assert_ok!(TestRegistrar::<Test>::register(
955 1,
956 ParaId::from(1_u32),
957 dummy_head_data(),
958 dummy_validation_code(),
959 ));
960
961 assert_eq!(assigned_slots::PermanentSlotCount::<Test>::get(), 0);
962 assert_eq!(assigned_slots::PermanentSlots::<Test>::get(ParaId::from(1_u32)), None);
963
964 assert_ok!(AssignedSlots::assign_perm_teyrchain_slot(
965 RuntimeOrigin::root(),
966 ParaId::from(1_u32),
967 ));
968
969 while block < 9 {
972 println!("block #{}", block);
973
974 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), true);
975
976 assert_eq!(assigned_slots::PermanentSlotCount::<Test>::get(), 1);
977 assert_eq!(AssignedSlots::has_permanent_slot(ParaId::from(1_u32)), true);
978 assert_eq!(
979 assigned_slots::PermanentSlots::<Test>::get(ParaId::from(1_u32)),
980 Some((0, 3))
981 );
982
983 assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 2), true);
984
985 block += 1;
986 System::run_to_block::<AllPalletsWithSystem>(block);
987 }
988
989 assert_eq!(TestRegistrar::<Test>::is_parathread(ParaId::from(1_u32)), true);
991 assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 5), false);
992 });
993 }
994
995 #[test]
996 fn assign_temp_slot_fails_for_unknown_para() {
997 new_test_ext().execute_with(|| {
998 System::run_to_block::<AllPalletsWithSystem>(1);
999
1000 assert_noop!(
1001 AssignedSlots::assign_temp_teyrchain_slot(
1002 RuntimeOrigin::root(),
1003 ParaId::from(1_u32),
1004 SlotLeasePeriodStart::Current
1005 ),
1006 Error::<Test>::ParaDoesntExist
1007 );
1008 });
1009 }
1010
1011 #[test]
1012 fn assign_temp_slot_fails_for_invalid_origin() {
1013 new_test_ext().execute_with(|| {
1014 System::run_to_block::<AllPalletsWithSystem>(1);
1015
1016 assert_noop!(
1017 AssignedSlots::assign_temp_teyrchain_slot(
1018 RuntimeOrigin::signed(1),
1019 ParaId::from(1_u32),
1020 SlotLeasePeriodStart::Current
1021 ),
1022 BadOrigin
1023 );
1024 });
1025 }
1026
1027 #[test]
1028 fn assign_temp_slot_fails_when_not_parathread() {
1029 new_test_ext().execute_with(|| {
1030 System::run_to_block::<AllPalletsWithSystem>(1);
1031
1032 assert_ok!(TestRegistrar::<Test>::register(
1033 1,
1034 ParaId::from(1_u32),
1035 dummy_head_data(),
1036 dummy_validation_code(),
1037 ));
1038 assert_ok!(TestRegistrar::<Test>::make_teyrchain(ParaId::from(1_u32)));
1039
1040 assert_noop!(
1041 AssignedSlots::assign_temp_teyrchain_slot(
1042 RuntimeOrigin::root(),
1043 ParaId::from(1_u32),
1044 SlotLeasePeriodStart::Current
1045 ),
1046 Error::<Test>::NotParathread
1047 );
1048 });
1049 }
1050
1051 #[test]
1052 fn assign_temp_slot_fails_when_existing_lease() {
1053 new_test_ext().execute_with(|| {
1054 System::run_to_block::<AllPalletsWithSystem>(1);
1055
1056 assert_ok!(TestRegistrar::<Test>::register(
1057 1,
1058 ParaId::from(1_u32),
1059 dummy_head_data(),
1060 dummy_validation_code(),
1061 ));
1062
1063 assert_ok!(Slots::lease_out(ParaId::from(1_u32), &1, 1, 1, 1));
1065 assert_noop!(
1067 AssignedSlots::assign_temp_teyrchain_slot(
1068 RuntimeOrigin::root(),
1069 ParaId::from(1_u32),
1070 SlotLeasePeriodStart::Current
1071 ),
1072 Error::<Test>::OngoingLeaseExists
1073 );
1074
1075 assert_ok!(Slots::clear_all_leases(RuntimeOrigin::root(), 1.into()));
1077
1078 assert_ok!(Slots::lease_out(ParaId::from(1_u32), &1, 1, 2, 1));
1080 assert_noop!(
1082 AssignedSlots::assign_temp_teyrchain_slot(
1083 RuntimeOrigin::root(),
1084 ParaId::from(1_u32),
1085 SlotLeasePeriodStart::Current
1086 ),
1087 Error::<Test>::OngoingLeaseExists
1088 );
1089 });
1090 }
1091
1092 #[test]
1093 fn assign_temp_slot_fails_when_max_temp_slots_exceeded() {
1094 new_test_ext().execute_with(|| {
1095 System::run_to_block::<AllPalletsWithSystem>(1);
1096
1097 for n in 0..=5 {
1099 assert_ok!(TestRegistrar::<Test>::register(
1100 n,
1101 ParaId::from(n as u32),
1102 dummy_head_data(),
1103 dummy_validation_code()
1104 ));
1105
1106 assert_ok!(AssignedSlots::assign_temp_teyrchain_slot(
1107 RuntimeOrigin::root(),
1108 ParaId::from(n as u32),
1109 SlotLeasePeriodStart::Current
1110 ));
1111 }
1112
1113 assert_eq!(assigned_slots::TemporarySlotCount::<Test>::get(), 6);
1114
1115 assert_ok!(TestRegistrar::<Test>::register(
1117 7,
1118 ParaId::from(7_u32),
1119 dummy_head_data(),
1120 dummy_validation_code(),
1121 ));
1122 assert_noop!(
1123 AssignedSlots::assign_temp_teyrchain_slot(
1124 RuntimeOrigin::root(),
1125 ParaId::from(7_u32),
1126 SlotLeasePeriodStart::Current
1127 ),
1128 Error::<Test>::MaxTemporarySlotsExceeded
1129 );
1130 });
1131 }
1132
1133 #[test]
1134 fn assign_temp_slot_succeeds_for_single_parathread() {
1135 new_test_ext().execute_with(|| {
1136 let mut block = 1;
1137 System::run_to_block::<AllPalletsWithSystem>(block);
1138 assert_ok!(TestRegistrar::<Test>::register(
1139 1,
1140 ParaId::from(1_u32),
1141 dummy_head_data(),
1142 dummy_validation_code(),
1143 ));
1144
1145 assert_eq!(assigned_slots::TemporarySlots::<Test>::get(ParaId::from(1_u32)), None);
1146
1147 assert_ok!(AssignedSlots::assign_temp_teyrchain_slot(
1148 RuntimeOrigin::root(),
1149 ParaId::from(1_u32),
1150 SlotLeasePeriodStart::Current
1151 ));
1152 assert_eq!(assigned_slots::TemporarySlotCount::<Test>::get(), 1);
1153 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 1);
1154
1155 while block < 6 {
1159 println!("block #{}", block);
1160 println!("lease period #{}", AssignedSlots::current_lease_period_index());
1161 println!("lease {:?}", slots::Leases::<Test>::get(ParaId::from(1_u32)));
1162
1163 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), true);
1164
1165 assert_eq!(AssignedSlots::has_temporary_slot(ParaId::from(1_u32)), true);
1166 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 1);
1167 assert_eq!(
1168 assigned_slots::TemporarySlots::<Test>::get(ParaId::from(1_u32)),
1169 Some(TeyrchainTemporarySlot {
1170 manager: 1,
1171 period_begin: 0,
1172 period_count: 2, last_lease: Some(0),
1174 lease_count: 1
1175 })
1176 );
1177
1178 assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 1), true);
1179
1180 block += 1;
1181 System::run_to_block::<AllPalletsWithSystem>(block);
1182 }
1183
1184 println!("block #{}", block);
1186 println!("lease period #{}", AssignedSlots::current_lease_period_index());
1187 println!("lease {:?}", slots::Leases::<Test>::get(ParaId::from(1_u32)));
1188
1189 assert_eq!(TestRegistrar::<Test>::is_parathread(ParaId::from(1_u32)), true);
1191 assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 3), false);
1192 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 0);
1193
1194 System::run_to_block::<AllPalletsWithSystem>(12);
1197 println!("block #{}", block);
1198 println!("lease period #{}", AssignedSlots::current_lease_period_index());
1199 println!("lease {:?}", slots::Leases::<Test>::get(ParaId::from(1_u32)));
1200
1201 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), true);
1202 assert_eq!(Slots::already_leased(ParaId::from(1_u32), 4, 5), true);
1203 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 1);
1204 });
1205 }
1206
1207 #[test]
1208 fn assign_temp_slot_succeeds_for_multiple_parathreads() {
1209 new_test_ext().execute_with(|| {
1210 System::run_to_block::<AllPalletsWithSystem>(1);
1212
1213 for n in 0..=5 {
1216 assert_ok!(TestRegistrar::<Test>::register(
1217 n,
1218 ParaId::from(n as u32),
1219 dummy_head_data(),
1220 dummy_validation_code()
1221 ));
1222
1223 assert_ok!(AssignedSlots::assign_temp_teyrchain_slot(
1224 RuntimeOrigin::root(),
1225 ParaId::from(n as u32),
1226 if (n % 2).is_zero() {
1227 SlotLeasePeriodStart::Current
1228 } else {
1229 SlotLeasePeriodStart::Next
1230 }
1231 ));
1232 }
1233
1234 for n in 1..=5 {
1236 if n > 1 {
1237 System::run_to_block::<AllPalletsWithSystem>(n);
1238 }
1239 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(0)), true);
1240 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), false);
1241 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(2_u32)), true);
1242 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(3_u32)), false);
1243 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(4_u32)), false);
1244 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(5_u32)), false);
1245 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 2);
1246 }
1247
1248 for n in 6..=11 {
1250 System::run_to_block::<AllPalletsWithSystem>(n);
1251 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(0)), false);
1252 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), true);
1253 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(2_u32)), false);
1254 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(3_u32)), true);
1255 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(4_u32)), false);
1256 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(5_u32)), false);
1257 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 2);
1258 }
1259
1260 for n in 12..=17 {
1262 System::run_to_block::<AllPalletsWithSystem>(n);
1263 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(0)), false);
1264 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), false);
1265 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(2_u32)), false);
1266 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(3_u32)), false);
1267 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(4_u32)), true);
1268 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(5_u32)), true);
1269 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 2);
1270 }
1271
1272 for n in 18..=23 {
1274 System::run_to_block::<AllPalletsWithSystem>(n);
1275 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(0)), true);
1276 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), false);
1277 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(2_u32)), true);
1278 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(3_u32)), false);
1279 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(4_u32)), false);
1280 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(5_u32)), false);
1281 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 2);
1282 }
1283
1284 for n in 24..=29 {
1286 System::run_to_block::<AllPalletsWithSystem>(n);
1287 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(0)), false);
1288 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), true);
1289 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(2_u32)), false);
1290 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(3_u32)), true);
1291 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(4_u32)), false);
1292 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(5_u32)), false);
1293 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 2);
1294 }
1295
1296 for n in 30..=35 {
1298 System::run_to_block::<AllPalletsWithSystem>(n);
1299 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(0)), false);
1300 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), false);
1301 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(2_u32)), false);
1302 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(3_u32)), false);
1303 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(4_u32)), true);
1304 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(5_u32)), true);
1305 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 2);
1306 }
1307 });
1308 }
1309
1310 #[test]
1311 fn unassign_slot_fails_for_unknown_para() {
1312 new_test_ext().execute_with(|| {
1313 System::run_to_block::<AllPalletsWithSystem>(1);
1314
1315 assert_noop!(
1316 AssignedSlots::unassign_teyrchain_slot(RuntimeOrigin::root(), ParaId::from(1_u32),),
1317 Error::<Test>::SlotNotAssigned
1318 );
1319 });
1320 }
1321
1322 #[test]
1323 fn unassign_slot_fails_for_invalid_origin() {
1324 new_test_ext().execute_with(|| {
1325 System::run_to_block::<AllPalletsWithSystem>(1);
1326
1327 assert_noop!(
1328 AssignedSlots::assign_perm_teyrchain_slot(
1329 RuntimeOrigin::signed(1),
1330 ParaId::from(1_u32),
1331 ),
1332 BadOrigin
1333 );
1334 });
1335 }
1336
1337 #[test]
1338 fn unassign_perm_slot_succeeds() {
1339 new_test_ext().execute_with(|| {
1340 System::run_to_block::<AllPalletsWithSystem>(1);
1341
1342 assert_ok!(TestRegistrar::<Test>::register(
1343 1,
1344 ParaId::from(1_u32),
1345 dummy_head_data(),
1346 dummy_validation_code(),
1347 ));
1348
1349 assert_ok!(AssignedSlots::assign_perm_teyrchain_slot(
1350 RuntimeOrigin::root(),
1351 ParaId::from(1_u32),
1352 ));
1353
1354 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), true);
1355
1356 assert_ok!(AssignedSlots::unassign_teyrchain_slot(
1357 RuntimeOrigin::root(),
1358 ParaId::from(1_u32),
1359 ));
1360
1361 assert_eq!(assigned_slots::PermanentSlotCount::<Test>::get(), 0);
1362 assert_eq!(AssignedSlots::has_permanent_slot(ParaId::from(1_u32)), false);
1363 assert_eq!(assigned_slots::PermanentSlots::<Test>::get(ParaId::from(1_u32)), None);
1364
1365 assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 2), false);
1366 });
1367 }
1368
1369 #[test]
1370 fn unassign_temp_slot_succeeds() {
1371 new_test_ext().execute_with(|| {
1372 System::run_to_block::<AllPalletsWithSystem>(1);
1373
1374 assert_ok!(TestRegistrar::<Test>::register(
1375 1,
1376 ParaId::from(1_u32),
1377 dummy_head_data(),
1378 dummy_validation_code(),
1379 ));
1380
1381 assert_ok!(AssignedSlots::assign_temp_teyrchain_slot(
1382 RuntimeOrigin::root(),
1383 ParaId::from(1_u32),
1384 SlotLeasePeriodStart::Current
1385 ));
1386
1387 assert_eq!(TestRegistrar::<Test>::is_teyrchain(ParaId::from(1_u32)), true);
1388
1389 assert_ok!(AssignedSlots::unassign_teyrchain_slot(
1390 RuntimeOrigin::root(),
1391 ParaId::from(1_u32),
1392 ));
1393
1394 assert_eq!(assigned_slots::TemporarySlotCount::<Test>::get(), 0);
1395 assert_eq!(assigned_slots::ActiveTemporarySlotCount::<Test>::get(), 0);
1396 assert_eq!(AssignedSlots::has_temporary_slot(ParaId::from(1_u32)), false);
1397 assert_eq!(assigned_slots::TemporarySlots::<Test>::get(ParaId::from(1_u32)), None);
1398
1399 assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 1), false);
1400 });
1401 }
1402 #[test]
1403 fn set_max_permanent_slots_fails_for_no_root_origin() {
1404 new_test_ext().execute_with(|| {
1405 System::run_to_block::<AllPalletsWithSystem>(1);
1406
1407 assert_noop!(
1408 AssignedSlots::set_max_permanent_slots(RuntimeOrigin::signed(1), 5),
1409 BadOrigin
1410 );
1411 });
1412 }
1413 #[test]
1414 fn set_max_permanent_slots_succeeds() {
1415 new_test_ext().execute_with(|| {
1416 System::run_to_block::<AllPalletsWithSystem>(1);
1417
1418 assert_eq!(MaxPermanentSlots::<Test>::get(), 2);
1419 assert_ok!(AssignedSlots::set_max_permanent_slots(RuntimeOrigin::root(), 10),);
1420 assert_eq!(MaxPermanentSlots::<Test>::get(), 10);
1421 });
1422 }
1423
1424 #[test]
1425 fn set_max_temporary_slots_fails_for_no_root_origin() {
1426 new_test_ext().execute_with(|| {
1427 System::run_to_block::<AllPalletsWithSystem>(1);
1428
1429 assert_noop!(
1430 AssignedSlots::set_max_temporary_slots(RuntimeOrigin::signed(1), 5),
1431 BadOrigin
1432 );
1433 });
1434 }
1435 #[test]
1436 fn set_max_temporary_slots_succeeds() {
1437 new_test_ext().execute_with(|| {
1438 System::run_to_block::<AllPalletsWithSystem>(1);
1439
1440 assert_eq!(MaxTemporarySlots::<Test>::get(), 6);
1441 assert_ok!(AssignedSlots::set_max_temporary_slots(RuntimeOrigin::root(), 12),);
1442 assert_eq!(MaxTemporarySlots::<Test>::get(), 12);
1443 });
1444 }
1445}