use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
pub use pallet::*;
use parity_scale_codec::Encode;
use primitives::v2::Id as ParaId;
use runtime_parachains::{
configuration, dmp, hrmp,
paras::{self, ParaGenesisArgs},
ump, ParaLifecycle,
};
use sp_std::boxed::Box;
#[frame_support::pallet]
pub mod pallet {
use super::*;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
#[pallet::config]
#[pallet::disable_frame_system_supertrait_check]
pub trait Config:
configuration::Config + paras::Config + dmp::Config + ump::Config + hrmp::Config
{
}
#[pallet::error]
pub enum Error<T> {
ParaDoesntExist,
ParaAlreadyExists,
ExceedsMaxMessageSize,
CouldntCleanup,
NotParathread,
NotParachain,
CannotUpgrade,
CannotDowngrade,
}
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight((1_000, DispatchClass::Operational))]
pub fn sudo_schedule_para_initialize(
origin: OriginFor<T>,
id: ParaId,
genesis: ParaGenesisArgs,
) -> DispatchResult {
ensure_root(origin)?;
runtime_parachains::schedule_para_initialize::<T>(id, genesis)
.map_err(|_| Error::<T>::ParaAlreadyExists)?;
Ok(())
}
#[pallet::call_index(1)]
#[pallet::weight((1_000, DispatchClass::Operational))]
pub fn sudo_schedule_para_cleanup(origin: OriginFor<T>, id: ParaId) -> DispatchResult {
ensure_root(origin)?;
runtime_parachains::schedule_para_cleanup::<T>(id)
.map_err(|_| Error::<T>::CouldntCleanup)?;
Ok(())
}
#[pallet::call_index(2)]
#[pallet::weight((1_000, DispatchClass::Operational))]
pub fn sudo_schedule_parathread_upgrade(
origin: OriginFor<T>,
id: ParaId,
) -> DispatchResult {
ensure_root(origin)?;
ensure!(
paras::Pallet::<T>::lifecycle(id) == Some(ParaLifecycle::Parathread),
Error::<T>::NotParathread,
);
runtime_parachains::schedule_parathread_upgrade::<T>(id)
.map_err(|_| Error::<T>::CannotUpgrade)?;
Ok(())
}
#[pallet::call_index(3)]
#[pallet::weight((1_000, DispatchClass::Operational))]
pub fn sudo_schedule_parachain_downgrade(
origin: OriginFor<T>,
id: ParaId,
) -> DispatchResult {
ensure_root(origin)?;
ensure!(
paras::Pallet::<T>::lifecycle(id) == Some(ParaLifecycle::Parachain),
Error::<T>::NotParachain,
);
runtime_parachains::schedule_parachain_downgrade::<T>(id)
.map_err(|_| Error::<T>::CannotDowngrade)?;
Ok(())
}
#[pallet::call_index(4)]
#[pallet::weight((1_000, DispatchClass::Operational))]
pub fn sudo_queue_downward_xcm(
origin: OriginFor<T>,
id: ParaId,
xcm: Box<xcm::opaque::VersionedXcm>,
) -> DispatchResult {
ensure_root(origin)?;
ensure!(<paras::Pallet<T>>::is_valid_para(id), Error::<T>::ParaDoesntExist);
let config = <configuration::Pallet<T>>::config();
<dmp::Pallet<T>>::queue_downward_message(&config, id, xcm.encode()).map_err(|e| match e
{
dmp::QueueDownwardMessageError::ExceedsMaxMessageSize =>
Error::<T>::ExceedsMaxMessageSize.into(),
})
}
#[pallet::call_index(5)]
#[pallet::weight((1_000, DispatchClass::Operational))]
pub fn sudo_establish_hrmp_channel(
origin: OriginFor<T>,
sender: ParaId,
recipient: ParaId,
max_capacity: u32,
max_message_size: u32,
) -> DispatchResult {
ensure_root(origin)?;
<hrmp::Pallet<T>>::init_open_channel(
sender,
recipient,
max_capacity,
max_message_size,
)?;
<hrmp::Pallet<T>>::accept_open_channel(recipient, sender)?;
Ok(())
}
}
}