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

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

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

            
14
// You should have received a copy of the GNU General Public License
15
// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
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

            
30
extern crate alloc;
31

            
32
use alloc::{collections::btree_map::BTreeMap, vec, vec::Vec};
33
use codec::{Decode, Encode};
34
use core::cmp;
35
use cumulus_primitives_core::{
36
	relay_chain, AbridgedHostConfiguration, ChannelInfo, ChannelStatus, CollationInfo,
37
	GetChannelInfo, InboundDownwardMessage, InboundHrmpMessage, ListChannelInfos, MessageSendError,
38
	OutboundHrmpMessage, ParaId, PersistedValidationData, UpwardMessage, UpwardMessageSender,
39
	XcmpMessageHandler, XcmpMessageSource,
40
};
41
use cumulus_primitives_parachain_inherent::{MessageQueueChain, ParachainInherentData};
42
use frame_support::{
43
	defensive,
44
	dispatch::{DispatchResult, Pays, PostDispatchInfo},
45
	ensure,
46
	inherent::{InherentData, InherentIdentifier, ProvideInherent},
47
	traits::{Get, HandleMessage},
48
	weights::Weight,
49
};
50
use frame_system::{ensure_none, ensure_root, pallet_prelude::HeaderFor};
51
use polkadot_parachain_primitives::primitives::RelayChainBlockNumber;
52
use polkadot_runtime_parachains::FeeTracker;
53
use scale_info::TypeInfo;
54
use sp_runtime::{
55
	traits::{Block as BlockT, BlockNumberProvider, Hash},
56
	transaction_validity::{
57
		InvalidTransaction, TransactionSource, TransactionValidity, ValidTransaction,
58
	},
59
	BoundedSlice, FixedU128, RuntimeDebug, Saturating,
60
};
61
use xcm::{latest::XcmHash, VersionedLocation, VersionedXcm};
62
use xcm_builder::InspectMessageQueues;
63

            
64
mod benchmarking;
65
pub mod migration;
66
mod mock;
67
#[cfg(test)]
68
mod tests;
69
pub mod weights;
70

            
71
pub use weights::WeightInfo;
72

            
73
mod unincluded_segment;
74

            
75
pub mod consensus_hook;
76
pub mod relay_state_snapshot;
77
#[macro_use]
78
pub mod validate_block;
79

            
80
use unincluded_segment::{
81
	Ancestor, HrmpChannelUpdate, HrmpWatermarkUpdate, OutboundBandwidthLimits, SegmentTracker,
82
	UsedBandwidth,
83
};
84

            
85
pub use consensus_hook::{ConsensusHook, ExpectParentIncluded};
86
/// Register the `validate_block` function that is used by parachains to validate blocks on a
87
/// validator.
88
///
89
/// Does *nothing* when `std` feature is enabled.
90
///
91
/// Expects as parameters the runtime, a block executor and an inherent checker.
92
///
93
/// # Example
94
///
95
/// ```
96
///     struct BlockExecutor;
97
///     struct Runtime;
98
///     struct CheckInherents;
99
///
100
///     cumulus_pallet_parachain_system::register_validate_block! {
101
///         Runtime = Runtime,
102
///         BlockExecutor = Executive,
103
///         CheckInherents = CheckInherents,
104
///     }
105
///
106
/// # fn main() {}
107
/// ```
108
pub use cumulus_pallet_parachain_system_proc_macro::register_validate_block;
109
pub use relay_state_snapshot::{MessagingStateSnapshot, RelayChainStateProof};
110

            
111
pub use pallet::*;
112

            
113
/// Something that can check the associated relay block number.
114
///
115
/// Each Parachain block is built in the context of a relay chain block, this trait allows us
116
/// to validate the given relay chain block number. With async backing it is legal to build
117
/// multiple Parachain blocks per relay chain parent. With this trait it is possible for the
118
/// Parachain to ensure that still only one Parachain block is build per relay chain parent.
119
///
120
/// By default [`RelayNumberStrictlyIncreases`] and [`AnyRelayNumber`] are provided.
121
pub trait CheckAssociatedRelayNumber {
122
	/// Check the current relay number versus the previous relay number.
123
	///
124
	/// The implementation should panic when there is something wrong.
125
	fn check_associated_relay_number(
126
		current: RelayChainBlockNumber,
127
		previous: RelayChainBlockNumber,
128
	);
129
}
130

            
131
/// Provides an implementation of [`CheckAssociatedRelayNumber`].
132
///
133
/// It will ensure that the associated relay block number strictly increases between Parachain
134
/// blocks. This should be used by production Parachains when in doubt.
135
pub struct RelayNumberStrictlyIncreases;
136

            
137
impl CheckAssociatedRelayNumber for RelayNumberStrictlyIncreases {
138
	fn check_associated_relay_number(
139
		current: RelayChainBlockNumber,
140
		previous: RelayChainBlockNumber,
141
	) {
142
		if current <= previous {
143
			panic!("Relay chain block number needs to strictly increase between Parachain blocks!")
144
		}
145
	}
146
}
147

            
148
/// Provides an implementation of [`CheckAssociatedRelayNumber`].
149
///
150
/// This will accept any relay chain block number combination. This is mainly useful for
151
/// test parachains.
152
pub struct AnyRelayNumber;
153

            
154
impl CheckAssociatedRelayNumber for AnyRelayNumber {
155
	fn check_associated_relay_number(_: RelayChainBlockNumber, _: RelayChainBlockNumber) {}
156
}
157

            
158
/// Provides an implementation of [`CheckAssociatedRelayNumber`].
159
///
160
/// It will ensure that the associated relay block number monotonically increases between Parachain
161
/// blocks. This should be used when asynchronous backing is enabled.
162
pub struct RelayNumberMonotonicallyIncreases;
163

            
164
impl CheckAssociatedRelayNumber for RelayNumberMonotonicallyIncreases {
165
	fn check_associated_relay_number(
166
		current: RelayChainBlockNumber,
167
		previous: RelayChainBlockNumber,
168
	) {
169
		if current < previous {
170
			panic!("Relay chain block number needs to monotonically increase between Parachain blocks!")
171
		}
172
	}
173
}
174

            
175
/// The max length of a DMP message.
176
pub type MaxDmpMessageLenOf<T> = <<T as Config>::DmpQueue as HandleMessage>::MaxMessageLen;
177

            
178
pub mod ump_constants {
179
	use super::FixedU128;
180

            
181
	/// `host_config.max_upward_queue_size / THRESHOLD_FACTOR` is the threshold after which delivery
182
	/// starts getting exponentially more expensive.
183
	/// `2` means the price starts to increase when queue is half full.
184
	pub const THRESHOLD_FACTOR: u32 = 2;
185
	/// The base number the delivery fee factor gets multiplied by every time it is increased.
186
	/// Also the number it gets divided by when decreased.
187
	pub const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(105, 100); // 1.05
188
	/// The base number message size in KB is multiplied by before increasing the fee factor.
189
	pub const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0.001
190
}
191

            
192
#[frame_support::pallet]
193
pub mod pallet {
194
	use super::*;
195
	use frame_support::pallet_prelude::*;
196
	use frame_system::{pallet_prelude::*, WeightInfo as SystemWeightInfo};
197

            
198
	#[pallet::pallet]
199
	#[pallet::storage_version(migration::STORAGE_VERSION)]
200
	#[pallet::without_storage_info]
201
	pub struct Pallet<T>(_);
202

            
203
	#[pallet::config]
204
	pub trait Config: frame_system::Config<OnSetCode = ParachainSetCode<Self>> {
205
		/// The overarching event type.
206
		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
207

            
208
		/// Something which can be notified when the validation data is set.
209
		type OnSystemEvent: OnSystemEvent;
210

            
211
		/// Returns the parachain ID we are running with.
212
		#[pallet::constant]
213
		type SelfParaId: Get<ParaId>;
214

            
215
		/// The place where outbound XCMP messages come from. This is queried in `finalize_block`.
216
		type OutboundXcmpMessageSource: XcmpMessageSource;
217

            
218
		/// Queues inbound downward messages for delayed processing.
219
		///
220
		/// All inbound DMP messages from the relay are pushed into this. The handler is expected to
221
		/// eventually process all the messages that are pushed to it.
222
		type DmpQueue: HandleMessage;
223

            
224
		/// The weight we reserve at the beginning of the block for processing DMP messages.
225
		type ReservedDmpWeight: Get<Weight>;
226

            
227
		/// The message handler that will be invoked when messages are received via XCMP.
228
		///
229
		/// This should normally link to the XCMP Queue pallet.
230
		type XcmpMessageHandler: XcmpMessageHandler;
231

            
232
		/// The weight we reserve at the beginning of the block for processing XCMP messages.
233
		type ReservedXcmpWeight: Get<Weight>;
234

            
235
		/// Something that can check the associated relay parent block number.
236
		type CheckAssociatedRelayNumber: CheckAssociatedRelayNumber;
237

            
238
		/// Weight info for functions and calls.
239
		type WeightInfo: WeightInfo;
240

            
241
		/// An entry-point for higher-level logic to manage the backlog of unincluded parachain
242
		/// blocks and authorship rights for those blocks.
243
		///
244
		/// Typically, this should be a hook tailored to the collator-selection/consensus mechanism
245
		/// that is used for this chain.
246
		///
247
		/// However, to maintain the same behavior as prior to asynchronous backing, provide the
248
		/// [`consensus_hook::ExpectParentIncluded`] here. This is only necessary in the case
249
		/// that collators aren't expected to have node versions that supply the included block
250
		/// in the relay-chain state proof.
251
		type ConsensusHook: ConsensusHook;
252
	}
253

            
254
	#[pallet::hooks]
255
	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
256
		/// Handles actually sending upward messages by moving them from `PendingUpwardMessages` to
257
		/// `UpwardMessages`. Decreases the delivery fee factor if after sending messages, the queue
258
		/// total size is less than the threshold (see [`ump_constants::THRESHOLD_FACTOR`]).
259
		/// Also does the sending for HRMP messages it takes from `OutboundXcmpMessageSource`.
260
		fn on_finalize(_: BlockNumberFor<T>) {
261
			<DidSetValidationCode<T>>::kill();
262
			<UpgradeRestrictionSignal<T>>::kill();
263
			let relay_upgrade_go_ahead = <UpgradeGoAhead<T>>::take();
264

            
265
			let vfp = <ValidationData<T>>::get()
266
				.expect("set_validation_data inherent needs to be present in every block!");
267

            
268
			LastRelayChainBlockNumber::<T>::put(vfp.relay_parent_number);
269

            
270
			let host_config = match HostConfiguration::<T>::get() {
271
				Some(ok) => ok,
272
				None => {
273
					debug_assert!(
274
						false,
275
						"host configuration is promised to set until `on_finalize`; qed",
276
					);
277
					return
278
				},
279
			};
280

            
281
			// Before updating the relevant messaging state, we need to extract
282
			// the total bandwidth limits for the purpose of updating the unincluded
283
			// segment.
284
			let total_bandwidth_out = match RelevantMessagingState::<T>::get() {
285
				Some(s) => OutboundBandwidthLimits::from_relay_chain_state(&s),
286
				None => {
287
					debug_assert!(
288
						false,
289
						"relevant messaging state is promised to be set until `on_finalize`; \
290
							qed",
291
					);
292
					return
293
				},
294
			};
295

            
296
			// After this point, the `RelevantMessagingState` in storage reflects the
297
			// unincluded segment.
298
			Self::adjust_egress_bandwidth_limits();
299

            
300
			let (ump_msg_count, ump_total_bytes) = <PendingUpwardMessages<T>>::mutate(|up| {
301
				let (available_capacity, available_size) = match RelevantMessagingState::<T>::get()
302
				{
303
					Some(limits) => (
304
						limits.relay_dispatch_queue_remaining_capacity.remaining_count,
305
						limits.relay_dispatch_queue_remaining_capacity.remaining_size,
306
					),
307
					None => {
308
						debug_assert!(
309
							false,
310
							"relevant messaging state is promised to be set until `on_finalize`; \
311
								qed",
312
						);
313
						return (0, 0)
314
					},
315
				};
316

            
317
				let available_capacity =
318
					cmp::min(available_capacity, host_config.max_upward_message_num_per_candidate);
319

            
320
				// Count the number of messages we can possibly fit in the given constraints, i.e.
321
				// available_capacity and available_size.
322
				let (num, total_size) = up
323
					.iter()
324
					.scan((0u32, 0u32), |state, msg| {
325
						let (cap_used, size_used) = *state;
326
						let new_cap = cap_used.saturating_add(1);
327
						let new_size = size_used.saturating_add(msg.len() as u32);
328
						match available_capacity
329
							.checked_sub(new_cap)
330
							.and(available_size.checked_sub(new_size))
331
						{
332
							Some(_) => {
333
								*state = (new_cap, new_size);
334
								Some(*state)
335
							},
336
							_ => None,
337
						}
338
					})
339
					.last()
340
					.unwrap_or_default();
341

            
342
				// TODO: #274 Return back messages that do not longer fit into the queue.
343

            
344
				UpwardMessages::<T>::put(&up[..num as usize]);
345
				*up = up.split_off(num as usize);
346

            
347
				// If the total size of the pending messages is less than the threshold,
348
				// we decrease the fee factor, since the queue is less congested.
349
				// This makes delivery of new messages cheaper.
350
				let threshold = host_config
351
					.max_upward_queue_size
352
					.saturating_div(ump_constants::THRESHOLD_FACTOR);
353
				let remaining_total_size: usize = up.iter().map(UpwardMessage::len).sum();
354
				if remaining_total_size <= threshold as usize {
355
					Self::decrease_fee_factor(());
356
				}
357

            
358
				(num, total_size)
359
			});
360

            
361
			// Sending HRMP messages is a little bit more involved. There are the following
362
			// constraints:
363
			//
364
			// - a channel should exist (and it can be closed while a message is buffered),
365
			// - at most one message can be sent in a channel,
366
			// - the sent out messages should be ordered by ascension of recipient para id.
367
			// - the capacity and total size of the channel is limited,
368
			// - the maximum size of a message is limited (and can potentially be changed),
369

            
370
			let maximum_channels = host_config
371
				.hrmp_max_message_num_per_candidate
372
				.min(<AnnouncedHrmpMessagesPerCandidate<T>>::take()) as usize;
373

            
374
			// Note: this internally calls the `GetChannelInfo` implementation for this
375
			// pallet, which draws on the `RelevantMessagingState`. That in turn has
376
			// been adjusted above to reflect the correct limits in all channels.
377
			let outbound_messages =
378
				T::OutboundXcmpMessageSource::take_outbound_messages(maximum_channels)
379
					.into_iter()
380
					.map(|(recipient, data)| OutboundHrmpMessage { recipient, data })
381
					.collect::<Vec<_>>();
382

            
383
			// Update the unincluded segment length; capacity checks were done previously in
384
			// `set_validation_data`, so this can be done unconditionally.
385
			{
386
				let hrmp_outgoing = outbound_messages
387
					.iter()
388
					.map(|msg| {
389
						(
390
							msg.recipient,
391
							HrmpChannelUpdate { msg_count: 1, total_bytes: msg.data.len() as u32 },
392
						)
393
					})
394
					.collect();
395
				let used_bandwidth =
396
					UsedBandwidth { ump_msg_count, ump_total_bytes, hrmp_outgoing };
397

            
398
				let mut aggregated_segment =
399
					AggregatedUnincludedSegment::<T>::get().unwrap_or_default();
400
				let consumed_go_ahead_signal =
401
					if aggregated_segment.consumed_go_ahead_signal().is_some() {
402
						// Some ancestor within the segment already processed this signal --
403
						// validated during inherent creation.
404
						None
405
					} else {
406
						relay_upgrade_go_ahead
407
					};
408
				// The bandwidth constructed was ensured to satisfy relay chain constraints.
409
				let ancestor = Ancestor::new_unchecked(used_bandwidth, consumed_go_ahead_signal);
410

            
411
				let watermark = HrmpWatermark::<T>::get();
412
				let watermark_update = HrmpWatermarkUpdate::new(watermark, vfp.relay_parent_number);
413

            
414
				aggregated_segment
415
					.append(&ancestor, watermark_update, &total_bandwidth_out)
416
					.expect("unincluded segment limits exceeded");
417
				AggregatedUnincludedSegment::<T>::put(aggregated_segment);
418
				// Check in `on_initialize` guarantees there's space for this block.
419
				UnincludedSegment::<T>::append(ancestor);
420
			}
421
			HrmpOutboundMessages::<T>::put(outbound_messages);
422
		}
423

            
424
		fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
425
			let mut weight = Weight::zero();
426

            
427
			// To prevent removing `NewValidationCode` that was set by another `on_initialize`
428
			// like for example from scheduler, we only kill the storage entry if it was not yet
429
			// updated in the current block.
430
			if !<DidSetValidationCode<T>>::get() {
431
				NewValidationCode::<T>::kill();
432
				weight += T::DbWeight::get().writes(1);
433
			}
434

            
435
			// The parent hash was unknown during block finalization. Update it here.
436
			{
437
				<UnincludedSegment<T>>::mutate(|chain| {
438
					if let Some(ancestor) = chain.last_mut() {
439
						let parent = frame_system::Pallet::<T>::parent_hash();
440
						// Ancestor is the latest finalized block, thus current parent is
441
						// its output head.
442
						ancestor.replace_para_head_hash(parent);
443
					}
444
				});
445
				weight += T::DbWeight::get().reads_writes(1, 1);
446

            
447
				// Weight used during finalization.
448
				weight += T::DbWeight::get().reads_writes(3, 2);
449
			}
450

            
451
			// Remove the validation from the old block.
452
			ValidationData::<T>::kill();
453
			ProcessedDownwardMessages::<T>::kill();
454
			HrmpWatermark::<T>::kill();
455
			UpwardMessages::<T>::kill();
456
			HrmpOutboundMessages::<T>::kill();
457
			CustomValidationHeadData::<T>::kill();
458

            
459
			weight += T::DbWeight::get().writes(6);
460

            
461
			// Here, in `on_initialize` we must report the weight for both `on_initialize` and
462
			// `on_finalize`.
463
			//
464
			// One complication here, is that the `host_configuration` is updated by an inherent
465
			// and those are processed after the block initialization phase. Therefore, we have to
466
			// be content only with the configuration as per the previous block. That means that
467
			// the configuration can be either stale (or be absent altogether in case of the
468
			// beginning of the chain).
469
			//
470
			// In order to mitigate this, we do the following. At the time, we are only concerned
471
			// about `hrmp_max_message_num_per_candidate`. We reserve the amount of weight to
472
			// process the number of HRMP messages according to the potentially stale
473
			// configuration. In `on_finalize` we will process only the maximum between the
474
			// announced number of messages and the actual received in the fresh configuration.
475
			//
476
			// In the common case, they will be the same. In the case the actual value is smaller
477
			// than the announced, we would waste some of weight. In the case the actual value is
478
			// greater than the announced, we will miss opportunity to send a couple of messages.
479
			weight += T::DbWeight::get().reads_writes(1, 1);
480
			let hrmp_max_message_num_per_candidate = HostConfiguration::<T>::get()
481
				.map(|cfg| cfg.hrmp_max_message_num_per_candidate)
482
				.unwrap_or(0);
483
			<AnnouncedHrmpMessagesPerCandidate<T>>::put(hrmp_max_message_num_per_candidate);
484

            
485
			// NOTE that the actual weight consumed by `on_finalize` may turn out lower.
486
			weight += T::DbWeight::get().reads_writes(
487
				3 + hrmp_max_message_num_per_candidate as u64,
488
				4 + hrmp_max_message_num_per_candidate as u64,
489
			);
490

            
491
			// Weight for updating the last relay chain block number in `on_finalize`.
492
			weight += T::DbWeight::get().reads_writes(1, 1);
493

            
494
			// Weight for adjusting the unincluded segment in `on_finalize`.
495
			weight += T::DbWeight::get().reads_writes(6, 3);
496

            
497
			// Always try to read `UpgradeGoAhead` in `on_finalize`.
498
			weight += T::DbWeight::get().reads(1);
499

            
500
			weight
501
		}
