mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Parachain Onboarding Extras (#2713)
* clear_lease * schedule upgrade and downgrade * fix compile * comments
This commit is contained in:
@@ -25,7 +25,9 @@ use frame_support::{
|
||||
};
|
||||
use frame_system::ensure_root;
|
||||
use runtime_parachains::{
|
||||
configuration, dmp, ump, hrmp, paras::{self, ParaGenesisArgs},
|
||||
configuration, dmp, ump, hrmp,
|
||||
ParaLifecycle,
|
||||
paras::{self, ParaGenesisArgs},
|
||||
};
|
||||
use primitives::v1::Id as ParaId;
|
||||
use parity_scale_codec::Encode;
|
||||
@@ -49,6 +51,14 @@ decl_error! {
|
||||
DefinitelyNotWasm,
|
||||
/// Could not schedule para cleanup.
|
||||
CouldntCleanup,
|
||||
/// Not a parathread.
|
||||
NotParathread,
|
||||
/// Not a parachain.
|
||||
NotParachain,
|
||||
/// Cannot upgrade parathread.
|
||||
CannotUpgrade,
|
||||
/// Cannot downgrade parachain.
|
||||
CannotDowngrade,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +88,26 @@ decl_module! {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Upgrade a parathread to a parachain
|
||||
#[weight = (1_000, DispatchClass::Operational)]
|
||||
pub fn sudo_schedule_parathread_upgrade(origin, id: ParaId) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
// Para backend should think this is a parathread...
|
||||
ensure!(paras::Module::<T>::lifecycle(id) == Some(ParaLifecycle::Parathread), Error::<T>::NotParathread);
|
||||
runtime_parachains::schedule_parathread_upgrade::<T>(id).map_err(|_| Error::<T>::CannotUpgrade)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Downgrade a parachain to a parathread
|
||||
#[weight = (1_000, DispatchClass::Operational)]
|
||||
pub fn sudo_schedule_parachain_downgrade(origin, id: ParaId) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
// Para backend should think this is a parachain...
|
||||
ensure!(paras::Module::<T>::lifecycle(id) == Some(ParaLifecycle::Parachain), Error::<T>::NotParachain);
|
||||
runtime_parachains::schedule_parachain_downgrade::<T>(id).map_err(|_| Error::<T>::CannotDowngrade)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Send a downward XCM to the given para.
|
||||
///
|
||||
/// The given parachain should exist and the payload should not exceed the preconfigured size
|
||||
|
||||
@@ -154,6 +154,8 @@ decl_module! {
|
||||
|
||||
/// Just a hotwire into the `lease_out` call, in case Root wants to force some lease to happen
|
||||
/// independently of any other on-chain mechanism to use it.
|
||||
///
|
||||
/// Can only be called by the Root origin.
|
||||
#[weight = T::WeightInfo::force_lease()]
|
||||
fn force_lease(origin,
|
||||
para: ParaId,
|
||||
@@ -167,6 +169,26 @@ decl_module! {
|
||||
.map_err(|_| Error::<T>::LeaseError)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Clear all leases for a Para Id, refunding any deposits back to the original owners.
|
||||
///
|
||||
/// Can only be called by the Root origin.
|
||||
#[weight = 0] // TODO: Benchmarks
|
||||
fn clear_all_leases(origin,
|
||||
para: ParaId,
|
||||
) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
let deposits = Self::all_deposits_held(para);
|
||||
|
||||
// Refund any deposits for these leases
|
||||
for (who, deposit) in deposits {
|
||||
let err_amount = T::Currency::unreserve(&who, deposit);
|
||||
debug_assert!(err_amount.is_zero());
|
||||
}
|
||||
|
||||
Leases::<T>::remove(para);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,7 +238,7 @@ impl<T: Config> Module<T> {
|
||||
// If this is less than what we were holding for this leaser's now-ended lease, then
|
||||
// unreserve it.
|
||||
if let Some(rebate) = ended_lease.1.checked_sub(&now_held) {
|
||||
T::Currency::unreserve( &ended_lease.0, rebate);
|
||||
T::Currency::unreserve(&ended_lease.0, rebate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +271,34 @@ impl<T: Config> Module<T> {
|
||||
parachains.len() as u32,
|
||||
)
|
||||
}
|
||||
|
||||
// Return a vector of (user, balance) for all deposits for a parachain.
|
||||
// Useful when trying to clean up a parachain leases, as this would tell
|
||||
// you all the balances you need to unreserve.
|
||||
fn all_deposits_held(para: ParaId) -> Vec<(T::AccountId, BalanceOf<T>)> {
|
||||
let mut tracker = sp_std::collections::btree_map::BTreeMap::new();
|
||||
Leases::<T>::get(para)
|
||||
.into_iter()
|
||||
.for_each(|lease| {
|
||||
match lease {
|
||||
Some((who, amount)) => {
|
||||
match tracker.get(&who) {
|
||||
Some(prev_amount) => {
|
||||
if amount > *prev_amount {
|
||||
tracker.insert(who, amount);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
tracker.insert(who, amount);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
});
|
||||
|
||||
tracker.into_iter().collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> crate::traits::OnSwap for Module<T> {
|
||||
@@ -653,6 +703,37 @@ mod tests {
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clear_all_leases_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
|
||||
assert_ok!(TestRegistrar::<Test>::register(1, ParaId::from(1), Default::default(), Default::default()));
|
||||
|
||||
let max_num = 5u32;
|
||||
|
||||
// max_num different people are reserved for leases to Para ID 1
|
||||
for i in 1u32 ..= max_num {
|
||||
let j: u64 = i.into();
|
||||
assert_ok!(Slots::lease_out(1.into(), &j, j * 10, i * i, i));
|
||||
assert_eq!(Slots::deposit_held(1.into(), &j), j * 10);
|
||||
assert_eq!(Balances::reserved_balance(j), j * 10);
|
||||
}
|
||||
|
||||
assert_ok!(Slots::clear_all_leases(Origin::root(), 1.into()));
|
||||
|
||||
// Balances cleaned up correctly
|
||||
for i in 1u32 ..= max_num {
|
||||
let j: u64 = i.into();
|
||||
assert_eq!(Slots::deposit_held(1.into(), &j), 0);
|
||||
assert_eq!(Balances::reserved_balance(j), 0);
|
||||
}
|
||||
|
||||
// Leases is empty.
|
||||
assert!(Leases::<Test>::get(ParaId::from(1)).is_empty());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
|
||||
@@ -78,6 +78,7 @@ pub trait Registrar {
|
||||
}
|
||||
|
||||
/// Error type for something that went wrong with leasing.
|
||||
#[derive(Debug)]
|
||||
pub enum LeaseError {
|
||||
/// Unable to reserve the funds in the leaser's account.
|
||||
ReserveFailed,
|
||||
|
||||
Reference in New Issue
Block a user