1
// Copyright (C) Parity Technologies (UK) Ltd.
2
// This file is part of Polkadot.
3

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

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

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

            
17
//! Primitive types which are strictly necessary from a parachain-execution point
18
//! of view.
19

            
20
use alloc::vec::Vec;
21

            
22
use bounded_collections::{BoundedVec, ConstU32};
23
use codec::{CompactAs, Decode, Encode, MaxEncodedLen};
24
use scale_info::TypeInfo;
25
use serde::{Deserialize, Serialize};
26
use sp_core::{bytes, RuntimeDebug, TypeId};
27
use sp_runtime::traits::Hash as _;
28
use sp_weights::Weight;
29

            
30
use polkadot_core_primitives::{Hash, OutboundHrmpMessage};
31

            
32
/// Block number type used by the relay chain.
33
pub use polkadot_core_primitives::BlockNumber as RelayChainBlockNumber;
34

            
35
/// Parachain head data included in the chain.
36
#[derive(
37
	PartialEq,
38
	Eq,
39
	Clone,
40
	PartialOrd,
41
	Ord,
42
	Encode,
43
	Decode,
44
	RuntimeDebug,
45
	derive_more::From,
46
	TypeInfo,
47
	Serialize,
48
	Deserialize,
49
)]
50
#[cfg_attr(feature = "std", derive(Hash, Default))]
51
pub struct HeadData(#[serde(with = "bytes")] pub Vec<u8>);
52

            
53
impl HeadData {
54
	/// Returns the hash of this head data.
55
	pub fn hash(&self) -> Hash {
56
		sp_runtime::traits::BlakeTwo256::hash(&self.0)
57
	}
58
}
59

            
60
/// Parachain validation code.
61
#[derive(
62
	PartialEq,
63
	Eq,
64
	Clone,
65
	Encode,
66
	Decode,
67
	RuntimeDebug,
68
	derive_more::From,
69
	TypeInfo,
70
	Serialize,
71
	Deserialize,
72
)]
73
#[cfg_attr(feature = "std", derive(Hash))]
74
pub struct ValidationCode(#[serde(with = "bytes")] pub Vec<u8>);
75

            
76
impl ValidationCode {
77
	/// Get the blake2-256 hash of the validation code bytes.
78
346
	pub fn hash(&self) -> ValidationCodeHash {
79
346
		ValidationCodeHash(sp_runtime::traits::BlakeTwo256::hash(&self.0[..]))
80
346
	}
81
}
82

            
83
/// Unit type wrapper around [`type@Hash`] that represents the blake2-256 hash
84
/// of validation code in particular.
85
///
86
/// This type is produced by [`ValidationCode::hash`].
87
///
88
/// This type makes it easy to enforce that a hash is a validation code hash on the type level.
89
#[derive(Clone, Copy, Encode, Decode, Hash, Eq, PartialEq, PartialOrd, Ord, TypeInfo)]
90
pub struct ValidationCodeHash(Hash);
91

            
92
impl core::fmt::Display for ValidationCodeHash {
93
	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
94
		self.0.fmt(f)
95
	}
96
}
97

            
98
impl core::fmt::Debug for ValidationCodeHash {
99
	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
100
		write!(f, "{:?}", self.0)
101
	}
102
}
103

            
104
impl AsRef<[u8]> for ValidationCodeHash {
105
	fn as_ref(&self) -> &[u8] {
106
		self.0.as_ref()
107
	}
108
}
109

            
110
impl From<Hash> for ValidationCodeHash {
111
	fn from(hash: Hash) -> ValidationCodeHash {
112
		ValidationCodeHash(hash)
113
	}
114
}
115

            
116
impl From<[u8; 32]> for ValidationCodeHash {
117
	fn from(hash: [u8; 32]) -> ValidationCodeHash {
118
		ValidationCodeHash(hash.into())
119
	}
120
}
121

            
122
impl core::fmt::LowerHex for ValidationCodeHash {
123
	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
124
		core::fmt::LowerHex::fmt(&self.0, f)
125
	}