502
	}
503

            
504
	#[pallet::call]
505
	impl<T: Config> Pallet<T> {
506
		/// Set the current validation data.
507
		///
508
		/// This should be invoked exactly once per block. It will panic at the finalization
509
		/// phase if the call was not invoked.
510
		///
511
		/// The dispatch origin for this call must be `Inherent`
512
		///
513
		/// As a side effect, this function upgrades the current validation function
514
		/// if the appropriate time has come.
515
		#[pallet::call_index(0)]
516
		#[pallet::weight((0, DispatchClass::Mandatory))]
517
		// TODO: This weight should be corrected.
518
		pub fn set_validation_data(
519
			origin: OriginFor<T>,
520
			data: ParachainInherentData,
521
		) -> DispatchResultWithPostInfo {
522
			ensure_none(origin)?;
523
			assert!(
524
				!<ValidationData<T>>::exists(),
525
				"ValidationData must be updated only once in a block",
526
			);
527

            
528
			// TODO: This is more than zero, but will need benchmarking to figure out what.
529
			let mut total_weight = Weight::zero();
530

            
531
			// NOTE: the inherent data is expected to be unique, even if this block is built
532
			// in the context of the same relay parent as the previous one. In particular,
533
			// the inherent shouldn't contain messages that were already processed by any of the
534
			// ancestors.
535
			//
536
			// This invariant should be upheld by the `ProvideInherent` implementation.
537
			let ParachainInherentData {
538
				validation_data: vfp,
539
				relay_chain_state,
540
				downward_messages,
541
				horizontal_messages,
542
			} = data;
543

            
544
			// Check that the associated relay chain block number is as expected.
545
			T::CheckAssociatedRelayNumber::check_associated_relay_number(
546
				vfp.relay_parent_number,
547
				LastRelayChainBlockNumber::<T>::get(),
548
			);
549

            
550
			let relay_state_proof = RelayChainStateProof::new(
551
				T::SelfParaId::get(),
552
				vfp.relay_parent_storage_root,
553
				relay_chain_state.clone(),
554
			)
555
			.expect("Invalid relay chain state proof");
556

            
557
			// Update the desired maximum capacity according to the consensus hook.
558
			let (consensus_hook_weight, capacity) =
559
				T::ConsensusHook::on_state_proof(&relay_state_proof);
560
			total_weight += consensus_hook_weight;
561
			total_weight += Self::maybe_drop_included_ancestors(&relay_state_proof, capacity);
562
			// Deposit a log indicating the relay-parent storage root.
563
			// TODO: remove this in favor of the relay-parent's hash after
564
			// https://github.com/paritytech/cumulus/issues/303
565
			frame_system::Pallet::<T>::deposit_log(
566
				cumulus_primitives_core::rpsr_digest::relay_parent_storage_root_item(
567
					vfp.relay_parent_storage_root,
568
					vfp.relay_parent_number,
569
				),
570
			);
571

            
572
			// initialization logic: we know that this runs exactly once every block,
573
			// which means we can put the initialization logic here to remove the
574
			// sequencing problem.
575
			let upgrade_go_ahead_signal = relay_state_proof
576
				.read_upgrade_go_ahead_signal()
577
				.expect("Invalid upgrade go ahead signal");
578

            
579
			let upgrade_signal_in_segment = AggregatedUnincludedSegment::<T>::get()
580
				.as_ref()
581
				.and_then(SegmentTracker::consumed_go_ahead_signal);
582
			if let Some(signal_in_segment) = upgrade_signal_in_segment.as_ref() {
583
				// Unincluded ancestor consuming upgrade signal is still within the segment,
584
				// sanity check that it matches with the signal from relay chain.
585
				assert_eq!(upgrade_go_ahead_signal, Some(*signal_in_segment));
586
			}
587
			match upgrade_go_ahead_signal {
588
				Some(_signal) if upgrade_signal_in_segment.is_some() => {
589
					// Do nothing, processing logic was executed by unincluded ancestor.
590
				},
591
				Some(relay_chain::UpgradeGoAhead::GoAhead) => {
592
					assert!(
593
						<PendingValidationCode<T>>::exists(),
594
						"No new validation function found in storage, GoAhead signal is not expected",
595
					);
596
					let validation_code = <PendingValidationCode<T>>::take();
597

            
598
					frame_system::Pallet::<T>::update_code_in_storage(&validation_code);
599
					<T::OnSystemEvent as OnSystemEvent>::on_validation_code_applied();
600
					Self::deposit_event(Event::ValidationFunctionApplied {
601
						relay_chain_block_num: vfp.relay_parent_number,
602
					});
603
				},
604
				Some(relay_chain::UpgradeGoAhead::Abort) => {
605
					<PendingValidationCode<T>>::kill();
606
					Self::deposit_event(Event::ValidationFunctionDiscarded);
607
				},
608
				None => {},
609
			}
610
			<UpgradeRestrictionSignal<T>>::put(
611
				relay_state_proof
612
					.read_upgrade_restriction_signal()
613
					.expect("Invalid upgrade restriction signal"),
614
			);
615
			<UpgradeGoAhead<T>>::put(upgrade_go_ahead_signal);
616

            
617
			let host_config = relay_state_proof
618
				.read_abridged_host_configuration()
619
				.expect("Invalid host configuration in relay chain state proof");
620

            
621
			let relevant_messaging_state = relay_state_proof
622
				.read_messaging_state_snapshot(&host_config)
623
				.expect("Invalid messaging state in relay chain state proof");
624

            
625
			<ValidationData<T>>::put(&vfp);
626
			<RelayStateProof<T>>::put(relay_chain_state);
627
			<RelevantMessagingState<T>>::put(relevant_messaging_state.clone());
628
			<HostConfiguration<T>>::put(host_config);
629

            
630
			<T::OnSystemEvent as OnSystemEvent>::on_validation_data(&vfp);
631

            
632
			total_weight.saturating_accrue(Self::enqueue_inbound_downward_messages(
633
				relevant_messaging_state.dmq_mqc_head,
634
				downward_messages,
635
			));
636
			total_weight.saturating_accrue(Self::enqueue_inbound_horizontal_messages(
637
				&relevant_messaging_state.ingress_channels,
638
				horizontal_messages,
639
				vfp.relay_parent_number,
640
			));
641

            
642
			Ok(PostDispatchInfo { actual_weight: Some(total_weight), pays_fee: Pays::No })
643
		}
644

            
645
		#[pallet::call_index(1)]
646
		#[pallet::weight((1_000, DispatchClass::Operational))]
647
		pub fn sudo_send_upward_message(
648
			origin: OriginFor<T>,
649
			message: UpwardMessage,
650
		) -> DispatchResult {
651
			ensure_root(origin)?;
652
			let _ = Self::send_upward_message(message);
653
			Ok(())
654
		}
655

            
656
		/// Authorize an upgrade to a given `code_hash` for the runtime. The runtime can be supplied
657
		/// later.
658
		///
659
		/// The `check_version` parameter sets a boolean flag for whether or not the runtime's spec
660
		/// version and name should be verified on upgrade. Since the authorization only has a hash,
661
		/// it cannot actually perform the verification.
662
		///
663
		/// This call requires Root origin.
664
		#[pallet::call_index(2)]
665
		#[pallet::weight(<T as frame_system::Config>::SystemWeightInfo::authorize_upgrade())]
666
		#[allow(deprecated)]
667
		#[deprecated(
668
			note = "To be removed after June 2024. Migrate to `frame_system::authorize_upgrade`."
669
		)]
