1use alloc::vec::Vec;
21
22use bounded_collections::{BoundedVec, ConstU32};
23use codec::{CompactAs, Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
24use scale_info::TypeInfo;
25use serde::{Deserialize, Serialize};
26use sp_core::{bytes, TypeId};
27use sp_runtime::traits::Hash as _;
28use sp_weights::Weight;
29
30use polkadot_core_primitives::{Hash, OutboundHrmpMessage};
31
32pub use polkadot_core_primitives::BlockNumber as RelayChainBlockNumber;
34
35#[derive(
37 PartialEq,
38 Eq,
39 Clone,
40 PartialOrd,
41 Ord,
42 Encode,
43 Decode,
44 DecodeWithMemTracking,
45 derive_more::From,
46 TypeInfo,
47 Serialize,
48 Deserialize,
49)]
50#[cfg_attr(feature = "std", derive(Hash, Default))]
51pub struct HeadData(#[serde(with = "bytes")] pub Vec<u8>);
52
53impl core::fmt::Debug for HeadData {
54 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55 write!(f, "HeadData({})", array_bytes::bytes2hex("0x", &self.0))
56 }
57}
58
59impl HeadData {
60 pub fn hash(&self) -> Hash {
62 sp_runtime::traits::BlakeTwo256::hash(&self.0)
63 }
64}
65
66impl codec::EncodeLike<HeadData> for alloc::vec::Vec<u8> {}
67
68#[derive(
70 PartialEq,
71 Eq,
72 Clone,
73 Encode,
74 Decode,
75 DecodeWithMemTracking,
76 derive_more::From,
77 TypeInfo,
78 Serialize,
79 Deserialize,
80)]
81#[cfg_attr(feature = "std", derive(Hash))]
82pub struct ValidationCode(#[serde(with = "bytes")] pub Vec<u8>);
83
84impl core::fmt::Debug for ValidationCode {
85 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
86 write!(f, "ValidationCode({})", array_bytes::bytes2hex("0x", &self.0))
87 }
88}
89
90impl ValidationCode {
91 pub fn hash(&self) -> ValidationCodeHash {
93 ValidationCodeHash(sp_runtime::traits::BlakeTwo256::hash(&self.0[..]))
94 }
95}
96
97#[derive(
104 Clone,
105 Copy,
106 Encode,
107 Decode,
108 DecodeWithMemTracking,
109 Hash,
110 Eq,
111 PartialEq,
112 PartialOrd,
113 Ord,
114 TypeInfo,
115)]
116pub struct ValidationCodeHash(Hash);
117
118impl core::fmt::Display for ValidationCodeHash {
119 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
120 self.0.fmt(f)
121 }
122}
123
124impl core::fmt::Debug for ValidationCodeHash {
125 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
126 write!(f, "{:?}", self.0)
127 }
128}
129
130impl AsRef<[u8]> for ValidationCodeHash {
131 fn as_ref(&self) -> &[u8] {
132 self.0.as_ref()
133 }
134}
135
136impl From<Hash> for ValidationCodeHash {
137 fn from(hash: Hash) -> ValidationCodeHash {
138 ValidationCodeHash(hash)
139 }
140}
141
142impl From<[u8; 32]> for ValidationCodeHash {
143 fn from(hash: [u8; 32]) -> ValidationCodeHash {
144 ValidationCodeHash(hash.into())
145 }
146}
147
148impl core::fmt::LowerHex for ValidationCodeHash {
149 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
150 core::fmt::LowerHex::fmt(&self.0, f)
151 }
152}
153
154#[derive(PartialEq, Eq, Clone, Encode, Decode, derive_more::From, TypeInfo, Debug)]
158#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
159pub struct BlockData(#[cfg_attr(feature = "std", serde(with = "bytes"))] pub Vec<u8>);
160
161#[derive(
163 Clone,
164 CompactAs,
165 Copy,
166 Decode,
167 DecodeWithMemTracking,
168 Default,
169 Encode,
170 Eq,
171 Hash,
172 MaxEncodedLen,
173 Ord,
174 PartialEq,
175 PartialOrd,
176 serde::Serialize,
177 serde::Deserialize,
178 TypeInfo,
179)]
180#[cfg_attr(feature = "std", derive(derive_more::Display))]
181pub struct Id(u32);
182
183impl core::fmt::Debug for Id {
184 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
185 self.0.fmt(f)
186 }
187}
188
189impl codec::EncodeLike<u32> for Id {}
190impl codec::EncodeLike<Id> for u32 {}
191
192impl TypeId for Id {
193 const TYPE_ID: [u8; 4] = *b"para";
194}
195
196impl From<Id> for u32 {
197 fn from(x: Id) -> Self {
198 x.0
199 }
200}
201
202impl From<u32> for Id {
203 fn from(x: u32) -> Self {
204 Id(x)
205 }
206}
207
208#[cfg(any(feature = "std", feature = "runtime-benchmarks"))]
209impl From<usize> for Id {
210 fn from(x: usize) -> Self {
211 let x = x.try_into().unwrap_or(u32::MAX);
213 Id(x)
214 }
215}
216
217impl From<i32> for Id {
233 fn from(x: i32) -> Self {
234 Id(x as u32)
235 }
236}
237
238const SYSTEM_INDEX_END: u32 = 1999;
240const PUBLIC_INDEX_START: u32 = 2000;
241
242pub const LOWEST_PUBLIC_ID: Id = Id(PUBLIC_INDEX_START);
244
245impl Id {
246 pub const fn new(id: u32) -> Self {
248 Self(id)
249 }
250}
251
252pub trait IsSystem {
254 fn is_system(&self) -> bool;
256}
257
258impl IsSystem for Id {
259 fn is_system(&self) -> bool {
260 self.0 <= SYSTEM_INDEX_END
261 }
262}
263
264impl core::ops::Add<u32> for Id {
265 type Output = Self;
266
267 fn add(self, other: u32) -> Self {
268 Self(self.0 + other)
269 }
270}
271
272impl core::ops::Sub<u32> for Id {
273 type Output = Self;
274
275 fn sub(self, other: u32) -> Self {
276 Self(self.0 - other)
277 }
278}
279
280#[derive(Clone, Copy, Default, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, Debug, TypeInfo)]
281pub struct Sibling(pub Id);
282
283impl From<Id> for Sibling {
284 fn from(i: Id) -> Self {
285 Self(i)
286 }
287}
288
289impl From<Sibling> for Id {
290 fn from(i: Sibling) -> Self {
291 i.0
292 }
293}
294
295impl AsRef<Id> for Sibling {
296 fn as_ref(&self) -> &Id {
297 &self.0
298 }
299}
300
301impl TypeId for Sibling {
302 const TYPE_ID: [u8; 4] = *b"sibl";
303}
304
305impl From<Sibling> for u32 {
306 fn from(x: Sibling) -> Self {
307 x.0.into()
308 }
309}
310
311impl From<u32> for Sibling {
312 fn from(x: u32) -> Self {
313 Sibling(x.into())
314 }
315}
316
317impl IsSystem for Sibling {
318 fn is_system(&self) -> bool {
319 IsSystem::is_system(&self.0)
320 }
321}
322
323#[derive(
331 Clone, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, DecodeWithMemTracking, Debug, TypeInfo,
332)]
333#[cfg_attr(feature = "std", derive(Hash))]
334pub struct HrmpChannelId {
335 pub sender: Id,
337 pub recipient: Id,
339}
340
341impl HrmpChannelId {
342 pub fn is_participant(&self, id: Id) -> bool {
344 id == self.sender || id == self.recipient
345 }
346}
347
348pub type UpwardMessage = Vec<u8>;
350
351pub trait DmpMessageHandler {
353 fn handle_dmp_messages(
357 iter: impl Iterator<Item = (RelayChainBlockNumber, Vec<u8>)>,
358 max_weight: Weight,
359 ) -> Weight;
360}
361impl DmpMessageHandler for () {
362 fn handle_dmp_messages(
363 iter: impl Iterator<Item = (RelayChainBlockNumber, Vec<u8>)>,
364 _max_weight: Weight,
365 ) -> Weight {
366 iter.for_each(drop);
367 Weight::zero()
368 }
369}
370
371#[derive(
373 Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo, Debug, MaxEncodedLen,
374)]
375pub enum XcmpMessageFormat {
376 ConcatenatedVersionedXcm,
378 ConcatenatedEncodedBlob,
380 Signals,
383 ConcatenatedOpaqueVersionedXcm,
385}
386
387pub trait XcmpMessageHandler {
389 fn handle_xcmp_messages<'a, I: Iterator<Item = (Id, RelayChainBlockNumber, &'a [u8])>>(
394 iter: I,
395 max_weight: Weight,
396 ) -> Weight;
397}
398impl XcmpMessageHandler for () {
399 fn handle_xcmp_messages<'a, I: Iterator<Item = (Id, RelayChainBlockNumber, &'a [u8])>>(
400 iter: I,
401 _max_weight: Weight,
402 ) -> Weight {
403 for _ in iter {}
404 Weight::zero()
405 }
406}
407
408#[derive(PartialEq, Eq, Decode, Clone)]
411#[cfg_attr(feature = "std", derive(Debug, Encode))]
412pub struct ValidationParams {
413 pub parent_head: HeadData,
415 pub block_data: BlockData,
417 pub relay_parent_number: RelayChainBlockNumber,
419 pub relay_parent_storage_root: Hash,
421}
422
423pub const MAX_HORIZONTAL_MESSAGE_NUM: u32 = 16 * 1024;
428pub const MAX_UPWARD_MESSAGE_NUM: u32 = 16 * 1024;
433
434pub type UpwardMessages = BoundedVec<UpwardMessage, ConstU32<MAX_UPWARD_MESSAGE_NUM>>;
435
436pub type HorizontalMessages =
437 BoundedVec<OutboundHrmpMessage<Id>, ConstU32<MAX_HORIZONTAL_MESSAGE_NUM>>;
438
439#[derive(PartialEq, Eq, Clone, Encode)]
442#[cfg_attr(feature = "std", derive(Debug, Decode))]
443pub struct ValidationResult {
444 pub head_data: HeadData,
446 pub new_validation_code: Option<ValidationCode>,
448 pub upward_messages: UpwardMessages,
450 pub horizontal_messages: HorizontalMessages,
452 pub processed_downward_messages: u32,
456 pub hrmp_watermark: RelayChainBlockNumber,
459}
460
461#[cfg(test)]
462mod tests {
463 use super::*;
464
465 #[test]
466 fn para_id_debug() {
467 let id = Id::new(42);
468 assert_eq!(format!("{:?}", id), "42");
469 }
470}