polkadot_runtime_common/
paras_sudo_wrapper.rs1use alloc::boxed::Box;
20use codec::Encode;
21use frame_support::pallet_prelude::*;
22use frame_system::pallet_prelude::*;
23pub use pallet::*;
24use polkadot_primitives::Id as ParaId;
25use polkadot_runtime_parachains::{
26	configuration, dmp, hrmp,
27	paras::{self, AssignCoretime, ParaGenesisArgs, ParaKind},
28	ParaLifecycle,
29};
30
31#[frame_support::pallet]
32pub mod pallet {
33	use super::*;
34
35	#[pallet::pallet]
36	pub struct Pallet<T>(_);
37
38	#[pallet::config]
39	#[pallet::disable_frame_system_supertrait_check]
40	pub trait Config: configuration::Config + paras::Config + dmp::Config + hrmp::Config {}
41
42	#[pallet::error]
43	pub enum Error<T> {
44		ParaDoesntExist,
46		ParaAlreadyExists,
48		ExceedsMaxMessageSize,
51		Unroutable,
53		CouldntCleanup,
55		NotParathread,
57		NotParachain,
59		CannotUpgrade,
61		CannotDowngrade,
63		TooManyCores,
65	}
66
67	#[pallet::hooks]
68	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
69
70	#[pallet::call]
71	impl<T: Config> Pallet<T> {
72		#[pallet::call_index(0)]
78		#[pallet::weight((1_000, DispatchClass::Operational))]
79		pub fn sudo_schedule_para_initialize(
80			origin: OriginFor<T>,
81			id: ParaId,
82			genesis: ParaGenesisArgs,
83		) -> DispatchResult {
84			ensure_root(origin)?;
85
86			let assign_coretime = genesis.para_kind == ParaKind::Parachain;
87
88			polkadot_runtime_parachains::schedule_para_initialize::<T>(id, genesis)
89				.map_err(|_| Error::<T>::ParaAlreadyExists)?;
90
91			if assign_coretime {
92				T::AssignCoretime::assign_coretime(id)?;
93			}
94
95			Ok(())
96		}
97
98		#[pallet::call_index(1)]
100		#[pallet::weight((1_000, DispatchClass::Operational))]
101		pub fn sudo_schedule_para_cleanup(origin: OriginFor<T>, id: ParaId) -> DispatchResult {
102			ensure_root(origin)?;
103			polkadot_runtime_parachains::schedule_para_cleanup::<T>(id)
104				.map_err(|_| Error::<T>::CouldntCleanup)?;
105			Ok(())
106		}
107
108		#[pallet::call_index(2)]
110		#[pallet::weight((1_000, DispatchClass::Operational))]
111		pub fn sudo_schedule_parathread_upgrade(
112			origin: OriginFor<T>,
113			id: ParaId,
114		) -> DispatchResult {
115			ensure_root(origin)?;
116			ensure!(
118				paras::Pallet::<T>::lifecycle(id) == Some(ParaLifecycle::Parathread),
119				Error::<T>::NotParathread,
120			);
121			polkadot_runtime_parachains::schedule_parathread_upgrade::<T>(id)
122				.map_err(|_| Error::<T>::CannotUpgrade)?;
123			Ok(())
124		}
125
126		#[pallet::call_index(3)]
128		#[pallet::weight((1_000, DispatchClass::Operational))]
129		pub fn sudo_schedule_parachain_downgrade(
130			origin: OriginFor<T>,
131			id: ParaId,
132		) -> DispatchResult {
133			ensure_root(origin)?;
134			ensure!(
136				paras::Pallet::<T>::lifecycle(id) == Some(ParaLifecycle::Parachain),
137				Error::<T>::NotParachain,
138			);
139			polkadot_runtime_parachains::schedule_parachain_downgrade::<T>(id)
140				.map_err(|_| Error::<T>::CannotDowngrade)?;
141			Ok(())
142		}
143
144		#[pallet::call_index(4)]
149		#[pallet::weight((1_000, DispatchClass::Operational))]
150		pub fn sudo_queue_downward_xcm(
151			origin: OriginFor<T>,
152			id: ParaId,
153			xcm: Box<xcm::opaque::VersionedXcm>,
154		) -> DispatchResult {
155			ensure_root(origin)?;
156			ensure!(paras::Pallet::<T>::is_valid_para(id), Error::<T>::ParaDoesntExist);
157			let config = configuration::ActiveConfig::<T>::get();
158			dmp::Pallet::<T>::queue_downward_message(&config, id, xcm.encode()).map_err(|e| match e
159			{
160				dmp::QueueDownwardMessageError::ExceedsMaxMessageSize =>
161					Error::<T>::ExceedsMaxMessageSize.into(),
162				dmp::QueueDownwardMessageError::Unroutable => Error::<T>::Unroutable.into(),
163			})
164		}
165
166		#[pallet::call_index(5)]
171		#[pallet::weight((1_000, DispatchClass::Operational))]
172		pub fn sudo_establish_hrmp_channel(
173			origin: OriginFor<T>,
174			sender: ParaId,
175			recipient: ParaId,
176			max_capacity: u32,
177			max_message_size: u32,
178		) -> DispatchResult {
179			ensure_root(origin)?;
180
181			hrmp::Pallet::<T>::init_open_channel(
182				sender,
183				recipient,
184				max_capacity,
185				max_message_size,
186			)?;
187			hrmp::Pallet::<T>::accept_open_channel(recipient, sender)?;
188			Ok(())
189		}
190	}
191}