670
		pub fn authorize_upgrade(
671
			origin: OriginFor<T>,
672
			code_hash: T::Hash,
673
			check_version: bool,
674
		) -> DispatchResult {
675
			ensure_root(origin)?;
676
			frame_system::Pallet::<T>::do_authorize_upgrade(code_hash, check_version);
677
			Ok(())
678
		}
679

            
680
		/// Provide the preimage (runtime binary) `code` for an upgrade that has been authorized.
681
		///
682
		/// If the authorization required a version check, this call will ensure the spec name
683
		/// remains unchanged and that the spec version has increased.
684
		///
685
		/// Note that this function will not apply the new `code`, but only attempt to schedule the
686
		/// upgrade with the Relay Chain.
687
		///
688
		/// All origins are allowed.
689
		#[pallet::call_index(3)]
690
		#[pallet::weight(<T as frame_system::Config>::SystemWeightInfo::apply_authorized_upgrade())]
691
		#[allow(deprecated)]
692
		#[deprecated(
693
			note = "To be removed after June 2024. Migrate to `frame_system::apply_authorized_upgrade`."
694
		)]
695
		pub fn enact_authorized_upgrade(
696
			_: OriginFor<T>,
697
			code: Vec<u8>,
698
		) -> DispatchResultWithPostInfo {
699
			let post = frame_system::Pallet::<T>::do_apply_authorize_upgrade(code)?;
700
			Ok(post)
701
		}