126
}
127

            
128
/// Parachain block data.
129
///
130
/// Contains everything required to validate para-block, may contain block and witness data.
131
#[derive(PartialEq, Eq, Clone, Encode, Decode, derive_more::From, TypeInfo, RuntimeDebug)]
132
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
133
pub struct BlockData(#[cfg_attr(feature = "std", serde(with = "bytes"))] pub Vec<u8>);
134

            
135
/// Unique identifier of a parachain.
136
#[derive(
137
	Clone,
138
	CompactAs,
139
	Copy,
140
	Decode,
141
	Default,
142
	Encode,
143
	Eq,
144
	Hash,
145
	MaxEncodedLen,
146
	Ord,
147
	PartialEq,
148
	PartialOrd,
149
	RuntimeDebug,
150
	serde::Serialize,
151
	serde::Deserialize,
152
	TypeInfo,
153
)]
154
#[cfg_attr(feature = "std", derive(derive_more::Display))]
155
pub struct Id(u32);
156

            
157
impl TypeId for Id {
158
	const TYPE_ID: [u8; 4] = *b"para";
159
}
160

            
161
impl From<Id> for u32 {
162
	fn from(x: Id) -> Self {
163
		x.0
164
	}
165
}
166

            
167
impl From<u32> for Id {
168
228740
	fn from(x: u32) -> Self {
169
228740
		Id(x)
170
228740
	}
171
}
172

            
173
impl From<usize> for Id {
174
	fn from(x: usize) -> Self {
175
		// can't panic, so need to truncate
176
		let x = x.try_into().unwrap_or(u32::MAX);
177
		Id(x)
178
	}
179
}
180

            
181
// When we added a second From impl for Id, type inference could no longer
182
// determine which impl should apply for things like `5.into()`. It therefore
183
// raised a bunch of errors in our test code, scattered throughout the
184
// various modules' tests, that there is no impl of `From<i32>` (`i32` being
185
// the default numeric type).
186
//
187
// We can't use `cfg(test)` here, because that configuration directive does not
188
// propagate between crates, which would fail to fix tests in crates other than
189
// this one.
190
//
191
// Instead, let's take advantage of the observation that what really matters for a
192
// ParaId within a test context is that it is unique and constant. I believe that
193
// there is no case where someone does `(-1).into()` anyway, but if they do, it
194
// never matters whether the actual contained ID is `-1` or `4294967295`. Nobody
195
// does arithmetic on a `ParaId`; doing so would be a bug.
196
impl From<i32> for Id {
197
12
	fn from(x: i32) -> Self {
198
12
		Id(x as u32)
199
12
	}
200
}
201

            
202
// System parachain ID is considered `< 2000`.
203
const SYSTEM_INDEX_END: u32 = 1999;
204
const PUBLIC_INDEX_START: u32 = 2000;
205

            
206
/// The ID of the first publicly registrable parachain.
207
pub const LOWEST_PUBLIC_ID: Id = Id(PUBLIC_INDEX_START);
208

            
209
impl Id {
210
	/// Create an `Id`.
211
	pub const fn new(id: u32) -> Self {
212
		Self(id)
213
	}
214
}
215

            
216
/// Determine if a parachain is a system parachain or not.
217
pub trait IsSystem {
218
	/// Returns `true` if a parachain is a system parachain, `false` otherwise.
219
	fn is_system(&self) -> bool;
220
}
221

            
222
impl IsSystem for Id {
223
2084
	fn is_system(&self) -> bool {
224
2084
		self.0 <= SYSTEM_INDEX_END
225
2084
	}
226
}
227

            
228
impl core::ops::Add<u32> for Id {
229
	type Output = Self;
230

            
231
30
	fn add(self, other: u32) -> Self {
232
30
		Self(self.0 + other)
233
30
	}
234
}
235

            
236
impl core::ops::Sub<u32> for Id {
237
	type Output = Self;
238

            
239
	fn sub(self, other: u32) -> Self {
240
		Self(self.0 - other)
241
	}
242
}
243

            
244
#[derive(
245
	Clone, Copy, Default, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo,
