referrerpolicy=no-referrer-when-downgrade

cumulus_pallet_parachain_system/
lib.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3// SPDX-License-Identifier: Apache-2.0
4
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// 	http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#![cfg_attr(not(feature = "std"), no_std)]
18
19//! `cumulus-pallet-parachain-system` is a base pallet for Cumulus-based parachains.
20//!
21//! This pallet handles low-level details of being a parachain. Its responsibilities include:
22//!
23//! - ingestion of the parachain validation data;
24//! - ingestion and dispatch of incoming downward and lateral messages;
25//! - coordinating upgrades with the Relay Chain; and
26//! - communication of parachain outputs, such as sent messages, signaling an upgrade, etc.
27//!
28//! Users must ensure that they register this pallet as an inherent provider.
29
30extern crate alloc;
31
32use alloc::{collections::btree_map::BTreeMap, vec, vec::Vec};
33use codec::{Decode, Encode};
34use core::cmp;
35use cumulus_primitives_core::{
36	relay_chain::{self, UMPSignal, UMP_SEPARATOR},
37	AbridgedHostConfiguration, ChannelInfo, ChannelStatus, CollationInfo, CoreInfo,
38	CumulusDigestItem, GetChannelInfo, ListChannelInfos, MessageSendError, OutboundHrmpMessage,
39	ParaId, PersistedValidationData, UpwardMessage, UpwardMessageSender, VerifySchedulingSignature,
40	XcmpMessageHandler, XcmpMessageSource,
41};
42use cumulus_primitives_parachain_inherent::{
43	v0, HashedMessage, MessageQueueChain, ParachainInherentData,
44};
45use frame_support::{
46	dispatch::{DispatchClass, DispatchResult},
47	ensure,
48	inherent::{InherentData, InherentIdentifier, ProvideInherent},
49	traits::{Get, HandleMessage},
50	weights::Weight,
51};
52use frame_system::{ensure_none, ensure_root, pallet_prelude::HeaderFor};
53use parachain_inherent::{
54	deconstruct_parachain_inherent_data, AbridgedInboundDownwardMessages,
55	AbridgedInboundHrmpMessages, BasicParachainInherentData, InboundMessageId, InboundMessagesData,
56};
57use polkadot_parachain_primitives::primitives::RelayChainBlockNumber;
58use polkadot_runtime_parachains::{FeeTracker, GetMinFeeFactor};
59use scale_info::TypeInfo;
60use sp_runtime::{
61	traits::{BlockNumberProvider, Hash},
62	Debug, FixedU128, SaturatedConversion,
63};
64use xcm::{latest::XcmHash, VersionedLocation, VersionedXcm};
65use xcm_builder::InspectMessageQueues;
66
67mod benchmarking;
68pub mod block_weight;
69pub mod consensus_hook;
70pub mod migration;
71mod mock;
72pub mod relay_state_snapshot;
73#[cfg(test)]
74mod tests;
75mod unincluded_segment;
76pub mod weights;
77#[macro_use]
78pub mod validate_block;
79mod descendant_validation;
80pub mod parachain_inherent;
81
82use unincluded_segment::{
83	HrmpChannelUpdate, HrmpWatermarkUpdate, OutboundBandwidthLimits, SegmentTracker,
84};
85
86pub use consensus_hook::{ConsensusHook, ExpectParentIncluded};
87/// Register the `validate_block` function that is used by parachains to validate blocks on a
88/// validator.
89///
90/// Does *nothing* when `std` feature is enabled.
91///
92/// Expects as parameters the runtime, a block executor and an inherent checker.
93///
94/// # Example
95///
96/// ```
97///     struct BlockExecutor;
98///     struct Runtime;
99///
100///     cumulus_pallet_parachain_system::register_validate_block! {
101///         Runtime = Runtime,
102///         BlockExecutor = Executive,
103///     }
104///
105/// # fn main() {}
106/// ```
107pub use cumulus_pallet_parachain_system_proc_macro::register_validate_block;
108pub use relay_state_snapshot::{MessagingStateSnapshot, RelayChainStateProof};
109pub use unincluded_segment::{Ancestor, UsedBandwidth};
110pub use weights::WeightInfo;
111
112use crate::parachain_inherent::{AbridgedInboundMessagesSizeInfo, InboundHrmpMessageId};
113pub use pallet::*;
114
115const LOG_TARGET: &str = "runtime::parachain-system";
116
117/// Tracks cumulative UMP and HRMP message counts sent across blocks within a single PoV.
118#[derive(Encode, Decode, Clone, Debug, TypeInfo, Default)]
119pub struct PoVMessages {
120	/// Relay parent storage root of the current PoV.
121	pub relay_storage_root_or_hash: relay_chain::Hash,
122	/// The core selector of the current Pov.
123	pub core_selector: u8,
124	/// The bundle index of the current PoV. `None` when `BundleInfo` digest is absent.
125	pub bundle_index: u8,
126	/// Cumulative count of UMP messages sent in this PoV.
127	pub ump_msg_count: u32,
128	/// Cumulative count of HRMP outbound messages sent in this PoV.
129	pub hrmp_outbound_count: u32,
130	/// Recipients already used for HRMP outbound messages in this PoV.
131	pub hrmp_outbound_recipients: Vec<ParaId>,
132}
133
134/// Something that can check the associated relay block number.
135///
136/// Each Parachain block is built in the context of a relay chain block, this trait allows us
137/// to validate the given relay chain block number. With async backing it is legal to build
138/// multiple Parachain blocks per relay chain parent. With this trait it is possible for the
139/// Parachain to ensure that still only one Parachain block is build per relay chain parent.
140///
141/// By default [`RelayNumberStrictlyIncreases`] and [`AnyRelayNumber`] are provided.
142pub trait CheckAssociatedRelayNumber {
143	/// Check the current relay number versus the previous relay number.
144	///
145	/// The implementation should panic when there is something wrong.
146	fn check_associated_relay_number(
147		current: RelayChainBlockNumber,
148		previous: RelayChainBlockNumber,
149	);
150}
151
152/// Provides an implementation of [`CheckAssociatedRelayNumber`].
153///
154/// It will ensure that the associated relay block number strictly increases between Parachain
155/// blocks. This should be used by production Parachains when in doubt.
156pub struct RelayNumberStrictlyIncreases;
157
158impl CheckAssociatedRelayNumber for RelayNumberStrictlyIncreases {
159	fn check_associated_relay_number(
160		current: RelayChainBlockNumber,
161		previous: RelayChainBlockNumber,
162	) {
163		if current <= previous {
164			panic!("Relay chain block number needs to strictly increase between Parachain blocks!")
165		}
166	}
167}
168
169/// Provides an implementation of [`CheckAssociatedRelayNumber`].
170///
171/// This will accept any relay chain block number combination. This is mainly useful for
172/// test parachains.
173pub struct AnyRelayNumber;
174
175impl CheckAssociatedRelayNumber for AnyRelayNumber {
176	fn check_associated_relay_number(_: RelayChainBlockNumber, _: RelayChainBlockNumber) {}
177}
178
179/// Provides an implementation of [`CheckAssociatedRelayNumber`].
180///
181/// It will ensure that the associated relay block number monotonically increases between Parachain
182/// blocks. This should be used when asynchronous backing is enabled.
183pub struct RelayNumberMonotonicallyIncreases;
184
185impl CheckAssociatedRelayNumber for RelayNumberMonotonicallyIncreases {
186	fn check_associated_relay_number(
187		current: RelayChainBlockNumber,
188		previous: RelayChainBlockNumber,
189	) {
190		if current < previous {
191			panic!(
192				"Relay chain block number needs to monotonically increase between Parachain blocks!"
193			)
194		}
195	}
196}
197
198/// The max length of a DMP message.
199pub type MaxDmpMessageLenOf<T> = <<T as Config>::DmpQueue as HandleMessage>::MaxMessageLen;
200
201pub mod ump_constants {
202	/// `host_config.max_upward_queue_size / THRESHOLD_FACTOR` is the threshold after which delivery
203	/// starts getting exponentially more expensive.
204	/// `2` means the price starts to increase when queue is half full.
205	pub const THRESHOLD_FACTOR: u32 = 2;
206}
207
208const V3_CLAIM_QUEUE_LOOKAHEAD: u8 = 2;
209const V2_CLAIM_QUEUE_LOOKAHEAD: u8 = 1;
210
211/// The largest `claim_queue_offset` a candidate may declare.
212///
213/// With V3 the collator reads the claim queue at the scheduling parent, which is the fresh tip, so
214/// the bound is just the V3 lookahead. Without V3 it reads at the relay parent, which sits
215/// `relay_parent_offset` blocks behind the tip, so the bound grows by that much.
216fn max_allowed_claim_queue_offset(v3_enabled: bool, relay_parent_offset: u8) -> u8 {
217	if v3_enabled {
218		V3_CLAIM_QUEUE_LOOKAHEAD
219	} else {
220		V2_CLAIM_QUEUE_LOOKAHEAD.saturating_add(relay_parent_offset)
221	}
222}
223
224#[frame_support::pallet]
225pub mod pallet {
226	use super::*;
227	use codec::Compact;
228	use cumulus_primitives_core::CoreInfoExistsAtMaxOnce;
229	use frame_support::pallet_prelude::{ValueQuery, *};
230	use frame_system::pallet_prelude::*;
231
232	#[pallet::pallet]
233	#[pallet::storage_version(migration::STORAGE_VERSION)]
234	#[pallet::without_storage_info]
235	pub struct Pallet<T>(_);
236
237	#[pallet::config]
238	pub trait Config: frame_system::Config<OnSetCode = ParachainSetCode<Self>> {
239		/// The overarching event type.
240		#[allow(deprecated)]
241		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
242
243		/// Something which can be notified when the validation data is set.
244		type OnSystemEvent: OnSystemEvent;
245
246		/// Returns the parachain ID we are running with.
247		#[pallet::constant]
248		type SelfParaId: Get<ParaId>;
249
250		/// The place where outbound XCMP messages come from. This is queried in `finalize_block`.
251		type OutboundXcmpMessageSource: XcmpMessageSource;
252
253		/// Queues inbound downward messages for delayed processing.
254		///
255		/// All inbound DMP messages from the relay are pushed into this. The handler is expected to
256		/// eventually process all the messages that are pushed to it.
257		type DmpQueue: HandleMessage;
258
259		/// The weight we reserve at the beginning of the block for processing DMP messages.
260		type ReservedDmpWeight: Get<Weight>;
261
262		/// The message handler that will be invoked when messages are received via XCMP.
263		///
264		/// This should normally link to the XCMP Queue pallet.
265		type XcmpMessageHandler: XcmpMessageHandler;
266
267		/// The weight we reserve at the beginning of the block for processing XCMP messages.
268		type ReservedXcmpWeight: Get<Weight>;
269
270		/// Something that can check the associated relay parent block number.
271		type CheckAssociatedRelayNumber: CheckAssociatedRelayNumber;
272
273		/// Weight info for functions and calls.
274		type WeightInfo: WeightInfo;
275
276		/// An entry-point for higher-level logic to manage the backlog of unincluded parachain
277		/// blocks and authorship rights for those blocks.
278		///
279		/// Typically, this should be a hook tailored to the collator-selection/consensus mechanism
280		/// that is used for this chain.
281		///
282		/// However, to maintain the same behavior as prior to asynchronous backing, provide the
283		/// [`consensus_hook::ExpectParentIncluded`] here. This is only necessary in the case
284		/// that collators aren't expected to have node versions that supply the included block
285		/// in the relay-chain state proof.
286		type ConsensusHook: ConsensusHook;
287
288		/// The offset between the tip of the relay chain and the parent relay block used as parent
289		/// when authoring a parachain block.
290		///
291		/// This setting directly impacts the number of descendant headers that are expected in the
292		/// `set_validation_data` inherent.
293		///
294		/// For any setting `N` larger than zero, the inherent expects that the inherent includes
295		/// the relay parent plus `N` descendants. These headers are required to validate that new
296		/// parachain blocks are authored at the correct offset.
297		///
298		/// While this helps to reduce forks on the parachain side, it increases the delay for
299		/// processing XCM messages. So, the value should be chosen wisely.
300		///
301		/// If set to 0, this config has no impact.
302		type RelayParentOffset: Get<u32>;
303
304		/// Verifier for V3 scheduling proofs.
305		///
306		/// Reports whether V3 scheduling validation is enabled and supplies the
307		/// verification logic for the proof itself. Use `()` to keep V3 scheduling
308		/// disabled.
309		///
310		/// When enabled, this changes how building on older relay parents is enforced:
311		/// - The old `relay_parent_descendants` validation in the inherent is disabled
312		/// - V3 scheduling validation is used instead, with the header chain provided via PVF
313		///   parameters
314		///
315		/// # Migration Guide
316		///
317		/// v3 scheduling is work in progress, and for the moment this should be left as
318		/// `()`. If V3 is wrongfully enabled, the parachain will stall.
319		///
320		/// Before enabling this:
321		/// 1. Ensure all collators are updated to a version that supports V3 candidates
322		/// 2. Ensure the relay chain has `CandidateReceiptV3` node feature enabled
323		/// 3. Swap the verifier for one whose `V3_SCHEDULING_ENABLED` const is `true`, via a
324		///    runtime upgrade.
325		///
326		/// Once enabled, collators will:
327		/// - Stop providing `relay_parent_descendants` in the inherent (empty vec)
328		/// - Provide the header chain via V3 extension in PVF parameters
329		///
330		/// The `RelayParentOffset` config continues to define the header chain length.
331		type SchedulingSignatureVerifier: cumulus_primitives_core::VerifySchedulingSignature;
332	}
333
334	#[pallet::hooks]
335	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
336		/// Handles actually sending upward messages by moving them from `PendingUpwardMessages` to
337		/// `UpwardMessages`. Decreases the delivery fee factor if after sending messages, the queue
338		/// total size is less than the threshold (see [`ump_constants::THRESHOLD_FACTOR`]).
339		/// Also does the sending for HRMP messages it takes from `OutboundXcmpMessageSource`.
340		fn on_finalize(_: BlockNumberFor<T>) {
341			<DidSetValidationCode<T>>::kill();
342			<UpgradeRestrictionSignal<T>>::kill();
343			let relay_upgrade_go_ahead = <UpgradeGoAhead<T>>::take();
344
345			let vfp = <ValidationData<T>>::get().expect(
346				r"Missing required set_validation_data inherent. This inherent must be
347				present in every block. This error typically occurs when the set_validation_data
348				execution failed and was rejected by the block builder. Check earlier log entries
349				for the specific cause of the failure.",
350			);
351
352			LastRelayChainBlockNumber::<T>::put(vfp.relay_parent_number);
353
354			let host_config = match HostConfiguration::<T>::get() {
355				Some(ok) => ok,
356				None => {
357					debug_assert!(
358						false,
359						"host configuration is promised to set until `on_finalize`; qed",
360					);
361					return;
362				},
363			};
364
365			// Before updating the relevant messaging state, we need to extract
366			// the total bandwidth limits for the purpose of updating the unincluded
367			// segment.
368			let total_bandwidth_out = match RelevantMessagingState::<T>::get() {
369				Some(s) => OutboundBandwidthLimits::from_relay_chain_state(&s),
370				None => {
371					debug_assert!(
372						false,
373						"relevant messaging state is promised to be set until `on_finalize`; \
374							qed",
375					);
376					return;
377				},
378			};
379
380			// After this point, the `RelevantMessagingState` in storage reflects the
381			// unincluded segment.
382			Self::adjust_egress_bandwidth_limits();
383
384			let current_core_selector =
385				CumulusDigestItem::find_core_info(&frame_system::Pallet::<T>::digest())
386					.map_or(0, |ci| ci.selector.0);
387
388			let current_bundle_index =
389				CumulusDigestItem::find_block_bundle_info(&frame_system::Pallet::<T>::digest())
390					.map_or(0, |bi| bi.index);
391
392			let mut pov_tracker = PoVMessagesTracker::<T>::get()
393				.filter(|tracker| {
394					// If the relay parent changes, this is for sure a different `PoV`.
395					tracker.relay_storage_root_or_hash == vfp.relay_parent_storage_root &&
396					// A different core selector also means we are on a different `PoV`.
397					tracker.core_selector == current_core_selector &&
398					// The bundle index needs to increase, or we are in a different `PoV`.
399					current_bundle_index > tracker.bundle_index
400				})
401				.unwrap_or_default();
402
403			pov_tracker.bundle_index = current_bundle_index;
404			pov_tracker.core_selector = current_core_selector;
405			pov_tracker.relay_storage_root_or_hash = vfp.relay_parent_storage_root;
406
407			let (ump_msg_count, ump_total_bytes) = <PendingUpwardMessages<T>>::mutate(|up| {
408				let (available_capacity, available_size) = match RelevantMessagingState::<T>::get()
409				{
410					Some(limits) => (
411						limits.relay_dispatch_queue_remaining_capacity.remaining_count,
412						limits.relay_dispatch_queue_remaining_capacity.remaining_size,
413					),
414					None => {
415						debug_assert!(
416							false,
417							"relevant messaging state is promised to be set until `on_finalize`; \
418								qed",
419						);
420						return (0, 0);
421					},
422				};
423
424				let available_capacity = cmp::min(
425					available_capacity,
426					host_config
427						.max_upward_message_num_per_candidate
428						.saturating_sub(pov_tracker.ump_msg_count),
429				);
430
431				// Count the number of messages we can possibly fit in the given constraints, i.e.
432				// available_capacity and available_size.
433				let (num, total_size) = up
434					.iter()
435					.scan((0u32, 0u32), |state, msg| {
436						let (cap_used, size_used) = *state;
437						let new_cap = cap_used.saturating_add(1);
438						let new_size = size_used.saturating_add(msg.len() as u32);
439						match available_capacity
440							.checked_sub(new_cap)
441							.and(available_size.checked_sub(new_size))
442						{
443							Some(_) => {
444								*state = (new_cap, new_size);
445								Some(*state)
446							},
447							_ => None,
448						}
449					})
450					.last()
451					.unwrap_or_default();
452
453				// TODO: #274 Return back messages that do not longer fit into the queue.
454
455				UpwardMessages::<T>::put(&up[..num as usize]);
456				*up = up.split_off(num as usize);
457
458				pov_tracker.ump_msg_count = pov_tracker.ump_msg_count.saturating_add(num);
459
460				let digest = frame_system::Pallet::<T>::digest();
461
462				let core_info = CumulusDigestItem::find_core_info(&digest);
463				PreviousCoreCount::<T>::put(
464					core_info.as_ref().map_or(Compact(1u16), |ci| ci.number_of_cores),
465				);
466
467				// Only send UMP signals on the last block of a PoV.
468				// For single-block PoVs (no BlockBundleInfo), always send signals.
469				if CumulusDigestItem::is_last_block_in_core(&digest).unwrap_or(true) {
470					Self::send_ump_signals(core_info);
471				}
472
473				// If the total size of the pending messages is less than the threshold,
474				// we decrease the fee factor, since the queue is less congested.
475				// This makes delivery of new messages cheaper.
476				let threshold = host_config
477					.max_upward_queue_size
478					.saturating_div(ump_constants::THRESHOLD_FACTOR);
479				let remaining_total_size: usize = up.iter().map(UpwardMessage::len).sum();
480				if remaining_total_size <= threshold as usize {
481					Self::decrease_fee_factor(());
482				}
483
484				(num, total_size)
485			});
486
487			// Sending HRMP messages is a little bit more involved. There are the following
488			// constraints:
489			//
490			// - a channel should exist (and it can be closed while a message is buffered),
491			// - at most one message can be sent in a channel,
492			// - the sent out messages should be ordered by ascension of recipient para id.
493			// - the capacity and total size of the channel is limited,
494			// - the maximum size of a message is limited (and can potentially be changed),
495
496			let maximum_channels = host_config
497				.hrmp_max_message_num_per_candidate
498				.min(<AnnouncedHrmpMessagesPerCandidate<T>>::take())
499				as usize;
500
501			let maximum_channels =
502				maximum_channels.saturating_sub(pov_tracker.hrmp_outbound_count as usize);
503
504			// Note: this internally calls the `GetChannelInfo` implementation for this
505			// pallet, which draws on the `RelevantMessagingState`. That in turn has
506			// been adjusted above to reflect the correct limits in all channels.
507			let outbound_messages = T::OutboundXcmpMessageSource::take_outbound_messages(
508				maximum_channels,
509				&pov_tracker.hrmp_outbound_recipients,
510			)
511			.into_iter()
512			.map(|(recipient, data)| OutboundHrmpMessage { recipient, data })
513			.collect::<Vec<_>>();
514
515			pov_tracker
516				.hrmp_outbound_recipients
517				.extend(outbound_messages.iter().map(|m| m.recipient));
518			pov_tracker.hrmp_outbound_count =
519				pov_tracker.hrmp_outbound_count.saturating_add(outbound_messages.len() as u32);
520			PoVMessagesTracker::<T>::put(pov_tracker);
521
522			// Update the unincluded segment length; capacity checks were done previously in
523			// `set_validation_data`, so this can be done unconditionally.
524			{
525				let hrmp_outgoing = outbound_messages
526					.iter()
527					.map(|msg| {
528						(
529							msg.recipient,
530							HrmpChannelUpdate { msg_count: 1, total_bytes: msg.data.len() as u32 },
531						)
532					})
533					.collect();
534				let used_bandwidth =
535					UsedBandwidth { ump_msg_count, ump_total_bytes, hrmp_outgoing };
536
537				let mut aggregated_segment =
538					AggregatedUnincludedSegment::<T>::get().unwrap_or_default();
539				let consumed_go_ahead_signal =
540					if aggregated_segment.consumed_go_ahead_signal().is_some() {
541						// Some ancestor within the segment already processed this signal --
542						// validated during inherent creation.
543						None
544					} else {
545						relay_upgrade_go_ahead
546					};
547				// The bandwidth constructed was ensured to satisfy relay chain constraints.
548				let ancestor = Ancestor::new_unchecked(used_bandwidth, consumed_go_ahead_signal);
549
550				let watermark = HrmpWatermark::<T>::get();
551				let watermark_update = HrmpWatermarkUpdate::new(watermark, vfp.relay_parent_number);
552
553				aggregated_segment
554					.append(&ancestor, watermark_update, &total_bandwidth_out)
555					.expect("unincluded segment limits exceeded");
556				AggregatedUnincludedSegment::<T>::put(aggregated_segment);
557				// Check in `on_initialize` guarantees there's space for this block.
558				UnincludedSegment::<T>::append(ancestor);
559			}
560
561			HrmpOutboundMessages::<T>::put(outbound_messages);
562		}
563
564		fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
565			let mut weight = Weight::zero();
566
567			// To prevent removing `NewValidationCode` that was set by another `on_initialize`
568			// like for example from scheduler, we only kill the storage entry if it was not yet
569			// updated in the current block.
570			if !<DidSetValidationCode<T>>::get() {
571				// NOTE: Killing here is required to at least include the trie nodes down to the key
572				// in the proof. Because this value will be read in `validate_block` and thus,
573				// needs to be reachable by the proof.
574				NewValidationCode::<T>::kill();
575				weight += T::DbWeight::get().writes(1);
576			}
577
578			// The parent hash was unknown during block finalization. Update it here.
579			{
580				<UnincludedSegment<T>>::mutate(|chain| {
581					if let Some(ancestor) = chain.last_mut() {
582						let parent = frame_system::Pallet::<T>::parent_hash();
583						// Ancestor is the latest finalized block, thus current parent is
584						// its output head.
585						ancestor.replace_para_head_hash(parent);
586					}
587				});
588				weight += T::DbWeight::get().reads_writes(1, 1);
589
590				// Weight used during finalization.
591				weight += T::DbWeight::get().reads_writes(3, 2);
592			}
593
594			BlockWeightMode::<T>::kill();
595
596			// Remove the validation from the old block.
597			ValidationData::<T>::kill();
598			// NOTE: Killing here is required to at least include the trie nodes down to the keys
599			// in the proof. Because these values will be read in `validate_block` and thus,
600			// need to be reachable by the proof.
601			ProcessedDownwardMessages::<T>::kill();
602			UpwardMessages::<T>::kill();
603			HrmpOutboundMessages::<T>::kill();
604			CustomValidationHeadData::<T>::kill();
605			// The same as above. Reading here to make sure that the key is included in the proof.
606			HrmpWatermark::<T>::get();
607			weight += T::DbWeight::get().reads_writes(1, 5);
608
609			// Here, in `on_initialize` we must report the weight for both `on_initialize` and
610			// `on_finalize`.
611			//
612			// One complication here, is that the `host_configuration` is updated by an inherent
613			// and those are processed after the block initialization phase. Therefore, we have to
614			// be content only with the configuration as per the previous block. That means that
615			// the configuration can be either stale (or be absent altogether in case of the
616			// beginning of the chain).
617			//
618			// In order to mitigate this, we do the following. At the time, we are only concerned
619			// about `hrmp_max_message_num_per_candidate`. We reserve the amount of weight to
620			// process the number of HRMP messages according to the potentially stale
621			// configuration. In `on_finalize` we will process only the maximum between the
622			// announced number of messages and the actual received in the fresh configuration.
623			//
624			// In the common case, they will be the same. In the case the actual value is smaller
625			// than the announced, we would waste some of weight. In the case the actual value is
626			// greater than the announced, we will miss opportunity to send a couple of messages.
627			weight += T::DbWeight::get().reads_writes(1, 1);
628			let hrmp_max_message_num_per_candidate = HostConfiguration::<T>::get()
629				.map(|cfg| cfg.hrmp_max_message_num_per_candidate)
630				.unwrap_or(0);
631			<AnnouncedHrmpMessagesPerCandidate<T>>::put(hrmp_max_message_num_per_candidate);
632
633			// NOTE that the actual weight consumed by `on_finalize` may turn out lower.
634			weight += T::DbWeight::get().reads_writes(
635				3 + hrmp_max_message_num_per_candidate as u64,
636				4 + hrmp_max_message_num_per_candidate as u64,
637			);
638
639			// Weight for updating the last relay chain block number in `on_finalize`.
640			weight += T::DbWeight::get().reads_writes(1, 1);
641
642			// Weight for adjusting the unincluded segment in `on_finalize`.
643			weight += T::DbWeight::get().reads_writes(6, 3);
644
645			// Always try to read `UpgradeGoAhead` in `on_finalize`.
646			weight += T::DbWeight::get().reads(1);
647
648			// Ensure `CoreInfo` digest exists only once and validate claim_queue_offset.
649			match CumulusDigestItem::core_info_exists_at_max_once(
650				&frame_system::Pallet::<T>::digest(),
651			) {
652				CoreInfoExistsAtMaxOnce::Once(core_info) => {
653					let max_allowed_offset = max_allowed_claim_queue_offset(
654						T::SchedulingSignatureVerifier::V3_SCHEDULING_ENABLED,
655						T::RelayParentOffset::get().saturated_into::<u8>(),
656					);
657					assert!(
658						core_info.claim_queue_offset.0 <= max_allowed_offset,
659						"claim_queue_offset {} exceeds maximum allowed {}",
660						core_info.claim_queue_offset.0,
661						max_allowed_offset,
662					);
663				},
664				CoreInfoExistsAtMaxOnce::NotFound => {},
665				CoreInfoExistsAtMaxOnce::MoreThanOnce => {
666					panic!("`CumulusDigestItem::CoreInfo` must exist at max once.");
667				},
668			}
669
670			weight
671		}
672	}
673
674	#[pallet::call]
675	impl<T: Config> Pallet<T> {
676		/// Set the current validation data.
677		///
678		/// This should be invoked exactly once per block. It will panic at the finalization
679		/// phase if the call was not invoked.
680		///
681		/// The dispatch origin for this call must be `Inherent`
682		///
683		/// As a side effect, this function upgrades the current validation function
684		/// if the appropriate time has come.
685		#[pallet::call_index(0)]
686		#[pallet::weight((0, DispatchClass::Mandatory))]
687		// TODO: This weight should be corrected. Currently the weight is registered manually in the
688		// call with `register_extra_weight_unchecked`.
689		pub fn set_validation_data(
690			origin: OriginFor<T>,
691			data: BasicParachainInherentData,
692			inbound_messages_data: InboundMessagesData,
693		) -> DispatchResult {
694			ensure_none(origin)?;
695			assert!(
696				!<ValidationData<T>>::exists(),
697				"ValidationData must be updated only once in a block",
698			);
699
700			// TODO: This is more than zero, but will need benchmarking to figure out what.
701			let mut total_weight = Weight::zero();
702
703			// NOTE: the inherent data is expected to be unique, even if this block is build
704			// in the context of the same relay parent as the previous one. In particular,
705			// the inherent shouldn't contain messages that were already processed by any of the
706			// ancestors.
707			//
708			// This invariant should be upheld by the `ProvideInherent` implementation.
709			let BasicParachainInherentData {
710				validation_data: vfp,
711				relay_chain_state,
712				relay_parent_descendants,
713				collator_peer_id,
714			} = data;
715
716			// Check that the associated relay chain block number is as expected.
717			T::CheckAssociatedRelayNumber::check_associated_relay_number(
718				vfp.relay_parent_number,
719				LastRelayChainBlockNumber::<T>::get(),
720			);
721
722			let relay_state_proof = RelayChainStateProof::new(
723				T::SelfParaId::get(),
724				vfp.relay_parent_storage_root,
725				relay_chain_state.clone(),
726			)
727			.expect("Invalid relay chain state proof");
728
729			// Relay parent offset validation:
730			// When V3 scheduling is disabled: validate relay_parent_descendants (old mechanism)
731			// When V3 scheduling is enabled: skip this validation, V3 scheduling validation
732			// happens in validate_block with header chain from PVF params
733			let expected_rp_descendants_num = T::RelayParentOffset::get();
734			let v3_enabled = T::SchedulingSignatureVerifier::V3_SCHEDULING_ENABLED;
735
736			if expected_rp_descendants_num > 0 && !v3_enabled {
737				if let Err(err) = descendant_validation::verify_relay_parent_descendants(
738					&relay_state_proof,
739					relay_parent_descendants,
740					vfp.relay_parent_storage_root,
741					expected_rp_descendants_num,
742				) {
743					panic!(
744						"Unable to verify provided relay parent descendants. \
745						expected_rp_descendants_num: {expected_rp_descendants_num} \
746						error: {err:?}"
747					);
748				};
749			}
750
751			// Update the desired maximum capacity according to the consensus hook.
752			let (consensus_hook_weight, capacity) =
753				T::ConsensusHook::on_state_proof(&relay_state_proof);
754			total_weight += consensus_hook_weight;
755			total_weight += Self::maybe_drop_included_ancestors(&relay_state_proof, capacity);
756			// Deposit a log indicating the relay-parent storage root.
757			// TODO: remove this in favor of the relay-parent's hash after
758			// https://github.com/paritytech/cumulus/issues/303
759			frame_system::Pallet::<T>::deposit_log(
760				cumulus_primitives_core::rpsr_digest::relay_parent_storage_root_item(
761					vfp.relay_parent_storage_root,
762					vfp.relay_parent_number,
763				),
764			);
765
766			// Initialization logic: we know that this runs exactly once every block,
767			// which means we can put the initialization logic here to remove the
768			// sequencing problem.
769			let upgrade_go_ahead_signal = relay_state_proof
770				.read_upgrade_go_ahead_signal()
771				.expect("Invalid upgrade go ahead signal");
772
773			let upgrade_signal_in_segment = AggregatedUnincludedSegment::<T>::get()
774				.as_ref()
775				.and_then(SegmentTracker::consumed_go_ahead_signal);
776			if let Some(signal_in_segment) = upgrade_signal_in_segment.as_ref() {
777				// Unincluded ancestor consuming upgrade signal is still within the segment,
778				// sanity check that it matches with the signal from relay chain.
779				assert_eq!(upgrade_go_ahead_signal, Some(*signal_in_segment));
780			}
781			match upgrade_go_ahead_signal {
782				Some(_signal) if upgrade_signal_in_segment.is_some() => {
783					// Do nothing, processing logic was executed by unincluded ancestor.
784				},
785				Some(relay_chain::UpgradeGoAhead::GoAhead) => {
786					assert!(
787						<PendingValidationCode<T>>::exists(),
788						"No new validation function found in storage, GoAhead signal is not expected",
789					);
790					let validation_code = <PendingValidationCode<T>>::take();
791
792					frame_system::Pallet::<T>::update_code_in_storage(&validation_code);
793					<T::OnSystemEvent as OnSystemEvent>::on_validation_code_applied();
794					Self::deposit_event(Event::ValidationFunctionApplied {
795						relay_chain_block_num: vfp.relay_parent_number,
796					});
797				},
798				Some(relay_chain::UpgradeGoAhead::Abort) => {
799					<PendingValidationCode<T>>::kill();
800					Self::deposit_event(Event::ValidationFunctionDiscarded);
801				},
802				None => {},
803			}
804			<UpgradeRestrictionSignal<T>>::put(
805				relay_state_proof
806					.read_upgrade_restriction_signal()
807					.expect("Invalid upgrade restriction signal"),
808			);
809			<UpgradeGoAhead<T>>::put(upgrade_go_ahead_signal);
810
811			let host_config = relay_state_proof
812				.read_abridged_host_configuration()
813				.expect("Invalid host configuration in relay chain state proof");
814
815			let relevant_messaging_state = relay_state_proof
816				.read_messaging_state_snapshot(&host_config)
817				.expect("Invalid messaging state in relay chain state proof");
818
819			<ValidationData<T>>::put(&vfp);
820			<RelayStateProof<T>>::put(relay_chain_state);
821			<RelevantMessagingState<T>>::put(relevant_messaging_state.clone());
822			<HostConfiguration<T>>::put(host_config);
823
824			total_weight.saturating_accrue(
825				<T::OnSystemEvent as OnSystemEvent>::on_relay_state_proof(&relay_state_proof),
826			);
827
828			<T::OnSystemEvent as OnSystemEvent>::on_validation_data(&vfp);
829
830			match collator_peer_id {
831				Some(peer_id) => PendingApprovedPeer::<T>::put(peer_id),
832				None => PendingApprovedPeer::<T>::kill(),
833			}
834
835			total_weight.saturating_accrue(Self::enqueue_inbound_downward_messages(
836				relevant_messaging_state.dmq_mqc_head,
837				inbound_messages_data.downward_messages,
838			));
839			total_weight.saturating_accrue(Self::enqueue_inbound_horizontal_messages(
840				&relevant_messaging_state.ingress_channels,
841				inbound_messages_data.horizontal_messages,
842				vfp.relay_parent_number,
843			));
844
845			frame_system::Pallet::<T>::register_extra_weight_unchecked(
846				total_weight,
847				DispatchClass::Mandatory,
848			);
849
850			Ok(())
851		}
852
853		#[pallet::call_index(1)]
854		#[pallet::weight((1_000, DispatchClass::Operational))]
855		pub fn sudo_send_upward_message(
856			origin: OriginFor<T>,
857			message: UpwardMessage,
858		) -> DispatchResult {
859			ensure_root(origin)?;
860			let _ = Self::send_upward_message(message);
861			Ok(())
862		}
863
864		// WARNING: call indices 2 and 3 were used in a former version of this pallet. Using them
865		// again will require to bump the transaction version of runtimes using this pallet.
866	}
867
868	#[pallet::event]
869	#[pallet::generate_deposit(pub(super) fn deposit_event)]
870	pub enum Event<T: Config> {
871		/// The validation function has been scheduled to apply.
872		ValidationFunctionStored,
873		/// The validation function was applied as of the contained relay chain block number.
874		ValidationFunctionApplied { relay_chain_block_num: RelayChainBlockNumber },
875		/// The relay-chain aborted the upgrade process.
876		ValidationFunctionDiscarded,
877		/// Some downward messages have been received and will be processed.
878		DownwardMessagesReceived { count: u32 },
879		/// Downward messages were processed using the given weight.
880		DownwardMessagesProcessed { weight_used: Weight, dmq_head: relay_chain::Hash },
881		/// An upward message was sent to the relay chain.
882		UpwardMessageSent { message_hash: Option<XcmHash> },
883	}
884
885	#[pallet::error]
886	pub enum Error<T> {
887		/// Attempt to upgrade validation function while existing upgrade pending.
888		OverlappingUpgrades,
889		/// Polkadot currently prohibits this parachain from upgrading its validation function.
890		ProhibitedByPolkadot,
891		/// The supplied validation function has compiled into a blob larger than Polkadot is
892		/// willing to run.
893		TooBig,
894		/// The inherent which supplies the validation data did not run this block.
895		ValidationDataNotAvailable,
896		/// The inherent which supplies the host configuration did not run this block.
897		HostConfigurationNotAvailable,
898		/// No validation function upgrade is currently scheduled.
899		NotScheduled,
900	}
901
902	/// The current block weight mode.
903	///
904	/// This is used to determine what is the maximum allowed block weight, for more information see
905	/// [`block_weight`].
906	///
907	/// Killed in [`Self::on_initialize`] and set by the [`block_weight`] logic.
908	#[pallet::storage]
909	#[pallet::whitelist_storage]
910	pub type BlockWeightMode<T: Config> =
911		StorageValue<_, block_weight::BlockWeightMode<T>, OptionQuery>;
912
913	/// The core count available to the parachain in the previous block.
914	///
915	/// This is mainly used for offchain functionality to calculate the correct target block weight.
916	#[pallet::storage]
917	#[pallet::whitelist_storage]
918	pub type PreviousCoreCount<T: Config> = StorageValue<_, Compact<u16>, OptionQuery>;
919
920	/// Latest included block descendants the runtime accepted. In other words, these are
921	/// ancestors of the currently executing block which have not been included in the observed
922	/// relay-chain state.
923	///
924	/// The segment length is limited by the capacity returned from the [`ConsensusHook`] configured
925	/// in the pallet.
926	#[pallet::storage]
927	pub type UnincludedSegment<T: Config> = StorageValue<_, Vec<Ancestor<T::Hash>>, ValueQuery>;
928
929	/// Storage field that keeps track of bandwidth used by the unincluded segment along with the
930	/// latest HRMP watermark. Used for limiting the acceptance of new blocks with
931	/// respect to relay chain constraints.
932	#[pallet::storage]
933	pub type AggregatedUnincludedSegment<T: Config> =
934		StorageValue<_, SegmentTracker<T::Hash>, OptionQuery>;
935
936	/// In case of a scheduled upgrade, this storage field contains the validation code to be
937	/// applied.
938	///
939	/// As soon as the relay chain gives us the go-ahead signal, we will overwrite the
940	/// [`:pending_code`][sp_core::storage::well_known_keys::PENDING_CODE] which will result the
941	/// next block to be processed with the new validation code. This concludes the upgrade process.
942	#[pallet::storage]
943	pub type PendingValidationCode<T: Config> = StorageValue<_, Vec<u8>, ValueQuery>;
944
945	/// Validation code that is set by the parachain and is to be communicated to collator and
946	/// consequently the relay-chain.
947	///
948	/// This will be cleared in `on_initialize` of each new block if no other pallet already set
949	/// the value.
950	#[pallet::storage]
951	pub type NewValidationCode<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
952
953	/// The [`PersistedValidationData`] set for this block.
954	///
955	/// This value is expected to be set only once by the [`Pallet::set_validation_data`] inherent.
956	#[pallet::storage]
957	pub type ValidationData<T: Config> = StorageValue<_, PersistedValidationData>;
958
959	/// Were the validation data set to notify the relay chain?
960	#[pallet::storage]
961	pub type DidSetValidationCode<T: Config> = StorageValue<_, bool, ValueQuery>;
962
963	/// The relay chain block number associated with the last parachain block.
964	///
965	/// This is updated in `on_finalize`.
966	#[pallet::storage]
967	pub type LastRelayChainBlockNumber<T: Config> =
968		StorageValue<_, RelayChainBlockNumber, ValueQuery>;
969
970	/// An option which indicates if the relay-chain restricts signalling a validation code upgrade.
971	/// In other words, if this is `Some` and [`NewValidationCode`] is `Some` then the produced
972	/// candidate will be invalid.
973	///
974	/// This storage item is a mirror of the corresponding value for the current parachain from the
975	/// relay-chain. This value is ephemeral which means it doesn't hit the storage. This value is
976	/// set after the inherent.
977	#[pallet::storage]
978	pub type UpgradeRestrictionSignal<T: Config> =
979		StorageValue<_, Option<relay_chain::UpgradeRestriction>, ValueQuery>;
980
981	/// Optional upgrade go-ahead signal from the relay-chain.
982	///
983	/// This storage item is a mirror of the corresponding value for the current parachain from the
984	/// relay-chain. This value is ephemeral which means it doesn't hit the storage. This value is
985	/// set after the inherent.
986	#[pallet::storage]
987	pub type UpgradeGoAhead<T: Config> =
988		StorageValue<_, Option<relay_chain::UpgradeGoAhead>, ValueQuery>;
989
990	/// The state proof for the last relay parent block.
991	///
992	/// This field is meant to be updated each block with the validation data inherent. Therefore,
993	/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
994	///
995	/// This data is also absent from the genesis.
996	#[pallet::storage]
997	pub type RelayStateProof<T: Config> = StorageValue<_, sp_trie::StorageProof>;
998
999	/// The snapshot of some state related to messaging relevant to the current parachain as per
1000	/// the relay parent.
1001	///
1002	/// This field is meant to be updated each block with the validation data inherent. Therefore,
1003	/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
1004	///
1005	/// This data is also absent from the genesis.
1006	#[pallet::storage]
1007	pub type RelevantMessagingState<T: Config> = StorageValue<_, MessagingStateSnapshot>;
1008
1009	/// The parachain host configuration that was obtained from the relay parent.
1010	///
1011	/// This field is meant to be updated each block with the validation data inherent. Therefore,
1012	/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
1013	///
1014	/// This data is also absent from the genesis.
1015	#[pallet::storage]
1016	#[pallet::disable_try_decode_storage]
1017	pub type HostConfiguration<T: Config> = StorageValue<_, AbridgedHostConfiguration>;
1018
1019	/// The last downward message queue chain head we have observed.
1020	///
1021	/// This value is loaded before and saved after processing inbound downward messages carried
1022	/// by the system inherent.
1023	#[pallet::storage]
1024	pub type LastDmqMqcHead<T: Config> = StorageValue<_, MessageQueueChain, ValueQuery>;
1025
1026	/// The message queue chain heads we have observed per each channel incoming channel.
1027	///
1028	/// This value is loaded before and saved after processing inbound downward messages carried
1029	/// by the system inherent.
1030	#[pallet::storage]
1031	pub type LastHrmpMqcHeads<T: Config> =
1032		StorageValue<_, BTreeMap<ParaId, MessageQueueChain>, ValueQuery>;
1033
1034	/// Number of downward messages processed in a block.
1035	///
1036	/// This will be cleared in `on_initialize` of each new block.
1037	#[pallet::storage]
1038	pub type ProcessedDownwardMessages<T: Config> = StorageValue<_, u32, ValueQuery>;
1039
1040	/// The last processed downward message.
1041	///
1042	/// We need to keep track of this to filter the messages that have been already processed.
1043	#[pallet::storage]
1044	pub type LastProcessedDownwardMessage<T: Config> = StorageValue<_, InboundMessageId>;
1045
1046	/// HRMP watermark that was set in a block.
1047	#[pallet::storage]
1048	pub type HrmpWatermark<T: Config> = StorageValue<_, relay_chain::BlockNumber, ValueQuery>;
1049
1050	/// The last processed HRMP message.
1051	///
1052	/// We need to keep track of this to filter the messages that have been already processed.
1053	#[pallet::storage]
1054	pub type LastProcessedHrmpMessage<T: Config> = StorageValue<_, InboundHrmpMessageId>;
1055
1056	/// HRMP messages that were sent in a block.
1057	///
1058	/// This will be cleared in `on_initialize` of each new block.
1059	#[pallet::storage]
1060	pub type HrmpOutboundMessages<T: Config> =
1061		StorageValue<_, Vec<OutboundHrmpMessage>, ValueQuery>;
1062
1063	/// Upward messages that were sent in a block.
1064	///
1065	/// This will be cleared in `on_initialize` for each new block.
1066	#[pallet::storage]
1067	pub type UpwardMessages<T: Config> = StorageValue<_, Vec<UpwardMessage>, ValueQuery>;
1068
1069	/// Upward messages that are still pending and not yet sent to the relay chain.
1070	#[pallet::storage]
1071	pub type PendingUpwardMessages<T: Config> = StorageValue<_, Vec<UpwardMessage>, ValueQuery>;
1072
1073	/// Upward signals that are still pending and not yet sent to the relay chain.
1074	///
1075	/// This will be cleared in `on_finalize` for each block.
1076	#[pallet::storage]
1077	pub type PendingUpwardSignals<T: Config> = StorageValue<_, Vec<UpwardMessage>, ValueQuery>;
1078
1079	/// The approved peer id to be sent as a UMP signal on the last block of the PoV.
1080	#[pallet::storage]
1081	pub type PendingApprovedPeer<T: Config> =
1082		StorageValue<_, relay_chain::ApprovedPeerId, OptionQuery>;
1083
1084	/// The factor to multiply the base delivery fee by for UMP.
1085	#[pallet::storage]
1086	pub type UpwardDeliveryFeeFactor<T: Config> =
1087		StorageValue<_, FixedU128, ValueQuery, GetMinFeeFactor<Pallet<T>>>;
1088
1089	/// The number of HRMP messages we observed in `on_initialize` and thus used that number for
1090	/// announcing the weight of `on_initialize` and `on_finalize`.
1091	#[pallet::storage]
1092	pub type AnnouncedHrmpMessagesPerCandidate<T: Config> = StorageValue<_, u32, ValueQuery>;
1093
1094	/// The weight we reserve at the beginning of the block for processing XCMP messages. This
1095	/// overrides the amount set in the Config trait.
1096	#[pallet::storage]
1097	pub type ReservedXcmpWeightOverride<T: Config> = StorageValue<_, Weight>;
1098
1099	/// The weight we reserve at the beginning of the block for processing DMP messages. This
1100	/// overrides the amount set in the Config trait.
1101	#[pallet::storage]
1102	pub type ReservedDmpWeightOverride<T: Config> = StorageValue<_, Weight>;
1103
1104	/// A custom head data that should be returned as result of `validate_block`.
1105	///
1106	/// See `Pallet::set_custom_validation_head_data` for more information.
1107	#[pallet::storage]
1108	pub type CustomValidationHeadData<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
1109
1110	/// Tracks cumulative `UMP` and `HRMP` messages sent across blocks in the current `PoV`.
1111	///
1112	/// Across different candidates/PoVs the budgets are tracked by [`AggregatedUnincludedSegment`].
1113	#[pallet::storage]
1114	pub type PoVMessagesTracker<T: Config> = StorageValue<_, PoVMessages, OptionQuery>;
1115
1116	#[pallet::inherent]
1117	impl<T: Config> ProvideInherent for Pallet<T> {
1118		type Call = Call<T>;
1119		type Error = sp_inherents::MakeFatalError<()>;
1120		const INHERENT_IDENTIFIER: InherentIdentifier =
1121			cumulus_primitives_parachain_inherent::INHERENT_IDENTIFIER;
1122
1123		fn create_inherent(data: &InherentData) -> Option<Self::Call> {
1124			let data = match data
1125				.get_data::<ParachainInherentData>(&Self::INHERENT_IDENTIFIER)
1126				.ok()
1127				.flatten()
1128			{
1129				None => {
1130					// Key Self::INHERENT_IDENTIFIER is expected to contain versioned inherent
1131					// data. Older nodes are unaware of the new format and might provide the
1132					// legacy data format. We try to load it and transform it into the current
1133					// version.
1134					let data = data
1135						.get_data::<v0::ParachainInherentData>(
1136							&cumulus_primitives_parachain_inherent::PARACHAIN_INHERENT_IDENTIFIER_V0,
1137						)
1138						.ok()
1139						.flatten()?;
1140					data.into()
1141				},
1142				Some(data) => data,
1143			};
1144
1145			Some(Self::do_create_inherent(data))
1146		}
1147
1148		fn is_inherent(call: &Self::Call) -> bool {
1149			matches!(call, Call::set_validation_data { .. })
1150		}
1151	}
1152
1153	#[pallet::genesis_config]
1154	#[derive(frame_support::DefaultNoBound)]
1155	pub struct GenesisConfig<T: Config> {
1156		#[serde(skip)]
1157		pub _config: core::marker::PhantomData<T>,
1158	}
1159
1160	#[pallet::genesis_build]
1161	impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
1162		fn build(&self) {
1163			// TODO: Remove after https://github.com/paritytech/cumulus/issues/479
1164			sp_io::storage::set(b":c", &[]);
1165		}
1166	}
1167}
1168
1169impl<T: Config> Pallet<T> {
1170	/// Get the unincluded segment size after the given hash.
1171	///
1172	/// If the unincluded segment doesn't contain the given hash, this returns the
1173	/// length of the entire unincluded segment.
1174	///
1175	/// This is intended to be used for determining how long the unincluded segment _would be_
1176	/// in runtime APIs related to authoring.
1177	pub fn unincluded_segment_size_after(included_hash: T::Hash) -> u32 {
1178		let segment = UnincludedSegment::<T>::get();
1179		crate::unincluded_segment::size_after_included(included_hash, &segment)
1180	}
1181
1182	/// Returns the configured maximum claim queue offset.
1183	///
1184	/// This is used by the [cumulus_primitives_core::RelayParentOffsetApi::max_claim_queue_offset]
1185	/// runtime API to expose the value to collators.
1186	pub fn max_claim_queue_offset() -> u8 {
1187		if !T::SchedulingSignatureVerifier::V3_SCHEDULING_ENABLED {
1188			return V2_CLAIM_QUEUE_LOOKAHEAD;
1189		}
1190
1191		V3_CLAIM_QUEUE_LOOKAHEAD
1192	}
1193}
1194
1195impl<T: Config> FeeTracker for Pallet<T> {
1196	type Id = ();
1197
1198	fn get_fee_factor(_id: Self::Id) -> FixedU128 {
1199		UpwardDeliveryFeeFactor::<T>::get()
1200	}
1201
1202	fn set_fee_factor(_id: Self::Id, val: FixedU128) {
1203		UpwardDeliveryFeeFactor::<T>::set(val);
1204	}
1205}
1206
1207impl<T: Config> ListChannelInfos for Pallet<T> {
1208	fn outgoing_channels() -> Vec<ParaId> {
1209		let Some(state) = RelevantMessagingState::<T>::get() else { return Vec::new() };
1210		state.egress_channels.into_iter().map(|(id, _)| id).collect()
1211	}
1212}
1213
1214impl<T: Config> GetChannelInfo for Pallet<T> {
1215	fn get_channel_status(id: ParaId) -> ChannelStatus {
1216		// Note, that we are using `relevant_messaging_state` which may be from the previous
1217		// block, in case this is called from `on_initialize`, i.e. before the inherent with
1218		// fresh data is submitted.
1219		//
1220		// That shouldn't be a problem though because this is anticipated and already can
1221		// happen. This is because sending implies that a message is buffered until there is
1222		// space to send a message in the candidate. After a while waiting in a buffer, it may
1223		// be discovered that the channel to which a message were addressed is now closed.
1224		// Another possibility, is that the maximum message size was decreased so that a
1225		// message in the buffer doesn't fit. Should any of that happen the sender should be
1226		// notified about the message was discarded.
1227		//
1228		// Here it a similar case, with the difference that the realization that the channel is
1229		// closed came the same block.
1230		let channels = match RelevantMessagingState::<T>::get() {
1231			None => {
1232				log::warn!("calling `get_channel_status` with no RelevantMessagingState?!");
1233				return ChannelStatus::Closed;
1234			},
1235			Some(d) => d.egress_channels,
1236		};
1237		// ^^^ NOTE: This storage field should carry over from the previous block. So if it's
1238		// None then it must be that this is an edge-case where a message is attempted to be
1239		// sent at the first block. It should be safe to assume that there are no channels
1240		// opened at all so early. At least, relying on this assumption seems to be a better
1241		// trade-off, compared to introducing an error variant that the clients should be
1242		// prepared to handle.
1243		let index = match channels.binary_search_by_key(&id, |item| item.0) {
1244			Err(_) => return ChannelStatus::Closed,
1245			Ok(i) => i,
1246		};
1247		let meta = &channels[index].1;
1248		if meta.msg_count + 1 > meta.max_capacity {
1249			// The channel is at its capacity. Skip it for now.
1250			return ChannelStatus::Full;
1251		}
1252		let max_size_now = meta.max_total_size - meta.total_size;
1253		let max_size_ever = meta.max_message_size;
1254		ChannelStatus::Ready(max_size_now as usize, max_size_ever as usize)
1255	}
1256
1257	fn get_channel_info(id: ParaId) -> Option<ChannelInfo> {
1258		let channels = RelevantMessagingState::<T>::get()?.egress_channels;
1259		let index = channels.binary_search_by_key(&id, |item| item.0).ok()?;
1260		let info = ChannelInfo {
1261			max_capacity: channels[index].1.max_capacity,
1262			max_total_size: channels[index].1.max_total_size,
1263			max_message_size: channels[index].1.max_message_size,
1264			msg_count: channels[index].1.msg_count,
1265			total_size: channels[index].1.total_size,
1266		};
1267		Some(info)
1268	}
1269}
1270
1271impl<T: Config> Pallet<T> {
1272	/// The bandwidth limit per block that applies when receiving messages from the relay chain via
1273	/// DMP or XCMP.
1274	///
1275	/// The limit is per message passing mechanism (e.g. 1 MiB for DMP, 1 MiB for XCMP).
1276	///
1277	/// The purpose of this limit is to make sure that the total size of the messages received by
1278	/// the parachain from the relay chain doesn't exceed the block size. Currently each message
1279	/// passing mechanism can use 1/6 of the total block PoV which means that in total 1/3
1280	/// of the block PoV can be used for message passing.
1281	fn messages_collection_size_limit() -> usize {
1282		let max_block_weight = <T as frame_system::Config>::BlockWeights::get().max_block;
1283		let max_block_pov = max_block_weight.proof_size();
1284
1285		let remaining_proof_size =
1286			frame_system::Pallet::<T>::remaining_block_weight().remaining().proof_size();
1287
1288		(max_block_pov / 6).min(remaining_proof_size).saturated_into()
1289	}
1290
1291	/// Updates inherent data to only include the messages that weren't already processed
1292	/// by the runtime and to compress (hash) the messages that exceed the allocated size.
1293	///
1294	/// This method doesn't check for mqc heads mismatch. If the MQC doesn't match after
1295	/// dropping messages, the runtime will panic when executing the inherent.
1296	fn do_create_inherent(data: ParachainInherentData) -> Call<T> {
1297		let (data, mut downward_messages, mut horizontal_messages) =
1298			deconstruct_parachain_inherent_data(data);
1299		let last_relay_block_number = LastRelayChainBlockNumber::<T>::get();
1300
1301		let messages_collection_size_limit = Self::messages_collection_size_limit();
1302		// DMQ.
1303		let last_processed_msg = LastProcessedDownwardMessage::<T>::get()
1304			.unwrap_or(InboundMessageId { sent_at: last_relay_block_number, reverse_idx: 0 });
1305		downward_messages.drop_processed_messages(&last_processed_msg);
1306		let mut size_limit = messages_collection_size_limit;
1307		let downward_messages = downward_messages.into_abridged(&mut size_limit);
1308
1309		// HRMP.
1310		let last_processed_msg =
1311			LastProcessedHrmpMessage::<T>::get().unwrap_or(InboundHrmpMessageId::Generic(
1312				InboundMessageId { sent_at: last_relay_block_number, reverse_idx: 0 },
1313			));
1314		horizontal_messages.drop_hrmp_processed_messages(&last_processed_msg);
1315		size_limit = size_limit.saturating_add(messages_collection_size_limit);
1316		let horizontal_messages = horizontal_messages.into_abridged(&mut size_limit);
1317
1318		let inbound_messages_data =
1319			InboundMessagesData::new(downward_messages, horizontal_messages);
1320
1321		Call::set_validation_data { data, inbound_messages_data }
1322	}
1323
1324	/// Enqueue all inbound downward messages relayed by the collator into the MQ pallet.
1325	///
1326	/// Checks if the sequence of the messages is valid, dispatches them and communicates the
1327	/// number of processed messages to the collator via a storage update.
1328	///
1329	/// # Panics
1330	///
1331	/// If it turns out that after processing all messages the Message Queue Chain
1332	/// hash doesn't match the expected.
1333	fn enqueue_inbound_downward_messages(
1334		expected_dmq_mqc_head: relay_chain::Hash,
1335		downward_messages: AbridgedInboundDownwardMessages,
1336	) -> Weight {
1337		downward_messages.check_enough_messages_included_basic("DMQ");
1338
1339		let mut dmq_head = <LastDmqMqcHead<T>>::get();
1340
1341		let (messages, hashed_messages) = downward_messages.messages();
1342		let message_count = messages.len() as u32;
1343		let weight_used = T::WeightInfo::enqueue_inbound_downward_messages(message_count);
1344		if let Some(last_msg) = messages.last() {
1345			Self::deposit_event(Event::DownwardMessagesReceived { count: message_count });
1346
1347			// Eagerly update the MQC head hash:
1348			for msg in messages {
1349				dmq_head.extend_downward(msg);
1350			}
1351			<LastDmqMqcHead<T>>::put(&dmq_head);
1352			Self::deposit_event(Event::DownwardMessagesProcessed {
1353				weight_used,
1354				dmq_head: dmq_head.head(),
1355			});
1356
1357			let mut last_processed_msg =
1358				InboundMessageId { sent_at: last_msg.sent_at, reverse_idx: 0 };
1359			for msg in hashed_messages {
1360				dmq_head.extend_with_hashed_msg(msg);
1361
1362				if msg.sent_at == last_processed_msg.sent_at {
1363					last_processed_msg.reverse_idx += 1;
1364				}
1365			}
1366			LastProcessedDownwardMessage::<T>::put(last_processed_msg);
1367
1368			T::DmpQueue::handle_messages(downward_messages.bounded_msgs_iter());
1369		}
1370
1371		// After hashing each message in the message queue chain submitted by the collator, we
1372		// should arrive to the MQC head provided by the relay chain.
1373		//
1374		// A mismatch means that at least some of the submitted messages were altered, omitted or
1375		// added improperly.
1376		assert_eq!(dmq_head.head(), expected_dmq_mqc_head, "DMQ head mismatch");
1377
1378		ProcessedDownwardMessages::<T>::put(message_count);
1379
1380		weight_used
1381	}
1382
1383	fn get_ingress_channel_or_panic(
1384		ingress_channels: &[(ParaId, cumulus_primitives_core::AbridgedHrmpChannel)],
1385		sender: ParaId,
1386	) -> &cumulus_primitives_core::AbridgedHrmpChannel {
1387		let maybe_channel_idx = ingress_channels
1388			.binary_search_by_key(&sender, |&(channel_sender, _)| channel_sender)
1389			.ok();
1390		let maybe_channel = maybe_channel_idx
1391			.and_then(|channel_idx| ingress_channels.get(channel_idx))
1392			.map(|(_, channel)| channel);
1393		maybe_channel.unwrap_or_else(|| {
1394			panic!(
1395				"One of the messages submitted by the collator was sent from a sender ({}) \
1396				that doesn't have a channel opened to this parachain",
1397				<ParaId as Into<u32>>::into(sender)
1398			)
1399		})
1400	}
1401
1402	fn check_hrmp_mcq_heads(
1403		ingress_channels: &[(ParaId, cumulus_primitives_core::AbridgedHrmpChannel)],
1404		mqc_heads: &mut BTreeMap<ParaId, MessageQueueChain>,
1405	) {
1406		// Check that the MQC heads for each channel provided by the relay chain match the MQC
1407		// heads we have after processing all incoming messages.
1408		//
1409		// Along the way we also carry over the relevant entries from the `last_mqc_heads` to
1410		// `running_mqc_heads`. Otherwise, in a block where no messages were sent in a channel
1411		// it won't get into next block's `last_mqc_heads` and thus will be all zeros, which
1412		// would corrupt the message queue chain.
1413		for (sender, channel) in ingress_channels {
1414			let cur_head = mqc_heads.entry(*sender).or_default().head();
1415			let target_head = channel.mqc_head.unwrap_or_default();
1416			assert_eq!(cur_head, target_head, "HRMP head mismatch");
1417		}
1418	}
1419
1420	/// Performs some checks related to the sender and the `sent_at` field of an HRMP message.
1421	///
1422	/// **Panics** if the message submitted by the collator doesn't respect the expected order or if
1423	///            it was sent from a para which has no open channel to this parachain.
1424	fn check_hrmp_message_metadata(
1425		ingress_channels: &[(ParaId, cumulus_primitives_core::AbridgedHrmpChannel)],
1426		maybe_prev_msg_metadata: &mut Option<(u32, ParaId)>,
1427		msg_metadata: (u32, ParaId),
1428	) {
1429		// Check that the message is properly ordered.
1430		if let Some(prev_msg) = maybe_prev_msg_metadata {
1431			assert!(&msg_metadata >= prev_msg, "[HRMP] Messages order violation");
1432		}
1433		*maybe_prev_msg_metadata = Some(msg_metadata);
1434
1435		// Check that the message is sent from an existing channel.
1436		Self::get_ingress_channel_or_panic(ingress_channels, msg_metadata.1);
1437	}
1438
1439	/// Process all inbound horizontal messages relayed by the collator.
1440	///
1441	/// This is similar to [`enqueue_inbound_downward_messages`], but works with multiple inbound
1442	/// channels. It immediately dispatches signals and queues all other XCMs. Blob messages are
1443	/// ignored.
1444	///
1445	/// **Panics** if either any of horizontal messages submitted by the collator was sent from
1446	///            a para which has no open channel to this parachain or if after processing
1447	///            messages across all inbound channels MQCs were obtained which do not
1448	///            correspond to the ones found on the relay-chain.
1449	fn enqueue_inbound_horizontal_messages(
1450		ingress_channels: &[(ParaId, cumulus_primitives_core::AbridgedHrmpChannel)],
1451		horizontal_messages: AbridgedInboundHrmpMessages,
1452		relay_parent_number: relay_chain::BlockNumber,
1453	) -> Weight {
1454		let mut mqc_heads = <LastHrmpMqcHeads<T>>::get();
1455		let (messages, hashed_messages) = horizontal_messages.messages();
1456
1457		// First, check the HRMP advancement rule.
1458		let maybe_first_hashed_msg_sender = hashed_messages.first().map(|(sender, _msg)| *sender);
1459		if let Some(first_hashed_msg_sender) = maybe_first_hashed_msg_sender {
1460			let channel =
1461				Self::get_ingress_channel_or_panic(ingress_channels, first_hashed_msg_sender);
1462			horizontal_messages.check_enough_messages_included_advanced(
1463				"HRMP",
1464				AbridgedInboundMessagesSizeInfo {
1465					max_full_messages_size: Self::messages_collection_size_limit(),
1466					first_hashed_msg_max_size: channel.max_message_size as usize,
1467				},
1468			);
1469		}
1470
1471		Self::prune_closed_mqc_heads(ingress_channels, &mut mqc_heads);
1472
1473		if messages.is_empty() {
1474			Self::check_hrmp_mcq_heads(ingress_channels, &mut mqc_heads);
1475
1476			HrmpWatermark::<T>::put(relay_parent_number);
1477			LastHrmpMqcHeads::<T>::put(&mqc_heads); // write back in case of modification
1478
1479			return T::DbWeight::get().reads_writes(1, 2);
1480		}
1481
1482		let max_weight =
1483			<ReservedXcmpWeightOverride<T>>::get().unwrap_or_else(T::ReservedXcmpWeight::get);
1484		let (mut num_processed_pages, weight_used) = T::XcmpMessageHandler::handle_xcmp_messages(
1485			horizontal_messages.flat_msgs_iter(),
1486			max_weight,
1487		);
1488		num_processed_pages = cmp::min(num_processed_pages, messages.len());
1489		let (processed_messages, unprocessed_messages) = messages.split_at(num_processed_pages);
1490
1491		let mut prev_msg_metadata = None;
1492		let mut last_processed_block = HrmpWatermark::<T>::get();
1493		let mut last_processed_msg =
1494			LastProcessedHrmpMessage::<T>::get().unwrap_or(InboundHrmpMessageId::Specific {
1495				sent_at: 0,
1496				sender: 0.into(),
1497				reverse_idx: u32::MAX,
1498			});
1499
1500		for (sender, msg) in processed_messages {
1501			Self::check_hrmp_message_metadata(
1502				ingress_channels,
1503				&mut prev_msg_metadata,
1504				(msg.sent_at, *sender),
1505			);
1506			mqc_heads.entry(*sender).or_default().extend_hrmp(msg);
1507
1508			if msg.sent_at > last_processed_msg.sent_at() {
1509				last_processed_block = last_processed_block.max(last_processed_msg.sent_at());
1510			}
1511			last_processed_msg = InboundHrmpMessageId::Specific {
1512				sent_at: msg.sent_at,
1513				sender: *sender,
1514				reverse_idx: 0,
1515			};
1516		}
1517
1518		LastHrmpMqcHeads::<T>::put(&mqc_heads);
1519
1520		let unprocessed_messages = unprocessed_messages
1521			.iter()
1522			.map(|(sender, msg)| (*sender, HashedMessage::from(msg)))
1523			.collect::<Vec<_>>();
1524		for (sender, msg) in unprocessed_messages.iter().chain(hashed_messages) {
1525			Self::check_hrmp_message_metadata(
1526				ingress_channels,
1527				&mut prev_msg_metadata,
1528				(msg.sent_at, *sender),
1529			);
1530			mqc_heads.entry(*sender).or_default().extend_with_hashed_msg(msg);
1531
1532			if last_processed_msg.sent_at() == msg.sent_at &&
1533				(last_processed_msg.sender() == Some(*sender) ||
1534					last_processed_msg.sender() == None)
1535			{
1536				last_processed_msg.inc_reverse_idx();
1537			}
1538		}
1539		match hashed_messages.first() {
1540			Some((_, first_hashed_msg)) => {
1541				if first_hashed_msg.sent_at > last_processed_msg.sent_at() {
1542					last_processed_block = last_processed_block.max(last_processed_msg.sent_at());
1543				}
1544			},
1545			None => {
1546				last_processed_block = last_processed_block.max(last_processed_msg.sent_at());
1547			},
1548		}
1549		LastProcessedHrmpMessage::<T>::put(&last_processed_msg);
1550		Self::check_hrmp_mcq_heads(ingress_channels, &mut mqc_heads);
1551
1552		// Update watermark
1553		HrmpWatermark::<T>::put(last_processed_block);
1554
1555		weight_used.saturating_add(T::DbWeight::get().reads_writes(2, 3))
1556	}
1557
1558	/// Remove all MQC heads that do not correspond to an open channel.
1559	fn prune_closed_mqc_heads(
1560		ingress_channels: &[(ParaId, cumulus_primitives_core::AbridgedHrmpChannel)],
1561		mqc_heads: &mut BTreeMap<ParaId, MessageQueueChain>,
1562	) {
1563		// Complexity is O(N * lg N) but could be optimized for O(N)
1564		mqc_heads.retain(|para, _| {
1565			ingress_channels
1566				.binary_search_by_key(para, |&(channel_sender, _)| channel_sender)
1567				.is_ok()
1568		});
1569	}
1570
1571	/// Drop blocks from the unincluded segment with respect to the latest parachain head.
1572	fn maybe_drop_included_ancestors(
1573		relay_state_proof: &RelayChainStateProof,
1574		capacity: consensus_hook::UnincludedSegmentCapacity,
1575	) -> Weight {
1576		let mut weight_used = Weight::zero();
1577		// If the unincluded segment length is nonzero, then the parachain head must be present.
1578		let para_head =
1579			relay_state_proof.read_included_para_head().ok().map(|h| T::Hashing::hash(&h.0));
1580
1581		let unincluded_segment_len = <UnincludedSegment<T>>::decode_len().unwrap_or(0);
1582		weight_used += T::DbWeight::get().reads(1);
1583
1584		// Clean up unincluded segment if nonempty.
1585		let included_head = match (para_head, capacity.is_expecting_included_parent()) {
1586			(Some(h), true) => {
1587				assert_eq!(
1588					h,
1589					frame_system::Pallet::<T>::parent_hash(),
1590					"expected parent to be included"
1591				);
1592
1593				h
1594			},
1595			(Some(h), false) => h,
1596			(None, true) => {
1597				// All this logic is essentially a workaround to support collators which
1598				// might still not provide the included block with the state proof.
1599				frame_system::Pallet::<T>::parent_hash()
1600			},
1601			(None, false) => panic!("included head not present in relay storage proof"),
1602		};
1603
1604		let new_len = {
1605			let para_head_hash = included_head;
1606			let dropped: Vec<Ancestor<T::Hash>> = <UnincludedSegment<T>>::mutate(|chain| {
1607				// Drop everything up to (inclusive) the block with an included para head, if
1608				// present.
1609				let idx = chain
1610					.iter()
1611					.position(|block| {
1612						let head_hash = block
1613							.para_head_hash()
1614							.expect("para head hash is updated during block initialization; qed");
1615						head_hash == &para_head_hash
1616					})
1617					.map_or(0, |idx| idx + 1); // inclusive.
1618
1619				chain.drain(..idx).collect()
1620			});
1621			weight_used += T::DbWeight::get().reads_writes(1, 1);
1622
1623			let new_len = unincluded_segment_len - dropped.len();
1624			if !dropped.is_empty() {
1625				<AggregatedUnincludedSegment<T>>::mutate(|agg| {
1626					let agg = agg.as_mut().expect(
1627						"dropped part of the segment wasn't empty, hence value exists; qed",
1628					);
1629					for block in dropped {
1630						agg.subtract(&block);
1631					}
1632				});
1633				weight_used += T::DbWeight::get().reads_writes(1, 1);
1634			}
1635
1636			new_len as u32
1637		};
1638
1639		// Current block validity check: ensure there is space in the unincluded segment.
1640		//
1641		// If this fails, the parachain needs to wait for ancestors to be included before
1642		// a new block is allowed.
1643		assert!(
1644			new_len < capacity.get(),
1645			"No space left for the block in the unincluded segment: new_len({new_len}) < capacity({})",
1646			capacity.get()
1647		);
1648		weight_used
1649	}
1650
1651	/// This adjusts the `RelevantMessagingState` according to the bandwidth limits in the
1652	/// unincluded segment.
1653	// Reads: 2
1654	// Writes: 1
1655	fn adjust_egress_bandwidth_limits() {
1656		let Some(unincluded_segment) = AggregatedUnincludedSegment::<T>::get() else { return };
1657
1658		<RelevantMessagingState<T>>::mutate(|messaging_state| {
1659			let Some(messaging_state) = messaging_state else { return };
1660
1661			let used_bandwidth = unincluded_segment.used_bandwidth();
1662
1663			let channels = &mut messaging_state.egress_channels;
1664			for (para_id, used) in used_bandwidth.hrmp_outgoing.iter() {
1665				let Ok(i) = channels.binary_search_by_key(para_id, |item| item.0) else {
1666					continue; // indicates channel closed.
1667				};
1668
1669				let c = &mut channels[i].1;
1670
1671				c.total_size = (c.total_size + used.total_bytes).min(c.max_total_size);
1672				c.msg_count = (c.msg_count + used.msg_count).min(c.max_capacity);
1673			}
1674
1675			let upward_capacity = &mut messaging_state.relay_dispatch_queue_remaining_capacity;
1676			upward_capacity.remaining_count =
1677				upward_capacity.remaining_count.saturating_sub(used_bandwidth.ump_msg_count);
1678			upward_capacity.remaining_size =
1679				upward_capacity.remaining_size.saturating_sub(used_bandwidth.ump_total_bytes);
1680		});
1681	}
1682
1683	/// Put a new validation function into a particular location where polkadot
1684	/// monitors for updates. Calling this function notifies polkadot that a new
1685	/// upgrade has been scheduled.
1686	fn notify_polkadot_of_pending_upgrade(code: &[u8]) {
1687		NewValidationCode::<T>::put(code);
1688		<DidSetValidationCode<T>>::put(true);
1689	}
1690
1691	/// The maximum code size permitted, in bytes.
1692	///
1693	/// Returns `None` if the relay chain parachain host configuration hasn't been submitted yet.
1694	pub fn max_code_size() -> Option<u32> {
1695		<HostConfiguration<T>>::get().map(|cfg| cfg.max_code_size)
1696	}
1697
1698	/// The implementation of the runtime upgrade functionality for parachains.
1699	pub fn schedule_code_upgrade(validation_function: Vec<u8>) -> DispatchResult {
1700		// Ensure that `ValidationData` exists. We do not care about the validation data per se,
1701		// but we do care about the [`UpgradeRestrictionSignal`] which arrives with the same
1702		// inherent.
1703		ensure!(<ValidationData<T>>::exists(), Error::<T>::ValidationDataNotAvailable);
1704		ensure!(<UpgradeRestrictionSignal<T>>::get().is_none(), Error::<T>::ProhibitedByPolkadot);
1705
1706		ensure!(!<PendingValidationCode<T>>::exists(), Error::<T>::OverlappingUpgrades);
1707		let cfg = HostConfiguration::<T>::get().ok_or(Error::<T>::HostConfigurationNotAvailable)?;
1708		ensure!(validation_function.len() <= cfg.max_code_size as usize, Error::<T>::TooBig);
1709
1710		// When a code upgrade is scheduled, it has to be applied in two
1711		// places, synchronized: both polkadot and the individual parachain
1712		// have to upgrade on the same relay chain block.
1713		//
1714		// `notify_polkadot_of_pending_upgrade` notifies polkadot; the `PendingValidationCode`
1715		// storage keeps track locally for the parachain upgrade, which will
1716		// be applied later: when the relay-chain communicates go-ahead signal to us.
1717		Self::notify_polkadot_of_pending_upgrade(&validation_function);
1718		<PendingValidationCode<T>>::put(validation_function);
1719		Self::deposit_event(Event::ValidationFunctionStored);
1720
1721		Ok(())
1722	}
1723
1724	/// Returns the [`CollationInfo`] of the current active block.
1725	///
1726	/// The given `header` is the header of the built block we are collecting the collation info
1727	/// for.
1728	///
1729	/// This is expected to be used by the
1730	/// [`CollectCollationInfo`](cumulus_primitives_core::CollectCollationInfo) runtime api.
1731	pub fn collect_collation_info(header: &HeaderFor<T>) -> CollationInfo {
1732		CollationInfo {
1733			hrmp_watermark: HrmpWatermark::<T>::get(),
1734			horizontal_messages: HrmpOutboundMessages::<T>::get(),
1735			upward_messages: UpwardMessages::<T>::get(),
1736			processed_downward_messages: ProcessedDownwardMessages::<T>::get(),
1737			new_validation_code: NewValidationCode::<T>::get().map(Into::into),
1738			// Check if there is a custom header that will also be returned by the validation phase.
1739			// If so, we need to also return it here.
1740			head_data: CustomValidationHeadData::<T>::get()
1741				.map_or_else(|| header.encode(), |v| v)
1742				.into(),
1743		}
1744	}
1745
1746	/// Set a custom head data that should be returned as result of `validate_block`.
1747	///
1748	/// This will overwrite the head data that is returned as result of `validate_block` while
1749	/// validating a `PoV` on the relay chain. Normally the head data that is being returned
1750	/// by `validate_block` is the header of the block that is validated, thus it can be
1751	/// enacted as the new best block. However, for features like forking it can be useful
1752	/// to overwrite the head data with a custom header.
1753	///
1754	/// # Attention
1755	///
1756	/// This should only be used when you are sure what you are doing as this can brick
1757	/// your Parachain.
1758	pub fn set_custom_validation_head_data(head_data: Vec<u8>) {
1759		CustomValidationHeadData::<T>::put(head_data);
1760	}
1761
1762	/// Send the pending ump signals
1763	fn send_ump_signals(core_info: Option<CoreInfo>) {
1764		let mut ump_signals = PendingUpwardSignals::<T>::take();
1765
1766		if let Some(core_info) = core_info {
1767			ump_signals.push(
1768				UMPSignal::SelectCore(core_info.selector, core_info.claim_queue_offset).encode(),
1769			);
1770		}
1771
1772		if let Some(approved_peer) = PendingApprovedPeer::<T>::take() {
1773			ump_signals.push(UMPSignal::ApprovedPeer(approved_peer).encode());
1774		}
1775
1776		if !ump_signals.is_empty() {
1777			UpwardMessages::<T>::append(UMP_SEPARATOR);
1778			ump_signals.into_iter().for_each(|s| UpwardMessages::<T>::append(s));
1779		}
1780	}
1781
1782	/// Open HRMP channel for using it in benchmarks or tests.
1783	///
1784	/// The caller assumes that the pallet will accept regular outbound message to the sibling
1785	/// `target_parachain` after this call. No other assumptions are made.
1786	#[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
1787	pub fn open_outbound_hrmp_channel_for_benchmarks_or_tests(target_parachain: ParaId) {
1788		RelevantMessagingState::<T>::put(MessagingStateSnapshot {
1789			dmq_mqc_head: Default::default(),
1790			relay_dispatch_queue_remaining_capacity: Default::default(),
1791			ingress_channels: Default::default(),
1792			egress_channels: vec![(
1793				target_parachain,
1794				cumulus_primitives_core::AbridgedHrmpChannel {
1795					max_capacity: 10,
1796					max_total_size: 10_000_000_u32,
1797					max_message_size: 10_000_000_u32,
1798					msg_count: 5,
1799					total_size: 5_000_000_u32,
1800					mqc_head: None,
1801				},
1802			)],
1803		})
1804	}
1805
1806	/// Open HRMP channel for using it in benchmarks or tests.
1807	///
1808	/// The caller assumes that the pallet will accept regular outbound message to the sibling
1809	/// `target_parachain` after this call. No other assumptions are made.
1810	#[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
1811	pub fn open_custom_outbound_hrmp_channel_for_benchmarks_or_tests(
1812		target_parachain: ParaId,
1813		channel: cumulus_primitives_core::AbridgedHrmpChannel,
1814	) {
1815		RelevantMessagingState::<T>::put(MessagingStateSnapshot {
1816			dmq_mqc_head: Default::default(),
1817			relay_dispatch_queue_remaining_capacity: Default::default(),
1818			ingress_channels: Default::default(),
1819			egress_channels: vec![(target_parachain, channel)],
1820		})
1821	}
1822
1823	/// Prepare/insert relevant data for `schedule_code_upgrade` for benchmarks.
1824	#[cfg(feature = "runtime-benchmarks")]
1825	pub fn initialize_for_set_code_benchmark(max_code_size: u32) {
1826		// insert dummy ValidationData
1827		let vfp = PersistedValidationData {
1828			parent_head: polkadot_parachain_primitives::primitives::HeadData(Default::default()),
1829			relay_parent_number: 1,
1830			relay_parent_storage_root: Default::default(),
1831			max_pov_size: 1_000,
1832		};
1833		<ValidationData<T>>::put(&vfp);
1834
1835		// insert dummy HostConfiguration with
1836		let host_config = AbridgedHostConfiguration {
1837			max_code_size,
1838			max_head_data_size: 32 * 1024,
1839			max_upward_queue_count: 8,
1840			max_upward_queue_size: 1024 * 1024,
1841			max_upward_message_size: 4 * 1024,
1842			max_upward_message_num_per_candidate: 2,
1843			hrmp_max_message_num_per_candidate: 2,
1844			validation_upgrade_cooldown: 2,
1845			validation_upgrade_delay: 2,
1846			async_backing_params: relay_chain::AsyncBackingParams {
1847				allowed_ancestry_len: 0,
1848				max_candidate_depth: 0,
1849			},
1850		};
1851		<HostConfiguration<T>>::put(host_config);
1852	}
1853}
1854
1855/// Type that implements `SetCode`.
1856pub struct ParachainSetCode<T>(core::marker::PhantomData<T>);
1857impl<T: Config> frame_system::SetCode<T> for ParachainSetCode<T> {
1858	fn set_code(code: Vec<u8>) -> DispatchResult {
1859		Pallet::<T>::schedule_code_upgrade(code)
1860	}
1861}
1862
1863impl<T: Config> Pallet<T> {
1864	/// Puts a message in the `PendingUpwardMessages` storage item.
1865	/// The message will be later sent in `on_finalize`.
1866	/// Checks host configuration to see if message is too big.
1867	/// Increases the delivery fee factor if the queue is sufficiently (see
1868	/// [`ump_constants::THRESHOLD_FACTOR`]) congested.
1869	pub fn send_upward_message(message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
1870		let message_len = message.len();
1871		// Check if the message fits into the relay-chain constraints.
1872		//
1873		// Note, that we are using `host_configuration` here which may be from the previous
1874		// block, in case this is called from `on_initialize`, i.e. before the inherent with fresh
1875		// data is submitted.
1876		//
1877		// That shouldn't be a problem since this is a preliminary check and the actual check would
1878		// be performed just before submitting the message from the candidate, and it already can
1879		// happen that during the time the message is buffered for sending the relay-chain setting
1880		// may change so that the message is no longer valid.
1881		//
1882		// However, changing this setting is expected to be rare.
1883		if let Some(cfg) = HostConfiguration::<T>::get() {
1884			if message_len > cfg.max_upward_message_size as usize {
1885				return Err(MessageSendError::TooBig);
1886			}
1887			let threshold =
1888				cfg.max_upward_queue_size.saturating_div(ump_constants::THRESHOLD_FACTOR);
1889			// We check the threshold against total size and not number of messages since messages
1890			// could be big or small.
1891			<PendingUpwardMessages<T>>::append(message.clone());
1892			let pending_messages = PendingUpwardMessages::<T>::get();
1893			let total_size: usize = pending_messages.iter().map(UpwardMessage::len).sum();
1894			if total_size > threshold as usize {
1895				// We increase the fee factor by a factor based on the new message's size in KB
1896				Self::increase_fee_factor((), message_len as u128);
1897			}
1898		} else {
1899			// This storage field should carry over from the previous block. So if it's None
1900			// then it must be that this is an edge-case where a message is attempted to be
1901			// sent at the first block.
1902			//
1903			// Let's pass this message through. I think it's not unreasonable to expect that
1904			// the message is not huge and it comes through, but if it doesn't it can be
1905			// returned back to the sender.
1906			//
1907			// Thus fall through here.
1908			<PendingUpwardMessages<T>>::append(message.clone());
1909		};
1910
1911		// The relay ump does not use using_encoded
1912		// We apply the same this to use the same hash
1913		let hash = sp_io::hashing::blake2_256(&message);
1914		Self::deposit_event(Event::UpwardMessageSent { message_hash: Some(hash) });
1915		Ok((0, hash))
1916	}
1917
1918	/// Get the relay chain block number which was used as an anchor for the last block in this
1919	/// chain.
1920	pub fn last_relay_block_number() -> RelayChainBlockNumber {
1921		LastRelayChainBlockNumber::<T>::get()
1922	}
1923}
1924
1925impl<T: Config> UpwardMessageSender for Pallet<T> {
1926	fn send_upward_message(message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
1927		Self::send_upward_message(message)
1928	}
1929
1930	fn can_send_upward_message(message: &UpwardMessage) -> Result<(), MessageSendError> {
1931		let max_upward_message_size = HostConfiguration::<T>::get()
1932			.map(|cfg| cfg.max_upward_message_size)
1933			.ok_or(MessageSendError::Other)?;
1934		if message.len() > max_upward_message_size as usize {
1935			Err(MessageSendError::TooBig)
1936		} else {
1937			Ok(())
1938		}
1939	}
1940
1941	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
1942	fn ensure_successful_delivery() {
1943		const MAX_UPWARD_MESSAGE_SIZE: u32 = 65_531 * 3;
1944		const MAX_CODE_SIZE: u32 = 3 * 1024 * 1024;
1945		HostConfiguration::<T>::mutate(|cfg| match cfg {
1946			Some(cfg) => cfg.max_upward_message_size = MAX_UPWARD_MESSAGE_SIZE,
1947			None => {
1948				*cfg = Some(AbridgedHostConfiguration {
1949					max_code_size: MAX_CODE_SIZE,
1950					max_head_data_size: 32 * 1024,
1951					max_upward_queue_count: 8,
1952					max_upward_queue_size: 1024 * 1024,
1953					max_upward_message_size: MAX_UPWARD_MESSAGE_SIZE,
1954					max_upward_message_num_per_candidate: 2,
1955					hrmp_max_message_num_per_candidate: 2,
1956					validation_upgrade_cooldown: 2,
1957					validation_upgrade_delay: 2,
1958					async_backing_params: relay_chain::AsyncBackingParams {
1959						allowed_ancestry_len: 0,
1960						max_candidate_depth: 0,
1961					},
1962				})
1963			},
1964		})
1965	}
1966}
1967
1968impl<T: Config> InspectMessageQueues for Pallet<T> {
1969	fn clear_messages() {
1970		PendingUpwardMessages::<T>::kill();
1971	}
1972
1973	fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
1974		use xcm::prelude::*;
1975
1976		let messages: Vec<VersionedXcm<()>> = PendingUpwardMessages::<T>::get()
1977			.iter()
1978			.map(|encoded_message| {
1979				VersionedXcm::<()>::decode_all_with_mem_and_depth_limit(&mut &encoded_message[..])
1980					.unwrap()
1981			})
1982			.collect();
1983
1984		if messages.is_empty() {
1985			vec![]
1986		} else {
1987			vec![(VersionedLocation::from(Location::parent()), messages)]
1988		}
1989	}
1990}
1991
1992#[cfg(feature = "runtime-benchmarks")]
1993impl<T: Config> polkadot_runtime_parachains::EnsureForParachain for Pallet<T> {
1994	fn ensure(para_id: ParaId) {
1995		if let ChannelStatus::Closed = Self::get_channel_status(para_id) {
1996			Self::open_outbound_hrmp_channel_for_benchmarks_or_tests(para_id)
1997		}
1998	}
1999}
2000
2001/// Something that should be informed about system related events.
2002///
2003/// This includes events like [`on_validation_data`](Self::on_validation_data) that is being
2004/// called when the parachain inherent is executed that contains the validation data.
2005/// Or like [`on_validation_code_applied`](Self::on_validation_code_applied) that is called
2006/// when the new validation is written to the state. This means that
2007/// from the next block the runtime is being using this new code.
2008pub trait OnSystemEvent {
2009	/// Called in each blocks once when the validation data is set by the inherent.
2010	fn on_validation_data(data: &PersistedValidationData);
2011	/// Called when the validation code is being applied, aka from the next block on this is the new
2012	/// runtime.
2013	fn on_validation_code_applied();
2014	/// Called to process keys from the verified relay chain state proof.
2015	fn on_relay_state_proof(
2016		relay_state_proof: &relay_state_snapshot::RelayChainStateProof,
2017	) -> Weight;
2018}
2019
2020#[impl_trait_for_tuples::impl_for_tuples(30)]
2021impl OnSystemEvent for Tuple {
2022	fn on_validation_data(data: &PersistedValidationData) {
2023		for_tuples!( #( Tuple::on_validation_data(data); )* );
2024	}
2025
2026	fn on_validation_code_applied() {
2027		for_tuples!( #( Tuple::on_validation_code_applied(); )* );
2028	}
2029
2030	fn on_relay_state_proof(
2031		relay_state_proof: &relay_state_snapshot::RelayChainStateProof,
2032	) -> Weight {
2033		let mut weight = Weight::zero();
2034		for_tuples!( #( weight = weight.saturating_add(Tuple::on_relay_state_proof(relay_state_proof)); )* );
2035		weight
2036	}
2037}
2038
2039/// Holds the most recent relay-parent state root and block number of the current parachain block.
2040#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Default, Debug)]
2041pub struct RelayChainState {
2042	/// Current relay chain height.
2043	pub number: relay_chain::BlockNumber,
2044	/// State root for current relay chain height.
2045	pub state_root: relay_chain::Hash,
2046}
2047
2048/// This exposes the [`RelayChainState`] to other runtime modules.
2049///
2050/// Enables parachains to read relay chain state via state proofs.
2051pub trait RelaychainStateProvider {
2052	/// May be called by any runtime module to obtain the current state of the relay chain.
2053	///
2054	/// **NOTE**: This is not guaranteed to return monotonically increasing relay parents.
2055	fn current_relay_chain_state() -> RelayChainState;
2056
2057	/// Utility function only to be used in benchmarking scenarios, to be implemented optionally,
2058	/// else a noop.
2059	///
2060	/// It allows for setting a custom RelayChainState.
2061	#[cfg(feature = "runtime-benchmarks")]
2062	fn set_current_relay_chain_state(_state: RelayChainState) {}
2063}
2064
2065/// Implements [`BlockNumberProvider`] that returns relay chain block number fetched from validation
2066/// data.
2067///
2068/// When validation data is not available (e.g. within `on_initialize`), it will fallback to use
2069/// [`Pallet::last_relay_block_number()`].
2070///
2071/// Implements [`BlockNumberProvider`] and [`RelaychainStateProvider`] that returns relevant relay
2072/// data fetched from validation data.
2073///
2074/// NOTE: When validation data is not available (e.g. within `on_initialize`):
2075///
2076/// - [`current_relay_chain_state`](Self::current_relay_chain_state): Will return the default value
2077///   of [`RelayChainState`].
2078/// - [`current_block_number`](Self::current_block_number): Will return
2079///   [`Pallet::last_relay_block_number()`].
2080pub struct RelaychainDataProvider<T>(core::marker::PhantomData<T>);
2081
2082impl<T: Config> BlockNumberProvider for RelaychainDataProvider<T> {
2083	type BlockNumber = relay_chain::BlockNumber;
2084
2085	fn current_block_number() -> relay_chain::BlockNumber {
2086		ValidationData::<T>::get()
2087			.map(|d| d.relay_parent_number)
2088			.unwrap_or_else(|| Pallet::<T>::last_relay_block_number())
2089	}
2090
2091	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2092	fn set_block_number(block: Self::BlockNumber) {
2093		let mut validation_data = ValidationData::<T>::get().unwrap_or_else(||
2094			// PersistedValidationData does not impl default in non-std
2095			PersistedValidationData {
2096				parent_head: vec![].into(),
2097				relay_parent_number: Default::default(),
2098				max_pov_size: Default::default(),
2099				relay_parent_storage_root: Default::default(),
2100			});
2101		validation_data.relay_parent_number = block;
2102		ValidationData::<T>::put(validation_data)
2103	}
2104}
2105
2106impl<T: Config> RelaychainStateProvider for RelaychainDataProvider<T> {
2107	fn current_relay_chain_state() -> RelayChainState {
2108		ValidationData::<T>::get()
2109			.map(|d| RelayChainState {
2110				number: d.relay_parent_number,
2111				state_root: d.relay_parent_storage_root,
2112			})
2113			.unwrap_or_default()
2114	}
2115
2116	#[cfg(feature = "runtime-benchmarks")]
2117	fn set_current_relay_chain_state(state: RelayChainState) {
2118		let mut validation_data = ValidationData::<T>::get().unwrap_or_else(||
2119			// PersistedValidationData does not impl default in non-std
2120			PersistedValidationData {
2121				parent_head: vec![].into(),
2122				relay_parent_number: Default::default(),
2123				max_pov_size: Default::default(),
2124				relay_parent_storage_root: Default::default(),
2125			});
2126		validation_data.relay_parent_number = state.number;
2127		validation_data.relay_parent_storage_root = state.state_root;
2128		ValidationData::<T>::put(validation_data)
2129	}
2130}