702
	}
703

            
704
	#[pallet::event]
705
	#[pallet::generate_deposit(pub(super) fn deposit_event)]
706
	pub enum Event<T: Config> {
707
		/// The validation function has been scheduled to apply.
708
		ValidationFunctionStored,
709
		/// The validation function was applied as of the contained relay chain block number.
710
		ValidationFunctionApplied { relay_chain_block_num: RelayChainBlockNumber },
711
		/// The relay-chain aborted the upgrade process.
712
		ValidationFunctionDiscarded,
713
		/// Some downward messages have been received and will be processed.
714
		DownwardMessagesReceived { count: u32 },
715
		/// Downward messages were processed using the given weight.
716
		DownwardMessagesProcessed { weight_used: Weight, dmq_head: relay_chain::Hash },
717
		/// An upward message was sent to the relay chain.
718
		UpwardMessageSent { message_hash: Option<XcmHash> },
719
	}
720

            
721
	#[pallet::error]
722
	pub enum Error<T> {
723
		/// Attempt to upgrade validation function while existing upgrade pending.
724
		OverlappingUpgrades,
725
		/// Polkadot currently prohibits this parachain from upgrading its validation function.
726
		ProhibitedByPolkadot,
727
		/// The supplied validation function has compiled into a blob larger than Polkadot is
728
		/// willing to run.
729
		TooBig,
730
		/// The inherent which supplies the validation data did not run this block.
731
		ValidationDataNotAvailable,
732
		/// The inherent which supplies the host configuration did not run this block.
733
		HostConfigurationNotAvailable,
734
		/// No validation function upgrade is currently scheduled.
735
		NotScheduled,
736
		/// No code upgrade has been authorized.
737
		NothingAuthorized,
738
		/// The given code upgrade has not been authorized.
739
		Unauthorized,
740
	}
741

            
742
	/// Latest included block descendants the runtime accepted. In other words, these are
743
	/// ancestors of the currently executing block which have not been included in the observed
744
	/// relay-chain state.
745
	///
746
	/// The segment length is limited by the capacity returned from the [`ConsensusHook`] configured
747
	/// in the pallet.
748
	#[pallet::storage]
749
	pub type UnincludedSegment<T: Config> = StorageValue<_, Vec<Ancestor<T::Hash>>, ValueQuery>;
750

            
751
	/// Storage field that keeps track of bandwidth used by the unincluded segment along with the
752
	/// latest HRMP watermark. Used for limiting the acceptance of new blocks with
753
	/// respect to relay chain constraints.
754
	#[pallet::storage]
755
	pub type AggregatedUnincludedSegment<T: Config> =
756
		StorageValue<_, SegmentTracker<T::Hash>, OptionQuery>;
757

            
758
	/// In case of a scheduled upgrade, this storage field contains the validation code to be
759
	/// applied.
760
	///
761
	/// As soon as the relay chain gives us the go-ahead signal, we will overwrite the
762
	/// [`:code`][sp_core::storage::well_known_keys::CODE] which will result the next block process
763
	/// with the new validation code. This concludes the upgrade process.
764
	#[pallet::storage]
765
	pub type PendingValidationCode<T: Config> = StorageValue<_, Vec<u8>, ValueQuery>;
766

            
767
	/// Validation code that is set by the parachain and is to be communicated to collator and
768
	/// consequently the relay-chain.
769
	///
770
	/// This will be cleared in `on_initialize` of each new block if no other pallet already set
771
	/// the value.
772
	#[pallet::storage]
773
	pub type NewValidationCode<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
774

            
775
	/// The [`PersistedValidationData`] set for this block.
776
	/// This value is expected to be set only once per block and it's never stored
777
	/// in the trie.
778
	#[pallet::storage]
779
	pub type ValidationData<T: Config> = StorageValue<_, PersistedValidationData>;
780

            
781
	/// Were the validation data set to notify the relay chain?
782
	#[pallet::storage]
783
	pub type DidSetValidationCode<T: Config> = StorageValue<_, bool, ValueQuery>;
784

            
785
	/// The relay chain block number associated with the last parachain block.
786
	///
787
	/// This is updated in `on_finalize`.
788
	#[pallet::storage]
789
	pub type LastRelayChainBlockNumber<T: Config> =
790
		StorageValue<_, RelayChainBlockNumber, ValueQuery>;
791

            
792
	/// An option which indicates if the relay-chain restricts signalling a validation code upgrade.
793
	/// In other words, if this is `Some` and [`NewValidationCode`] is `Some` then the produced
794
	/// candidate will be invalid.
795
	///
796
	/// This storage item is a mirror of the corresponding value for the current parachain from the
797
	/// relay-chain. This value is ephemeral which means it doesn't hit the storage. This value is
798
	/// set after the inherent.
799
	#[pallet::storage]
800
	pub type UpgradeRestrictionSignal<T: Config> =
801
		StorageValue<_, Option<relay_chain::UpgradeRestriction>, ValueQuery>;
802

            
803
	/// Optional upgrade go-ahead signal from the relay-chain.
804
	///
805
	/// This storage item is a mirror of the corresponding value for the current parachain from the
806
	/// relay-chain. This value is ephemeral which means it doesn't hit the storage. This value is
807
	/// set after the inherent.
808
	#[pallet::storage]
809
	pub type UpgradeGoAhead<T: Config> =
810
		StorageValue<_, Option<relay_chain::UpgradeGoAhead>, ValueQuery>;
811

            
812
	/// The state proof for the last relay parent block.
813
	///
814
	/// This field is meant to be updated each block with the validation data inherent. Therefore,
815
	/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
816
	///
817
	/// This data is also absent from the genesis.
818
	#[pallet::storage]
819
	pub type RelayStateProof<T: Config> = StorageValue<_, sp_trie::StorageProof>;
820

            
821
	/// The snapshot of some state related to messaging relevant to the current parachain as per
822
	/// the relay parent.
823
	///
824
	/// This field is meant to be updated each block with the validation data inherent. Therefore,
825
	/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
826
	///
827
	/// This data is also absent from the genesis.
828
	#[pallet::storage]
829
	pub type RelevantMessagingState<T: Config> = StorageValue<_, MessagingStateSnapshot>;
830

            
831
	/// The parachain host configuration that was obtained from the relay parent.
832
	///
833
	/// This field is meant to be updated each block with the validation data inherent. Therefore,
834
	/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
835
	///
836
	/// This data is also absent from the genesis.
837
	#[pallet::storage]
838
	#[pallet::disable_try_decode_storage]
839
	pub type HostConfiguration<T: Config> = StorageValue<_, AbridgedHostConfiguration>;
840

            
841
	/// The last downward message queue chain head we have observed.
842
	///
843
	/// This value is loaded before and saved after processing inbound downward messages carried
844
	/// by the system inherent.
845
	#[pallet::storage]
846
	pub type LastDmqMqcHead<T: Config> = StorageValue<_, MessageQueueChain, ValueQuery>;
847

            
848
	/// The message queue chain heads we have observed per each channel incoming channel.
849
	///
850
	/// This value is loaded before and saved after processing inbound downward messages carried
851
	/// by the system inherent.
852
	#[pallet::storage]
853
	pub type LastHrmpMqcHeads<T: Config> =
854
		StorageValue<_, BTreeMap<ParaId, MessageQueueChain>, ValueQuery>;
855

            
856
	/// Number of downward messages processed in a block.
857
	///
858
	/// This will be cleared in `on_initialize` of each new block.
859
	#[pallet::storage]
860
	pub type ProcessedDownwardMessages<T: Config> = StorageValue<_, u32, ValueQuery>;
861

            
862
	/// HRMP watermark that was set in a block.
863
	///