246
)]
247
pub struct Sibling(pub Id);
248

            
249
impl From<Id> for Sibling {
250
	fn from(i: Id) -> Self {
251
		Self(i)
252
	}
253
}
254

            
255
impl From<Sibling> for Id {
256
	fn from(i: Sibling) -> Self {
257
		i.0
258
	}
259
}
260

            
261
impl AsRef<Id> for Sibling {
262
	fn as_ref(&self) -> &Id {
263
		&self.0
264
	}
265
}
266

            
267
impl TypeId for Sibling {
268
	const TYPE_ID: [u8; 4] = *b"sibl";
269
}
270

            
271
impl From<Sibling> for u32 {
272
	fn from(x: Sibling) -> Self {
273
		x.0.into()
274
	}
275
}
276

            
277
impl From<u32> for Sibling {
278
	fn from(x: u32) -> Self {
279
		Sibling(x.into())
280
	}
281
}
282

            
283
impl IsSystem for Sibling {
284
	fn is_system(&self) -> bool {
285
		IsSystem::is_system(&self.0)
286
	}
287
}
288

            
289
/// A type that uniquely identifies an HRMP channel. An HRMP channel is established between two
290
/// paras. In text, we use the notation `(A, B)` to specify a channel between A and B. The channels
291
/// are unidirectional, meaning that `(A, B)` and `(B, A)` refer to different channels. The
292
/// convention is that we use the first item tuple for the sender and the second for the recipient.
293
/// Only one channel is allowed between two participants in one direction, i.e. there cannot be 2
294
/// different channels identified by `(A, B)`. A channel with the same para id in sender and
295
/// recipient is invalid. That is, however, not enforced.
296
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, RuntimeDebug, TypeInfo)]
297
#[cfg_attr(feature = "std", derive(Hash))]
298
pub struct HrmpChannelId {
299
	/// The para that acts as the sender in this channel.
300
	pub sender: Id,
301
	/// The para that acts as the recipient in this channel.
302
	pub recipient: Id,
303
}
304

            
305
impl HrmpChannelId {
306
	/// Returns true if the given id corresponds to either the sender or the recipient.
307
	pub fn is_participant(&self, id: Id) -> bool {
308
		id == self.sender || id == self.recipient
309
	}
310
}
311

            
312
/// A message from a parachain to its Relay Chain.
313
pub type UpwardMessage = Vec<u8>;
314

            
315
/// Something that should be called when a downward message is received.
316
pub trait DmpMessageHandler {
317
	/// Handle some incoming DMP messages (note these are individual XCM messages).
318
	///
319
	/// Also, process messages up to some `max_weight`.
320
	fn handle_dmp_messages(
321
		iter: impl Iterator<Item = (RelayChainBlockNumber, Vec<u8>)>,
322
		max_weight: Weight,
323
	) -> Weight;
324
}
325
impl DmpMessageHandler for () {
326
	fn handle_dmp_messages(
327
		iter: impl Iterator<Item = (RelayChainBlockNumber, Vec<u8>)>,
328
		_max_weight: Weight,
329
	) -> Weight {
330
		iter.for_each(drop);
331
		Weight::zero()
332
	}
333
}
334

            
335
/// The aggregate XCMP message format.
336
#[derive(
337
	Copy,
338
	Clone,
339
	Eq,
340
	PartialEq,
341
	Ord,
342
	PartialOrd,
343
	Encode,
344
	Decode,
345
	TypeInfo,
346
	RuntimeDebug,
347
	MaxEncodedLen,
