mod.rs 54.4 KiB
Newer Older
			// Deregister it
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id,));
			run_to_session(START_SESSION_INDEX + 8);
			// It is nothing
			assert!(!Parachains::is_parathread(para_id));
			assert!(!Parachains::is_parachain(para_id));
	#[test]
	fn register_works() {
		new_test_ext().execute_with(|| {
			const START_SESSION_INDEX: SessionIndex = 1;
			run_to_session(START_SESSION_INDEX);

			let para_id = LOWEST_PUBLIC_ID;
			assert!(!Parachains::is_parathread(para_id));

			let validation_code = test_validation_code(32);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
			assert_eq!(Balances::reserved_balance(&1), <Test as Config>::ParaDeposit::get());
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(1),
				test_genesis_head(32),
			conclude_pvf_checking::<Test>(&validation_code, VALIDATORS, START_SESSION_INDEX);

			run_to_session(START_SESSION_INDEX + 2);
			assert!(Parachains::is_parathread(para_id));
			// Even though the registered validation code has a smaller size than the maximum the
			// para manager's deposit is reserved as though they registered the maximum-sized code.
			// Consequently, they can upgrade their code to the maximum size at any point without
			// additional cost.
			let validation_code_deposit =
				max_code_size() as BalanceOf<Test> * <Test as Config>::DataDepositPerByte::get();
			let head_deposit = 32 * <Test as Config>::DataDepositPerByte::get();
			assert_eq!(
				Balances::reserved_balance(&1),
				<Test as Config>::ParaDeposit::get() + head_deposit + validation_code_deposit
	#[test]
	fn schedule_code_upgrade_validates_code() {
		new_test_ext().execute_with(|| {
			const START_SESSION_INDEX: SessionIndex = 1;
			run_to_session(START_SESSION_INDEX);

			let para_id = LOWEST_PUBLIC_ID;
			assert!(!Parachains::is_parathread(para_id));

			let validation_code = test_validation_code(32);
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
			assert_eq!(Balances::reserved_balance(&1), <Test as Config>::ParaDeposit::get());
			assert_ok!(Registrar::register(
				RuntimeOrigin::signed(1),
				para_id,
				test_genesis_head(32),
				validation_code.clone(),
			));
			conclude_pvf_checking::<Test>(&validation_code, VALIDATORS, START_SESSION_INDEX);

			run_to_session(START_SESSION_INDEX + 2);
			assert!(Parachains::is_parathread(para_id));

			let new_code = test_validation_code(0);
			assert_noop!(
				Registrar::schedule_code_upgrade(
					RuntimeOrigin::signed(1),
					para_id,
					new_code.clone(),
				),
				paras::Error::<Test>::InvalidCode
			);

			let new_code = test_validation_code(max_code_size() as usize + 1);
			assert_noop!(
				Registrar::schedule_code_upgrade(
					RuntimeOrigin::signed(1),
					para_id,
					new_code.clone(),
				),
				paras::Error::<Test>::InvalidCode
			);
		});
	}

	#[test]
	fn register_handles_basic_errors() {
		new_test_ext().execute_with(|| {
			let para_id = LOWEST_PUBLIC_ID;

			assert_noop!(
				Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
					RuntimeOrigin::signed(1),
					para_id,
					test_genesis_head(max_head_size() as usize),
					test_validation_code(max_code_size() as usize),
				),
				Error::<Test>::NotReserved
			);
			// Successfully register para
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
			assert_noop!(
				Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
					RuntimeOrigin::signed(2),
					para_id,
					test_genesis_head(max_head_size() as usize),
					test_validation_code(max_code_size() as usize),
				),
				Error::<Test>::NotOwner
			);
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(1),
				test_genesis_head(max_head_size() as usize),
				test_validation_code(max_code_size() as usize),
			// Can skip pre-check and deregister para which's still onboarding.
			run_to_session(2);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id));
			assert_noop!(
				Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
					RuntimeOrigin::signed(1),
					para_id,
					test_genesis_head(max_head_size() as usize),
					test_validation_code(max_code_size() as usize),
				),
				Error::<Test>::NotReserved
			);

			// Head Size Check
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2)));
			assert_noop!(
				Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
					RuntimeOrigin::signed(2),
					para_id + 1,
					test_genesis_head((max_head_size() + 1) as usize),
					test_validation_code(max_code_size() as usize),
				),
				Error::<Test>::HeadDataTooLarge
			);

			// Code Size Check
			assert_noop!(
				Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
					RuntimeOrigin::signed(2),
					para_id + 1,
					test_genesis_head(max_head_size() as usize),
					test_validation_code((max_code_size() + 1) as usize),
				),
				Error::<Test>::CodeTooLarge
			);

			// Needs enough funds for deposit
			assert_noop!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::reserve(RuntimeOrigin::signed(1337)),
				BalancesError::<Test, _>::InsufficientBalance
			);
	fn deregister_works() {
		new_test_ext().execute_with(|| {
			const START_SESSION_INDEX: SessionIndex = 1;
			run_to_session(START_SESSION_INDEX);

			let para_id = LOWEST_PUBLIC_ID;
			assert!(!Parachains::is_parathread(para_id));

			let validation_code = test_validation_code(32);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(1),
				test_genesis_head(32),
			conclude_pvf_checking::<Test>(&validation_code, VALIDATORS, START_SESSION_INDEX);

			run_to_session(START_SESSION_INDEX + 2);
			assert!(Parachains::is_parathread(para_id));
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::deregister(RuntimeOrigin::root(), para_id,));
			run_to_session(START_SESSION_INDEX + 4);
			assert!(paras::Pallet::<Test>::lifecycle(para_id).is_none());
			assert_eq!(Balances::reserved_balance(&1), 0);
		});
	}
	#[test]
	fn deregister_handles_basic_errors() {
		new_test_ext().execute_with(|| {
			const START_SESSION_INDEX: SessionIndex = 1;
			run_to_session(START_SESSION_INDEX);

			let para_id = LOWEST_PUBLIC_ID;
			assert!(!Parachains::is_parathread(para_id));

			let validation_code = test_validation_code(32);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(1),
				test_genesis_head(32),
			conclude_pvf_checking::<Test>(&validation_code, VALIDATORS, START_SESSION_INDEX);

			run_to_session(START_SESSION_INDEX + 2);
			assert!(Parachains::is_parathread(para_id));
Sergej Sakac's avatar
Sergej Sakac committed
			assert_noop!(Registrar::deregister(RuntimeOrigin::signed(2), para_id,), BadOrigin);
			assert_ok!(Registrar::make_parachain(para_id));
			run_to_session(START_SESSION_INDEX + 4);
			// Cant directly deregister parachain
			assert_noop!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::deregister(RuntimeOrigin::root(), para_id,),
				Error::<Test>::NotParathread
			);
	#[test]
	fn swap_works() {
		new_test_ext().execute_with(|| {
			const START_SESSION_INDEX: SessionIndex = 1;
			run_to_session(START_SESSION_INDEX);

			// Successfully register first two parachains
			let para_1 = LOWEST_PUBLIC_ID;
			let para_2 = LOWEST_PUBLIC_ID + 1;

			let validation_code = test_validation_code(max_code_size() as usize);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(1),
				test_genesis_head(max_head_size() as usize),
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2)));
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(2),
				test_genesis_head(max_head_size() as usize),
			conclude_pvf_checking::<Test>(&validation_code, VALIDATORS, START_SESSION_INDEX);

			run_to_session(START_SESSION_INDEX + 2);
			// 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);

			run_to_session(START_SESSION_INDEX + 4);
			// Roles are as we expect
			assert!(Parachains::is_parachain(para_1));
			assert!(!Parachains::is_parathread(para_1));
			assert!(!Parachains::is_parachain(para_2));
			assert!(Parachains::is_parathread(para_2));
			// Both paras initiate a swap
			// Swap between parachain and parathread
			assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_2,));
			assert_ok!(Registrar::swap(para_origin(para_2), para_2, para_1,));
			System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped {
				para_id: para_2,
				other_id: para_1,
			}));
			run_to_session(START_SESSION_INDEX + 6);
			// Roles are swapped
			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(&para_1).unwrap(), &1337);
			assert_eq!(SwapData::get().get(&para_2).unwrap(), &69);

			// Both paras initiate a swap
			// Swap between parathread and parachain
			assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_2,));
			assert_ok!(Registrar::swap(para_origin(para_2), para_2, para_1,));
			System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped {
				para_id: para_2,
				other_id: para_1,
			}));

			// Data is swapped
			assert_eq!(SwapData::get().get(&para_1).unwrap(), &69);
			assert_eq!(SwapData::get().get(&para_2).unwrap(), &1337);

			// Parachain to parachain swap
			let para_3 = LOWEST_PUBLIC_ID + 2;
			let validation_code = test_validation_code(max_code_size() as usize);
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(3)));
			assert_ok!(Registrar::register(
				RuntimeOrigin::signed(3),
				para_3,
				test_genesis_head(max_head_size() as usize),
			conclude_pvf_checking::<Test>(&validation_code, VALIDATORS, START_SESSION_INDEX + 6);
			run_to_session(START_SESSION_INDEX + 8);

			// Upgrade para 3 into a parachain
			assert_ok!(Registrar::make_parachain(para_3));

			// Set some mock swap data.
			let mut swap_data = SwapData::get();
			swap_data.insert(para_3, 777);
			SwapData::set(swap_data);

			run_to_session(START_SESSION_INDEX + 10);

			// Both are parachains
			assert!(Parachains::is_parachain(para_3));
			assert!(!Parachains::is_parathread(para_3));
			assert!(Parachains::is_parachain(para_1));
			assert!(!Parachains::is_parathread(para_1));

			// Both paras initiate a swap
			// Swap between parachain and parachain
			assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_3,));
			assert_ok!(Registrar::swap(para_origin(para_3), para_3, para_1,));
			System::assert_last_event(RuntimeEvent::Registrar(paras_registrar::Event::Swapped {
				para_id: para_3,
				other_id: para_1,
			}));

			// Data is swapped
			assert_eq!(SwapData::get().get(&para_3).unwrap(), &69);
			assert_eq!(SwapData::get().get(&para_1).unwrap(), &777);

	#[test]
	fn para_lock_works() {
		new_test_ext().execute_with(|| {
			run_to_block(1);

Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
			let para_id = LOWEST_PUBLIC_ID;
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(1),
Shawn Tabrizi's avatar
Shawn Tabrizi committed
			assert_noop!(Registrar::add_lock(RuntimeOrigin::signed(2), para_id), BadOrigin);

			// Once they produces new block, we lock them in.
			Registrar::on_new_head(para_id, &Default::default());

Shawn Tabrizi's avatar
Shawn Tabrizi committed
			// Owner cannot pass origin check when checking lock
Sergej Sakac's avatar
Sergej Sakac committed
			assert_noop!(
Shawn Tabrizi's avatar
Shawn Tabrizi committed
				Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id),
Sergej Sakac's avatar
Sergej Sakac committed
				BadOrigin
			);
Shawn Tabrizi's avatar
Shawn Tabrizi committed
			// Owner cannot remove lock.
			assert_noop!(Registrar::remove_lock(RuntimeOrigin::signed(1), para_id), BadOrigin);
			// Para can.
			assert_ok!(Registrar::remove_lock(para_origin(para_id), para_id));
			// Owner can pass origin check again
			assert_ok!(Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id));

			// Won't lock again after it is unlocked
			Registrar::on_new_head(para_id, &Default::default());

			assert_ok!(Registrar::ensure_root_para_or_owner(RuntimeOrigin::signed(1), para_id));

	#[test]
	fn swap_handles_bad_states() {
		new_test_ext().execute_with(|| {
			const START_SESSION_INDEX: SessionIndex = 1;
			run_to_session(START_SESSION_INDEX);

			let para_1 = LOWEST_PUBLIC_ID;
			let para_2 = LOWEST_PUBLIC_ID + 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!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::swap(RuntimeOrigin::root(), para_1, para_2),
				Error::<Test>::NotRegistered
			);

			// We register Paras 1 and 2
			let validation_code = test_validation_code(32);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(1)));
			assert_ok!(Registrar::reserve(RuntimeOrigin::signed(2)));
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(1),
				para_1,
				test_genesis_head(32),
			));
			assert_ok!(Registrar::register(
Sergej Sakac's avatar
Sergej Sakac committed
				RuntimeOrigin::signed(2),
				para_2,
				test_genesis_head(32),
			conclude_pvf_checking::<Test>(&validation_code, VALIDATORS, START_SESSION_INDEX);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
			assert_noop!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
				Error::<Test>::CannotSwap
			);

			run_to_session(START_SESSION_INDEX + 2);
			// They are now parathreads (on-demand parachains).
			assert!(Parachains::is_parathread(para_1));
			assert!(Parachains::is_parathread(para_2));

			// Cannot swap
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
			assert_noop!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
				Error::<Test>::CannotSwap
			);

			// Some other external process will elevate one on-demand
			// parachain to a lease holding parachain
			assert_ok!(Registrar::make_parachain(para_1));

			// Cannot swap
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
			assert_noop!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
				Error::<Test>::CannotSwap
			);

			run_to_session(START_SESSION_INDEX + 3);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
			assert_noop!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
				Error::<Test>::CannotSwap
			);

			run_to_session(START_SESSION_INDEX + 4);
			// It is now a lease holding parachain.
			assert!(Parachains::is_parachain(para_1));
			assert!(Parachains::is_parathread(para_2));

			// Swap works here.
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
			assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_2, para_1));
			assert!(System::events().iter().any(|r| matches!(
				r.event,
				RuntimeEvent::Registrar(paras_registrar::Event::Swapped { .. })
			)));
			run_to_session(START_SESSION_INDEX + 5);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
			assert_noop!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
				Error::<Test>::CannotSwap
			);

			run_to_session(START_SESSION_INDEX + 6);

			// Swap worked!
			assert!(Parachains::is_parachain(para_2));
			assert!(Parachains::is_parathread(para_1));
			assert!(System::events().iter().any(|r| matches!(
				r.event,
				RuntimeEvent::Registrar(paras_registrar::Event::Swapped { .. })
			)));

			// Something starts to downgrade a para
			assert_ok!(Registrar::make_parathread(para_2));

			run_to_session(START_SESSION_INDEX + 7);
