paras_sudo_wrapper.rs 3.85 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.

//! A simple wrapper allowing `Sudo` to call into `paras` routines.

19
use crate::WASM_MAGIC;
20
use sp_std::prelude::*;
21
use frame_support::{
22
	decl_error, decl_module, ensure,
23
24
25
	dispatch::DispatchResult,
	weights::DispatchClass,
};
26
use frame_system::ensure_root;
27
use runtime_parachains::{
28
	configuration, dmp, ump, hrmp, paras::{self, ParaGenesisArgs},
29
30
};
use primitives::v1::Id as ParaId;
Shawn Tabrizi's avatar
Shawn Tabrizi committed
31
use parity_scale_codec::Encode;
32
33

/// The module's configuration trait.
34
35
pub trait Config:
	configuration::Config + paras::Config + dmp::Config + ump::Config + hrmp::Config
36
37
{
}
38
39

decl_error! {
40
	pub enum Error for Module<T: Config> {
41
42
43
44
45
		/// The specified parachain or parathread is not registered.
		ParaDoesntExist,
		/// A DMP message couldn't be sent because it exceeds the maximum size allowed for a downward
		/// message.
		ExceedsMaxMessageSize,
46
47
		/// The validation code provided doesn't start with the Wasm file magic string.
		DefinitelyNotWasm,
48
	}
49
50
51
52
}

decl_module! {
	/// A sudo wrapper to call into v1 paras module.
53
	pub struct Module<T: Config> for enum Call where origin: <T as frame_system::Config>::Origin {
54
55
56
57
58
59
60
61
62
63
		type Error = Error<T>;

		/// Schedule a para to be initialized at the start of the next session.
		#[weight = (1_000, DispatchClass::Operational)]
		pub fn sudo_schedule_para_initialize(
			origin,
			id: ParaId,
			genesis: ParaGenesisArgs,
		) -> DispatchResult {
			ensure_root(origin)?;
64
			ensure!(genesis.validation_code.0.starts_with(WASM_MAGIC), Error::<T>::DefinitelyNotWasm);
65
			runtime_parachains::schedule_para_initialize::<T>(id, genesis);
66
67
68
69
70
71
72
			Ok(())
		}

		/// Schedule a para to be cleaned up at the start of the next session.
		#[weight = (1_000, DispatchClass::Operational)]
		pub fn sudo_schedule_para_cleanup(origin, id: ParaId) -> DispatchResult {
			ensure_root(origin)?;
73
			runtime_parachains::schedule_para_cleanup::<T>(id);
74
75
			Ok(())
		}
76

Shawn Tabrizi's avatar
Shawn Tabrizi committed
77
		/// Send a downward XCM to the given para.
78
79
80
81
		///
		/// The given parachain should exist and the payload should not exceed the preconfigured size
		/// `config.max_downward_message_size`.
		#[weight = (1_000, DispatchClass::Operational)]
Shawn Tabrizi's avatar
Shawn Tabrizi committed
82
		pub fn sudo_queue_downward_xcm(origin, id: ParaId, xcm: xcm::VersionedXcm) -> DispatchResult {
83
84
85
			ensure_root(origin)?;
			ensure!(<paras::Module<T>>::is_valid_para(id), Error::<T>::ParaDoesntExist);
			let config = <configuration::Module<T>>::config();
Shawn Tabrizi's avatar
Shawn Tabrizi committed
86
			<dmp::Module<T>>::queue_downward_message(&config, id, xcm.encode())
87
88
89
90
91
				.map_err(|e| match e {
					dmp::QueueDownwardMessageError::ExceedsMaxMessageSize =>
						Error::<T>::ExceedsMaxMessageSize.into(),
				})
		}
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

		/// Forcefully establish a channel from the sender to the recipient.
		///
		/// This is equivalent to sending an `Hrmp::hrmp_init_open_channel` extrinsic followed by
		/// `Hrmp::hrmp_accept_open_channel`.
		#[weight = (1_000, DispatchClass::Operational)]
		pub fn sudo_establish_hrmp_channel(
			origin,
			sender: ParaId,
			recipient: ParaId,
			max_capacity: u32,
			max_message_size: u32,
		) -> DispatchResult {
			ensure_root(origin)?;

			<hrmp::Module<T>>::init_open_channel(
				sender,
				recipient,
				max_capacity,
				max_message_size,
			)?;
			<hrmp::Module<T>>::accept_open_channel(recipient, sender)?;
			Ok(())
		}
116
117
	}
}