348
)]
349
pub enum XcmpMessageFormat {
350
	/// Encoded `VersionedXcm` messages, all concatenated.
351
	ConcatenatedVersionedXcm,
352
	/// Encoded `Vec<u8>` messages, all concatenated.
353
	ConcatenatedEncodedBlob,
354
	/// One or more channel control signals; these should be interpreted immediately upon receipt
355
	/// from the relay-chain.
356
	Signals,
357
}
358

            
359
/// Something that should be called for each batch of messages received over XCMP.
360
pub trait XcmpMessageHandler {
361
	/// Handle some incoming XCMP messages (note these are the big one-per-block aggregate
362
	/// messages).
363
	///
364
	/// Also, process messages up to some `max_weight`.
365
	fn handle_xcmp_messages<'a, I: Iterator<Item = (Id, RelayChainBlockNumber, &'a [u8])>>(
366
		iter: I,
367
		max_weight: Weight,
368
	) -> Weight;
369
}
370
impl XcmpMessageHandler for () {
371
	fn handle_xcmp_messages<'a, I: Iterator<Item = (Id, RelayChainBlockNumber, &'a [u8])>>(
372
		iter: I,
373
		_max_weight: Weight,
374
	) -> Weight {
375
		for _ in iter {}
376
		Weight::zero()
377
	}
378
}
379

            
380
/// Validation parameters for evaluating the parachain validity function.
381
// TODO: balance downloads (https://github.com/paritytech/polkadot/issues/220)
382
#[derive(PartialEq, Eq, Decode, Clone)]
383
#[cfg_attr(feature = "std", derive(Debug, Encode))]
384
pub struct ValidationParams {
385
	/// Previous head-data.
386
	pub parent_head: HeadData,
387
	/// The collation body.
388
	pub block_data: BlockData,
389
	/// The current relay-chain block number.
390
	pub relay_parent_number: RelayChainBlockNumber,
391
	/// The relay-chain block's storage root.
392
	pub relay_parent_storage_root: Hash,
393
}
394

            
395
/// Maximum number of HRMP messages allowed per candidate.
396
///
397
/// We also use this as a generous limit, which still prevents possible memory exhaustion, from
398
/// malicious parachains that may otherwise return a huge amount of messages in `ValidationResult`.
399
pub const MAX_HORIZONTAL_MESSAGE_NUM: u32 = 16 * 1024;
400
/// Maximum number of UMP messages allowed per candidate.
401
///
402
/// We also use this as a generous limit, which still prevents possible memory exhaustion, from
403
/// malicious parachains that may otherwise return a huge amount of messages in `ValidationResult`.
404
pub const MAX_UPWARD_MESSAGE_NUM: u32 = 16 * 1024;
405

            
406
pub type UpwardMessages = BoundedVec<UpwardMessage, ConstU32<MAX_UPWARD_MESSAGE_NUM>>;
407

            
408
pub type HorizontalMessages =
409
	BoundedVec<OutboundHrmpMessage<Id>, ConstU32<MAX_HORIZONTAL_MESSAGE_NUM>>;
410

            
411
/// The result of parachain validation.
412
// TODO: balance uploads (https://github.com/paritytech/polkadot/issues/220)
413
#[derive(PartialEq, Eq, Clone, Encode)]
414
#[cfg_attr(feature = "std", derive(Debug, Decode))]
415
pub struct ValidationResult {
416
	/// New head data that should be included in the relay chain state.
417
	pub head_data: HeadData,
418
	/// An update to the validation code that should be scheduled in the relay chain.
419
	pub new_validation_code: Option<ValidationCode>,
420
	/// Upward messages send by the Parachain.
421
	pub upward_messages: UpwardMessages,
422
	/// Outbound horizontal messages sent by the parachain.
423
	pub horizontal_messages: HorizontalMessages,
424
	/// Number of downward messages that were processed by the Parachain.
425
	///
426
	/// It is expected that the Parachain processes them from first to last.
427
	pub processed_downward_messages: u32,
428
	/// The mark which specifies the block number up to which all inbound HRMP messages are
429
	/// processed.
430
	pub hrmp_watermark: RelayChainBlockNumber,
431
}