Sergej Sakac's avatar
Sergej Sakac committed
			assert_ok!(Registrar::swap(RuntimeOrigin::root(), para_1, para_2));
			assert_noop!(
Sergej Sakac's avatar
Sergej Sakac committed
				Registrar::swap(RuntimeOrigin::root(), para_2, para_1),
				Error::<Test>::CannotSwap
			);

			run_to_session(START_SESSION_INDEX + 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 frame_support::assert_ok;
	use frame_system::RawOrigin;
	use primitives::{MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MIN_CODE_SIZE};
	use runtime_parachains::{paras, shared, Origin as ParaOrigin};
	use sp_runtime::traits::Bounded;
	use frame_benchmarking::{account, benchmarks, whitelisted_caller};
	fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
		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.clone()
		));
		assert_ok!(runtime_parachains::paras::Pallet::<T>::add_trusted_validation_code(
			frame_system::Origin::<T>::Root.into(),
			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();
Sergej Sakac's avatar
Sergej Sakac committed
		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.clone())
			assert_last_event::<T>(Event::<T>::Registered{ para_id: para, manager: caller }.into());
			assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
			assert_ok!(runtime_parachains::paras::Pallet::<T>::add_trusted_validation_code(
				frame_system::Origin::<T>::Root.into(),
				validation_code,
			));
			next_scheduled_session::<T>();
			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.clone())
			assert_last_event::<T>(Event::<T>::Registered { para_id: para, manager }.into());
			assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
			assert_ok!(runtime_parachains::paras::Pallet::<T>::add_trusted_validation_code(
				frame_system::Origin::<T>::Root.into(),
				validation_code,
			));
			next_scheduled_session::<T>();
			assert_eq!(paras::Pallet::<T>::lifecycle(para), Some(ParaLifecycle::Parathread));
		deregister {
			let para = register_para::<T>(LOWEST_PUBLIC_ID.into());
			next_scheduled_session::<T>();
			let caller: T::AccountId = whitelisted_caller();
		}: _(RawOrigin::Signed(caller), para)
			assert_last_event::<T>(Event::<T>::Deregistered { para_id: para }.into());
			// On demand parachain
			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));
Shawn Tabrizi's avatar
Shawn Tabrizi committed
		schedule_code_upgrade {
			let b in MIN_CODE_SIZE .. MAX_CODE_SIZE;
Shawn Tabrizi's avatar
Shawn Tabrizi committed
			let new_code = ValidationCode(vec![0; b as usize]);
			let para_id = ParaId::from(1000);
		}: _(RawOrigin::Root, para_id, new_code)

		set_current_head {
			let b in 1 .. MAX_HEAD_DATA_SIZE;
			let new_head = HeadData(vec![0; b as usize]);
			let para_id = ParaId::from(1000);
		}: _(RawOrigin::Root, para_id, new_head)

		impl_benchmark_test_suite!(
			Registrar,
			crate::integration_tests::new_test_ext(),
			crate::integration_tests::Test,
		);
	}