Newer
Older
test_genesis_head(32),
test_validation_code(32),
assert!(Parachains::is_parathread(para_id));
// Owner check
assert_noop!(Registrar::deregister(RuntimeOrigin::signed(2), para_id,), BadOrigin);
assert_ok!(Registrar::make_parachain(para_id));
run_to_session(4);
// Cant directly deregister parachain
Registrar::deregister(RuntimeOrigin::root(), para_id,),
#[test]
fn swap_works() {
new_test_ext().execute_with(|| {
// Successfully register first two parachains
let para_1 = LOWEST_PUBLIC_ID;
let para_2 = LOWEST_PUBLIC_ID + 1;
assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
Shawn Tabrizi
committed
test_genesis_head(max_head_size() as usize),
test_validation_code(max_code_size() as usize),
assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2)));
Shawn Tabrizi
committed
test_genesis_head(max_head_size() as usize),
test_validation_code(max_code_size() as usize),
// Upgrade para 1 into a parachain
assert_ok!(Registrar::make_parachain(para_1));
// Set some mock swap data.
let mut swap_data = SwapData::get();
swap_data.insert(para_1, 69);
swap_data.insert(para_2, 1337);
SwapData::set(swap_data);
assert!(Parachains::is_parachain(para_1));
assert!(!Parachains::is_parathread(para_1));
assert!(!Parachains::is_parachain(para_2));
assert!(Parachains::is_parathread(para_2));
assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_2,));
assert_ok!(Registrar::swap(para_origin(para_2), para_2, para_1,));
assert!(!Parachains::is_parachain(para_1));
assert!(Parachains::is_parathread(para_1));
assert!(Parachains::is_parachain(para_2));
assert!(!Parachains::is_parathread(para_2));
// Data is swapped
assert_eq!(SwapData::get().get(¶_1).unwrap(), &1337);
assert_eq!(SwapData::get().get(¶_2).unwrap(), &69);
#[test]
fn para_lock_works() {
new_test_ext().execute_with(|| {
run_to_block(1);
assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
let para_id = LOWEST_PUBLIC_ID;
assert_ok!(Registrar::register(
vec![1; 3].into(),
));
// Owner can call swap
assert_ok!(Registrar::swap(RuntimeOrigin::signed(1), para_id, para_id + 1));
// 2 session changes to fully onboard.
run_to_session(2);
assert_eq!(Parachains::lifecycle(para_id), Some(ParaLifecycle::Parathread));
// Once they begin onboarding, we lock them in.
assert_ok!(Registrar::make_parachain(para_id));
// Owner cannot call swap anymore
assert_noop!(
Registrar::swap(RuntimeOrigin::signed(1), para_id, para_id + 2),
BadOrigin
);
});
}
#[test]
fn swap_handles_bad_states() {
new_test_ext().execute_with(|| {
let para_1 = LOWEST_PUBLIC_ID;
let para_2 = LOWEST_PUBLIC_ID + 1;
run_to_block(1);
// paras are not yet registered
assert!(!Parachains::is_parathread(para_1));
assert!(!Parachains::is_parathread(para_2));
// Cannot even start a swap
assert_noop!(
Registrar::swap(RuntimeOrigin::root(), para_1, para_2),
Error::<Test>::NotRegistered
);
// We register Paras 1 and 2
assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2)));
para_1,
test_genesis_head(32),
test_validation_code(32),
));
assert_ok!(Registrar::register(
para_2,
test_genesis_head(32),
test_validation_code(32),
));
// Cannot swap
assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
Error::<Test>::CannotSwap
);
run_to_session(2);
// They are now a parathread.
assert!(Parachains::is_parathread(para_1));
assert!(Parachains::is_parathread(para_2));
// Cannot swap
assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
Error::<Test>::CannotSwap
);
// Some other external process will elevate one parathread to parachain
assert_ok!(Registrar::make_parachain(para_1));
// Cannot swap
assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
Error::<Test>::CannotSwap
);
run_to_session(3);
// Cannot swap
assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
Error::<Test>::CannotSwap
);
run_to_session(4);
// It is now a parachain.
assert!(Parachains::is_parachain(para_1));
assert!(Parachains::is_parathread(para_2));
// Swap works here.
assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_2, para_1));
run_to_session(5);
// Cannot swap
assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
Error::<Test>::CannotSwap
);
run_to_session(6);
// Swap worked!
assert!(Parachains::is_parachain(para_2));
assert!(Parachains::is_parathread(para_1));
// Something starts to downgrade a para
assert_ok!(Registrar::make_parathread(para_2));
run_to_session(7);
// Cannot swap
assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
Error::<Test>::CannotSwap
);
run_to_session(8);
assert!(Parachains::is_parathread(para_1));
assert!(Parachains::is_parathread(para_2));
});
}
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking {
use super::{Pallet as Registrar, *};
use crate::traits::Registrar as RegistrarT;
use runtime_parachains::{paras, shared, Origin as ParaOrigin};
use frame_benchmarking::{account, benchmarks, whitelisted_caller};
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
Shaun Wang
committed
let events = frame_system::Pallet::<T>::events();
let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
// compare to the last event record
let frame_system::EventRecord { event, .. } = &events[events.len() - 1];
assert_eq!(event, &system_event);
}
fn register_para<T: Config>(id: u32) -> ParaId {
let para = ParaId::from(id);
let genesis_head = Registrar::<T>::worst_head_data();
let validation_code = Registrar::<T>::worst_validation_code();
let caller: T::AccountId = whitelisted_caller();
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
assert_ok!(Registrar::<T>::reserve(RawOrigin::Signed(caller.clone()).into()));
assert_ok!(Registrar::<T>::register(
RawOrigin::Signed(caller).into(),
para,
genesis_head,
validation_code
));
return para
}
fn para_origin(id: u32) -> ParaOrigin {
ParaOrigin::Parachain(id.into())
}
// This function moves forward to the next scheduled session for parachain lifecycle upgrades.
fn next_scheduled_session<T: Config>() {
shared::Pallet::<T>::set_session_index(shared::Pallet::<T>::scheduled_session());
paras::Pallet::<T>::test_on_new_session();
where_clause { where ParaOrigin: Into<<T as frame_system::Config>::RuntimeOrigin> }
reserve {
let caller: T::AccountId = whitelisted_caller();
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
}: _(RawOrigin::Signed(caller.clone()))
verify {
assert_last_event::<T>(Event::<T>::Reserved { para_id: LOWEST_PUBLIC_ID, who: caller }.into());
assert!(Paras::<T>::get(LOWEST_PUBLIC_ID).is_some());
assert_eq!(paras::Pallet::<T>::lifecycle(LOWEST_PUBLIC_ID), None);
let para = LOWEST_PUBLIC_ID;
let genesis_head = Registrar::<T>::worst_head_data();
let validation_code = Registrar::<T>::worst_validation_code();
let caller: T::AccountId = whitelisted_caller();
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
assert_ok!(Registrar::<T>::reserve(RawOrigin::Signed(caller.clone()).into()));
}: _(RawOrigin::Signed(caller.clone()), para, genesis_head, validation_code)
verify {
assert_last_event::<T>(Event::<T>::Registered{ para_id: para, manager: caller }.into());
assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Parathread));
force_register {
let manager: T::AccountId = account("manager", 0, 0);
let deposit = 0u32.into();
let para = ParaId::from(69);
let genesis_head = Registrar::<T>::worst_head_data();
let validation_code = Registrar::<T>::worst_validation_code();
}: _(RawOrigin::Root, manager.clone(), deposit, para, genesis_head, validation_code)
verify {
assert_last_event::<T>(Event::<T>::Registered { para_id: para, manager }.into());
assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
next_scheduled_session::<T>();
assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Parathread));
let para = register_para::<T>(LOWEST_PUBLIC_ID.into());
let caller: T::AccountId = whitelisted_caller();
}: _(RawOrigin::Signed(caller), para)
assert_last_event::<T>(Event::<T>::Deregistered { para_id: para }.into());
let parathread = register_para::<T>(LOWEST_PUBLIC_ID.into());
let parachain = register_para::<T>((LOWEST_PUBLIC_ID + 1).into());
let parachain_origin = para_origin(parachain.into());
// Actually finish registration process
next_scheduled_session::<T>();
// Upgrade the parachain
Registrar::<T>::make_parachain(parachain)?;
next_scheduled_session::<T>();
assert_eq!(paras::Pallet::<T>::lifecycle(parachain), Some(ParaLifecycle::Parachain));
assert_eq!(paras::Pallet::<T>::lifecycle(parathread), Some(ParaLifecycle::Parathread));
let caller: T::AccountId = whitelisted_caller();
Registrar::<T>::swap(parachain_origin.into(), parachain, parathread)?;
}: _(RawOrigin::Signed(caller.clone()), parathread, parachain)
verify {
next_scheduled_session::<T>();
// Swapped!
assert_eq!(paras::Pallet::<T>::lifecycle(parachain), Some(ParaLifecycle::Parathread));
assert_eq!(paras::Pallet::<T>::lifecycle(parathread), Some(ParaLifecycle::Parachain));
impl_benchmark_test_suite!(
Registrar,
crate::integration_tests::new_test_ext(),
crate::integration_tests::Test,
);
}