864
	/// This will be cleared in `on_initialize` of each new block.
865
	#[pallet::storage]
866
	pub type HrmpWatermark<T: Config> = StorageValue<_, relay_chain::BlockNumber, ValueQuery>;
867

            
868
	/// HRMP messages that were sent in a block.
869
	///
870
	/// This will be cleared in `on_initialize` of each new block.
871
	#[pallet::storage]
872
	pub type HrmpOutboundMessages<T: Config> =
873
		StorageValue<_, Vec<OutboundHrmpMessage>, ValueQuery>;
874

            
875
	/// Upward messages that were sent in a block.
876
	///
877
	/// This will be cleared in `on_initialize` of each new block.
878
	#[pallet::storage]
879
	pub type UpwardMessages<T: Config> = StorageValue<_, Vec<UpwardMessage>, ValueQuery>;
880

            
881
	/// Upward messages that are still pending and not yet send to the relay chain.
882
	#[pallet::storage]
883
	pub type PendingUpwardMessages<T: Config> = StorageValue<_, Vec<UpwardMessage>, ValueQuery>;
884

            
885
	/// Initialization value for the delivery fee factor for UMP.
886
	#[pallet::type_value]
887
	pub fn UpwardInitialDeliveryFeeFactor() -> FixedU128 {
888
		FixedU128::from_u32(1)
889
	}
890

            
891
	/// The factor to multiply the base delivery fee by for UMP.
892
	#[pallet::storage]
893
	pub type UpwardDeliveryFeeFactor<T: Config> =
894
		StorageValue<_, FixedU128, ValueQuery, UpwardInitialDeliveryFeeFactor>;
895

            
896
	/// The number of HRMP messages we observed in `on_initialize` and thus used that number for
897
	/// announcing the weight of `on_initialize` and `on_finalize`.
898
	#[pallet::storage]
899
	pub type AnnouncedHrmpMessagesPerCandidate<T: Config> = StorageValue<_, u32, ValueQuery>;
900

            
901
	/// The weight we reserve at the beginning of the block for processing XCMP messages. This
902
	/// overrides the amount set in the Config trait.
903
	#[pallet::storage]
904
	pub type ReservedXcmpWeightOverride<T: Config> = StorageValue<_, Weight>;
905

            
906
	/// The weight we reserve at the beginning of the block for processing DMP messages. This
907
	/// overrides the amount set in the Config trait.
908
	#[pallet::storage]
909
	pub type ReservedDmpWeightOverride<T: Config> = StorageValue<_, Weight>;
910

            
911
	/// A custom head data that should be returned as result of `validate_block`.
912
	///
913
	/// See `Pallet::set_custom_validation_head_data` for more information.
914
	#[pallet::storage]
915
	pub type CustomValidationHeadData<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
916

            
917
	#[pallet::inherent]
918
	impl<T: Config> ProvideInherent for Pallet<T> {
919
		type Call = Call<T>;
920
		type Error = sp_inherents::MakeFatalError<()>;
921
		const INHERENT_IDENTIFIER: InherentIdentifier =
922
			cumulus_primitives_parachain_inherent::INHERENT_IDENTIFIER;
923

            
924
		fn create_inherent(data: &InherentData) -> Option<Self::Call> {
925
			let mut data: ParachainInherentData =
926
				data.get_data(&Self::INHERENT_IDENTIFIER).ok().flatten().expect(
927
					"validation function params are always injected into inherent data; qed",
928
				);
929

            
930
			Self::drop_processed_messages_from_inherent(&mut data);
931

            
932
			Some(Call::set_validation_data { data })
933
		}
934

            
935
		fn is_inherent(call: &Self::Call) -> bool {
936
			matches!(call, Call::set_validation_data { .. })
937
		}
938
	}
939

            
940
	#[pallet::genesis_config]
941
	#[derive(frame_support::DefaultNoBound)]
942
	pub struct GenesisConfig<T: Config> {
943
		#[serde(skip)]
944
		pub _config: core::marker::PhantomData<T>,
945
	}
946

            
947
	#[pallet::genesis_build]
948
	impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
949
		fn build(&self) {
950
			// TODO: Remove after https://github.com/paritytech/cumulus/issues/479
951
			sp_io::storage::set(b":c", &[]);
952
		}
953
	}
954

            
955
	#[pallet::validate_unsigned]
956
	impl<T: Config> sp_runtime::traits::ValidateUnsigned for Pallet<T> {
957
		type Call = Call<T>;
958

            
959
		fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
960
			if let Call::enact_authorized_upgrade { ref code } = call {
961
				if let Ok(hash) = frame_system::Pallet::<T>::validate_authorized_upgrade(&code[..])
962
				{
963
					return Ok(ValidTransaction {
964
						priority: 100,
965
						requires: Vec::new(),
966
						provides: vec![hash.as_ref().to_vec()],
967
						longevity: TransactionLongevity::max_value(),
968
						propagate: true,
969
					})
970
				}
971
			}
972
			if let Call::set_validation_data { .. } = call {
973
				return Ok(Default::default())
974
			}
975
			Err(InvalidTransaction::Call.into())
976
		}
977
	}
