referrerpolicy=no-referrer-when-downgrade

polkadot_primitives/v9/
mod.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! `V9` Primitives.
18
19use alloc::{
20	collections::{BTreeMap, BTreeSet, VecDeque},
21	vec,
22	vec::{IntoIter, Vec},
23};
24
25use bitvec::{field::BitField, prelude::*, slice::BitSlice};
26
27use codec::{Decode, DecodeWithMemTracking, Encode};
28use scale_info::TypeInfo;
29
30use core::{
31	marker::PhantomData,
32	slice::{Iter, IterMut},
33};
34
35use sp_application_crypto::{ByteArray, KeyTypeId};
36use sp_arithmetic::{
37	traits::{BaseArithmetic, Saturating},
38	Perbill,
39};
40
41use bounded_collections::BoundedVec;
42use serde::{Deserialize, Serialize};
43use sp_core::{ConstU32, RuntimeDebug};
44use sp_inherents::InherentIdentifier;
45
46// ==========
47// PUBLIC RE-EXPORTS
48// ==========
49
50pub use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
51pub use sp_consensus_slots::Slot;
52pub use sp_runtime::traits::{AppVerify, BlakeTwo256, Hash as HashT, Header as HeaderT};
53pub use sp_staking::SessionIndex;
54
55// Export some core primitives.
56pub use polkadot_core_primitives::v2::{
57	AccountId, AccountIndex, AccountPublic, Balance, Block, BlockId, BlockNumber, CandidateHash,
58	ChainId, DownwardMessage, Hash, Header, InboundDownwardMessage, InboundHrmpMessage, Moment,
59	Nonce, OutboundHrmpMessage, Remark, Signature, UncheckedExtrinsic,
60};
61
62// Export some polkadot-parachain primitives
63pub use polkadot_parachain_primitives::primitives::{
64	HeadData, HorizontalMessages, HrmpChannelId, Id, Id as ParaId, UpwardMessage, UpwardMessages,
65	ValidationCode, ValidationCodeHash, LOWEST_PUBLIC_ID,
66};
67
68/// Signed data.
69mod signed;
70pub use signed::{EncodeAs, Signed, UncheckedSigned};
71
72pub mod async_backing;
73pub mod executor_params;
74pub mod slashing;
75
76pub use async_backing::AsyncBackingParams;
77pub use executor_params::{
78	ExecutorParam, ExecutorParamError, ExecutorParams, ExecutorParamsHash, ExecutorParamsPrepHash,
79};
80
81mod metrics;
82pub use metrics::{
83	metric_definitions, RuntimeMetricLabel, RuntimeMetricLabelValue, RuntimeMetricLabelValues,
84	RuntimeMetricLabels, RuntimeMetricOp, RuntimeMetricUpdate,
85};
86
87/// The key type ID for a collator key.
88pub const COLLATOR_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"coll");
89const LOG_TARGET: &str = "runtime::primitives";
90
91mod collator_app {
92	use sp_application_crypto::{app_crypto, sr25519};
93	app_crypto!(sr25519, super::COLLATOR_KEY_TYPE_ID);
94}
95
96/// Identity that collators use.
97pub type CollatorId = collator_app::Public;
98
99/// A Parachain collator keypair.
100#[cfg(feature = "std")]
101pub type CollatorPair = collator_app::Pair;
102
103/// Signature on candidate's block data by a collator.
104pub type CollatorSignature = collator_app::Signature;
105
106/// The key type ID for a parachain validator key.
107pub const PARACHAIN_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"para");
108
109mod validator_app {
110	use sp_application_crypto::{app_crypto, sr25519};
111	app_crypto!(sr25519, super::PARACHAIN_KEY_TYPE_ID);
112}
113
114/// Identity that parachain validators use when signing validation messages.
115///
116/// For now we assert that parachain validator set is exactly equivalent to the authority set, and
117/// so we define it to be the same type as `SessionKey`. In the future it may have different crypto.
118pub type ValidatorId = validator_app::Public;
119
120/// Trait required for type specific indices e.g. `ValidatorIndex` and `GroupIndex`
121pub trait TypeIndex {
122	/// Returns the index associated to this value.
123	fn type_index(&self) -> usize;
124}
125
126/// Index of the validator is used as a lightweight replacement of the `ValidatorId` when
127/// appropriate.
128#[derive(
129	Eq,
130	Ord,
131	PartialEq,
132	PartialOrd,
133	Copy,
134	Clone,
135	Encode,
136	Decode,
137	DecodeWithMemTracking,
138	TypeInfo,
139	RuntimeDebug,
140)]
141#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash))]
142pub struct ValidatorIndex(pub u32);
143
144/// Index of an availability chunk.
145///
146/// The underlying type is identical to `ValidatorIndex`, because
147/// the number of chunks will always be equal to the number of validators.
148/// However, the chunk index held by a validator may not always be equal to its `ValidatorIndex`, so
149/// we use a separate type to make code easier to read.
150#[derive(Eq, Ord, PartialEq, PartialOrd, Copy, Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
151#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash))]
152pub struct ChunkIndex(pub u32);
153
154impl From<ChunkIndex> for ValidatorIndex {
155	fn from(c_index: ChunkIndex) -> Self {
156		ValidatorIndex(c_index.0)
157	}
158}
159
160impl From<ValidatorIndex> for ChunkIndex {
161	fn from(v_index: ValidatorIndex) -> Self {
162		ChunkIndex(v_index.0)
163	}
164}
165
166impl From<u32> for ChunkIndex {
167	fn from(n: u32) -> Self {
168		ChunkIndex(n)
169	}
170}
171
172// We should really get https://github.com/paritytech/polkadot/issues/2403 going ..
173impl From<u32> for ValidatorIndex {
174	fn from(n: u32) -> Self {
175		ValidatorIndex(n)
176	}
177}
178
179impl TypeIndex for ValidatorIndex {
180	fn type_index(&self) -> usize {
181		self.0 as usize
182	}
183}
184
185sp_application_crypto::with_pair! {
186	/// A Parachain validator keypair.
187	pub type ValidatorPair = validator_app::Pair;
188}
189
190/// Signature with which parachain validators sign blocks.
191///
192/// For now we assert that parachain validator set is exactly equivalent to the authority set, and
193/// so we define it to be the same type as `SessionKey`. In the future it may have different crypto.
194pub type ValidatorSignature = validator_app::Signature;
195
196/// A declarations of storage keys where an external observer can find some interesting data.
197pub mod well_known_keys {
198	use super::{HrmpChannelId, Id, WellKnownKey};
199	use alloc::vec::Vec;
200	use codec::Encode as _;
201	use hex_literal::hex;
202	use sp_io::hashing::twox_64;
203
204	// A note on generating these magic values below:
205	//
206	// The `StorageValue`, such as `ACTIVE_CONFIG` was obtained by calling:
207	//
208	//     ActiveConfig::<T>::hashed_key()
209	//
210	// The `StorageMap` values require `prefix`, and for example for `hrmp_egress_channel_index`,
211	// it could be obtained like:
212	//
213	//     HrmpEgressChannelsIndex::<T>::prefix_hash();
214	//
215
216	/// The current epoch index.
217	///
218	/// The storage item should be access as a `u64` encoded value.
219	pub const EPOCH_INDEX: &[u8] =
220		&hex!["1cb6f36e027abb2091cfb5110ab5087f38316cbf8fa0da822a20ac1c55bf1be3"];
221
222	/// The current relay chain block randomness
223	///
224	/// The storage item should be accessed as a `schnorrkel::Randomness` encoded value.
225	pub const CURRENT_BLOCK_RANDOMNESS: &[u8] =
226		&hex!["1cb6f36e027abb2091cfb5110ab5087fd077dfdb8adb10f78f10a5df8742c545"];
227
228	/// The randomness for one epoch ago
229	///
230	/// The storage item should be accessed as a `schnorrkel::Randomness` encoded value.
231	pub const ONE_EPOCH_AGO_RANDOMNESS: &[u8] =
232		&hex!["1cb6f36e027abb2091cfb5110ab5087f7ce678799d3eff024253b90e84927cc6"];
233
234	/// The randomness for two epochs ago
235	///
236	/// The storage item should be accessed as a `schnorrkel::Randomness` encoded value.
237	pub const TWO_EPOCHS_AGO_RANDOMNESS: &[u8] =
238		&hex!["1cb6f36e027abb2091cfb5110ab5087f7a414cb008e0e61e46722aa60abdd672"];
239
240	/// The current slot number.
241	///
242	/// The storage entry should be accessed as a `Slot` encoded value.
243	pub const CURRENT_SLOT: &[u8] =
244		&hex!["1cb6f36e027abb2091cfb5110ab5087f06155b3cd9a8c9e5e9a23fd5dc13a5ed"];
245
246	/// The currently active host configuration.
247	///
248	/// The storage entry should be accessed as an `AbridgedHostConfiguration` encoded value.
249	pub const ACTIVE_CONFIG: &[u8] =
250		&hex!["06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385"];
251
252	/// The authorities for the current epoch.
253	///
254	/// The storage entry should be accessed as an `Vec<(AuthorityId, BabeAuthorityWeight)>` encoded
255	/// value.
256	pub const AUTHORITIES: &[u8] =
257		&hex!["1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d"];
258
259	/// The authorities for the next epoch.
260	///
261	/// The storage entry should be accessed as an `Vec<(AuthorityId, BabeAuthorityWeight)>` encoded
262	/// value.
263	pub const NEXT_AUTHORITIES: &[u8] =
264		&hex!["1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c"];
265
266	/// Hash of the committed head data for a given registered para.
267	///
268	/// The storage entry stores wrapped `HeadData(Vec<u8>)`.
269	pub fn para_head(para_id: Id) -> Vec<u8> {
270		let prefix = hex!["cd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c3"];
271
272		para_id.using_encoded(|para_id: &[u8]| {
273			prefix
274				.as_ref()
275				.iter()
276				.chain(twox_64(para_id).iter())
277				.chain(para_id.iter())
278				.cloned()
279				.collect()
280		})
281	}
282
283	/// The upward message dispatch queue for the given para id.
284	///
285	/// The storage entry stores a tuple of two values:
286	///
287	/// - `count: u32`, the number of messages currently in the queue for given para,
288	/// - `total_size: u32`, the total size of all messages in the queue.
289	#[deprecated = "Use `relay_dispatch_queue_remaining_capacity` instead"]
290	pub fn relay_dispatch_queue_size(para_id: Id) -> Vec<u8> {
291		let prefix = hex!["f5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e"];
292
293		para_id.using_encoded(|para_id: &[u8]| {
294			prefix
295				.as_ref()
296				.iter()
297				.chain(twox_64(para_id).iter())
298				.chain(para_id.iter())
299				.cloned()
300				.collect()
301		})
302	}
303
304	/// Type safe version of `relay_dispatch_queue_size`.
305	#[deprecated = "Use `relay_dispatch_queue_remaining_capacity` instead"]
306	pub fn relay_dispatch_queue_size_typed(para: Id) -> WellKnownKey<(u32, u32)> {
307		#[allow(deprecated)]
308		relay_dispatch_queue_size(para).into()
309	}
310
311	/// The upward message dispatch queue remaining capacity for the given para id.
312	///
313	/// The storage entry stores a tuple of two values:
314	///
315	/// - `count: u32`, the number of additional messages which may be enqueued for the given para,
316	/// - `total_size: u32`, the total size of additional messages which may be enqueued for the
317	/// given para.
318	pub fn relay_dispatch_queue_remaining_capacity(para_id: Id) -> WellKnownKey<(u32, u32)> {
319		(b":relay_dispatch_queue_remaining_capacity", para_id).encode().into()
320	}
321
322	/// The HRMP channel for the given identifier.
323	///
324	/// The storage entry should be accessed as an `AbridgedHrmpChannel` encoded value.
325	pub fn hrmp_channels(channel: HrmpChannelId) -> Vec<u8> {
326		let prefix = hex!["6a0da05ca59913bc38a8630590f2627cb6604cff828a6e3f579ca6c59ace013d"];
327
328		channel.using_encoded(|channel: &[u8]| {
329			prefix
330				.as_ref()
331				.iter()
332				.chain(twox_64(channel).iter())
333				.chain(channel.iter())
334				.cloned()
335				.collect()
336		})
337	}
338
339	/// The list of inbound channels for the given para.
340	///
341	/// The storage entry stores a `Vec<ParaId>`
342	pub fn hrmp_ingress_channel_index(para_id: Id) -> Vec<u8> {
343		let prefix = hex!["6a0da05ca59913bc38a8630590f2627c1d3719f5b0b12c7105c073c507445948"];
344
345		para_id.using_encoded(|para_id: &[u8]| {
346			prefix
347				.as_ref()
348				.iter()
349				.chain(twox_64(para_id).iter())
350				.chain(para_id.iter())
351				.cloned()
352				.collect()
353		})
354	}
355
356	/// The list of outbound channels for the given para.
357	///
358	/// The storage entry stores a `Vec<ParaId>`
359	pub fn hrmp_egress_channel_index(para_id: Id) -> Vec<u8> {
360		let prefix = hex!["6a0da05ca59913bc38a8630590f2627cf12b746dcf32e843354583c9702cc020"];
361
362		para_id.using_encoded(|para_id: &[u8]| {
363			prefix
364				.as_ref()
365				.iter()
366				.chain(twox_64(para_id).iter())
367				.chain(para_id.iter())
368				.cloned()
369				.collect()
370		})
371	}
372
373	/// The MQC head for the downward message queue of the given para. See more in the `Dmp` module.
374	///
375	/// The storage entry stores a `Hash`. This is polkadot hash which is at the moment
376	/// `blake2b-256`.
377	pub fn dmq_mqc_head(para_id: Id) -> Vec<u8> {
378		let prefix = hex!["63f78c98723ddc9073523ef3beefda0c4d7fefc408aac59dbfe80a72ac8e3ce5"];
379
380		para_id.using_encoded(|para_id: &[u8]| {
381			prefix
382				.as_ref()
383				.iter()
384				.chain(twox_64(para_id).iter())
385				.chain(para_id.iter())
386				.cloned()
387				.collect()
388		})
389	}
390
391	/// The signal that indicates whether the parachain should go-ahead with the proposed validation
392	/// code upgrade.
393	///
394	/// The storage entry stores a value of `UpgradeGoAhead` type.
395	pub fn upgrade_go_ahead_signal(para_id: Id) -> Vec<u8> {
396		let prefix = hex!["cd710b30bd2eab0352ddcc26417aa1949e94c040f5e73d9b7addd6cb603d15d3"];
397
398		para_id.using_encoded(|para_id: &[u8]| {
399			prefix
400				.as_ref()
401				.iter()
402				.chain(twox_64(para_id).iter())
403				.chain(para_id.iter())
404				.cloned()
405				.collect()
406		})
407	}
408
409	/// The signal that indicates whether the parachain is disallowed to signal an upgrade at this
410	/// relay-parent.
411	///
412	/// The storage entry stores a value of `UpgradeRestriction` type.
413	pub fn upgrade_restriction_signal(para_id: Id) -> Vec<u8> {
414		let prefix = hex!["cd710b30bd2eab0352ddcc26417aa194f27bbb460270642b5bcaf032ea04d56a"];
415
416		para_id.using_encoded(|para_id: &[u8]| {
417			prefix
418				.as_ref()
419				.iter()
420				.chain(twox_64(para_id).iter())
421				.chain(para_id.iter())
422				.cloned()
423				.collect()
424		})
425	}
426}
427
428/// Unique identifier for the Parachains Inherent
429pub const PARACHAINS_INHERENT_IDENTIFIER: InherentIdentifier = *b"parachn0";
430
431/// The key type ID for parachain assignment key.
432pub const ASSIGNMENT_KEY_TYPE_ID: KeyTypeId = KeyTypeId(*b"asgn");
433
434/// Compressed or not the wasm blob can never be less than 9 bytes.
435pub const MIN_CODE_SIZE: u32 = 9;
436
437/// Maximum compressed code size we support right now.
438/// At the moment we have runtime upgrade on chain, which restricts scalability severely. If we want
439/// to have bigger values, we should fix that first.
440///
441/// Used for:
442/// * initial genesis for the Parachains configuration
443/// * checking updates to this stored runtime configuration do not exceed this limit
444/// * when detecting a code decompression bomb in the client
445// NOTE: This value is used in the runtime so be careful when changing it.
446pub const MAX_CODE_SIZE: u32 = 3 * 1024 * 1024;
447
448/// Maximum head data size we support right now.
449///
450/// Used for:
451/// * initial genesis for the Parachains configuration
452/// * checking updates to this stored runtime configuration do not exceed this limit
453// NOTE: This value is used in the runtime so be careful when changing it.
454pub const MAX_HEAD_DATA_SIZE: u32 = 1 * 1024 * 1024;
455
456/// Maximum PoV size we support right now.
457///
458/// Used for:
459/// * initial genesis for the Parachains configuration
460/// * checking updates to this stored runtime configuration do not exceed this limit
461/// * when detecting a PoV decompression bomb in the client
462// NOTE: This value is used in the runtime so be careful when changing it.
463pub const MAX_POV_SIZE: u32 = 10 * 1024 * 1024;
464
465/// Default queue size we use for the on-demand order book.
466///
467/// Can be adjusted in configuration.
468pub const ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE: u32 = 10_000;
469
470/// Maximum for maximum queue size.
471///
472/// Setting `on_demand_queue_max_size` to a value higher than this is unsound. This is more a
473/// theoretical limit, just below enough what the target type supports, so comparisons are possible
474/// even with indices that are overflowing the underyling type.
475pub const ON_DEMAND_MAX_QUEUE_MAX_SIZE: u32 = 1_000_000_000;
476
477/// Backing votes threshold used from the host prior to runtime API version 6 and from the runtime
478/// prior to v9 configuration migration.
479pub const LEGACY_MIN_BACKING_VOTES: u32 = 2;
480
481/// Default value for `SchedulerParams.lookahead`
482pub const DEFAULT_SCHEDULING_LOOKAHEAD: u32 = 3;
483
484// The public key of a keypair used by a validator for determining assignments
485/// to approve included parachain candidates.
486mod assignment_app {
487	use sp_application_crypto::{app_crypto, sr25519};
488	app_crypto!(sr25519, super::ASSIGNMENT_KEY_TYPE_ID);
489}
490
491/// The public key of a keypair used by a validator for determining assignments
492/// to approve included parachain candidates.
493pub type AssignmentId = assignment_app::Public;
494
495sp_application_crypto::with_pair! {
496	/// The full keypair used by a validator for determining assignments to approve included
497	/// parachain candidates.
498	pub type AssignmentPair = assignment_app::Pair;
499}
500
501/// The index of the candidate in the list of candidates fully included as-of the block.
502pub type CandidateIndex = u32;
503
504/// The validation data provides information about how to create the inputs for validation of a
505/// candidate. This information is derived from the chain state and will vary from para to para,
506/// although some fields may be the same for every para.
507///
508/// Since this data is used to form inputs to the validation function, it needs to be persisted by
509/// the availability system to avoid dependence on availability of the relay-chain state.
510///
511/// Furthermore, the validation data acts as a way to authorize the additional data the collator
512/// needs to pass to the validation function. For example, the validation function can check whether
513/// the incoming messages (e.g. downward messages) were actually sent by using the data provided in
514/// the validation data using so called MQC heads.
515///
516/// Since the commitments of the validation function are checked by the relay-chain, secondary
517/// checkers can rely on the invariant that the relay-chain only includes para-blocks for which
518/// these checks have already been done. As such, there is no need for the validation data used to
519/// inform validators and collators about the checks the relay-chain will perform to be persisted by
520/// the availability system.
521///
522/// The `PersistedValidationData` should be relatively lightweight primarily because it is
523/// constructed during inclusion for each candidate and therefore lies on the critical path of
524/// inclusion.
525#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo, RuntimeDebug)]
526#[cfg_attr(feature = "std", derive(Default))]
527pub struct PersistedValidationData<H = Hash, N = BlockNumber> {
528	/// The parent head-data.
529	pub parent_head: HeadData,
530	/// The relay-chain block number this is in the context of.
531	pub relay_parent_number: N,
532	/// The relay-chain block storage root this is in the context of.
533	pub relay_parent_storage_root: H,
534	/// The maximum legal size of a POV block, in bytes.
535	pub max_pov_size: u32,
536}
537
538impl<H: Encode, N: Encode> PersistedValidationData<H, N> {
539	/// Compute the blake2-256 hash of the persisted validation data.
540	pub fn hash(&self) -> Hash {
541		BlakeTwo256::hash_of(self)
542	}
543}
544
545/// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation.
546#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo, RuntimeDebug)]
547#[cfg_attr(feature = "std", derive(Default, Hash))]
548pub struct CandidateCommitments<N = BlockNumber> {
549	/// Messages destined to be interpreted by the Relay chain itself.
550	pub upward_messages: UpwardMessages,
551	/// Horizontal messages sent by the parachain.
552	pub horizontal_messages: HorizontalMessages,
553	/// New validation code.
554	pub new_validation_code: Option<ValidationCode>,
555	/// The head-data produced as a result of execution.
556	pub head_data: HeadData,
557	/// The number of messages processed from the DMQ.
558	pub processed_downward_messages: u32,
559	/// The mark which specifies the block number up to which all inbound HRMP messages are
560	/// processed.
561	pub hrmp_watermark: N,
562}
563
564impl CandidateCommitments {
565	/// Compute the blake2-256 hash of the commitments.
566	pub fn hash(&self) -> Hash {
567		BlakeTwo256::hash_of(self)
568	}
569}
570
571/// A bitfield concerning availability of backed candidates.
572///
573/// Every bit refers to an availability core index.
574#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, RuntimeDebug, TypeInfo)]
575pub struct AvailabilityBitfield(pub BitVec<u8, bitvec::order::Lsb0>);
576
577impl From<BitVec<u8, bitvec::order::Lsb0>> for AvailabilityBitfield {
578	fn from(inner: BitVec<u8, bitvec::order::Lsb0>) -> Self {
579		AvailabilityBitfield(inner)
580	}
581}
582
583/// A signed compact statement, suitable to be sent to the chain.
584pub type SignedStatement = Signed<CompactStatement>;
585/// A signed compact statement, with signature not yet checked.
586pub type UncheckedSignedStatement = UncheckedSigned<CompactStatement>;
587
588/// A bitfield signed by a particular validator about the availability of pending candidates.
589pub type SignedAvailabilityBitfield = Signed<AvailabilityBitfield>;
590/// A signed bitfield with signature not yet checked.
591pub type UncheckedSignedAvailabilityBitfield = UncheckedSigned<AvailabilityBitfield>;
592
593/// A set of signed availability bitfields. Should be sorted by validator index, ascending.
594pub type SignedAvailabilityBitfields = Vec<SignedAvailabilityBitfield>;
595/// A set of unchecked signed availability bitfields. Should be sorted by validator index,
596/// ascending.
597pub type UncheckedSignedAvailabilityBitfields = Vec<UncheckedSignedAvailabilityBitfield>;
598
599/// Verify the backing of the given candidate.
600///
601/// Provide a lookup from the index of a validator within the group assigned to this para,
602/// as opposed to the index of the validator within the overall validator set, as well as
603/// the number of validators in the group.
604///
605/// Also provide the signing context.
606///
607/// Returns either an error, indicating that one of the signatures was invalid or that the index
608/// was out-of-bounds, or the number of signatures checked.
609pub fn check_candidate_backing<H: AsRef<[u8]> + Clone + Encode + core::fmt::Debug>(
610	candidate_hash: CandidateHash,
611	validity_votes: &[ValidityAttestation],
612	validator_indices: &BitSlice<u8, bitvec::order::Lsb0>,
613	signing_context: &SigningContext<H>,
614	group_len: usize,
615	validator_lookup: impl Fn(usize) -> Option<ValidatorId>,
616) -> Result<usize, ()> {
617	if validator_indices.len() != group_len {
618		log::debug!(
619			target: LOG_TARGET,
620			"Check candidate backing: indices mismatch: group_len = {} , indices_len = {}",
621			group_len,
622			validator_indices.len(),
623		);
624		return Err(())
625	}
626
627	if validity_votes.len() > group_len {
628		log::debug!(
629			target: LOG_TARGET,
630			"Check candidate backing: Too many votes, expected: {}, found: {}",
631			group_len,
632			validity_votes.len(),
633		);
634		return Err(())
635	}
636
637	let mut signed = 0;
638	for ((val_in_group_idx, _), attestation) in validator_indices
639		.iter()
640		.enumerate()
641		.filter(|(_, signed)| **signed)
642		.zip(validity_votes.iter())
643	{
644		let validator_id = validator_lookup(val_in_group_idx).ok_or(())?;
645		let payload = attestation.signed_payload(candidate_hash, signing_context);
646		let sig = attestation.signature();
647
648		if sig.verify(&payload[..], &validator_id) {
649			signed += 1;
650		} else {
651			log::debug!(
652				target: LOG_TARGET,
653				"Check candidate backing: Invalid signature. validator_id = {:?}, validator_index = {} ",
654				validator_id,
655				val_in_group_idx,
656			);
657			return Err(())
658		}
659	}
660
661	if signed != validity_votes.len() {
662		log::error!(
663			target: LOG_TARGET,
664			"Check candidate backing: Too many signatures, expected = {}, found = {}",
665			validity_votes.len(),
666			signed,
667		);
668		return Err(())
669	}
670
671	Ok(signed)
672}
673
674/// The unique (during session) index of a core.
675#[derive(
676	Encode,
677	Decode,
678	DecodeWithMemTracking,
679	Default,
680	PartialOrd,
681	Ord,
682	Eq,
683	PartialEq,
684	Clone,
685	Copy,
686	TypeInfo,
687	RuntimeDebug,
688)]
689#[cfg_attr(feature = "std", derive(Hash))]
690pub struct CoreIndex(pub u32);
691
692impl From<u32> for CoreIndex {
693	fn from(i: u32) -> CoreIndex {
694		CoreIndex(i)
695	}
696}
697
698impl TypeIndex for CoreIndex {
699	fn type_index(&self) -> usize {
700		self.0 as usize
701	}
702}
703
704/// The unique (during session) index of a validator group.
705#[derive(
706	Encode,
707	Decode,
708	DecodeWithMemTracking,
709	Default,
710	Clone,
711	Copy,
712	Debug,
713	PartialEq,
714	Eq,
715	TypeInfo,
716	PartialOrd,
717	Ord,
718)]
719#[cfg_attr(feature = "std", derive(Hash))]
720pub struct GroupIndex(pub u32);
721
722impl From<u32> for GroupIndex {
723	fn from(i: u32) -> GroupIndex {
724		GroupIndex(i)
725	}
726}
727
728impl TypeIndex for GroupIndex {
729	fn type_index(&self) -> usize {
730		self.0 as usize
731	}
732}
733
734/// A claim on authoring the next block for a given parathread (on-demand parachain).
735#[derive(Clone, Encode, Decode, TypeInfo, PartialEq, RuntimeDebug)]
736pub struct ParathreadClaim(pub Id, pub Option<CollatorId>);
737
738/// An entry tracking a claim to ensure it does not pass the maximum number of retries.
739#[derive(Clone, Encode, Decode, TypeInfo, PartialEq, RuntimeDebug)]
740pub struct ParathreadEntry {
741	/// The claim.
742	pub claim: ParathreadClaim,
743	/// Number of retries
744	pub retries: u32,
745}
746
747/// A helper data-type for tracking validator-group rotations.
748#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
749#[cfg_attr(feature = "std", derive(PartialEq))]
750pub struct GroupRotationInfo<N = BlockNumber> {
751	/// The block number where the session started.
752	pub session_start_block: N,
753	/// How often groups rotate. 0 means never.
754	pub group_rotation_frequency: N,
755	/// The current block number.
756	pub now: N,
757}
758
759impl GroupRotationInfo {
760	/// Returns the index of the group needed to validate the core at the given index, assuming
761	/// the given number of cores.
762	///
763	/// `core_index` should be less than `cores`, which is capped at `u32::max()`.
764	pub fn group_for_core(&self, core_index: CoreIndex, cores: usize) -> GroupIndex {
765		if self.group_rotation_frequency == 0 {
766			return GroupIndex(core_index.0)
767		}
768		if cores == 0 {
769			return GroupIndex(0)
770		}
771
772		let cores = core::cmp::min(cores, u32::MAX as usize);
773		let blocks_since_start = self.now.saturating_sub(self.session_start_block);
774		let rotations = blocks_since_start / self.group_rotation_frequency;
775
776		// g = c + r mod cores
777
778		let idx = (core_index.0 as usize + rotations as usize) % cores;
779		GroupIndex(idx as u32)
780	}
781
782	/// Returns the index of the group assigned to the given core. This does no checking or
783	/// whether the group index is in-bounds.
784	///
785	/// `core_index` should be less than `cores`, which is capped at `u32::max()`.
786	pub fn core_for_group(&self, group_index: GroupIndex, cores: usize) -> CoreIndex {
787		if self.group_rotation_frequency == 0 {
788			return CoreIndex(group_index.0)
789		}
790		if cores == 0 {
791			return CoreIndex(0)
792		}
793
794		let cores = core::cmp::min(cores, u32::MAX as usize);
795		let blocks_since_start = self.now.saturating_sub(self.session_start_block);
796		let rotations = blocks_since_start / self.group_rotation_frequency;
797		let rotations = rotations % cores as u32;
798
799		// g = c + r mod cores
800		// c = g - r mod cores
801		// x = x + cores mod cores
802		// c = (g + cores) - r mod cores
803
804		let idx = (group_index.0 as usize + cores - rotations as usize) % cores;
805		CoreIndex(idx as u32)
806	}
807
808	/// Create a new `GroupRotationInfo` with one further rotation applied.
809	pub fn bump_rotation(&self) -> Self {
810		GroupRotationInfo {
811			session_start_block: self.session_start_block,
812			group_rotation_frequency: self.group_rotation_frequency,
813			now: self.next_rotation_at(),
814		}
815	}
816}
817
818impl<N: Saturating + BaseArithmetic + Copy> GroupRotationInfo<N> {
819	/// Returns the block number of the next rotation after the current block. If the current block
820	/// is 10 and the rotation frequency is 5, this should return 15.
821	pub fn next_rotation_at(&self) -> N {
822		let cycle_once = self.now + self.group_rotation_frequency;
823		cycle_once -
824			(cycle_once.saturating_sub(self.session_start_block) % self.group_rotation_frequency)
825	}
826
827	/// Returns the block number of the last rotation before or including the current block. If the
828	/// current block is 10 and the rotation frequency is 5, this should return 10.
829	pub fn last_rotation_at(&self) -> N {
830		self.now -
831			(self.now.saturating_sub(self.session_start_block) % self.group_rotation_frequency)
832	}
833}
834
835/// Information about a core which is currently occupied.
836#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
837#[cfg_attr(feature = "std", derive(PartialEq))]
838pub struct ScheduledCore {
839	/// The ID of a para scheduled.
840	pub para_id: Id,
841	/// DEPRECATED: see: <https://github.com/paritytech/polkadot/issues/7575>
842	///
843	/// Will be removed in a future version.
844	pub collator: Option<CollatorId>,
845}
846
847/// An assumption being made about the state of an occupied core.
848#[derive(Clone, Copy, Encode, Decode, TypeInfo, RuntimeDebug)]
849#[cfg_attr(feature = "std", derive(PartialEq, Eq, Hash))]
850pub enum OccupiedCoreAssumption {
851	/// The candidate occupying the core was made available and included to free the core.
852	#[codec(index = 0)]
853	Included,
854	/// The candidate occupying the core timed out and freed the core without advancing the para.
855	#[codec(index = 1)]
856	TimedOut,
857	/// The core was not occupied to begin with.
858	#[codec(index = 2)]
859	Free,
860}
861
862/// A vote of approval on a candidate.
863#[derive(Clone, RuntimeDebug)]
864pub struct ApprovalVote(pub CandidateHash);
865
866impl ApprovalVote {
867	/// Yields the signing payload for this approval vote.
868	pub fn signing_payload(&self, session_index: SessionIndex) -> Vec<u8> {
869		const MAGIC: [u8; 4] = *b"APPR";
870
871		(MAGIC, &self.0, session_index).encode()
872	}
873}
874
875/// A vote of approval for multiple candidates.
876#[derive(Clone, RuntimeDebug)]
877pub struct ApprovalVoteMultipleCandidates<'a>(pub &'a [CandidateHash]);
878
879impl<'a> ApprovalVoteMultipleCandidates<'a> {
880	/// Yields the signing payload for this approval vote.
881	pub fn signing_payload(&self, session_index: SessionIndex) -> Vec<u8> {
882		const MAGIC: [u8; 4] = *b"APPR";
883		// Make this backwards compatible with `ApprovalVote` so if we have just on candidate the
884		// signature will look the same.
885		// This gives us the nice benefit that old nodes can still check signatures when len is 1
886		// and the new node can check the signature coming from old nodes.
887		if self.0.len() == 1 {
888			(MAGIC, self.0.first().expect("QED: we just checked"), session_index).encode()
889		} else {
890			(MAGIC, &self.0, session_index).encode()
891		}
892	}
893}
894
895/// Approval voting configuration parameters
896#[derive(
897	RuntimeDebug,
898	Copy,
899	Clone,
900	PartialEq,
901	Encode,
902	Decode,
903	DecodeWithMemTracking,
904	TypeInfo,
905	serde::Serialize,
906	serde::Deserialize,
907)]
908pub struct ApprovalVotingParams {
909	/// The maximum number of candidates `approval-voting` can vote for with
910	/// a single signatures.
911	///
912	/// Setting it to 1, means we send the approval as soon as we have it available.
913	pub max_approval_coalesce_count: u32,
914}
915
916impl Default for ApprovalVotingParams {
917	fn default() -> Self {
918		Self { max_approval_coalesce_count: 1 }
919	}
920}
921
922/// Custom validity errors used in Polkadot while validating transactions.
923#[repr(u8)]
924pub enum ValidityError {
925	/// The Ethereum signature is invalid.
926	InvalidEthereumSignature = 0,
927	/// The signer has no claim.
928	SignerHasNoClaim = 1,
929	/// No permission to execute the call.
930	NoPermission = 2,
931	/// An invalid statement was made for a claim.
932	InvalidStatement = 3,
933}
934
935impl From<ValidityError> for u8 {
936	fn from(err: ValidityError) -> Self {
937		err as u8
938	}
939}
940
941/// Abridged version of `HostConfiguration` (from the `Configuration` parachains host runtime
942/// module) meant to be used by a parachain or PDK such as cumulus.
943#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
944#[cfg_attr(feature = "std", derive(PartialEq))]
945pub struct AbridgedHostConfiguration {
946	/// The maximum validation code size, in bytes.
947	pub max_code_size: u32,
948	/// The maximum head-data size, in bytes.
949	pub max_head_data_size: u32,
950	/// Total number of individual messages allowed in the parachain -> relay-chain message queue.
951	pub max_upward_queue_count: u32,
952	/// Total size of messages allowed in the parachain -> relay-chain message queue before which
953	/// no further messages may be added to it. If it exceeds this then the queue may contain only
954	/// a single message.
955	pub max_upward_queue_size: u32,
956	/// The maximum size of an upward message that can be sent by a candidate.
957	///
958	/// This parameter affects the size upper bound of the `CandidateCommitments`.
959	pub max_upward_message_size: u32,
960	/// The maximum number of messages that a candidate can contain.
961	///
962	/// This parameter affects the size upper bound of the `CandidateCommitments`.
963	pub max_upward_message_num_per_candidate: u32,
964	/// The maximum number of outbound HRMP messages can be sent by a candidate.
965	///
966	/// This parameter affects the upper bound of size of `CandidateCommitments`.
967	pub hrmp_max_message_num_per_candidate: u32,
968	/// The minimum period, in blocks, between which parachains can update their validation code.
969	pub validation_upgrade_cooldown: BlockNumber,
970	/// The delay, in blocks, before a validation upgrade is applied.
971	pub validation_upgrade_delay: BlockNumber,
972	/// Asynchronous backing parameters.
973	pub async_backing_params: AsyncBackingParams,
974}
975
976/// Abridged version of `HrmpChannel` (from the `Hrmp` parachains host runtime module) meant to be
977/// used by a parachain or PDK such as cumulus.
978#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
979#[cfg_attr(feature = "std", derive(Default, PartialEq))]
980pub struct AbridgedHrmpChannel {
981	/// The maximum number of messages that can be pending in the channel at once.
982	pub max_capacity: u32,
983	/// The maximum total size of the messages that can be pending in the channel at once.
984	pub max_total_size: u32,
985	/// The maximum message size that could be put into the channel.
986	pub max_message_size: u32,
987	/// The current number of messages pending in the channel.
988	/// Invariant: should be less or equal to `max_capacity`.s`.
989	pub msg_count: u32,
990	/// The total size in bytes of all message payloads in the channel.
991	/// Invariant: should be less or equal to `max_total_size`.
992	pub total_size: u32,
993	/// A head of the Message Queue Chain for this channel. Each link in this chain has a form:
994	/// `(prev_head, B, H(M))`, where
995	/// - `prev_head`: is the previous value of `mqc_head` or zero if none.
996	/// - `B`: is the [relay-chain] block number in which a message was appended
997	/// - `H(M)`: is the hash of the message being appended.
998	/// This value is initialized to a special value that consists of all zeroes which indicates
999	/// that no messages were previously added.
1000	pub mqc_head: Option<Hash>,
1001}
1002
1003/// A possible upgrade restriction that prevents a parachain from performing an upgrade.
1004#[derive(Copy, Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)]
1005pub enum UpgradeRestriction {
1006	/// There is an upgrade restriction and there are no details about its specifics nor how long
1007	/// it could last.
1008	#[codec(index = 0)]
1009	Present,
1010}
1011
1012/// A struct that the relay-chain communicates to a parachain indicating what course of action the
1013/// parachain should take in the coordinated parachain validation code upgrade process.
1014///
1015/// This data type appears in the last step of the upgrade process. After the parachain observes it
1016/// and reacts to it the upgrade process concludes.
1017#[derive(Copy, Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)]
1018pub enum UpgradeGoAhead {
1019	/// Abort the upgrade process. There is something wrong with the validation code previously
1020	/// submitted by the parachain. This variant can also be used to prevent upgrades by the
1021	/// governance should an emergency emerge.
1022	///
1023	/// The expected reaction on this variant is that the parachain will admit this message and
1024	/// remove all the data about the pending upgrade. Depending on the nature of the problem (to
1025	/// be examined offchain for now), it can try to send another validation code or just retry
1026	/// later.
1027	#[codec(index = 0)]
1028	Abort,
1029	/// Apply the pending code change. The parablock that is built on a relay-parent that is
1030	/// descendant of the relay-parent where the parachain observed this signal must use the
1031	/// upgraded validation code.
1032	#[codec(index = 1)]
1033	GoAhead,
1034}
1035
1036/// Consensus engine id for polkadot v1 consensus engine.
1037pub const POLKADOT_ENGINE_ID: sp_runtime::ConsensusEngineId = *b"POL1";
1038
1039/// A consensus log item for polkadot validation. To be used with [`POLKADOT_ENGINE_ID`].
1040#[derive(Decode, Encode, Clone, PartialEq, Eq)]
1041pub enum ConsensusLog {
1042	/// A parachain upgraded its code.
1043	#[codec(index = 1)]
1044	ParaUpgradeCode(Id, ValidationCodeHash),
1045	/// A parachain scheduled a code upgrade.
1046	#[codec(index = 2)]
1047	ParaScheduleUpgradeCode(Id, ValidationCodeHash, BlockNumber),
1048	/// Governance requests to auto-approve every candidate included up to the given block
1049	/// number in the current chain, inclusive.
1050	#[codec(index = 3)]
1051	ForceApprove(BlockNumber),
1052	/// A signal to revert the block number in the same chain as the
1053	/// header this digest is part of and all of its descendants.
1054	///
1055	/// It is a no-op for a block to contain a revert digest targeting
1056	/// its own number or a higher number.
1057	///
1058	/// In practice, these are issued when on-chain logic has detected an
1059	/// invalid parachain block within its own chain, due to a dispute.
1060	#[codec(index = 4)]
1061	Revert(BlockNumber),
1062}
1063
1064impl ConsensusLog {
1065	/// Attempt to convert a reference to a generic digest item into a consensus log.
1066	pub fn from_digest_item(
1067		digest_item: &sp_runtime::DigestItem,
1068	) -> Result<Option<Self>, codec::Error> {
1069		match digest_item {
1070			sp_runtime::DigestItem::Consensus(id, encoded) if id == &POLKADOT_ENGINE_ID =>
1071				Ok(Some(Self::decode(&mut &encoded[..])?)),
1072			_ => Ok(None),
1073		}
1074	}
1075}
1076
1077impl From<ConsensusLog> for sp_runtime::DigestItem {
1078	fn from(c: ConsensusLog) -> sp_runtime::DigestItem {
1079		Self::Consensus(POLKADOT_ENGINE_ID, c.encode())
1080	}
1081}
1082
1083/// A statement about a candidate, to be used within the dispute resolution process.
1084///
1085/// Statements are either in favor of the candidate's validity or against it.
1086#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, RuntimeDebug, TypeInfo)]
1087pub enum DisputeStatement {
1088	/// A valid statement, of the given kind.
1089	#[codec(index = 0)]
1090	Valid(ValidDisputeStatementKind),
1091	/// An invalid statement, of the given kind.
1092	#[codec(index = 1)]
1093	Invalid(InvalidDisputeStatementKind),
1094}
1095
1096impl DisputeStatement {
1097	/// Get the payload data for this type of dispute statement.
1098	///
1099	/// Returns Error if the candidate_hash is not included in the list of signed
1100	/// candidate from ApprovalCheckingMultipleCandidate.
1101	pub fn payload_data(
1102		&self,
1103		candidate_hash: CandidateHash,
1104		session: SessionIndex,
1105	) -> Result<Vec<u8>, ()> {
1106		match self {
1107			DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) =>
1108				Ok(ExplicitDisputeStatement { valid: true, candidate_hash, session }
1109					.signing_payload()),
1110			DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded(
1111				inclusion_parent,
1112			)) => Ok(CompactStatement::Seconded(candidate_hash).signing_payload(&SigningContext {
1113				session_index: session,
1114				parent_hash: *inclusion_parent,
1115			})),
1116			DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(inclusion_parent)) =>
1117				Ok(CompactStatement::Valid(candidate_hash).signing_payload(&SigningContext {
1118					session_index: session,
1119					parent_hash: *inclusion_parent,
1120				})),
1121			DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) =>
1122				Ok(ApprovalVote(candidate_hash).signing_payload(session)),
1123			DisputeStatement::Valid(
1124				ValidDisputeStatementKind::ApprovalCheckingMultipleCandidates(candidate_hashes),
1125			) =>
1126				if candidate_hashes.contains(&candidate_hash) {
1127					Ok(ApprovalVoteMultipleCandidates(candidate_hashes).signing_payload(session))
1128				} else {
1129					Err(())
1130				},
1131			DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) =>
1132				Ok(ExplicitDisputeStatement { valid: false, candidate_hash, session }
1133					.signing_payload()),
1134		}
1135	}
1136
1137	/// Check the signature on a dispute statement.
1138	pub fn check_signature(
1139		&self,
1140		validator_public: &ValidatorId,
1141		candidate_hash: CandidateHash,
1142		session: SessionIndex,
1143		validator_signature: &ValidatorSignature,
1144	) -> Result<(), ()> {
1145		let payload = self.payload_data(candidate_hash, session)?;
1146
1147		if validator_signature.verify(&payload[..], &validator_public) {
1148			Ok(())
1149		} else {
1150			Err(())
1151		}
1152	}
1153
1154	/// Whether the statement indicates validity.
1155	pub fn indicates_validity(&self) -> bool {
1156		match *self {
1157			DisputeStatement::Valid(_) => true,
1158			DisputeStatement::Invalid(_) => false,
1159		}
1160	}
1161
1162	/// Whether the statement indicates invalidity.
1163	pub fn indicates_invalidity(&self) -> bool {
1164		match *self {
1165			DisputeStatement::Valid(_) => false,
1166			DisputeStatement::Invalid(_) => true,
1167		}
1168	}
1169
1170	/// Statement is backing statement.
1171	pub fn is_backing(&self) -> bool {
1172		match self {
1173			Self::Valid(s) => s.is_backing(),
1174			Self::Invalid(_) => false,
1175		}
1176	}
1177}
1178
1179/// Different kinds of statements of validity on  a candidate.
1180#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, RuntimeDebug, TypeInfo)]
1181pub enum ValidDisputeStatementKind {
1182	/// An explicit statement issued as part of a dispute.
1183	#[codec(index = 0)]
1184	Explicit,
1185	/// A seconded statement on a candidate from the backing phase.
1186	#[codec(index = 1)]
1187	BackingSeconded(Hash),
1188	/// A valid statement on a candidate from the backing phase.
1189	#[codec(index = 2)]
1190	BackingValid(Hash),
1191	/// An approval vote from the approval checking phase.
1192	#[codec(index = 3)]
1193	ApprovalChecking,
1194	/// An approval vote from the new version.
1195	/// We can't create this version until all nodes
1196	/// have been updated to support it and max_approval_coalesce_count
1197	/// is set to more than 1.
1198	#[codec(index = 4)]
1199	ApprovalCheckingMultipleCandidates(Vec<CandidateHash>),
1200}
1201
1202impl ValidDisputeStatementKind {
1203	/// Whether the statement is from the backing phase.
1204	pub fn is_backing(&self) -> bool {
1205		match self {
1206			ValidDisputeStatementKind::BackingSeconded(_) |
1207			ValidDisputeStatementKind::BackingValid(_) => true,
1208			ValidDisputeStatementKind::Explicit |
1209			ValidDisputeStatementKind::ApprovalChecking |
1210			ValidDisputeStatementKind::ApprovalCheckingMultipleCandidates(_) => false,
1211		}
1212	}
1213}
1214
1215/// Different kinds of statements of invalidity on a candidate.
1216#[derive(Encode, Decode, DecodeWithMemTracking, Copy, Clone, PartialEq, RuntimeDebug, TypeInfo)]
1217pub enum InvalidDisputeStatementKind {
1218	/// An explicit statement issued as part of a dispute.
1219	#[codec(index = 0)]
1220	Explicit,
1221}
1222
1223/// An explicit statement on a candidate issued as part of a dispute.
1224#[derive(Clone, PartialEq, RuntimeDebug)]
1225pub struct ExplicitDisputeStatement {
1226	/// Whether the candidate is valid
1227	pub valid: bool,
1228	/// The candidate hash.
1229	pub candidate_hash: CandidateHash,
1230	/// The session index of the candidate.
1231	pub session: SessionIndex,
1232}
1233
1234impl ExplicitDisputeStatement {
1235	/// Produce the payload used for signing this type of statement.
1236	pub fn signing_payload(&self) -> Vec<u8> {
1237		const MAGIC: [u8; 4] = *b"DISP";
1238
1239		(MAGIC, self.valid, self.candidate_hash, self.session).encode()
1240	}
1241}
1242
1243/// A set of statements about a specific candidate.
1244#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, RuntimeDebug, TypeInfo)]
1245pub struct DisputeStatementSet {
1246	/// The candidate referenced by this set.
1247	pub candidate_hash: CandidateHash,
1248	/// The session index of the candidate.
1249	pub session: SessionIndex,
1250	/// Statements about the candidate.
1251	pub statements: Vec<(DisputeStatement, ValidatorIndex, ValidatorSignature)>,
1252}
1253
1254impl From<CheckedDisputeStatementSet> for DisputeStatementSet {
1255	fn from(other: CheckedDisputeStatementSet) -> Self {
1256		other.0
1257	}
1258}
1259
1260impl AsRef<DisputeStatementSet> for DisputeStatementSet {
1261	fn as_ref(&self) -> &DisputeStatementSet {
1262		&self
1263	}
1264}
1265
1266/// A set of dispute statements.
1267pub type MultiDisputeStatementSet = Vec<DisputeStatementSet>;
1268
1269/// A _checked_ set of dispute statements.
1270#[derive(Clone, PartialEq, RuntimeDebug, Encode)]
1271pub struct CheckedDisputeStatementSet(DisputeStatementSet);
1272
1273impl AsRef<DisputeStatementSet> for CheckedDisputeStatementSet {
1274	fn as_ref(&self) -> &DisputeStatementSet {
1275		&self.0
1276	}
1277}
1278
1279impl core::cmp::PartialEq<DisputeStatementSet> for CheckedDisputeStatementSet {
1280	fn eq(&self, other: &DisputeStatementSet) -> bool {
1281		self.0.eq(other)
1282	}
1283}
1284
1285impl CheckedDisputeStatementSet {
1286	/// Convert from an unchecked, the verification of correctness of the `unchecked` statement set
1287	/// _must_ be done before calling this function!
1288	pub fn unchecked_from_unchecked(unchecked: DisputeStatementSet) -> Self {
1289		Self(unchecked)
1290	}
1291}
1292
1293/// A set of _checked_ dispute statements.
1294pub type CheckedMultiDisputeStatementSet = Vec<CheckedDisputeStatementSet>;
1295
1296/// The entire state of a dispute.
1297#[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, TypeInfo)]
1298pub struct DisputeState<N = BlockNumber> {
1299	/// A bitfield indicating all validators for the candidate.
1300	pub validators_for: BitVec<u8, bitvec::order::Lsb0>, // one bit per validator.
1301	/// A bitfield indicating all validators against the candidate.
1302	pub validators_against: BitVec<u8, bitvec::order::Lsb0>, // one bit per validator.
1303	/// The block number at which the dispute started on-chain.
1304	pub start: N,
1305	/// The block number at which the dispute concluded on-chain.
1306	pub concluded_at: Option<N>,
1307}
1308
1309/// An either implicit or explicit attestation to the validity of a parachain
1310/// candidate.
1311#[derive(Clone, Eq, PartialEq, Decode, DecodeWithMemTracking, Encode, RuntimeDebug, TypeInfo)]
1312pub enum ValidityAttestation {
1313	/// Implicit validity attestation by issuing.
1314	/// This corresponds to issuance of a `Candidate` statement.
1315	#[codec(index = 1)]
1316	Implicit(ValidatorSignature),
1317	/// An explicit attestation. This corresponds to issuance of a
1318	/// `Valid` statement.
1319	#[codec(index = 2)]
1320	Explicit(ValidatorSignature),
1321}
1322
1323impl ValidityAttestation {
1324	/// Produce the underlying signed payload of the attestation, given the hash of the candidate,
1325	/// which should be known in context.
1326	pub fn to_compact_statement(&self, candidate_hash: CandidateHash) -> CompactStatement {
1327		// Explicit and implicit map directly from
1328		// `ValidityVote::Valid` and `ValidityVote::Issued`, and hence there is a
1329		// `1:1` relationship which enables the conversion.
1330		match *self {
1331			ValidityAttestation::Implicit(_) => CompactStatement::Seconded(candidate_hash),
1332			ValidityAttestation::Explicit(_) => CompactStatement::Valid(candidate_hash),
1333		}
1334	}
1335
1336	/// Get a reference to the signature.
1337	pub fn signature(&self) -> &ValidatorSignature {
1338		match *self {
1339			ValidityAttestation::Implicit(ref sig) => sig,
1340			ValidityAttestation::Explicit(ref sig) => sig,
1341		}
1342	}
1343
1344	/// Produce the underlying signed payload of the attestation, given the hash of the candidate,
1345	/// which should be known in context.
1346	pub fn signed_payload<H: Encode>(
1347		&self,
1348		candidate_hash: CandidateHash,
1349		signing_context: &SigningContext<H>,
1350	) -> Vec<u8> {
1351		match *self {
1352			ValidityAttestation::Implicit(_) =>
1353				(CompactStatement::Seconded(candidate_hash), signing_context).encode(),
1354			ValidityAttestation::Explicit(_) =>
1355				(CompactStatement::Valid(candidate_hash), signing_context).encode(),
1356		}
1357	}
1358}
1359
1360/// A type returned by runtime with current session index and a parent hash.
1361#[derive(Clone, Eq, PartialEq, Default, Decode, Encode, RuntimeDebug)]
1362pub struct SigningContext<H = Hash> {
1363	/// Current session index.
1364	pub session_index: sp_staking::SessionIndex,
1365	/// Hash of the parent.
1366	pub parent_hash: H,
1367}
1368
1369const BACKING_STATEMENT_MAGIC: [u8; 4] = *b"BKNG";
1370
1371/// Statements that can be made about parachain candidates. These are the
1372/// actual values that are signed.
1373#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug)]
1374#[cfg_attr(feature = "std", derive(Hash))]
1375pub enum CompactStatement {
1376	/// Proposal of a parachain candidate.
1377	Seconded(CandidateHash),
1378	/// State that a parachain candidate is valid.
1379	Valid(CandidateHash),
1380}
1381
1382impl CompactStatement {
1383	/// Yields the payload used for validator signatures on this kind
1384	/// of statement.
1385	pub fn signing_payload(&self, context: &SigningContext) -> Vec<u8> {
1386		(self, context).encode()
1387	}
1388
1389	/// Get the underlying candidate hash this references.
1390	pub fn candidate_hash(&self) -> &CandidateHash {
1391		match *self {
1392			CompactStatement::Seconded(ref h) | CompactStatement::Valid(ref h) => h,
1393		}
1394	}
1395}
1396
1397// Inner helper for codec on `CompactStatement`.
1398#[derive(Encode, Decode, TypeInfo)]
1399enum CompactStatementInner {
1400	#[codec(index = 1)]
1401	Seconded(CandidateHash),
1402	#[codec(index = 2)]
1403	Valid(CandidateHash),
1404}
1405
1406impl From<CompactStatement> for CompactStatementInner {
1407	fn from(s: CompactStatement) -> Self {
1408		match s {
1409			CompactStatement::Seconded(h) => CompactStatementInner::Seconded(h),
1410			CompactStatement::Valid(h) => CompactStatementInner::Valid(h),
1411		}
1412	}
1413}
1414
1415impl codec::Encode for CompactStatement {
1416	fn size_hint(&self) -> usize {
1417		// magic + discriminant + payload
1418		4 + 1 + 32
1419	}
1420
1421	fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
1422		dest.write(&BACKING_STATEMENT_MAGIC);
1423		CompactStatementInner::from(self.clone()).encode_to(dest)
1424	}
1425}
1426
1427impl codec::Decode for CompactStatement {
1428	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
1429		let maybe_magic = <[u8; 4]>::decode(input)?;
1430		if maybe_magic != BACKING_STATEMENT_MAGIC {
1431			return Err(codec::Error::from("invalid magic string"))
1432		}
1433
1434		Ok(match CompactStatementInner::decode(input)? {
1435			CompactStatementInner::Seconded(h) => CompactStatement::Seconded(h),
1436			CompactStatementInner::Valid(h) => CompactStatement::Valid(h),
1437		})
1438	}
1439}
1440
1441/// `IndexedVec` struct indexed by type specific indices.
1442#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
1443#[cfg_attr(feature = "std", derive(PartialEq))]
1444pub struct IndexedVec<K, V>(Vec<V>, PhantomData<fn(K) -> K>);
1445
1446impl<K, V> Default for IndexedVec<K, V> {
1447	fn default() -> Self {
1448		Self(vec![], PhantomData)
1449	}
1450}
1451
1452impl<K, V> From<Vec<V>> for IndexedVec<K, V> {
1453	fn from(validators: Vec<V>) -> Self {
1454		Self(validators, PhantomData)
1455	}
1456}
1457
1458impl<K, V> FromIterator<V> for IndexedVec<K, V> {
1459	fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
1460		Self(Vec::from_iter(iter), PhantomData)
1461	}
1462}
1463
1464impl<K, V> IndexedVec<K, V>
1465where
1466	V: Clone,
1467{
1468	/// Returns a reference to an element indexed using `K`.
1469	pub fn get(&self, index: K) -> Option<&V>
1470	where
1471		K: TypeIndex,
1472	{
1473		self.0.get(index.type_index())
1474	}
1475
1476	/// Returns a mutable reference to an element indexed using `K`.
1477	pub fn get_mut(&mut self, index: K) -> Option<&mut V>
1478	where
1479		K: TypeIndex,
1480	{
1481		self.0.get_mut(index.type_index())
1482	}
1483
1484	/// Returns number of elements in vector.
1485	pub fn len(&self) -> usize {
1486		self.0.len()
1487	}
1488
1489	/// Returns contained vector.
1490	pub fn to_vec(&self) -> Vec<V> {
1491		self.0.clone()
1492	}
1493
1494	/// Returns an iterator over the underlying vector.
1495	pub fn iter(&self) -> Iter<'_, V> {
1496		self.0.iter()
1497	}
1498
1499	/// Returns a mutable iterator over the underlying vector.
1500	pub fn iter_mut(&mut self) -> IterMut<'_, V> {
1501		self.0.iter_mut()
1502	}
1503
1504	/// Creates a consuming iterator.
1505	pub fn into_iter(self) -> IntoIter<V> {
1506		self.0.into_iter()
1507	}
1508
1509	/// Returns true if the underlying container is empty.
1510	pub fn is_empty(&self) -> bool {
1511		self.0.is_empty()
1512	}
1513}
1514
1515/// The maximum number of validators `f` which may safely be faulty.
1516///
1517/// The total number of validators is `n = 3f + e` where `e in { 1, 2, 3 }`.
1518pub const fn byzantine_threshold(n: usize) -> usize {
1519	n.saturating_sub(1) / 3
1520}
1521
1522/// The supermajority threshold of validators which represents a subset
1523/// guaranteed to have at least f+1 honest validators.
1524pub const fn supermajority_threshold(n: usize) -> usize {
1525	n - byzantine_threshold(n)
1526}
1527
1528/// Adjust the configured needed backing votes with the size of the backing group.
1529pub fn effective_minimum_backing_votes(
1530	group_len: usize,
1531	configured_minimum_backing_votes: u32,
1532) -> usize {
1533	core::cmp::min(group_len, configured_minimum_backing_votes as usize)
1534}
1535
1536/// Information about validator sets of a session.
1537///
1538/// NOTE: `SessionInfo` is frozen. Do not include new fields, consider creating a separate runtime
1539/// API. Reasoning and further outlook [here](https://github.com/paritytech/polkadot/issues/6586).
1540#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
1541#[cfg_attr(feature = "std", derive(PartialEq))]
1542pub struct SessionInfo {
1543	/****** New in v2 ****** */
1544	/// All the validators actively participating in parachain consensus.
1545	/// Indices are into the broader validator set.
1546	pub active_validator_indices: Vec<ValidatorIndex>,
1547	/// A secure random seed for the session, gathered from BABE.
1548	pub random_seed: [u8; 32],
1549	/// The amount of sessions to keep for disputes.
1550	pub dispute_period: SessionIndex,
1551
1552	/****** Old fields ***** */
1553	/// Validators in canonical ordering.
1554	///
1555	/// NOTE: There might be more authorities in the current session, than `validators`
1556	/// participating in parachain consensus. See
1557	/// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148).
1558	///
1559	/// `SessionInfo::validators` will be limited to `max_validators` when set.
1560	pub validators: IndexedVec<ValidatorIndex, ValidatorId>,
1561	/// Validators' authority discovery keys for the session in canonical ordering.
1562	///
1563	/// NOTE: The first `validators.len()` entries will match the corresponding validators in
1564	/// `validators`, afterwards any remaining authorities can be found. This is any authorities
1565	/// not participating in parachain consensus - see
1566	/// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148)
1567	pub discovery_keys: Vec<AuthorityDiscoveryId>,
1568	/// The assignment keys for validators.
1569	///
1570	/// NOTE: There might be more authorities in the current session, than validators participating
1571	/// in parachain consensus. See
1572	/// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148).
1573	///
1574	/// Therefore:
1575	/// ```ignore
1576	/// 	assignment_keys.len() == validators.len() && validators.len() <= discovery_keys.len()
1577	/// ```
1578	pub assignment_keys: Vec<AssignmentId>,
1579	/// Validators in shuffled ordering - these are the validator groups as produced
1580	/// by the `Scheduler` module for the session and are typically referred to by
1581	/// `GroupIndex`.
1582	pub validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
1583	/// The number of availability cores used by the protocol during this session.
1584	pub n_cores: u32,
1585	/// The zeroth delay tranche width.
1586	pub zeroth_delay_tranche_width: u32,
1587	/// The number of samples we do of `relay_vrf_modulo`.
1588	pub relay_vrf_modulo_samples: u32,
1589	/// The number of delay tranches in total.
1590	pub n_delay_tranches: u32,
1591	/// How many slots (BABE / SASSAFRAS) must pass before an assignment is considered a
1592	/// no-show.
1593	pub no_show_slots: u32,
1594	/// The number of validators needed to approve a block.
1595	pub needed_approvals: u32,
1596}
1597
1598/// A statement from the specified validator whether the given validation code passes PVF
1599/// pre-checking or not anchored to the given session index.
1600#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, RuntimeDebug, TypeInfo)]
1601pub struct PvfCheckStatement {
1602	/// `true` if the subject passed pre-checking and `false` otherwise.
1603	pub accept: bool,
1604	/// The validation code hash that was checked.
1605	pub subject: ValidationCodeHash,
1606	/// The index of a session during which this statement is considered valid.
1607	pub session_index: SessionIndex,
1608	/// The index of the validator from which this statement originates.
1609	pub validator_index: ValidatorIndex,
1610}
1611
1612impl PvfCheckStatement {
1613	/// Produce the payload used for signing this type of statement.
1614	///
1615	/// It is expected that it will be signed by the validator at `validator_index` in the
1616	/// `session_index`.
1617	pub fn signing_payload(&self) -> Vec<u8> {
1618		const MAGIC: [u8; 4] = *b"VCPC"; // for "validation code pre-checking"
1619		(MAGIC, self.accept, self.subject, self.session_index, self.validator_index).encode()
1620	}
1621}
1622
1623/// A well-known and typed storage key.
1624///
1625/// Allows for type-safe access to raw well-known storage keys.
1626pub struct WellKnownKey<T> {
1627	/// The raw storage key.
1628	pub key: Vec<u8>,
1629	_p: core::marker::PhantomData<T>,
1630}
1631
1632impl<T> From<Vec<u8>> for WellKnownKey<T> {
1633	fn from(key: Vec<u8>) -> Self {
1634		Self { key, _p: Default::default() }
1635	}
1636}
1637
1638impl<T> AsRef<[u8]> for WellKnownKey<T> {
1639	fn as_ref(&self) -> &[u8] {
1640		self.key.as_ref()
1641	}
1642}
1643
1644impl<T: Decode> WellKnownKey<T> {
1645	/// Gets the value or `None` if it does not exist or decoding failed.
1646	pub fn get(&self) -> Option<T> {
1647		sp_io::storage::get(&self.key)
1648			.and_then(|raw| codec::DecodeAll::decode_all(&mut raw.as_ref()).ok())
1649	}
1650}
1651
1652impl<T: Encode> WellKnownKey<T> {
1653	/// Sets the value.
1654	pub fn set(&self, value: T) {
1655		sp_io::storage::set(&self.key, &value.encode());
1656	}
1657}
1658
1659/// Type discriminator for PVF preparation.
1660#[derive(
1661	Encode,
1662	Decode,
1663	DecodeWithMemTracking,
1664	TypeInfo,
1665	Clone,
1666	Copy,
1667	Debug,
1668	PartialEq,
1669	Eq,
1670	Serialize,
1671	Deserialize,
1672)]
1673pub enum PvfPrepKind {
1674	/// For prechecking requests.
1675	Precheck,
1676
1677	/// For execution and heads-up requests.
1678	Prepare,
1679}
1680
1681/// Type discriminator for PVF execution.
1682#[derive(
1683	Encode,
1684	Decode,
1685	DecodeWithMemTracking,
1686	TypeInfo,
1687	Clone,
1688	Copy,
1689	Debug,
1690	PartialEq,
1691	Eq,
1692	Serialize,
1693	Deserialize,
1694)]
1695pub enum PvfExecKind {
1696	/// For backing requests.
1697	Backing,
1698	/// For approval and dispute request.
1699	Approval,
1700}
1701
1702/// Bit indices in the `HostConfiguration.node_features` that correspond to different node features.
1703pub type NodeFeatures = BitVec<u8, bitvec::order::Lsb0>;
1704
1705/// Module containing feature-specific bit indices into the `NodeFeatures` bitvec.
1706pub mod node_features {
1707	/// A feature index used to identify a bit into the node_features array stored
1708	/// in the HostConfiguration.
1709	#[repr(u8)]
1710	#[derive(Clone, Copy)]
1711	pub enum FeatureIndex {
1712		/// Tells if tranch0 assignments could be sent in a single certificate.
1713		/// Reserved for: `<https://github.com/paritytech/polkadot-sdk/issues/628>`
1714		EnableAssignmentsV2 = 0,
1715		/// This feature enables the extension of `BackedCandidate::validator_indices` by 8 bits.
1716		/// The value stored there represents the assumed core index where the candidates
1717		/// are backed. This is needed for the elastic scaling MVP.
1718		ElasticScalingMVP = 1,
1719		/// Tells if the chunk mapping feature is enabled.
1720		/// Enables the implementation of
1721		/// [RFC-47](https://github.com/polkadot-fellows/RFCs/blob/main/text/0047-assignment-of-availability-chunks.md).
1722		/// Must not be enabled unless all validators and collators have stopped using `req_chunk`
1723		/// protocol version 1. If it is enabled, validators can start systematic chunk recovery.
1724		AvailabilityChunkMapping = 2,
1725		/// Enables node side support of `CoreIndex` committed candidate receipts.
1726		/// See [RFC-103](https://github.com/polkadot-fellows/RFCs/pull/103) for details.
1727		/// Only enable if at least 2/3 of nodes support the feature.
1728		CandidateReceiptV2 = 3,
1729		/// First unassigned feature bit.
1730		/// Every time a new feature flag is assigned it should take this value.
1731		/// and this should be incremented.
1732		FirstUnassigned = 4,
1733	}
1734}
1735
1736/// Scheduler configuration parameters. All coretime/ondemand parameters are here.
1737#[derive(
1738	RuntimeDebug,
1739	Copy,
1740	Clone,
1741	PartialEq,
1742	Encode,
1743	Decode,
1744	DecodeWithMemTracking,
1745	TypeInfo,
1746	serde::Serialize,
1747	serde::Deserialize,
1748)]
1749pub struct SchedulerParams<BlockNumber> {
1750	/// How often parachain groups should be rotated across parachains.
1751	///
1752	/// Must be non-zero.
1753	pub group_rotation_frequency: BlockNumber,
1754	/// Availability timeout for a block on a core, measured in blocks.
1755	///
1756	/// This is the maximum amount of blocks after a core became occupied that validators have time
1757	/// to make the block available.
1758	///
1759	/// This value only has effect on group rotations. If backers backed something at the end of
1760	/// their rotation, the occupied core affects the backing group that comes afterwards. We limit
1761	/// the effect one backing group can have on the next to `paras_availability_period` blocks.
1762	///
1763	/// Within a group rotation there is no timeout as backers are only affecting themselves.
1764	///
1765	/// Must be at least 1. With a value of 1, the previous group will not be able to negatively
1766	/// affect the following group at the expense of a tight availability timeline at group
1767	/// rotation boundaries.
1768	pub paras_availability_period: BlockNumber,
1769	/// The maximum number of validators to have per core.
1770	///
1771	/// `None` means no maximum.
1772	pub max_validators_per_core: Option<u32>,
1773	/// The amount of blocks ahead to schedule paras.
1774	pub lookahead: u32,
1775	/// How many cores are managed by the coretime chain.
1776	pub num_cores: u32,
1777	/// Deprecated and no longer used by the runtime.
1778	/// Removal is tracked by <https://github.com/paritytech/polkadot-sdk/issues/6067>.
1779	#[deprecated]
1780	pub max_availability_timeouts: u32,
1781	/// The maximum queue size of the pay as you go module.
1782	pub on_demand_queue_max_size: u32,
1783	/// The target utilization of the spot price queue in percentages.
1784	pub on_demand_target_queue_utilization: Perbill,
1785	/// How quickly the fee rises in reaction to increased utilization.
1786	/// The lower the number the slower the increase.
1787	pub on_demand_fee_variability: Perbill,
1788	/// The minimum amount needed to claim a slot in the spot pricing queue.
1789	pub on_demand_base_fee: Balance,
1790	/// Deprecated and no longer used by the runtime.
1791	/// Removal is tracked by <https://github.com/paritytech/polkadot-sdk/issues/6067>.
1792	#[deprecated]
1793	pub ttl: BlockNumber,
1794}
1795
1796impl<BlockNumber: Default + From<u32>> Default for SchedulerParams<BlockNumber> {
1797	#[allow(deprecated)]
1798	fn default() -> Self {
1799		Self {
1800			group_rotation_frequency: 1u32.into(),
1801			paras_availability_period: 1u32.into(),
1802			max_validators_per_core: Default::default(),
1803			lookahead: 1,
1804			num_cores: Default::default(),
1805			max_availability_timeouts: Default::default(),
1806			on_demand_queue_max_size: ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE,
1807			on_demand_target_queue_utilization: Perbill::from_percent(25),
1808			on_demand_fee_variability: Perbill::from_percent(3),
1809			on_demand_base_fee: 10_000_000u128,
1810			ttl: 5u32.into(),
1811		}
1812	}
1813}
1814
1815/// A type representing the version of the candidate descriptor and internal version number.
1816#[derive(
1817	PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, Clone, TypeInfo, RuntimeDebug, Copy,
1818)]
1819pub struct InternalVersion(pub u8);
1820
1821/// A type representing the version of the candidate descriptor.
1822#[derive(PartialEq, Eq, Clone, TypeInfo, RuntimeDebug)]
1823pub enum CandidateDescriptorVersion {
1824	/// The old candidate descriptor version.
1825	V1,
1826	/// The new `CandidateDescriptorV2`.
1827	V2,
1828	/// An unknown version.
1829	Unknown,
1830}
1831
1832/// A unique descriptor of the candidate receipt.
1833#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo)]
1834pub struct CandidateDescriptorV2<H = Hash> {
1835	/// The ID of the para this is a candidate for.
1836	pub(super) para_id: ParaId,
1837	/// The hash of the relay-chain block this is executed in the context of.
1838	relay_parent: H,
1839	/// Version field. The raw value here is not exposed, instead it is used
1840	/// to determine the `CandidateDescriptorVersion`, see `fn version()`.
1841	/// For the current version this field is set to `0` and will be incremented
1842	/// by next versions.
1843	pub(super) version: InternalVersion,
1844	/// The core index where the candidate is backed.
1845	pub(super) core_index: u16,
1846	/// The session index of the candidate relay parent.
1847	session_index: SessionIndex,
1848	/// Reserved bytes.
1849	reserved1: [u8; 25],
1850	/// The blake2-256 hash of the persisted validation data. This is extra data derived from
1851	/// relay-chain state which may vary based on bitfields included before the candidate.
1852	/// Thus it cannot be derived entirely from the relay-parent.
1853	persisted_validation_data_hash: Hash,
1854	/// The blake2-256 hash of the PoV.
1855	pov_hash: Hash,
1856	/// The root of a block's erasure encoding Merkle tree.
1857	erasure_root: Hash,
1858	/// Reserved bytes.
1859	reserved2: [u8; 64],
1860	/// Hash of the para header that is being generated by this candidate.
1861	para_head: Hash,
1862	/// The blake2-256 hash of the validation code bytes.
1863	validation_code_hash: ValidationCodeHash,
1864}
1865
1866impl<H> CandidateDescriptorV2<H> {
1867	/// Returns the candidate descriptor version.
1868	///
1869	/// The candidate is at version 2 if the reserved fields are zeroed out
1870	/// and the internal `version` field is 0.
1871	pub fn version(&self) -> CandidateDescriptorVersion {
1872		if self.reserved2 != [0u8; 64] || self.reserved1 != [0u8; 25] {
1873			return CandidateDescriptorVersion::V1
1874		}
1875
1876		match self.version.0 {
1877			0 => CandidateDescriptorVersion::V2,
1878			_ => CandidateDescriptorVersion::Unknown,
1879		}
1880	}
1881}
1882
1883macro_rules! impl_getter {
1884	($field:ident, $type:ident) => {
1885		/// Returns the value of `$field` field.
1886		pub fn $field(&self) -> $type {
1887			self.$field
1888		}
1889	};
1890}
1891
1892impl<H: Copy> CandidateDescriptorV2<H> {
1893	impl_getter!(erasure_root, Hash);
1894	impl_getter!(para_head, Hash);
1895	impl_getter!(relay_parent, H);
1896	impl_getter!(para_id, ParaId);
1897	impl_getter!(persisted_validation_data_hash, Hash);
1898	impl_getter!(pov_hash, Hash);
1899	impl_getter!(validation_code_hash, ValidationCodeHash);
1900
1901	fn rebuild_collator_field(&self) -> CollatorId {
1902		let mut collator_id = Vec::with_capacity(32);
1903		let core_index: [u8; 2] = self.core_index.to_ne_bytes();
1904		let session_index: [u8; 4] = self.session_index.to_ne_bytes();
1905
1906		collator_id.push(self.version.0);
1907		collator_id.extend_from_slice(core_index.as_slice());
1908		collator_id.extend_from_slice(session_index.as_slice());
1909		collator_id.extend_from_slice(self.reserved1.as_slice());
1910
1911		CollatorId::from_slice(&collator_id.as_slice())
1912			.expect("Slice size is exactly 32 bytes; qed")
1913	}
1914
1915	#[cfg(feature = "test")]
1916	#[doc(hidden)]
1917	pub fn rebuild_collator_field_for_tests(&self) -> CollatorId {
1918		self.rebuild_collator_field()
1919	}
1920
1921	/// Returns the collator id if this is a v1 `CandidateDescriptor`
1922	pub fn collator(&self) -> Option<CollatorId> {
1923		if self.version() == CandidateDescriptorVersion::V1 {
1924			Some(self.rebuild_collator_field())
1925		} else {
1926			None
1927		}
1928	}
1929
1930	fn rebuild_signature_field(&self) -> CollatorSignature {
1931		CollatorSignature::from_slice(self.reserved2.as_slice())
1932			.expect("Slice size is exactly 64 bytes; qed")
1933	}
1934
1935	#[cfg(feature = "test")]
1936	#[doc(hidden)]
1937	pub fn rebuild_signature_field_for_tests(&self) -> CollatorSignature {
1938		self.rebuild_signature_field()
1939	}
1940
1941	/// Returns the collator signature of `V1` candidate descriptors, `None` otherwise.
1942	pub fn signature(&self) -> Option<CollatorSignature> {
1943		if self.version() == CandidateDescriptorVersion::V1 {
1944			return Some(self.rebuild_signature_field())
1945		}
1946
1947		None
1948	}
1949
1950	/// Returns the `core_index` of `V2` candidate descriptors, `None` otherwise.
1951	pub fn core_index(&self) -> Option<CoreIndex> {
1952		if self.version() == CandidateDescriptorVersion::V1 {
1953			return None
1954		}
1955
1956		Some(CoreIndex(self.core_index as u32))
1957	}
1958
1959	/// Returns the `session_index` of `V2` candidate descriptors, `None` otherwise.
1960	pub fn session_index(&self) -> Option<SessionIndex> {
1961		if self.version() == CandidateDescriptorVersion::V1 {
1962			return None
1963		}
1964
1965		Some(self.session_index)
1966	}
1967}
1968
1969impl<H> core::fmt::Debug for CandidateDescriptorV2<H>
1970where
1971	H: core::fmt::Debug,
1972{
1973	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1974		match self.version() {
1975			CandidateDescriptorVersion::V1 => f
1976				.debug_struct("CandidateDescriptorV1")
1977				.field("para_id", &self.para_id)
1978				.field("relay_parent", &self.relay_parent)
1979				.field("persisted_validation_hash", &self.persisted_validation_data_hash)
1980				.field("pov_hash", &self.pov_hash)
1981				.field("erasure_root", &self.erasure_root)
1982				.field("para_head", &self.para_head)
1983				.field("validation_code_hash", &self.validation_code_hash)
1984				.finish(),
1985			CandidateDescriptorVersion::V2 => f
1986				.debug_struct("CandidateDescriptorV2")
1987				.field("para_id", &self.para_id)
1988				.field("relay_parent", &self.relay_parent)
1989				.field("core_index", &self.core_index)
1990				.field("session_index", &self.session_index)
1991				.field("persisted_validation_data_hash", &self.persisted_validation_data_hash)
1992				.field("pov_hash", &self.pov_hash)
1993				.field("erasure_root", &self.pov_hash)
1994				.field("para_head", &self.para_head)
1995				.field("validation_code_hash", &self.validation_code_hash)
1996				.finish(),
1997			CandidateDescriptorVersion::Unknown => {
1998				write!(f, "Invalid CandidateDescriptorVersion")
1999			},
2000		}
2001	}
2002}
2003
2004impl<H: Copy + AsRef<[u8]>> CandidateDescriptorV2<H> {
2005	/// Constructor
2006	pub fn new(
2007		para_id: Id,
2008		relay_parent: H,
2009		core_index: CoreIndex,
2010		session_index: SessionIndex,
2011		persisted_validation_data_hash: Hash,
2012		pov_hash: Hash,
2013		erasure_root: Hash,
2014		para_head: Hash,
2015		validation_code_hash: ValidationCodeHash,
2016	) -> Self {
2017		Self {
2018			para_id,
2019			relay_parent,
2020			version: InternalVersion(0),
2021			core_index: core_index.0 as u16,
2022			session_index,
2023			reserved1: [0; 25],
2024			persisted_validation_data_hash,
2025			pov_hash,
2026			erasure_root,
2027			reserved2: [0; 64],
2028			para_head,
2029			validation_code_hash,
2030		}
2031	}
2032
2033	#[cfg(feature = "test")]
2034	#[doc(hidden)]
2035	pub fn new_from_raw(
2036		para_id: Id,
2037		relay_parent: H,
2038		version: InternalVersion,
2039		core_index: u16,
2040		session_index: SessionIndex,
2041		reserved1: [u8; 25],
2042		persisted_validation_data_hash: Hash,
2043		pov_hash: Hash,
2044		erasure_root: Hash,
2045		reserved2: [u8; 64],
2046		para_head: Hash,
2047		validation_code_hash: ValidationCodeHash,
2048	) -> Self {
2049		Self {
2050			para_id,
2051			relay_parent,
2052			version,
2053			core_index,
2054			session_index,
2055			reserved1,
2056			persisted_validation_data_hash,
2057			pov_hash,
2058			erasure_root,
2059			reserved2,
2060			para_head,
2061			validation_code_hash,
2062		}
2063	}
2064}
2065
2066/// A trait to allow changing the descriptor field values in tests.
2067#[cfg(feature = "test")]
2068pub trait MutateDescriptorV2<H> {
2069	/// Set the relay parent of the descriptor.
2070	fn set_relay_parent(&mut self, relay_parent: H);
2071	/// Set the `ParaId` of the descriptor.
2072	fn set_para_id(&mut self, para_id: Id);
2073	/// Set the PoV hash of the descriptor.
2074	fn set_pov_hash(&mut self, pov_hash: Hash);
2075	/// Set the version field of the descriptor.
2076	fn set_version(&mut self, version: InternalVersion);
2077	/// Set the PVD of the descriptor.
2078	fn set_persisted_validation_data_hash(&mut self, persisted_validation_data_hash: Hash);
2079	/// Set the validation code hash of the descriptor.
2080	fn set_validation_code_hash(&mut self, validation_code_hash: ValidationCodeHash);
2081	/// Set the erasure root of the descriptor.
2082	fn set_erasure_root(&mut self, erasure_root: Hash);
2083	/// Set the para head of the descriptor.
2084	fn set_para_head(&mut self, para_head: Hash);
2085	/// Set the core index of the descriptor.
2086	fn set_core_index(&mut self, core_index: CoreIndex);
2087	/// Set the session index of the descriptor.
2088	fn set_session_index(&mut self, session_index: SessionIndex);
2089	/// Set the reserved2 field of the descriptor.
2090	fn set_reserved2(&mut self, reserved2: [u8; 64]);
2091}
2092
2093#[cfg(feature = "test")]
2094impl<H> MutateDescriptorV2<H> for CandidateDescriptorV2<H> {
2095	fn set_para_id(&mut self, para_id: Id) {
2096		self.para_id = para_id;
2097	}
2098
2099	fn set_relay_parent(&mut self, relay_parent: H) {
2100		self.relay_parent = relay_parent;
2101	}
2102
2103	fn set_pov_hash(&mut self, pov_hash: Hash) {
2104		self.pov_hash = pov_hash;
2105	}
2106
2107	fn set_version(&mut self, version: InternalVersion) {
2108		self.version = version;
2109	}
2110
2111	fn set_core_index(&mut self, core_index: CoreIndex) {
2112		self.core_index = core_index.0 as u16;
2113	}
2114
2115	fn set_session_index(&mut self, session_index: SessionIndex) {
2116		self.session_index = session_index;
2117	}
2118
2119	fn set_persisted_validation_data_hash(&mut self, persisted_validation_data_hash: Hash) {
2120		self.persisted_validation_data_hash = persisted_validation_data_hash;
2121	}
2122
2123	fn set_validation_code_hash(&mut self, validation_code_hash: ValidationCodeHash) {
2124		self.validation_code_hash = validation_code_hash;
2125	}
2126
2127	fn set_erasure_root(&mut self, erasure_root: Hash) {
2128		self.erasure_root = erasure_root;
2129	}
2130
2131	fn set_para_head(&mut self, para_head: Hash) {
2132		self.para_head = para_head;
2133	}
2134
2135	fn set_reserved2(&mut self, reserved2: [u8; 64]) {
2136		self.reserved2 = reserved2;
2137	}
2138}
2139
2140/// A candidate-receipt at version 2.
2141#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo, RuntimeDebug)]
2142pub struct CandidateReceiptV2<H = Hash> {
2143	/// The descriptor of the candidate.
2144	pub descriptor: CandidateDescriptorV2<H>,
2145	/// The hash of the encoded commitments made as a result of candidate execution.
2146	pub commitments_hash: Hash,
2147}
2148
2149/// A candidate-receipt with commitments directly included.
2150#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo, RuntimeDebug)]
2151pub struct CommittedCandidateReceiptV2<H = Hash> {
2152	/// The descriptor of the candidate.
2153	pub descriptor: CandidateDescriptorV2<H>,
2154	/// The commitments of the candidate receipt.
2155	pub commitments: CandidateCommitments,
2156}
2157
2158/// An event concerning a candidate.
2159#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
2160#[cfg_attr(feature = "std", derive(PartialEq))]
2161pub enum CandidateEvent<H = Hash> {
2162	/// This candidate receipt was backed in the most recent block.
2163	/// This includes the core index the candidate is now occupying.
2164	#[codec(index = 0)]
2165	CandidateBacked(CandidateReceiptV2<H>, HeadData, CoreIndex, GroupIndex),
2166	/// This candidate receipt was included and became a parablock at the most recent block.
2167	/// This includes the core index the candidate was occupying as well as the group responsible
2168	/// for backing the candidate.
2169	#[codec(index = 1)]
2170	CandidateIncluded(CandidateReceiptV2<H>, HeadData, CoreIndex, GroupIndex),
2171	/// This candidate receipt was not made available in time and timed out.
2172	/// This includes the core index the candidate was occupying.
2173	#[codec(index = 2)]
2174	CandidateTimedOut(CandidateReceiptV2<H>, HeadData, CoreIndex),
2175}
2176
2177impl<H> CandidateReceiptV2<H> {
2178	/// Get a reference to the candidate descriptor.
2179	pub fn descriptor(&self) -> &CandidateDescriptorV2<H> {
2180		&self.descriptor
2181	}
2182
2183	/// Computes the blake2-256 hash of the receipt.
2184	pub fn hash(&self) -> CandidateHash
2185	where
2186		H: Encode,
2187	{
2188		CandidateHash(BlakeTwo256::hash_of(self))
2189	}
2190}
2191
2192impl<H: Clone> CommittedCandidateReceiptV2<H> {
2193	/// Transforms this into a plain `CandidateReceipt`.
2194	pub fn to_plain(&self) -> CandidateReceiptV2<H> {
2195		CandidateReceiptV2 {
2196			descriptor: self.descriptor.clone(),
2197			commitments_hash: self.commitments.hash(),
2198		}
2199	}
2200
2201	/// Computes the hash of the committed candidate receipt.
2202	///
2203	/// This computes the canonical hash, not the hash of the directly encoded data.
2204	/// Thus this is a shortcut for `candidate.to_plain().hash()`.
2205	pub fn hash(&self) -> CandidateHash
2206	where
2207		H: Encode,
2208	{
2209		self.to_plain().hash()
2210	}
2211
2212	/// Does this committed candidate receipt corresponds to the given [`CandidateReceiptV2`]?
2213	pub fn corresponds_to(&self, receipt: &CandidateReceiptV2<H>) -> bool
2214	where
2215		H: PartialEq,
2216	{
2217		receipt.descriptor == self.descriptor && receipt.commitments_hash == self.commitments.hash()
2218	}
2219}
2220
2221impl PartialOrd for CommittedCandidateReceiptV2 {
2222	fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
2223		Some(self.cmp(other))
2224	}
2225}
2226
2227impl Ord for CommittedCandidateReceiptV2 {
2228	fn cmp(&self, other: &Self) -> core::cmp::Ordering {
2229		self.descriptor
2230			.para_id
2231			.cmp(&other.descriptor.para_id)
2232			.then_with(|| self.commitments.head_data.cmp(&other.commitments.head_data))
2233	}
2234}
2235
2236/// A strictly increasing sequence number, typically this would be the least significant byte of the
2237/// block number.
2238#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug, Copy)]
2239pub struct CoreSelector(pub u8);
2240
2241/// An offset in the relay chain claim queue.
2242#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug, Copy)]
2243pub struct ClaimQueueOffset(pub u8);
2244
2245/// Signals that a parachain can send to the relay chain via the UMP queue.
2246#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug)]
2247pub enum UMPSignal {
2248	/// A message sent by a parachain to select the core the candidate is committed to.
2249	/// Relay chain validators, in particular backers, use the `CoreSelector` and
2250	/// `ClaimQueueOffset` to compute the index of the core the candidate has committed to.
2251	SelectCore(CoreSelector, ClaimQueueOffset),
2252	/// A message sent by a parachain to promote the reputation of a given peerid.
2253	ApprovedPeer(ApprovedPeerId),
2254}
2255
2256/// The default claim queue offset to be used if it's not configured/accessible in the parachain
2257/// runtime
2258pub const DEFAULT_CLAIM_QUEUE_OFFSET: u8 = 0;
2259
2260/// Approved PeerId type. PeerIds in polkadot should typically be 32 bytes long but for identity
2261/// multihash can go up to 64. Cannot reuse the PeerId type definition from the networking code as
2262/// it's too generic and extensible.
2263pub type ApprovedPeerId = BoundedVec<u8, ConstU32<64>>;
2264
2265#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug, Default)]
2266/// User-friendly representation of a candidate's UMP signals.
2267pub struct CandidateUMPSignals {
2268	pub(super) select_core: Option<(CoreSelector, ClaimQueueOffset)>,
2269	pub(super) approved_peer: Option<ApprovedPeerId>,
2270}
2271
2272impl CandidateUMPSignals {
2273	/// Get the core selector UMP signal.
2274	pub fn core_selector(&self) -> Option<(CoreSelector, ClaimQueueOffset)> {
2275		self.select_core
2276	}
2277
2278	/// Get a reference to the approved peer UMP signal.
2279	pub fn approved_peer(&self) -> Option<&ApprovedPeerId> {
2280		self.approved_peer.as_ref()
2281	}
2282
2283	/// Returns `true` if UMP signals are empty.
2284	pub fn is_empty(&self) -> bool {
2285		self.select_core.is_none() && self.approved_peer.is_none()
2286	}
2287
2288	fn try_decode_signal(
2289		&mut self,
2290		buffer: &mut impl codec::Input,
2291	) -> Result<(), CommittedCandidateReceiptError> {
2292		match UMPSignal::decode(buffer)
2293			.map_err(|_| CommittedCandidateReceiptError::UmpSignalDecode)?
2294		{
2295			UMPSignal::ApprovedPeer(approved_peer_id) if self.approved_peer.is_none() => {
2296				self.approved_peer = Some(approved_peer_id);
2297			},
2298			UMPSignal::SelectCore(core_selector, cq_offset) if self.select_core.is_none() => {
2299				self.select_core = Some((core_selector, cq_offset));
2300			},
2301			_ => {
2302				// This means that we got duplicate UMP signals.
2303				return Err(CommittedCandidateReceiptError::DuplicateUMPSignal)
2304			},
2305		};
2306
2307		Ok(())
2308	}
2309
2310	#[cfg(feature = "test")]
2311	#[doc(hidden)]
2312	pub fn dummy(
2313		select_core: Option<(CoreSelector, ClaimQueueOffset)>,
2314		approved_peer: Option<ApprovedPeerId>,
2315	) -> Self {
2316		Self { select_core, approved_peer }
2317	}
2318}
2319
2320/// Separator between `XCM` and `UMPSignal`.
2321pub const UMP_SEPARATOR: Vec<u8> = vec![];
2322
2323/// Utility function for skipping the ump signals.
2324pub fn skip_ump_signals<'a>(
2325	upward_messages: impl Iterator<Item = &'a Vec<u8>>,
2326) -> impl Iterator<Item = &'a Vec<u8>> {
2327	upward_messages.take_while(|message| *message != &UMP_SEPARATOR)
2328}
2329
2330impl CandidateCommitments {
2331	/// Returns the ump signals of this candidate, if any, or an error if they violate the expected
2332	/// format.
2333	pub fn ump_signals(&self) -> Result<CandidateUMPSignals, CommittedCandidateReceiptError> {
2334		let mut res = CandidateUMPSignals::default();
2335
2336		let mut signals_iter =
2337			self.upward_messages.iter().skip_while(|message| *message != &UMP_SEPARATOR);
2338
2339		if signals_iter.next().is_none() {
2340			// No UMP separator
2341			return Ok(res)
2342		}
2343
2344		// Process first signal
2345		let Some(first_signal) = signals_iter.next() else { return Ok(res) };
2346		res.try_decode_signal(&mut first_signal.as_slice())?;
2347
2348		// Process second signal
2349		let Some(second_signal) = signals_iter.next() else { return Ok(res) };
2350		res.try_decode_signal(&mut second_signal.as_slice())?;
2351
2352		// At most two signals are allowed
2353		if signals_iter.next().is_some() {
2354			return Err(CommittedCandidateReceiptError::TooManyUMPSignals)
2355		}
2356
2357		Ok(res)
2358	}
2359}
2360
2361/// CommittedCandidateReceiptError construction errors.
2362#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
2363#[cfg_attr(feature = "std", derive(thiserror::Error))]
2364pub enum CommittedCandidateReceiptError {
2365	/// The specified core index is invalid.
2366	#[cfg_attr(feature = "std", error("The specified core index is invalid"))]
2367	InvalidCoreIndex,
2368	/// The core index in commitments doesn't match the one in descriptor
2369	#[cfg_attr(
2370		feature = "std",
2371		error("The core index in commitments ({commitments:?}) doesn't match the one in descriptor ({descriptor:?})")
2372	)]
2373	CoreIndexMismatch {
2374		/// The core index as found in the descriptor.
2375		descriptor: CoreIndex,
2376		/// The core index as found in the commitments.
2377		commitments: CoreIndex,
2378	},
2379	/// The core selector or claim queue offset is invalid.
2380	#[cfg_attr(feature = "std", error("The core selector or claim queue offset is invalid"))]
2381	InvalidSelectedCore,
2382	#[cfg_attr(feature = "std", error("Could not decode UMP signal"))]
2383	/// Could not decode UMP signal.
2384	UmpSignalDecode,
2385	/// The parachain is not assigned to any core at specified claim queue offset.
2386	#[cfg_attr(
2387		feature = "std",
2388		error("The parachain is not assigned to any core at specified claim queue offset")
2389	)]
2390	NoAssignment,
2391	/// Unknown version.
2392	#[cfg_attr(feature = "std", error("Unknown internal version"))]
2393	UnknownVersion(InternalVersion),
2394	/// The allowed number of `UMPSignal` messages in the queue was exceeded.
2395	#[cfg_attr(feature = "std", error("Too many UMP signals"))]
2396	TooManyUMPSignals,
2397	/// Duplicated UMP signal.
2398	#[cfg_attr(feature = "std", error("Duplicate UMP signal"))]
2399	DuplicateUMPSignal,
2400	/// If the parachain runtime started sending ump signals, v1 descriptors are no longer
2401	/// allowed.
2402	#[cfg_attr(feature = "std", error("Version 1 receipt does not support ump signals"))]
2403	UMPSignalWithV1Decriptor,
2404}
2405
2406impl<H: Copy> CommittedCandidateReceiptV2<H> {
2407	/// Performs checks on the UMP signals and returns them.
2408	///
2409	/// Also checks if descriptor core index is equal to the committed core index.
2410	///
2411	/// Params:
2412	/// - `cores_per_para` is a claim queue snapshot at the candidate's relay parent, stored as
2413	/// a mapping between `ParaId` and the cores assigned per depth.
2414	pub fn parse_ump_signals(
2415		&self,
2416		cores_per_para: &TransposedClaimQueue,
2417	) -> Result<CandidateUMPSignals, CommittedCandidateReceiptError> {
2418		let signals = self.commitments.ump_signals()?;
2419
2420		match self.descriptor.version() {
2421			CandidateDescriptorVersion::V1 => {
2422				// If the parachain runtime started sending ump signals, v1 descriptors are no
2423				// longer allowed.
2424				if !signals.is_empty() {
2425					return Err(CommittedCandidateReceiptError::UMPSignalWithV1Decriptor)
2426				} else {
2427					// Nothing else to check for v1 descriptors.
2428					return Ok(CandidateUMPSignals::default())
2429				}
2430			},
2431			CandidateDescriptorVersion::V2 => {},
2432			CandidateDescriptorVersion::Unknown =>
2433				return Err(CommittedCandidateReceiptError::UnknownVersion(self.descriptor.version)),
2434		}
2435
2436		// Check the core index
2437		let (maybe_core_index_selector, cq_offset) = signals
2438			.core_selector()
2439			.map(|(selector, offset)| (Some(selector), offset))
2440			.unwrap_or_else(|| (None, ClaimQueueOffset(DEFAULT_CLAIM_QUEUE_OFFSET)));
2441
2442		self.check_core_index(cores_per_para, maybe_core_index_selector, cq_offset)?;
2443
2444		// Nothing to further check for the approved peer. If everything passed so far, return the
2445		// signals.
2446		Ok(signals)
2447	}
2448
2449	/// Checks if descriptor core index is equal to the committed core index.
2450	/// Input `cores_per_para` is a claim queue snapshot at the candidate's relay parent, stored as
2451	/// a mapping between `ParaId` and the cores assigned per depth.
2452	fn check_core_index(
2453		&self,
2454		cores_per_para: &TransposedClaimQueue,
2455		maybe_core_index_selector: Option<CoreSelector>,
2456		cq_offset: ClaimQueueOffset,
2457	) -> Result<(), CommittedCandidateReceiptError> {
2458		let assigned_cores = cores_per_para
2459			.get(&self.descriptor.para_id())
2460			.ok_or(CommittedCandidateReceiptError::NoAssignment)?
2461			.get(&cq_offset.0)
2462			.ok_or(CommittedCandidateReceiptError::NoAssignment)?;
2463
2464		if assigned_cores.is_empty() {
2465			return Err(CommittedCandidateReceiptError::NoAssignment)
2466		}
2467
2468		let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32);
2469
2470		let core_index_selector = if let Some(core_index_selector) = maybe_core_index_selector {
2471			// We have a committed core selector, we can use it.
2472			core_index_selector
2473		} else if assigned_cores.len() > 1 {
2474			// We got more than one assigned core and no core selector. Special care is needed.
2475			if !assigned_cores.contains(&descriptor_core_index) {
2476				// core index in the descriptor is not assigned to the para. Error.
2477				return Err(CommittedCandidateReceiptError::InvalidCoreIndex)
2478			} else {
2479				// the descriptor core index is indeed assigned to the para. This is the most we can
2480				// check for now
2481				return Ok(())
2482			}
2483		} else {
2484			// No core selector but there's only one assigned core, use it.
2485			CoreSelector(0)
2486		};
2487
2488		let core_index = assigned_cores
2489			.iter()
2490			.nth(core_index_selector.0 as usize % assigned_cores.len())
2491			.ok_or(CommittedCandidateReceiptError::InvalidSelectedCore)
2492			.copied()?;
2493
2494		if core_index != descriptor_core_index {
2495			return Err(CommittedCandidateReceiptError::CoreIndexMismatch {
2496				descriptor: descriptor_core_index,
2497				commitments: core_index,
2498			})
2499		}
2500
2501		Ok(())
2502	}
2503}
2504
2505/// A backed (or backable, depending on context) candidate.
2506#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
2507pub struct BackedCandidate<H = Hash> {
2508	/// The candidate referred to.
2509	candidate: CommittedCandidateReceiptV2<H>,
2510	/// The validity votes themselves, expressed as signatures.
2511	validity_votes: Vec<ValidityAttestation>,
2512	/// The indices of the validators within the group, expressed as a bitfield. May be extended
2513	/// beyond the backing group size to contain the assigned core index, if ElasticScalingMVP is
2514	/// enabled.
2515	validator_indices: BitVec<u8, bitvec::order::Lsb0>,
2516}
2517
2518/// Parachains inherent-data passed into the runtime by a block author
2519#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, RuntimeDebug, TypeInfo)]
2520pub struct InherentData<HDR: HeaderT = Header> {
2521	/// Signed bitfields by validators about availability.
2522	pub bitfields: UncheckedSignedAvailabilityBitfields,
2523	/// Backed candidates for inclusion in the block.
2524	pub backed_candidates: Vec<BackedCandidate<HDR::Hash>>,
2525	/// Sets of dispute votes for inclusion,
2526	pub disputes: MultiDisputeStatementSet,
2527	/// The parent block header. Used for checking state proofs.
2528	pub parent_header: HDR,
2529}
2530
2531impl<H> BackedCandidate<H> {
2532	/// Constructor
2533	pub fn new(
2534		candidate: CommittedCandidateReceiptV2<H>,
2535		validity_votes: Vec<ValidityAttestation>,
2536		validator_indices: BitVec<u8, bitvec::order::Lsb0>,
2537		core_index: CoreIndex,
2538	) -> Self {
2539		let mut instance = Self { candidate, validity_votes, validator_indices };
2540		instance.inject_core_index(core_index);
2541		instance
2542	}
2543
2544	/// Get a reference to the committed candidate receipt of the candidate.
2545	pub fn candidate(&self) -> &CommittedCandidateReceiptV2<H> {
2546		&self.candidate
2547	}
2548
2549	/// Get a mutable reference to the committed candidate receipt of the candidate.
2550	/// Only for testing.
2551	#[cfg(feature = "test")]
2552	pub fn candidate_mut(&mut self) -> &mut CommittedCandidateReceiptV2<H> {
2553		&mut self.candidate
2554	}
2555	/// Get a reference to the descriptor of the candidate.
2556	pub fn descriptor(&self) -> &CandidateDescriptorV2<H> {
2557		&self.candidate.descriptor
2558	}
2559
2560	/// Get a mutable reference to the descriptor of the candidate. Only for testing.
2561	#[cfg(feature = "test")]
2562	pub fn descriptor_mut(&mut self) -> &mut CandidateDescriptorV2<H> {
2563		&mut self.candidate.descriptor
2564	}
2565
2566	/// Get a reference to the validity votes of the candidate.
2567	pub fn validity_votes(&self) -> &[ValidityAttestation] {
2568		&self.validity_votes
2569	}
2570
2571	/// Get a mutable reference to validity votes of the para.
2572	pub fn validity_votes_mut(&mut self) -> &mut Vec<ValidityAttestation> {
2573		&mut self.validity_votes
2574	}
2575
2576	/// Compute this candidate's hash.
2577	pub fn hash(&self) -> CandidateHash
2578	where
2579		H: Clone + Encode,
2580	{
2581		self.candidate.to_plain().hash()
2582	}
2583
2584	/// Get this candidate's receipt.
2585	pub fn receipt(&self) -> CandidateReceiptV2<H>
2586	where
2587		H: Clone,
2588	{
2589		self.candidate.to_plain()
2590	}
2591
2592	/// Get a copy of the raw validator indices.
2593	#[cfg(feature = "test")]
2594	pub fn raw_validator_indices(&self) -> BitVec<u8, bitvec::order::Lsb0> {
2595		self.validator_indices.clone()
2596	}
2597
2598	/// Get a copy of the validator indices and the assumed core index, if any.
2599	pub fn validator_indices_and_core_index(
2600		&self,
2601	) -> (&BitSlice<u8, bitvec::order::Lsb0>, Option<CoreIndex>) {
2602		// `BackedCandidate::validity_indices` are extended to store a 8 bit core index.
2603		let core_idx_offset = self.validator_indices.len().saturating_sub(8);
2604		if core_idx_offset > 0 {
2605			let (validator_indices_slice, core_idx_slice) =
2606				self.validator_indices.split_at(core_idx_offset);
2607			return (validator_indices_slice, Some(CoreIndex(core_idx_slice.load::<u8>() as u32)));
2608		}
2609
2610		(&self.validator_indices, None)
2611	}
2612
2613	/// Inject a core index in the validator_indices bitvec.
2614	fn inject_core_index(&mut self, core_index: CoreIndex) {
2615		let core_index_to_inject: BitVec<u8, bitvec::order::Lsb0> =
2616			BitVec::from_vec(vec![core_index.0 as u8]);
2617		self.validator_indices.extend(core_index_to_inject);
2618	}
2619
2620	/// Update the validator indices and core index in the candidate.
2621	pub fn set_validator_indices_and_core_index(
2622		&mut self,
2623		new_indices: BitVec<u8, bitvec::order::Lsb0>,
2624		maybe_core_index: Option<CoreIndex>,
2625	) {
2626		self.validator_indices = new_indices;
2627
2628		if let Some(core_index) = maybe_core_index {
2629			self.inject_core_index(core_index);
2630		}
2631	}
2632}
2633
2634/// Scraped runtime backing votes and resolved disputes.
2635#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
2636#[cfg_attr(feature = "std", derive(PartialEq))]
2637pub struct ScrapedOnChainVotes<H: Encode + Decode = Hash> {
2638	/// The session in which the block was included.
2639	pub session: SessionIndex,
2640	/// Set of backing validators for each candidate, represented by its candidate
2641	/// receipt.
2642	pub backing_validators_per_candidate:
2643		Vec<(CandidateReceiptV2<H>, Vec<(ValidatorIndex, ValidityAttestation)>)>,
2644	/// On-chain-recorded set of disputes.
2645	/// Note that the above `backing_validators` are
2646	/// unrelated to the backers of the disputes candidates.
2647	pub disputes: MultiDisputeStatementSet,
2648}
2649
2650/// Information about a core which is currently occupied.
2651#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
2652#[cfg_attr(feature = "std", derive(PartialEq))]
2653pub struct OccupiedCore<H = Hash, N = BlockNumber> {
2654	// NOTE: this has no ParaId as it can be deduced from the candidate descriptor.
2655	/// If this core is freed by availability, this is the assignment that is next up on this
2656	/// core, if any. None if there is nothing queued for this core.
2657	pub next_up_on_available: Option<ScheduledCore>,
2658	/// The relay-chain block number this began occupying the core at.
2659	pub occupied_since: N,
2660	/// The relay-chain block this will time-out at, if any.
2661	pub time_out_at: N,
2662	/// If this core is freed by being timed-out, this is the assignment that is next up on this
2663	/// core. None if there is nothing queued for this core or there is no possibility of timing
2664	/// out.
2665	pub next_up_on_time_out: Option<ScheduledCore>,
2666	/// A bitfield with 1 bit for each validator in the set. `1` bits mean that the corresponding
2667	/// validators has attested to availability on-chain. A 2/3+ majority of `1` bits means that
2668	/// this will be available.
2669	pub availability: BitVec<u8, bitvec::order::Lsb0>,
2670	/// The group assigned to distribute availability pieces of this candidate.
2671	pub group_responsible: GroupIndex,
2672	/// The hash of the candidate occupying the core.
2673	pub candidate_hash: CandidateHash,
2674	/// The descriptor of the candidate occupying the core.
2675	pub candidate_descriptor: CandidateDescriptorV2<H>,
2676}
2677
2678impl<H, N> OccupiedCore<H, N> {
2679	/// Get the Para currently occupying this core.
2680	pub fn para_id(&self) -> Id {
2681		self.candidate_descriptor.para_id
2682	}
2683}
2684
2685/// The state of a particular availability core.
2686#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
2687#[cfg_attr(feature = "std", derive(PartialEq))]
2688pub enum CoreState<H = Hash, N = BlockNumber> {
2689	/// The core is currently occupied.
2690	#[codec(index = 0)]
2691	Occupied(OccupiedCore<H, N>),
2692	/// The core is currently free, with a para scheduled and given the opportunity
2693	/// to occupy.
2694	///
2695	/// If a particular Collator is required to author this block, that is also present in this
2696	/// variant.
2697	#[codec(index = 1)]
2698	Scheduled(ScheduledCore),
2699	/// The core is currently free and there is nothing scheduled. This can be the case for
2700	/// parathread cores when there are no parathread blocks queued. Parachain cores will never be
2701	/// left idle.
2702	#[codec(index = 2)]
2703	Free,
2704}
2705
2706impl<N> CoreState<N> {
2707	/// Returns the scheduled `ParaId` for the core or `None` if nothing is scheduled.
2708	///
2709	/// This function is deprecated. `ClaimQueue` should be used to obtain the scheduled `ParaId`s
2710	/// for each core.
2711	#[deprecated(
2712		note = "`para_id` will be removed. Use `ClaimQueue` to query the scheduled `para_id` instead."
2713	)]
2714	pub fn para_id(&self) -> Option<Id> {
2715		match self {
2716			Self::Occupied(ref core) => core.next_up_on_available.as_ref().map(|n| n.para_id),
2717			Self::Scheduled(core) => Some(core.para_id),
2718			Self::Free => None,
2719		}
2720	}
2721
2722	/// Is this core state `Self::Occupied`?
2723	pub fn is_occupied(&self) -> bool {
2724		matches!(self, Self::Occupied(_))
2725	}
2726}
2727
2728/// The claim queue mapped by parachain id.
2729pub type TransposedClaimQueue = BTreeMap<ParaId, BTreeMap<u8, BTreeSet<CoreIndex>>>;
2730
2731/// Returns a mapping between the para id and the core indices assigned at different
2732/// depths in the claim queue.
2733pub fn transpose_claim_queue(
2734	claim_queue: BTreeMap<CoreIndex, VecDeque<Id>>,
2735) -> TransposedClaimQueue {
2736	let mut per_para_claim_queue = BTreeMap::new();
2737
2738	for (core, paras) in claim_queue {
2739		// Iterate paras assigned to this core at each depth.
2740		for (depth, para) in paras.into_iter().enumerate() {
2741			let depths: &mut BTreeMap<u8, BTreeSet<CoreIndex>> =
2742				per_para_claim_queue.entry(para).or_insert_with(|| Default::default());
2743
2744			depths.entry(depth as u8).or_default().insert(core);
2745		}
2746	}
2747
2748	per_para_claim_queue
2749}
2750
2751// Approval Slashes primitives
2752/// Supercedes the old 'SlashingOffenceKind' enum.
2753#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, DecodeWithMemTracking, TypeInfo, Debug)]
2754pub enum DisputeOffenceKind {
2755	/// A severe offence when a validator backed an invalid block
2756	/// (backing only)
2757	#[codec(index = 0)]
2758	ForInvalidBacked,
2759	/// A minor offence when a validator disputed a valid block.
2760	/// (approval checking and dispute vote only)
2761	#[codec(index = 1)]
2762	AgainstValid,
2763	/// A medium offence when a validator approved an invalid block
2764	/// (approval checking and dispute vote only)
2765	#[codec(index = 2)]
2766	ForInvalidApproved,
2767}
2768
2769/// impl for a conversion from SlashingOffenceKind to DisputeOffenceKind
2770/// This creates DisputeOffenceKind that never contains ForInvalidApproved since it was not
2771/// supported in the past
2772impl From<super::v9::slashing::SlashingOffenceKind> for DisputeOffenceKind {
2773	fn from(value: super::v9::slashing::SlashingOffenceKind) -> Self {
2774		match value {
2775			super::v9::slashing::SlashingOffenceKind::ForInvalid => Self::ForInvalidBacked,
2776			super::v9::slashing::SlashingOffenceKind::AgainstValid => Self::AgainstValid,
2777		}
2778	}
2779}
2780
2781/// impl for a tryFrom conversion from DisputeOffenceKind to SlashingOffenceKind
2782impl TryFrom<DisputeOffenceKind> for super::v9::slashing::SlashingOffenceKind {
2783	type Error = ();
2784
2785	fn try_from(value: DisputeOffenceKind) -> Result<Self, Self::Error> {
2786		match value {
2787			DisputeOffenceKind::ForInvalidBacked => Ok(Self::ForInvalid),
2788			DisputeOffenceKind::AgainstValid => Ok(Self::AgainstValid),
2789			DisputeOffenceKind::ForInvalidApproved => Err(()),
2790		}
2791	}
2792}
2793
2794#[cfg(test)]
2795/// Basic tests
2796pub mod tests {
2797	use super::*;
2798
2799	#[test]
2800	fn group_rotation_info_calculations() {
2801		let info =
2802			GroupRotationInfo { session_start_block: 10u32, now: 15, group_rotation_frequency: 5 };
2803
2804		assert_eq!(info.next_rotation_at(), 20);
2805		assert_eq!(info.last_rotation_at(), 15);
2806	}
2807
2808	#[test]
2809	fn group_for_core_is_core_for_group() {
2810		for cores in 1..=256 {
2811			for rotations in 0..(cores * 2) {
2812				let info = GroupRotationInfo {
2813					session_start_block: 0u32,
2814					now: rotations,
2815					group_rotation_frequency: 1,
2816				};
2817
2818				for core in 0..cores {
2819					let group = info.group_for_core(CoreIndex(core), cores as usize);
2820					assert_eq!(info.core_for_group(group, cores as usize).0, core);
2821				}
2822			}
2823		}
2824	}
2825
2826	#[test]
2827	fn test_byzantine_threshold() {
2828		assert_eq!(byzantine_threshold(0), 0);
2829		assert_eq!(byzantine_threshold(1), 0);
2830		assert_eq!(byzantine_threshold(2), 0);
2831		assert_eq!(byzantine_threshold(3), 0);
2832		assert_eq!(byzantine_threshold(4), 1);
2833		assert_eq!(byzantine_threshold(5), 1);
2834		assert_eq!(byzantine_threshold(6), 1);
2835		assert_eq!(byzantine_threshold(7), 2);
2836	}
2837
2838	#[test]
2839	fn test_supermajority_threshold() {
2840		assert_eq!(supermajority_threshold(0), 0);
2841		assert_eq!(supermajority_threshold(1), 1);
2842		assert_eq!(supermajority_threshold(2), 2);
2843		assert_eq!(supermajority_threshold(3), 3);
2844		assert_eq!(supermajority_threshold(4), 3);
2845		assert_eq!(supermajority_threshold(5), 4);
2846		assert_eq!(supermajority_threshold(6), 5);
2847		assert_eq!(supermajority_threshold(7), 5);
2848	}
2849
2850	#[test]
2851	fn balance_bigger_than_usize() {
2852		let zero_b: Balance = 0;
2853		let zero_u: usize = 0;
2854
2855		assert!(zero_b.leading_zeros() >= zero_u.leading_zeros());
2856	}
2857}