1#![cfg_attr(not(feature = "std"), no_std)]
20
21extern crate alloc;
22
23use alloc::vec::Vec;
24use codec::{Decode, Encode, MaxEncodedLen};
25use polkadot_parachain_primitives::primitives::HeadData;
26use scale_info::TypeInfo;
27use sp_runtime::RuntimeDebug;
28
29pub use polkadot_core_primitives::InboundDownwardMessage;
30pub use polkadot_parachain_primitives::primitives::{
31 DmpMessageHandler, Id as ParaId, IsSystem, UpwardMessage, ValidationParams, XcmpMessageFormat,
32 XcmpMessageHandler,
33};
34pub use polkadot_primitives::{
35 vstaging::{ClaimQueueOffset, CoreSelector},
36 AbridgedHostConfiguration, AbridgedHrmpChannel, PersistedValidationData,
37};
38
39pub use sp_runtime::{
40 generic::{Digest, DigestItem},
41 traits::Block as BlockT,
42 ConsensusEngineId,
43};
44
45pub use xcm::latest::prelude::*;
46
47pub mod relay_chain {
49 pub use polkadot_core_primitives::*;
50 pub use polkadot_primitives::*;
51}
52
53pub type InboundHrmpMessage = polkadot_primitives::InboundHrmpMessage<relay_chain::BlockNumber>;
55
56pub type OutboundHrmpMessage = polkadot_primitives::OutboundHrmpMessage<ParaId>;
58
59#[derive(Eq, PartialEq, Copy, Clone, RuntimeDebug, Encode, Decode)]
61pub enum MessageSendError {
62 QueueFull,
64 NoChannel,
66 TooBig,
68 Other,
70 TooManyChannels,
72}
73
74impl From<MessageSendError> for &'static str {
75 fn from(e: MessageSendError) -> Self {
76 use MessageSendError::*;
77 match e {
78 QueueFull => "QueueFull",
79 NoChannel => "NoChannel",
80 TooBig => "TooBig",
81 Other => "Other",
82 TooManyChannels => "TooManyChannels",
83 }
84 }
85}
86
87#[derive(Encode, Decode, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)]
89pub enum AggregateMessageOrigin {
90 Here,
92 Parent,
96 Sibling(ParaId),
100}
101
102impl From<AggregateMessageOrigin> for Location {
103 fn from(origin: AggregateMessageOrigin) -> Self {
104 match origin {
105 AggregateMessageOrigin::Here => Location::here(),
106 AggregateMessageOrigin::Parent => Location::parent(),
107 AggregateMessageOrigin::Sibling(id) => Location::new(1, Junction::Parachain(id.into())),
108 }
109 }
110}
111
112#[cfg(feature = "runtime-benchmarks")]
113impl From<u32> for AggregateMessageOrigin {
114 fn from(x: u32) -> Self {
115 match x {
116 0 => Self::Here,
117 1 => Self::Parent,
118 p => Self::Sibling(ParaId::from(p)),
119 }
120 }
121}
122
123pub struct ChannelInfo {
125 pub max_capacity: u32,
127 pub max_total_size: u32,
129 pub max_message_size: u32,
131 pub msg_count: u32,
134 pub total_size: u32,
137}
138
139pub trait GetChannelInfo {
140 fn get_channel_status(id: ParaId) -> ChannelStatus;
141 fn get_channel_info(id: ParaId) -> Option<ChannelInfo>;
142}
143
144pub trait ListChannelInfos {
146 fn outgoing_channels() -> Vec<ParaId>;
147}
148
149pub trait UpwardMessageSender {
151 fn send_upward_message(msg: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError>;
155}
156impl UpwardMessageSender for () {
157 fn send_upward_message(_msg: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
158 Err(MessageSendError::NoChannel)
159 }
160}
161
162pub enum ChannelStatus {
164 Closed,
166 Full,
168 Ready(usize, usize),
173}
174
175pub trait XcmpMessageSource {
177 fn take_outbound_messages(maximum_channels: usize) -> Vec<(ParaId, Vec<u8>)>;
179}
180
181impl XcmpMessageSource for () {
182 fn take_outbound_messages(_maximum_channels: usize) -> Vec<(ParaId, Vec<u8>)> {
183 Vec::new()
184 }
185}
186
187#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)]
189pub enum ServiceQuality {
190 Ordered,
194 Fast,
197}
198
199#[derive(codec::Encode, codec::Decode, Clone)]
204pub struct ParachainBlockData<B: BlockT> {
205 header: B::Header,
207 extrinsics: alloc::vec::Vec<B::Extrinsic>,
209 storage_proof: sp_trie::CompactProof,
211}
212
213impl<B: BlockT> ParachainBlockData<B> {
214 pub fn new(
216 header: <B as BlockT>::Header,
217 extrinsics: alloc::vec::Vec<<B as BlockT>::Extrinsic>,
218 storage_proof: sp_trie::CompactProof,
219 ) -> Self {
220 Self { header, extrinsics, storage_proof }
221 }
222
223 pub fn into_block(self) -> B {
225 B::new(self.header, self.extrinsics)
226 }
227
228 pub fn into_header(self) -> B::Header {
230 self.header
231 }
232
233 pub fn header(&self) -> &B::Header {
235 &self.header
236 }
237
238 pub fn extrinsics(&self) -> &[B::Extrinsic] {
240 &self.extrinsics
241 }
242
243 pub fn storage_proof(&self) -> &sp_trie::CompactProof {
245 &self.storage_proof
246 }
247
248 pub fn deconstruct(self) -> (B::Header, alloc::vec::Vec<B::Extrinsic>, sp_trie::CompactProof) {
250 (self.header, self.extrinsics, self.storage_proof)
251 }
252}
253
254pub const CUMULUS_CONSENSUS_ID: ConsensusEngineId = *b"CMLS";
256
257#[derive(Clone, RuntimeDebug, Decode, Encode, PartialEq)]
259pub enum CumulusDigestItem {
260 #[codec(index = 0)]
262 RelayParent(relay_chain::Hash),
263}
264
265impl CumulusDigestItem {
266 pub fn to_digest_item(&self) -> DigestItem {
268 DigestItem::Consensus(CUMULUS_CONSENSUS_ID, self.encode())
269 }
270}
271
272pub fn extract_relay_parent(digest: &Digest) -> Option<relay_chain::Hash> {
277 digest.convert_first(|d| match d {
278 DigestItem::Consensus(id, val) if id == &CUMULUS_CONSENSUS_ID =>
279 match CumulusDigestItem::decode(&mut &val[..]) {
280 Ok(CumulusDigestItem::RelayParent(hash)) => Some(hash),
281 _ => None,
282 },
283 _ => None,
284 })
285}
286
287#[doc(hidden)]
304pub mod rpsr_digest {
305 use super::{relay_chain, ConsensusEngineId, Decode, Digest, DigestItem, Encode};
306 use codec::Compact;
307
308 pub const RPSR_CONSENSUS_ID: ConsensusEngineId = *b"RPSR";
310
311 pub fn relay_parent_storage_root_item(
313 storage_root: relay_chain::Hash,
314 number: impl Into<Compact<relay_chain::BlockNumber>>,
315 ) -> DigestItem {
316 DigestItem::Consensus(RPSR_CONSENSUS_ID, (storage_root, number.into()).encode())
317 }
318
319 pub fn extract_relay_parent_storage_root(
322 digest: &Digest,
323 ) -> Option<(relay_chain::Hash, relay_chain::BlockNumber)> {
324 digest.convert_first(|d| match d {
325 DigestItem::Consensus(id, val) if id == &RPSR_CONSENSUS_ID => {
326 let (h, n): (relay_chain::Hash, Compact<relay_chain::BlockNumber>) =
327 Decode::decode(&mut &val[..]).ok()?;
328
329 Some((h, n.0))
330 },
331 _ => None,
332 })
333 }
334}
335
336#[derive(Clone, Debug, codec::Decode, codec::Encode, PartialEq)]
340pub struct CollationInfoV1 {
341 pub upward_messages: Vec<UpwardMessage>,
343 pub horizontal_messages: Vec<OutboundHrmpMessage>,
345 pub new_validation_code: Option<relay_chain::ValidationCode>,
347 pub processed_downward_messages: u32,
349 pub hrmp_watermark: relay_chain::BlockNumber,
352}
353
354impl CollationInfoV1 {
355 pub fn into_latest(self, head_data: HeadData) -> CollationInfo {
357 CollationInfo {
358 upward_messages: self.upward_messages,
359 horizontal_messages: self.horizontal_messages,
360 new_validation_code: self.new_validation_code,
361 processed_downward_messages: self.processed_downward_messages,
362 hrmp_watermark: self.hrmp_watermark,
363 head_data,
364 }
365 }
366}
367
368#[derive(Clone, Debug, codec::Decode, codec::Encode, PartialEq, TypeInfo)]
370pub struct CollationInfo {
371 pub upward_messages: Vec<UpwardMessage>,
373 pub horizontal_messages: Vec<OutboundHrmpMessage>,
375 pub new_validation_code: Option<relay_chain::ValidationCode>,
377 pub processed_downward_messages: u32,
379 pub hrmp_watermark: relay_chain::BlockNumber,
382 pub head_data: HeadData,
384}
385
386sp_api::decl_runtime_apis! {
387 #[api_version(2)]
389 pub trait CollectCollationInfo {
390 #[changed_in(2)]
392 fn collect_collation_info() -> CollationInfoV1;
393 fn collect_collation_info(header: &Block::Header) -> CollationInfo;
398 }
399
400 pub trait GetCoreSelectorApi {
402 fn core_selector() -> (CoreSelector, ClaimQueueOffset);
404 }
405}