978
}
979

            
980
impl<T: Config> Pallet<T> {
981
	/// Get the unincluded segment size after the given hash.
982
	///
983
	/// If the unincluded segment doesn't contain the given hash, this returns the
984
	/// length of the entire unincluded segment.
985
	///
986
	/// This is intended to be used for determining how long the unincluded segment _would be_
987
	/// in runtime APIs related to authoring.
988
	pub fn unincluded_segment_size_after(included_hash: T::Hash) -> u32 {
989
		let segment = UnincludedSegment::<T>::get();
990
		crate::unincluded_segment::size_after_included(included_hash, &segment)
991
	}
992
}
993

            
994
impl<T: Config> FeeTracker for Pallet<T> {
995
	type Id = ();
996

            
997
	fn get_fee_factor(_: Self::Id) -> FixedU128 {
998
		UpwardDeliveryFeeFactor::<T>::get()
999
	}
	fn increase_fee_factor(_: Self::Id, message_size_factor: FixedU128) -> FixedU128 {
		<UpwardDeliveryFeeFactor<T>>::mutate(|f| {
			*f = f.saturating_mul(
				ump_constants::EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor),
			);
			*f
		})
	}
	fn decrease_fee_factor(_: Self::Id) -> FixedU128 {
		<UpwardDeliveryFeeFactor<T>>::mutate(|f| {
			*f =
				UpwardInitialDeliveryFeeFactor::get().max(*f / ump_constants::EXPONENTIAL_FEE_BASE);
			*f
		})
	}
}
impl<T: Config> ListChannelInfos for Pallet<T> {
	fn outgoing_channels() -> Vec<ParaId> {
		let Some(state) = RelevantMessagingState::<T>::get() else { return Vec::new() };
		state.egress_channels.into_iter().map(|(id, _)| id).collect()
	}
}
impl<T: Config> GetChannelInfo for Pallet<T> {
	fn get_channel_status(id: ParaId) -> ChannelStatus {
		// Note, that we are using `relevant_messaging_state` which may be from the previous
		// block, in case this is called from `on_initialize`, i.e. before the inherent with
		// fresh data is submitted.
		//
		// That shouldn't be a problem though because this is anticipated and already can
		// happen. This is because sending implies that a message is buffered until there is
		// space to send a message in the candidate. After a while waiting in a buffer, it may
		// be discovered that the channel to which a message were addressed is now closed.
		// Another possibility, is that the maximum message size was decreased so that a
		// message in the buffer doesn't fit. Should any of that happen the sender should be
		// notified about the message was discarded.
		//
		// Here it a similar case, with the difference that the realization that the channel is
		// closed came the same block.
		let channels = match RelevantMessagingState::<T>::get() {
			None => {
				log::warn!("calling `get_channel_status` with no RelevantMessagingState?!");
				return ChannelStatus::Closed
			},
			Some(d) => d.egress_channels,
		};
		// ^^^ NOTE: This storage field should carry over from the previous block. So if it's
		// None then it must be that this is an edge-case where a message is attempted to be
		// sent at the first block. It should be safe to assume that there are no channels
		// opened at all so early. At least, relying on this assumption seems to be a better
		// trade-off, compared to introducing an error variant that the clients should be
		// prepared to handle.
		let index = match channels.binary_search_by_key(&id, |item| item.0) {
			Err(_) => return ChannelStatus::Closed,
			Ok(i) => i,
		};
		let meta = &channels[index].1;
		if meta.msg_count + 1 > meta.max_capacity {
			// The channel is at its capacity. Skip it for now.
			return ChannelStatus::Full
		}
		let max_size_now = meta.max_total_size - meta.total_size;
		let max_size_ever = meta.max_message_size;
		ChannelStatus::Ready(max_size_now as usize, max_size_ever as usize)
	}
	fn get_channel_info(id: ParaId) -> Option<ChannelInfo> {
		let channels = RelevantMessagingState::<T>::get()?.egress_channels;
		let index = channels.binary_search_by_key(&id, |item| item.0).ok()?;
		let info = ChannelInfo {
			max_capacity: channels[index].1.max_capacity,
			max_total_size: channels[index].1.max_total_size,
			max_message_size: channels[index].1.max_message_size,
			msg_count: channels[index].1.msg_count,
			total_size: channels[index].1.total_size,
		};
		Some(info)
	}
}
impl<T: Config> Pallet<T> {
	/// Updates inherent data to only contain messages that weren't already processed
	/// by the runtime based on last relay chain block number.
	///
	/// This method doesn't check for mqc heads mismatch.
	fn drop_processed_messages_from_inherent(para_inherent: &mut ParachainInherentData) {
		let ParachainInherentData { downward_messages, horizontal_messages, .. } = para_inherent;
		// Last relay chain block number. Any message with sent-at block number less
		// than or equal to this value is assumed to be processed previously.
		let last_relay_block_number = LastRelayChainBlockNumber::<T>::get();
		// DMQ.
		let dmq_processed_num = downward_messages
			.iter()
			.take_while(|message| message.sent_at <= last_relay_block_number)
			.count();
		downward_messages.drain(..dmq_processed_num);
		// HRMP.
		for horizontal in horizontal_messages.values_mut() {
			let horizontal_processed_num = horizontal
				.iter()
				.take_while(|message| message.sent_at <= last_relay_block_number)
				.count();
			horizontal.drain(..horizontal_processed_num);
		}
		// If MQC doesn't match after dropping messages, the runtime will panic when creating
		// inherent.
	}
	/// Enqueue all inbound downward messages relayed by the collator into the MQ pallet.
	///
	/// Checks if the sequence of the messages is valid, dispatches them and communicates the
	/// number of processed messages to the collator via a storage update.
	///
	/// # Panics
	///
	/// If it turns out that after processing all messages the Message Queue Chain
	/// hash doesn't match the expected.
	fn enqueue_inbound_downward_messages(
		expected_dmq_mqc_head: relay_chain::Hash,
		downward_messages: Vec<InboundDownwardMessage>,
	) -> Weight {
		let dm_count = downward_messages.len() as u32;
		let mut dmq_head = <LastDmqMqcHead<T>>::get();
		let weight_used = T::WeightInfo::enqueue_inbound_downward_messages(dm_count);
		if dm_count != 0 {
			Self::deposit_event(Event::DownwardMessagesReceived { count: dm_count });
			// Eagerly update the MQC head hash:
			for m in &downward_messages {
				dmq_head.extend_downward(m);
			}
			let bounded = downward_messages
				.iter()
				// Note: we are not using `.defensive()` here since that prints the whole value to
				// console. In case that the message is too long, this clogs up the log quite badly.
				.filter_map(|m| match BoundedSlice::try_from(&m.msg[..]) {
					Ok(bounded) => Some(bounded),
					Err(_) => {
						defensive!("Inbound Downward message was too long; dropping");
						None
					},
				});
			T::DmpQueue::handle_messages(bounded);
			<LastDmqMqcHead<T>>::put(&dmq_head);
			Self::deposit_event(Event::DownwardMessagesProcessed {
				weight_used,
				dmq_head: dmq_head.head(),
			});
		}
		// After hashing each message in the message queue chain submitted by the collator, we
		// should arrive to the MQC head provided by the relay chain.
		//
		// A mismatch means that at least some of the submitted messages were altered, omitted or
		// added improperly.
		assert_eq!(dmq_head.head(), expected_dmq_mqc_head);
		ProcessedDownwardMessages::<T>::put(dm_count);
		weight_used
	}
	/// Process all inbound horizontal messages relayed by the collator.
	///
	/// This is similar to [`enqueue_inbound_downward_messages`], but works with multiple inbound
	/// channels. It immediately dispatches signals and queues all other XCMs. Blob messages are
	/// ignored.
	///
	/// **Panics** if either any of horizontal messages submitted by the collator was sent from
	///            a para which has no open channel to this parachain or if after processing
	///            messages across all inbound channels MQCs were obtained which do not
	///            correspond to the ones found on the relay-chain.
	fn enqueue_inbound_horizontal_messages(
		ingress_channels: &[(ParaId, cumulus_primitives_core::AbridgedHrmpChannel)],
		horizontal_messages: BTreeMap<ParaId, Vec<InboundHrmpMessage>>,
		relay_parent_number: relay_chain::BlockNumber,
	) -> Weight {
		// First, check that all submitted messages are sent from channels that exist. The
		// channel exists if its MQC head is present in `vfp.hrmp_mqc_heads`.
		for sender in horizontal_messages.keys() {
			// A violation of the assertion below indicates that one of the messages submitted
			// by the collator was sent from a sender that doesn't have a channel opened to
			// this parachain, according to the relay-parent state.
			assert!(ingress_channels.binary_search_by_key(sender, |&(s, _)| s).is_ok(),);
		}
		// Second, prepare horizontal messages for a more convenient processing:
		//
		// instead of a mapping from a para to a list of inbound HRMP messages, we will have a
		// list of tuples `(sender, message)` first ordered by `sent_at` (the relay chain block
		// number in which the message hit the relay-chain) and second ordered by para id
		// ascending.
		//
		// The messages will be dispatched in this order.
		let mut horizontal_messages = horizontal_messages
			.into_iter()
			.flat_map(|(sender, channel_contents)| {
				channel_contents.into_iter().map(move |message| (sender, message))
			})
			.collect::<Vec<_>>();
		horizontal_messages.sort_by(|a, b| {
			// first sort by sent-at and then by the para id
			match a.1.sent_at.cmp(&b.1.sent_at) {
				cmp::Ordering::Equal => a.0.cmp(&b.0),
				ord => ord,
			}
		});
		let last_mqc_heads = <LastHrmpMqcHeads<T>>::get();
		let mut running_mqc_heads = BTreeMap::new();
		let mut hrmp_watermark = None;
		{
			for (sender, ref horizontal_message) in &horizontal_messages {
				if hrmp_watermark.map(|w| w < horizontal_message.sent_at).unwrap_or(true) {
					hrmp_watermark = Some(horizontal_message.sent_at);
				}
				running_mqc_heads
					.entry(sender)
					.or_insert_with(|| last_mqc_heads.get(sender).cloned().unwrap_or_default())
					.extend_hrmp(horizontal_message);
			}
		}
		let message_iter = horizontal_messages
			.iter()
			.map(|&(sender, ref message)| (sender, message.sent_at, &message.data[..]));
		let max_weight =
			<ReservedXcmpWeightOverride<T>>::get().unwrap_or_else(T::ReservedXcmpWeight::get);
		let weight_used = T::XcmpMessageHandler::handle_xcmp_messages(message_iter, max_weight);
		// Check that the MQC heads for each channel provided by the relay chain match the MQC
		// heads we have after processing all incoming messages.
		//
		// Along the way we also carry over the relevant entries from the `last_mqc_heads` to
		// `running_mqc_heads`. Otherwise, in a block where no messages were sent in a channel
		// it won't get into next block's `last_mqc_heads` and thus will be all zeros, which
		// would corrupt the message queue chain.
		for (sender, channel) in ingress_channels {
			let cur_head = running_mqc_heads
				.entry(sender)
				.or_insert_with(|| last_mqc_heads.get(sender).cloned().unwrap_or_default())
				.head();
			let target_head = channel.mqc_head.unwrap_or_default();
			assert!(cur_head == target_head);
		}
		<LastHrmpMqcHeads<T>>::put(running_mqc_heads);
		// If we processed at least one message, then advance watermark to that location or if there
		// were no messages, set it to the block number of the relay parent.
		HrmpWatermark::<T>::put(hrmp_watermark.unwrap_or(relay_parent_number));
		weight_used
	}
	/// Drop blocks from the unincluded segment with respect to the latest parachain head.
	fn maybe_drop_included_ancestors(
		relay_state_proof: &RelayChainStateProof,
		capacity: consensus_hook::UnincludedSegmentCapacity,
	) -> Weight {
		let mut weight_used = Weight::zero();
		// If the unincluded segment length is nonzero, then the parachain head must be present.
		let para_head =
			relay_state_proof.read_included_para_head().ok().map(|h| T::Hashing::hash(&h.0));
		let unincluded_segment_len = <UnincludedSegment<T>>::decode_len().unwrap_or(0);
		weight_used += T::DbWeight::get().reads(1);
		// Clean up unincluded segment if nonempty.
		let included_head = match (para_head, capacity.is_expecting_included_parent()) {
			(Some(h), true) => {
				assert_eq!(
					h,
					frame_system::Pallet::<T>::parent_hash(),
					"expected parent to be included"
				);
				h
			},
			(Some(h), false) => h,
			(None, true) => {
				// All this logic is essentially a workaround to support collators which
				// might still not provide the included block with the state proof.
				frame_system::Pallet::<T>::parent_hash()
			},
			(None, false) => panic!("included head not present in relay storage proof"),
		};
		let new_len = {
			let para_head_hash = included_head;
			let dropped: Vec<Ancestor<T::Hash>> = <UnincludedSegment<T>>::mutate(|chain| {
				// Drop everything up to (inclusive) the block with an included para head, if
				// present.
				let idx = chain
					.iter()
					.position(|block| {
						let head_hash = block
							.para_head_hash()
							.expect("para head hash is updated during block initialization; qed");
						head_hash == &para_head_hash
					})
					.map_or(0, |idx| idx + 1); // inclusive.
				chain.drain(..idx).collect()
			});
			weight_used += T::DbWeight::get().reads_writes(1, 1);
			let new_len = unincluded_segment_len - dropped.len();
			if !dropped.is_empty() {
				<AggregatedUnincludedSegment<T>>::mutate(|agg| {
					let agg = agg.as_mut().expect(
						"dropped part of the segment wasn't empty, hence value exists; qed",
					);
					for block in dropped {
						agg.subtract(&block);
					}
				});
				weight_used += T::DbWeight::get().reads_writes(1, 1);
			}
			new_len as u32
		};
		// Current block validity check: ensure there is space in the unincluded segment.
		//
		// If this fails, the parachain needs to wait for ancestors to be included before
		// a new block is allowed.
		assert!(new_len < capacity.get(), "no space left for the block in the unincluded segment");
		weight_used
	}
	/// This adjusts the `RelevantMessagingState` according to the bandwidth limits in the
	/// unincluded segment.
	//
	// Reads: 2
	// Writes: 1
	fn adjust_egress_bandwidth_limits() {
		let unincluded_segment = match AggregatedUnincludedSegment::<T>::get() {
			None => return,
			Some(s) => s,
		};
		<RelevantMessagingState<T>>::mutate(|messaging_state| {
			let messaging_state = match messaging_state {
				None => return,
				Some(s) => s,
			};
			let used_bandwidth = unincluded_segment.used_bandwidth();
			let channels = &mut messaging_state.egress_channels;
			for (para_id, used) in used_bandwidth.hrmp_outgoing.iter() {
				let i = match channels.binary_search_by_key(para_id, |item| item.0) {
					Ok(i) => i,
					Err(_) => continue, // indicates channel closed.
				};
				let c = &mut channels[i].1;
				c.total_size = (c.total_size + used.total_bytes).min(c.max_total_size);
				c.msg_count = (c.msg_count + used.msg_count).min(c.max_capacity);
			}
			let upward_capacity = &mut messaging_state.relay_dispatch_queue_remaining_capacity;
			upward_capacity.remaining_count =
				upward_capacity.remaining_count.saturating_sub(used_bandwidth.ump_msg_count);
			upward_capacity.remaining_size =
				upward_capacity.remaining_size.saturating_sub(used_bandwidth.ump_total_bytes);
		});
	}
	/// Put a new validation function into a particular location where polkadot
	/// monitors for updates. Calling this function notifies polkadot that a new
	/// upgrade has been scheduled.
	fn notify_polkadot_of_pending_upgrade(code: &[u8]) {
		NewValidationCode::<T>::put(code);
		<DidSetValidationCode<T>>::put(true);
	}
	/// The maximum code size permitted, in bytes.
	///
	/// Returns `None` if the relay chain parachain host configuration hasn't been submitted yet.
	pub fn max_code_size() -> Option<u32> {
		<HostConfiguration<T>>::get().map(|cfg| cfg.max_code_size)
	}
	/// The implementation of the runtime upgrade functionality for parachains.
	pub fn schedule_code_upgrade(validation_function: Vec<u8>) -> DispatchResult {
		// Ensure that `ValidationData` exists. We do not care about the validation data per se,
		// but we do care about the [`UpgradeRestrictionSignal`] which arrives with the same
		// inherent.
		ensure!(<ValidationData<T>>::exists(), Error::<T>::ValidationDataNotAvailable,);
		ensure!(<UpgradeRestrictionSignal<T>>::get().is_none(), Error::<T>::ProhibitedByPolkadot);
		ensure!(!<PendingValidationCode<T>>::exists(), Error::<T>::OverlappingUpgrades);
		let cfg = HostConfiguration::<T>::get().ok_or(Error::<T>::HostConfigurationNotAvailable)?;
		ensure!(validation_function.len() <= cfg.max_code_size as usize, Error::<T>::TooBig);
		// When a code upgrade is scheduled, it has to be applied in two
		// places, synchronized: both polkadot and the individual parachain
		// have to upgrade on the same relay chain block.
		//
		// `notify_polkadot_of_pending_upgrade` notifies polkadot; the `PendingValidationCode`
		// storage keeps track locally for the parachain upgrade, which will
		// be applied later: when the relay-chain communicates go-ahead signal to us.
		Self::notify_polkadot_of_pending_upgrade(&validation_function);
		<PendingValidationCode<T>>::put(validation_function);
		Self::deposit_event(Event::ValidationFunctionStored);
		Ok(())
	}
	/// Returns the [`CollationInfo`] of the current active block.
	///
	/// The given `header` is the header of the built block we are collecting the collation info
	/// for.
	///
	/// This is expected to be used by the
	/// [`CollectCollationInfo`](cumulus_primitives_core::CollectCollationInfo) runtime api.
	pub fn collect_collation_info(header: &HeaderFor<T>) -> CollationInfo {
		CollationInfo {
			hrmp_watermark: HrmpWatermark::<T>::get(),
			horizontal_messages: HrmpOutboundMessages::<T>::get(),
			upward_messages: UpwardMessages::<T>::get(),
			processed_downward_messages: ProcessedDownwardMessages::<T>::get(),
			new_validation_code: NewValidationCode::<T>::get().map(Into::into),
			// Check if there is a custom header that will also be returned by the validation phase.
			// If so, we need to also return it here.
			head_data: CustomValidationHeadData::<T>::get()
				.map_or_else(|| header.encode(), |v| v)
				.into(),
		}
	}
	/// Set a custom head data that should be returned as result of `validate_block`.
	///
	/// This will overwrite the head data that is returned as result of `validate_block` while
	/// validating a `PoV` on the relay chain. Normally the head data that is being returned
	/// by `validate_block` is the header of the block that is validated, thus it can be
	/// enacted as the new best block. However, for features like forking it can be useful
	/// to overwrite the head data with a custom header.
	///
	/// # Attention
	///
	/// This should only be used when you are sure what you are doing as this can brick
	/// your Parachain.
	pub fn set_custom_validation_head_data(head_data: Vec<u8>) {
		CustomValidationHeadData::<T>::put(head_data);
	}
	/// Open HRMP channel for using it in benchmarks or tests.
	///
	/// The caller assumes that the pallet will accept regular outbound message to the sibling
	/// `target_parachain` after this call. No other assumptions are made.
	#[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
	pub fn open_outbound_hrmp_channel_for_benchmarks_or_tests(target_parachain: ParaId) {
		RelevantMessagingState::<T>::put(MessagingStateSnapshot {
			dmq_mqc_head: Default::default(),
			relay_dispatch_queue_remaining_capacity: Default::default(),
			ingress_channels: Default::default(),
			egress_channels: vec![(
				target_parachain,
				cumulus_primitives_core::AbridgedHrmpChannel {
					max_capacity: 10,
					max_total_size: 10_000_000_u32,
					max_message_size: 10_000_000_u32,
					msg_count: 5,
					total_size: 5_000_000_u32,
					mqc_head: None,
				},
			)],
		})
	}
	/// Open HRMP channel for using it in benchmarks or tests.
	///
	/// The caller assumes that the pallet will accept regular outbound message to the sibling
	/// `target_parachain` after this call. No other assumptions are made.
	#[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
	pub fn open_custom_outbound_hrmp_channel_for_benchmarks_or_tests(
		target_parachain: ParaId,
		channel: cumulus_primitives_core::AbridgedHrmpChannel,
	) {
		RelevantMessagingState::<T>::put(MessagingStateSnapshot {
			dmq_mqc_head: Default::default(),
			relay_dispatch_queue_remaining_capacity: Default::default(),
			ingress_channels: Default::default(),
			egress_channels: vec![(target_parachain, channel)],
		})
	}
	/// Prepare/insert relevant data for `schedule_code_upgrade` for benchmarks.
	#[cfg(feature = "runtime-benchmarks")]
	pub fn initialize_for_set_code_benchmark(max_code_size: u32) {
		// insert dummy ValidationData
		let vfp = PersistedValidationData {
			parent_head: polkadot_parachain_primitives::primitives::HeadData(Default::default()),
			relay_parent_number: 1,
			relay_parent_storage_root: Default::default(),
			max_pov_size: 1_000,
		};
		<ValidationData<T>>::put(&vfp);
		// insert dummy HostConfiguration with
		let host_config = AbridgedHostConfiguration {
			max_code_size,
			max_head_data_size: 32 * 1024,
			max_upward_queue_count: 8,
			max_upward_queue_size: 1024 * 1024,
			max_upward_message_size: 4 * 1024,
			max_upward_message_num_per_candidate: 2,
			hrmp_max_message_num_per_candidate: 2,
			validation_upgrade_cooldown: 2,
			validation_upgrade_delay: 2,
			async_backing_params: relay_chain::AsyncBackingParams {
				allowed_ancestry_len: 0,
				max_candidate_depth: 0,
			},
		};
		<HostConfiguration<T>>::put(host_config);
	}
}
/// Type that implements `SetCode`.
pub struct ParachainSetCode<T>(core::marker::PhantomData<T>);
impl<T: Config> frame_system::SetCode<T> for ParachainSetCode<T> {
	fn set_code(code: Vec<u8>) -> DispatchResult {
		Pallet::<T>::schedule_code_upgrade(code)
	}
}
impl<T: Config> Pallet<T> {
	/// Puts a message in the `PendingUpwardMessages` storage item.
	/// The message will be later sent in `on_finalize`.
	/// Checks host configuration to see if message is too big.
	/// Increases the delivery fee factor if the queue is sufficiently (see
	/// [`ump_constants::THRESHOLD_FACTOR`]) congested.
	pub fn send_upward_message(message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
		let message_len = message.len();
		// Check if the message fits into the relay-chain constraints.
		//
		// Note, that we are using `host_configuration` here which may be from the previous
		// block, in case this is called from `on_initialize`, i.e. before the inherent with fresh
		// data is submitted.
		//
		// That shouldn't be a problem since this is a preliminary check and the actual check would
		// be performed just before submitting the message from the candidate, and it already can
		// happen that during the time the message is buffered for sending the relay-chain setting
		// may change so that the message is no longer valid.
		//
		// However, changing this setting is expected to be rare.
		if let Some(cfg) = HostConfiguration::<T>::get() {
			if message_len > cfg.max_upward_message_size as usize {
				return Err(MessageSendError::TooBig)
			}
			let threshold =
				cfg.max_upward_queue_size.saturating_div(ump_constants::THRESHOLD_FACTOR);
			// We check the threshold against total size and not number of messages since messages
			// could be big or small.
			<PendingUpwardMessages<T>>::append(message.clone());
			let pending_messages = PendingUpwardMessages::<T>::get();
			let total_size: usize = pending_messages.iter().map(UpwardMessage::len).sum();
			if total_size > threshold as usize {
				// We increase the fee factor by a factor based on the new message's size in KB
				let message_size_factor = FixedU128::from((message_len / 1024) as u128)
					.saturating_mul(ump_constants::MESSAGE_SIZE_FEE_BASE);
				Self::increase_fee_factor((), message_size_factor);
			}
		} else {
			// This storage field should carry over from the previous block. So if it's None
			// then it must be that this is an edge-case where a message is attempted to be
			// sent at the first block.
			//
			// Let's pass this message through. I think it's not unreasonable to expect that
			// the message is not huge and it comes through, but if it doesn't it can be
			// returned back to the sender.
			//
			// Thus fall through here.
			<PendingUpwardMessages<T>>::append(message.clone());
		};
		// The relay ump does not use using_encoded
		// We apply the same this to use the same hash
		let hash = sp_io::hashing::blake2_256(&message);
		Self::deposit_event(Event::UpwardMessageSent { message_hash: Some(hash) });
		Ok((0, hash))
	}
	/// Get the relay chain block number which was used as an anchor for the last block in this
	/// chain.
	pub fn last_relay_block_number() -> RelayChainBlockNumber {
		LastRelayChainBlockNumber::<T>::get()
	}
}
impl<T: Config> UpwardMessageSender for Pallet<T> {
	fn send_upward_message(message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
		Self::send_upward_message(message)
	}
}
impl<T: Config> InspectMessageQueues for Pallet<T> {
	fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
		use xcm::prelude::*;
		let messages: Vec<VersionedXcm<()>> = PendingUpwardMessages::<T>::get()
			.iter()
			.map(|encoded_message| VersionedXcm::<()>::decode(&mut &encoded_message[..]).unwrap())
			.collect();
		vec![(VersionedLocation::V4(Parent.into()), messages)]
	}
}
#[cfg(feature = "runtime-benchmarks")]
impl<T: Config> polkadot_runtime_common::xcm_sender::EnsureForParachain for Pallet<T> {
	fn ensure(para_id: ParaId) {
		if let ChannelStatus::Closed = Self::get_channel_status(para_id) {
			Self::open_outbound_hrmp_channel_for_benchmarks_or_tests(para_id)
		}
	}
}
/// Something that can check the inherents of a block.
#[deprecated(note = "This trait is deprecated and will be removed by September 2024. \
		Consider switching to `cumulus-pallet-parachain-system::ConsensusHook`")]
