mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 07:01:03 +00:00
Introduce System Parachains into Registrar (#2858)
* initial stuff * adjust deposit * remove unused * weight stuff * Update integration_tests.rs * Update paras_registrar.rs * Update paras_registrar.rs * add test * Update paras_registrar.rs Co-authored-by: parity-processbot <>
This commit is contained in:
@@ -26,7 +26,7 @@ use frame_support::{
|
||||
};
|
||||
use frame_system::{self, ensure_root, ensure_signed};
|
||||
use primitives::v1::{
|
||||
Id as ParaId, ValidationCode, HeadData,
|
||||
Id as ParaId, ValidationCode, HeadData, LOWEST_USER_ID,
|
||||
};
|
||||
use runtime_parachains::{
|
||||
paras::{
|
||||
@@ -56,6 +56,7 @@ type BalanceOf<T> =
|
||||
|
||||
pub trait WeightInfo {
|
||||
fn register() -> Weight;
|
||||
fn force_register() -> Weight;
|
||||
fn deregister() -> Weight;
|
||||
fn swap() -> Weight;
|
||||
}
|
||||
@@ -63,6 +64,7 @@ pub trait WeightInfo {
|
||||
pub struct TestWeightInfo;
|
||||
impl WeightInfo for TestWeightInfo {
|
||||
fn register() -> Weight { 0 }
|
||||
fn force_register() -> Weight { 0 }
|
||||
fn deregister() -> Weight { 0 }
|
||||
fn swap() -> Weight { 0 }
|
||||
}
|
||||
@@ -148,6 +150,8 @@ decl_error! {
|
||||
CannotUpgrade,
|
||||
/// Para is locked from manipulation by the manager. Must use parachain or relay chain governance.
|
||||
ParaLocked,
|
||||
/// The id you are trying to register is reserved for system parachains.
|
||||
InvalidParaId,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +175,8 @@ decl_module! {
|
||||
/// This function must be called by a signed origin.
|
||||
///
|
||||
/// The origin must pay a deposit for the registration information,
|
||||
/// including the genesis information and validation code.
|
||||
/// including the genesis information and validation code. ParaId
|
||||
/// must be greater than or equal to 1000.
|
||||
#[weight = T::WeightInfo::register()]
|
||||
pub fn register(
|
||||
origin,
|
||||
@@ -180,7 +185,27 @@ decl_module! {
|
||||
validation_code: ValidationCode,
|
||||
) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
Self::do_register(who, id, genesis_head, validation_code)
|
||||
ensure!(id >= LOWEST_USER_ID, Error::<T>::InvalidParaId);
|
||||
Self::do_register(who, None, id, genesis_head, validation_code)
|
||||
}
|
||||
|
||||
/// Force the registration of a Para Id on the relay chain.
|
||||
///
|
||||
/// This function must be called by a Root origin.
|
||||
///
|
||||
/// The deposit taken can be specified for this registration. Any ParaId
|
||||
/// can be registered, including sub-1000 IDs which are System Parachains.
|
||||
#[weight = T::WeightInfo::force_register()]
|
||||
pub fn force_register(
|
||||
origin,
|
||||
who: T::AccountId,
|
||||
deposit: BalanceOf<T>,
|
||||
id: ParaId,
|
||||
genesis_head: HeadData,
|
||||
validation_code: ValidationCode,
|
||||
) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
Self::do_register(who, Some(deposit), id, genesis_head, validation_code)
|
||||
}
|
||||
|
||||
/// Deregister a Para Id, freeing all data and returning any deposit.
|
||||
@@ -236,6 +261,16 @@ decl_module! {
|
||||
PendingSwap::insert(id, other);
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove a manager lock from a para. This will allow the manager of a
|
||||
/// previously locked para to deregister or swap a para without using governance.
|
||||
///
|
||||
/// Can only be called by the Root origin.
|
||||
#[weight = T::DbWeight::get().reads_writes(1, 1)]
|
||||
fn force_remove_lock(origin, para: ParaId) {
|
||||
ensure_root(origin)?;
|
||||
Self::remove_lock(para);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,13 +308,16 @@ impl<T: Config> Registrar for Module<T> {
|
||||
}
|
||||
|
||||
// Register a Para ID under control of `manager`.
|
||||
//
|
||||
// Note this is a backend registration api, so verification of ParaId
|
||||
// is not done here to prevent.
|
||||
fn register(
|
||||
manager: T::AccountId,
|
||||
id: ParaId,
|
||||
genesis_head: HeadData,
|
||||
validation_code: ValidationCode,
|
||||
) -> DispatchResult {
|
||||
Self::do_register(manager, id, genesis_head, validation_code)
|
||||
Self::do_register(manager, None, id, genesis_head, validation_code)
|
||||
}
|
||||
|
||||
// Deregister a Para ID, free any data, and return any deposits.
|
||||
@@ -357,6 +395,7 @@ impl<T: Config> Module<T> {
|
||||
/// system with the given information.
|
||||
fn do_register(
|
||||
who: T::AccountId,
|
||||
deposit_override: Option<BalanceOf<T>>,
|
||||
id: ParaId,
|
||||
genesis_head: HeadData,
|
||||
validation_code: ValidationCode,
|
||||
@@ -369,6 +408,7 @@ impl<T: Config> Module<T> {
|
||||
false
|
||||
)?;
|
||||
|
||||
let deposit = deposit_override.unwrap_or(deposit);
|
||||
<T as Config>::Currency::reserve(&who, deposit)?;
|
||||
let info = ParaInfo {
|
||||
manager: who.clone(),
|
||||
@@ -610,39 +650,39 @@ mod tests {
|
||||
fn end_to_end_scenario_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
// 32 is not yet registered
|
||||
assert!(!Parachains::is_parathread(32.into()));
|
||||
// 1032 is not yet registered
|
||||
assert!(!Parachains::is_parathread(1032.into()));
|
||||
// We register the Para ID
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
test_genesis_head(32),
|
||||
test_validation_code(32),
|
||||
));
|
||||
run_to_session(2);
|
||||
// It is now a parathread.
|
||||
assert!(Parachains::is_parathread(32.into()));
|
||||
assert!(!Parachains::is_parachain(32.into()));
|
||||
assert!(Parachains::is_parathread(1032.into()));
|
||||
assert!(!Parachains::is_parachain(1032.into()));
|
||||
// Some other external process will elevate parathread to parachain
|
||||
assert_ok!(Registrar::make_parachain(32.into()));
|
||||
assert_ok!(Registrar::make_parachain(1032.into()));
|
||||
run_to_session(4);
|
||||
// It is now a parachain.
|
||||
assert!(!Parachains::is_parathread(32.into()));
|
||||
assert!(Parachains::is_parachain(32.into()));
|
||||
assert!(!Parachains::is_parathread(1032.into()));
|
||||
assert!(Parachains::is_parachain(1032.into()));
|
||||
// Turn it back into a parathread
|
||||
assert_ok!(Registrar::make_parathread(32.into()));
|
||||
assert_ok!(Registrar::make_parathread(1032.into()));
|
||||
run_to_session(6);
|
||||
assert!(Parachains::is_parathread(32.into()));
|
||||
assert!(!Parachains::is_parachain(32.into()));
|
||||
assert!(Parachains::is_parathread(1032.into()));
|
||||
assert!(!Parachains::is_parachain(1032.into()));
|
||||
// Deregister it
|
||||
assert_ok!(Registrar::deregister(
|
||||
Origin::root(),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
));
|
||||
run_to_session(8);
|
||||
// It is nothing
|
||||
assert!(!Parachains::is_parathread(32.into()));
|
||||
assert!(!Parachains::is_parachain(32.into()));
|
||||
assert!(!Parachains::is_parathread(1032.into()));
|
||||
assert!(!Parachains::is_parachain(1032.into()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -650,15 +690,15 @@ mod tests {
|
||||
fn register_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
assert!(!Parachains::is_parathread(32.into()));
|
||||
assert!(!Parachains::is_parathread(1032.into()));
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
test_genesis_head(32),
|
||||
test_validation_code(32),
|
||||
));
|
||||
run_to_session(2);
|
||||
assert!(Parachains::is_parathread(32.into()));
|
||||
assert!(Parachains::is_parathread(1032.into()));
|
||||
assert_eq!(
|
||||
Balances::reserved_balance(&1),
|
||||
<Test as Config>::ParaDeposit::get() + 64 * <Test as Config>::DataDepositPerByte::get()
|
||||
@@ -669,22 +709,30 @@ mod tests {
|
||||
#[test]
|
||||
fn register_handles_basic_errors() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Successfully register 32
|
||||
assert_ok!(Registrar::register(
|
||||
// Can't register system parachain
|
||||
assert_noop!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
32.into(),
|
||||
test_genesis_head(<Test as super::Config>::MaxHeadSize::get() as usize),
|
||||
test_validation_code(<Test as super::Config>::MaxCodeSize::get() as usize),
|
||||
), Error::<Test>::InvalidParaId);
|
||||
|
||||
// Successfully register 1032
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
1032.into(),
|
||||
test_genesis_head(<Test as super::Config>::MaxHeadSize::get() as usize),
|
||||
test_validation_code(<Test as super::Config>::MaxCodeSize::get() as usize),
|
||||
));
|
||||
|
||||
run_to_session(2);
|
||||
|
||||
assert_ok!(Registrar::deregister(Origin::root(), 32u32.into()));
|
||||
assert_ok!(Registrar::deregister(Origin::root(), 1032.into()));
|
||||
|
||||
// Can't do it again
|
||||
// Can't do it again until offboarded from the paras backend
|
||||
assert_noop!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
test_genesis_head(<Test as super::Config>::MaxHeadSize::get() as usize),
|
||||
test_validation_code(<Test as super::Config>::MaxCodeSize::get() as usize),
|
||||
), Error::<Test>::AlreadyRegistered);
|
||||
@@ -692,7 +740,7 @@ mod tests {
|
||||
// Head Size Check
|
||||
assert_noop!(Registrar::register(
|
||||
Origin::signed(2),
|
||||
23.into(),
|
||||
1023.into(),
|
||||
test_genesis_head((<Test as super::Config>::MaxHeadSize::get() + 1) as usize),
|
||||
test_validation_code(<Test as super::Config>::MaxCodeSize::get() as usize),
|
||||
), Error::<Test>::HeadDataTooLarge);
|
||||
@@ -700,7 +748,7 @@ mod tests {
|
||||
// Code Size Check
|
||||
assert_noop!(Registrar::register(
|
||||
Origin::signed(2),
|
||||
23.into(),
|
||||
1023.into(),
|
||||
test_genesis_head(<Test as super::Config>::MaxHeadSize::get() as usize),
|
||||
test_validation_code((<Test as super::Config>::MaxCodeSize::get() + 1) as usize),
|
||||
), Error::<Test>::CodeTooLarge);
|
||||
@@ -708,7 +756,7 @@ mod tests {
|
||||
// Needs enough funds for deposit
|
||||
assert_noop!(Registrar::register(
|
||||
Origin::signed(1337),
|
||||
23.into(),
|
||||
1023.into(),
|
||||
test_genesis_head(<Test as super::Config>::MaxHeadSize::get() as usize),
|
||||
test_validation_code(<Test as super::Config>::MaxCodeSize::get() as usize),
|
||||
), BalancesError::<Test, _>::InsufficientBalance);
|
||||
@@ -719,10 +767,10 @@ mod tests {
|
||||
fn deregister_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
assert!(!Parachains::is_parathread(32.into()));
|
||||
assert!(!Parachains::is_parathread(1032.into()));
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
test_genesis_head(32),
|
||||
test_validation_code(32),
|
||||
));
|
||||
@@ -731,13 +779,13 @@ mod tests {
|
||||
<Test as Config>::ParaDeposit::get() + 64 * <Test as Config>::DataDepositPerByte::get()
|
||||
);
|
||||
run_to_session(2);
|
||||
assert!(Parachains::is_parathread(32.into()));
|
||||
assert!(Parachains::is_parathread(1032.into()));
|
||||
assert_ok!(Registrar::deregister(
|
||||
Origin::root(),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
));
|
||||
run_to_session(4);
|
||||
assert!(paras::Module::<Test>::lifecycle(32.into()).is_none());
|
||||
assert!(paras::Module::<Test>::lifecycle(1032.into()).is_none());
|
||||
assert_eq!(Balances::reserved_balance(&1), 0);
|
||||
});
|
||||
}
|
||||
@@ -746,26 +794,26 @@ mod tests {
|
||||
fn deregister_handles_basic_errors() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
assert!(!Parachains::is_parathread(32.into()));
|
||||
assert!(!Parachains::is_parathread(1032.into()));
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
test_genesis_head(32),
|
||||
test_validation_code(32),
|
||||
));
|
||||
run_to_session(2);
|
||||
assert!(Parachains::is_parathread(32.into()));
|
||||
assert!(Parachains::is_parathread(1032.into()));
|
||||
// Owner check
|
||||
assert_noop!(Registrar::deregister(
|
||||
Origin::signed(2),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
), BadOrigin);
|
||||
assert_ok!(Registrar::make_parachain(32.into()));
|
||||
assert_ok!(Registrar::make_parachain(1032.into()));
|
||||
run_to_session(4);
|
||||
// Cant directly deregister parachain
|
||||
assert_noop!(Registrar::deregister(
|
||||
Origin::root(),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
), Error::<Test>::NotParathread);
|
||||
});
|
||||
}
|
||||
@@ -773,57 +821,57 @@ mod tests {
|
||||
#[test]
|
||||
fn swap_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Successfully register 23 and 32
|
||||
// Successfully register 1023 and 1032
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
23.into(),
|
||||
1023.into(),
|
||||
test_genesis_head(<Test as super::Config>::MaxHeadSize::get() as usize),
|
||||
test_validation_code(<Test as super::Config>::MaxCodeSize::get() as usize),
|
||||
));
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(2),
|
||||
32.into(),
|
||||
1032.into(),
|
||||
test_genesis_head(<Test as super::Config>::MaxHeadSize::get() as usize),
|
||||
test_validation_code(<Test as super::Config>::MaxCodeSize::get() as usize),
|
||||
));
|
||||
run_to_session(2);
|
||||
|
||||
// Upgrade 23 into a parachain
|
||||
assert_ok!(Registrar::make_parachain(23.into()));
|
||||
// Upgrade 1023 into a parachain
|
||||
assert_ok!(Registrar::make_parachain(1023.into()));
|
||||
|
||||
run_to_session(4);
|
||||
|
||||
// Roles are as we expect
|
||||
assert!(Parachains::is_parachain(23.into()));
|
||||
assert!(!Parachains::is_parathread(23.into()));
|
||||
assert!(!Parachains::is_parachain(32.into()));
|
||||
assert!(Parachains::is_parathread(32.into()));
|
||||
assert!(Parachains::is_parachain(1023.into()));
|
||||
assert!(!Parachains::is_parathread(1023.into()));
|
||||
assert!(!Parachains::is_parachain(1032.into()));
|
||||
assert!(Parachains::is_parathread(1032.into()));
|
||||
|
||||
// Both paras initiate a swap
|
||||
assert_ok!(Registrar::swap(
|
||||
para_origin(23.into()),
|
||||
23.into(),
|
||||
32.into(),
|
||||
para_origin(1023.into()),
|
||||
1023.into(),
|
||||
1032.into(),
|
||||
));
|
||||
assert_ok!(Registrar::swap(
|
||||
para_origin(32.into()),
|
||||
32.into(),
|
||||
23.into(),
|
||||
para_origin(1032.into()),
|
||||
1032.into(),
|
||||
1023.into(),
|
||||
));
|
||||
|
||||
run_to_session(6);
|
||||
|
||||
// Deregister a parathread that was originally a parachain
|
||||
assert_eq!(Parachains::lifecycle(23u32.into()), Some(ParaLifecycle::Parathread));
|
||||
assert_ok!(Registrar::deregister(runtime_parachains::Origin::Parachain(23u32.into()).into(), 23u32.into()));
|
||||
assert_eq!(Parachains::lifecycle(1023.into()), Some(ParaLifecycle::Parathread));
|
||||
assert_ok!(Registrar::deregister(runtime_parachains::Origin::Parachain(1023.into()).into(), 1023.into()));
|
||||
|
||||
run_to_block(21);
|
||||
|
||||
// Roles are swapped
|
||||
assert!(!Parachains::is_parachain(23.into()));
|
||||
assert!(Parachains::is_parathread(23.into()));
|
||||
assert!(Parachains::is_parachain(32.into()));
|
||||
assert!(!Parachains::is_parathread(32.into()));
|
||||
assert!(!Parachains::is_parachain(1023.into()));
|
||||
assert!(Parachains::is_parathread(1023.into()));
|
||||
assert!(Parachains::is_parachain(1032.into()));
|
||||
assert!(!Parachains::is_parathread(1032.into()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -834,7 +882,7 @@ mod tests {
|
||||
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
1u32.into(),
|
||||
1001.into(),
|
||||
vec![1; 3].into(),
|
||||
vec![1, 2, 3].into()
|
||||
));
|
||||
@@ -842,15 +890,15 @@ mod tests {
|
||||
// 2 session changes to fully onboard.
|
||||
run_to_session(2);
|
||||
|
||||
assert_eq!(Parachains::lifecycle(1u32.into()), Some(ParaLifecycle::Parathread));
|
||||
assert_ok!(Registrar::deregister(Origin::root(), 1u32.into()));
|
||||
assert_eq!(Parachains::lifecycle(1001.into()), Some(ParaLifecycle::Parathread));
|
||||
assert_ok!(Registrar::deregister(Origin::root(), 1001.into()));
|
||||
|
||||
// Cannot register while it is offboarding.
|
||||
run_to_session(3);
|
||||
|
||||
assert_noop!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
1u32.into(),
|
||||
1001.into(),
|
||||
vec![1; 3].into(),
|
||||
vec![1, 2, 3].into()
|
||||
), Error::<Test>::AlreadyRegistered);
|
||||
@@ -860,7 +908,7 @@ mod tests {
|
||||
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
1u32.into(),
|
||||
1001.into(),
|
||||
vec![1; 3].into(),
|
||||
vec![1, 2, 3].into()
|
||||
));
|
||||
@@ -874,23 +922,23 @@ mod tests {
|
||||
|
||||
assert_ok!(Registrar::register(
|
||||
Origin::signed(1),
|
||||
1u32.into(),
|
||||
1001.into(),
|
||||
vec![1; 3].into(),
|
||||
vec![1, 2, 3].into(),
|
||||
));
|
||||
|
||||
// Owner can call swap
|
||||
assert_ok!(Registrar::swap(Origin::signed(1), 1u32.into(), 2u32.into()));
|
||||
assert_ok!(Registrar::swap(Origin::signed(1), 1001.into(), 1002.into()));
|
||||
|
||||
// 2 session changes to fully onboard.
|
||||
run_to_session(2);
|
||||
assert_eq!(Parachains::lifecycle(1u32.into()), Some(ParaLifecycle::Parathread));
|
||||
assert_eq!(Parachains::lifecycle(1001.into()), Some(ParaLifecycle::Parathread));
|
||||
|
||||
// Once they begin onboarding, we lock them in.
|
||||
assert_ok!(Registrar::make_parachain(1u32.into()));
|
||||
assert_ok!(Registrar::make_parachain(1001.into()));
|
||||
|
||||
// Owner cannot call swap anymore
|
||||
assert_noop!(Registrar::swap(Origin::signed(1), 1u32.into(), 3u32.into()), BadOrigin);
|
||||
assert_noop!(Registrar::swap(Origin::signed(1), 1001.into(), 1003.into()), BadOrigin);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -904,7 +952,7 @@ mod benchmarking {
|
||||
use crate::traits::{Registrar as RegistrarT};
|
||||
use runtime_parachains::{paras, shared, Origin as ParaOrigin};
|
||||
|
||||
use frame_benchmarking::{benchmarks, whitelisted_caller, impl_benchmark_test_suite};
|
||||
use frame_benchmarking::{account, benchmarks, whitelisted_caller, impl_benchmark_test_suite};
|
||||
|
||||
fn assert_last_event<T: Config>(generic_event: <T as Config>::Event) {
|
||||
let events = frame_system::Pallet::<T>::events();
|
||||
@@ -953,6 +1001,20 @@ mod benchmarking {
|
||||
assert_eq!(paras::Module::<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>(RawEvent::Registered(para, manager).into());
|
||||
assert_eq!(paras::Module::<T>::lifecycle(para), Some(ParaLifecycle::Onboarding));
|
||||
next_scheduled_session::<T>();
|
||||
assert_eq!(paras::Module::<T>::lifecycle(para), Some(ParaLifecycle::Parathread));
|
||||
}
|
||||
|
||||
deregister {
|
||||
let para = register_para::<T>(1337);
|
||||
next_scheduled_session::<T>();
|
||||
|
||||
Reference in New Issue
Block a user