pub trait CheckInherents<Block: BlockT> {
	/// Check all inherents of the block.
	///
	/// This function gets passed all the extrinsics of the block, so it is up to the callee to
	/// identify the inherents. The `validation_data` can be used to access the
	fn check_inherents(
		block: &Block,
		validation_data: &RelayChainStateProof,
	) -> frame_support::inherent::CheckInherentsResult;
}
/// Struct that always returns `Ok` on inherents check, needed for backwards-compatibility.
#[doc(hidden)]
pub struct DummyCheckInherents<Block>(core::marker::PhantomData<Block>);
#[allow(deprecated)]
impl<Block: BlockT> CheckInherents<Block> for DummyCheckInherents<Block> {
	fn check_inherents(
		_: &Block,
		_: &RelayChainStateProof,
	) -> frame_support::inherent::CheckInherentsResult {
		sp_inherents::CheckInherentsResult::new()
	}
}
/// Something that should be informed about system related events.
///
/// This includes events like [`on_validation_data`](Self::on_validation_data) that is being
/// called when the parachain inherent is executed that contains the validation data.
/// Or like [`on_validation_code_applied`](Self::on_validation_code_applied) that is called
/// when the new validation is written to the state. This means that
/// from the next block the runtime is being using this new code.
#[impl_trait_for_tuples::impl_for_tuples(30)]
pub trait OnSystemEvent {
	/// Called in each blocks once when the validation data is set by the inherent.
	fn on_validation_data(data: &PersistedValidationData);
	/// Called when the validation code is being applied, aka from the next block on this is the new
	/// runtime.
	fn on_validation_code_applied();
}
/// Holds the most recent relay-parent state root and block number of the current parachain block.
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Default, RuntimeDebug)]
pub struct RelayChainState {
	/// Current relay chain height.
	pub number: relay_chain::BlockNumber,
	/// State root for current relay chain height.
	pub state_root: relay_chain::Hash,
}
/// This exposes the [`RelayChainState`] to other runtime modules.
///
/// Enables parachains to read relay chain state via state proofs.
pub trait RelaychainStateProvider {
	/// May be called by any runtime module to obtain the current state of the relay chain.
	///
	/// **NOTE**: This is not guaranteed to return monotonically increasing relay parents.
	fn current_relay_chain_state() -> RelayChainState;
	/// Utility function only to be used in benchmarking scenarios, to be implemented optionally,
	/// else a noop.
	///
	/// It allows for setting a custom RelayChainState.
	#[cfg(feature = "runtime-benchmarks")]
	fn set_current_relay_chain_state(_state: RelayChainState) {}
}
/// Implements [`BlockNumberProvider`] that returns relay chain block number fetched from validation
/// data.
///
/// When validation data is not available (e.g. within `on_initialize`), it will fallback to use
/// [`Pallet::last_relay_block_number()`].
///
/// **NOTE**: This has been deprecated, please use [`RelaychainDataProvider`]
#[deprecated = "Use `RelaychainDataProvider` instead"]
pub type RelaychainBlockNumberProvider<T> = RelaychainDataProvider<T>;
/// Implements [`BlockNumberProvider`] and [`RelaychainStateProvider`] that returns relevant relay
/// data fetched from validation data.
///
/// NOTE: When validation data is not available (e.g. within `on_initialize`):
///
/// - [`current_relay_chain_state`](Self::current_relay_chain_state): Will return the default value
///   of [`RelayChainState`].
/// - [`current_block_number`](Self::current_block_number): Will return
///   [`Pallet::last_relay_block_number()`].
pub struct RelaychainDataProvider<T>(core::marker::PhantomData<T>);
impl<T: Config> BlockNumberProvider for RelaychainDataProvider<T> {
	type BlockNumber = relay_chain::BlockNumber;
	fn current_block_number() -> relay_chain::BlockNumber {
		ValidationData::<T>::get()
			.map(|d| d.relay_parent_number)
			.unwrap_or_else(|| Pallet::<T>::last_relay_block_number())
	}
	#[cfg(feature = "runtime-benchmarks")]
	fn set_block_number(block: Self::BlockNumber) {
		let mut validation_data = ValidationData::<T>::get().unwrap_or_else(||
			// PersistedValidationData does not impl default in non-std
			PersistedValidationData {
				parent_head: vec![].into(),
				relay_parent_number: Default::default(),
				max_pov_size: Default::default(),
				relay_parent_storage_root: Default::default(),
			});
		validation_data.relay_parent_number = block;
		ValidationData::<T>::put(validation_data)
	}
}
impl<T: Config> RelaychainStateProvider for RelaychainDataProvider<T> {
	fn current_relay_chain_state() -> RelayChainState {
		ValidationData::<T>::get()
			.map(|d| RelayChainState {
				number: d.relay_parent_number,
				state_root: d.relay_parent_storage_root,
			})
			.unwrap_or_default()
	}
	#[cfg(feature = "runtime-benchmarks")]
	fn set_current_relay_chain_state(state: RelayChainState) {
		let mut validation_data = ValidationData::<T>::get().unwrap_or_else(||
			// PersistedValidationData does not impl default in non-std
			PersistedValidationData {
				parent_head: vec![].into(),
				relay_parent_number: Default::default(),
				max_pov_size: Default::default(),
				relay_parent_storage_root: Default::default(),
			});
		validation_data.relay_parent_number = state.number;
		validation_data.relay_parent_storage_root = state.state_root;
		ValidationData::<T>::put(validation_data)
	}
}