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;
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	Debug,
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, Debug)]
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, Debug)]
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, Debug)]
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, Debug, 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	Debug,
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, Debug)]
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, Debug)]
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, Debug)]
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, Debug)]
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, Debug)]
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, Debug)]
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, Debug)]
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	Debug,
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, Debug, 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, Debug, 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, Debug, 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, Debug, 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, Debug, 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, Debug, 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, Debug, 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, Debug)]
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, Debug, 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, Debug, 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, Debug, 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, Debug, 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, Debug)]
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, Debug)]
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, Debug, 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, Debug, 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, Debug, 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	Debug,
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(PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, Clone, TypeInfo, Debug, Copy)]
1817pub struct InternalVersion(pub u8);
1818
1819/// A type representing the version of the candidate descriptor.
1820#[derive(PartialEq, Eq, Clone, TypeInfo, Debug)]
1821pub enum CandidateDescriptorVersion {
1822	/// The old candidate descriptor version.
1823	V1,
1824	/// The new `CandidateDescriptorV2`.
1825	V2,
1826	/// An unknown version.
1827	Unknown,
1828}
1829
1830/// A unique descriptor of the candidate receipt.
1831#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo)]
1832pub struct CandidateDescriptorV2<H = Hash> {
1833	/// The ID of the para this is a candidate for.
1834	pub(super) para_id: ParaId,
1835	/// The hash of the relay-chain block this is executed in the context of.
1836	relay_parent: H,
1837	/// Version field. The raw value here is not exposed, instead it is used
1838	/// to determine the `CandidateDescriptorVersion`, see `fn version()`.
1839	/// For the current version this field is set to `0` and will be incremented
1840	/// by next versions.
1841	pub(super) version: InternalVersion,
1842	/// The core index where the candidate is backed.
1843	pub(super) core_index: u16,
1844	/// The session index of the candidate relay parent.
1845	session_index: SessionIndex,
1846	/// Reserved bytes.
1847	reserved1: [u8; 25],
1848	/// The blake2-256 hash of the persisted validation data. This is extra data derived from
1849	/// relay-chain state which may vary based on bitfields included before the candidate.
1850	/// Thus it cannot be derived entirely from the relay-parent.
1851	persisted_validation_data_hash: Hash,
1852	/// The blake2-256 hash of the PoV.
1853	pov_hash: Hash,
1854	/// The root of a block's erasure encoding Merkle tree.
1855	erasure_root: Hash,
1856	/// Reserved bytes.
1857	reserved2: [u8; 64],
1858	/// Hash of the para header that is being generated by this candidate.
1859	para_head: Hash,
1860	/// The blake2-256 hash of the validation code bytes.
1861	validation_code_hash: ValidationCodeHash,
1862}
1863
1864impl<H> CandidateDescriptorV2<H> {
1865	/// Returns the candidate descriptor version.
1866	///
1867	/// The candidate is at version 2 if the reserved fields are zeroed out
1868	/// and the internal `version` field is 0.
1869	pub fn version(&self) -> CandidateDescriptorVersion {
1870		if self.reserved2 != [0u8; 64] || self.reserved1 != [0u8; 25] {
1871			return CandidateDescriptorVersion::V1
1872		}
1873
1874		match self.version.0 {
1875			0 => CandidateDescriptorVersion::V2,
1876			_ => CandidateDescriptorVersion::Unknown,
1877		}
1878	}
1879}
1880
1881macro_rules! impl_getter {
1882	($field:ident, $type:ident) => {
1883		/// Returns the value of `$field` field.
1884		pub fn $field(&self) -> $type {
1885			self.$field
1886		}
1887	};
1888}
1889
1890impl<H: Copy> CandidateDescriptorV2<H> {
1891	impl_getter!(erasure_root, Hash);
1892	impl_getter!(para_head, Hash);
1893	impl_getter!(relay_parent, H);
1894	impl_getter!(para_id, ParaId);
1895	impl_getter!(persisted_validation_data_hash, Hash);
1896	impl_getter!(pov_hash, Hash);
1897	impl_getter!(validation_code_hash, ValidationCodeHash);
1898
1899	fn rebuild_collator_field(&self) -> CollatorId {
1900		let mut collator_id = Vec::with_capacity(32);
1901		let core_index: [u8; 2] = self.core_index.to_ne_bytes();
1902		let session_index: [u8; 4] = self.session_index.to_ne_bytes();
1903
1904		collator_id.push(self.version.0);
1905		collator_id.extend_from_slice(core_index.as_slice());
1906		collator_id.extend_from_slice(session_index.as_slice());
1907		collator_id.extend_from_slice(self.reserved1.as_slice());
1908
1909		CollatorId::from_slice(&collator_id.as_slice())
1910			.expect("Slice size is exactly 32 bytes; qed")
1911	}
1912
1913	#[cfg(feature = "test")]
1914	#[doc(hidden)]
1915	pub fn rebuild_collator_field_for_tests(&self) -> CollatorId {
1916		self.rebuild_collator_field()
1917	}
1918
1919	/// Returns the collator id if this is a v1 `CandidateDescriptor`
1920	pub fn collator(&self) -> Option<CollatorId> {
1921		if self.version() == CandidateDescriptorVersion::V1 {
1922			Some(self.rebuild_collator_field())
1923		} else {
1924			None
1925		}
1926	}
1927
1928	fn rebuild_signature_field(&self) -> CollatorSignature {
1929		CollatorSignature::from_slice(self.reserved2.as_slice())
1930			.expect("Slice size is exactly 64 bytes; qed")
1931	}
1932
1933	#[cfg(feature = "test")]
1934	#[doc(hidden)]
1935	pub fn rebuild_signature_field_for_tests(&self) -> CollatorSignature {
1936		self.rebuild_signature_field()
1937	}
1938
1939	/// Returns the collator signature of `V1` candidate descriptors, `None` otherwise.
1940	pub fn signature(&self) -> Option<CollatorSignature> {
1941		if self.version() == CandidateDescriptorVersion::V1 {
1942			return Some(self.rebuild_signature_field())
1943		}
1944
1945		None
1946	}
1947
1948	/// Returns the `core_index` of `V2` candidate descriptors, `None` otherwise.
1949	pub fn core_index(&self) -> Option<CoreIndex> {
1950		if self.version() == CandidateDescriptorVersion::V1 {
1951			return None
1952		}
1953
1954		Some(CoreIndex(self.core_index as u32))
1955	}
1956
1957	/// Returns the `session_index` of `V2` candidate descriptors, `None` otherwise.
1958	pub fn session_index(&self) -> Option<SessionIndex> {
1959		if self.version() == CandidateDescriptorVersion::V1 {
1960			return None
1961		}
1962
1963		Some(self.session_index)
1964	}
1965}
1966
1967impl<H> core::fmt::Debug for CandidateDescriptorV2<H>
1968where
1969	H: core::fmt::Debug,
1970{
1971	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1972		match self.version() {
1973			CandidateDescriptorVersion::V1 => f
1974				.debug_struct("CandidateDescriptorV1")
1975				.field("para_id", &self.para_id)
1976				.field("relay_parent", &self.relay_parent)
1977				.field("persisted_validation_hash", &self.persisted_validation_data_hash)
1978				.field("pov_hash", &self.pov_hash)
1979				.field("erasure_root", &self.erasure_root)
1980				.field("para_head", &self.para_head)
1981				.field("validation_code_hash", &self.validation_code_hash)
1982				.finish(),
1983			CandidateDescriptorVersion::V2 => f
1984				.debug_struct("CandidateDescriptorV2")
1985				.field("para_id", &self.para_id)
1986				.field("relay_parent", &self.relay_parent)
1987				.field("core_index", &self.core_index)
1988				.field("session_index", &self.session_index)
1989				.field("persisted_validation_data_hash", &self.persisted_validation_data_hash)
1990				.field("pov_hash", &self.pov_hash)
1991				.field("erasure_root", &self.pov_hash)
1992				.field("para_head", &self.para_head)
1993				.field("validation_code_hash", &self.validation_code_hash)
1994				.finish(),
1995			CandidateDescriptorVersion::Unknown => {
1996				write!(f, "Invalid CandidateDescriptorVersion")
1997			},
1998		}
1999	}
2000}
2001
2002impl<H: Copy + AsRef<[u8]>> CandidateDescriptorV2<H> {
2003	/// Constructor
2004	pub fn new(
2005		para_id: Id,
2006		relay_parent: H,
2007		core_index: CoreIndex,
2008		session_index: SessionIndex,
2009		persisted_validation_data_hash: Hash,
2010		pov_hash: Hash,
2011		erasure_root: Hash,
2012		para_head: Hash,
2013		validation_code_hash: ValidationCodeHash,
2014	) -> Self {
2015		Self {
2016			para_id,
2017			relay_parent,
2018			version: InternalVersion(0),
2019			core_index: core_index.0 as u16,
2020			session_index,
2021			reserved1: [0; 25],
2022			persisted_validation_data_hash,
2023			pov_hash,
2024			erasure_root,
2025			reserved2: [0; 64],
2026			para_head,
2027			validation_code_hash,
2028		}
2029	}
2030
2031	#[cfg(feature = "test")]
2032	#[doc(hidden)]
2033	pub fn new_from_raw(
2034		para_id: Id,
2035		relay_parent: H,
2036		version: InternalVersion,
2037		core_index: u16,
2038		session_index: SessionIndex,
2039		reserved1: [u8; 25],
2040		persisted_validation_data_hash: Hash,
2041		pov_hash: Hash,
2042		erasure_root: Hash,
2043		reserved2: [u8; 64],
2044		para_head: Hash,
2045		validation_code_hash: ValidationCodeHash,
2046	) -> Self {
2047		Self {
2048			para_id,
2049			relay_parent,
2050			version,
2051			core_index,
2052			session_index,
2053			reserved1,
2054			persisted_validation_data_hash,
2055			pov_hash,
2056			erasure_root,
2057			reserved2,
2058			para_head,
2059			validation_code_hash,
2060		}
2061	}
2062}
2063
2064/// A trait to allow changing the descriptor field values in tests.
2065#[cfg(feature = "test")]
2066pub trait MutateDescriptorV2<H> {
2067	/// Set the relay parent of the descriptor.
2068	fn set_relay_parent(&mut self, relay_parent: H);
2069	/// Set the `ParaId` of the descriptor.
2070	fn set_para_id(&mut self, para_id: Id);
2071	/// Set the PoV hash of the descriptor.
2072	fn set_pov_hash(&mut self, pov_hash: Hash);
2073	/// Set the version field of the descriptor.
2074	fn set_version(&mut self, version: InternalVersion);
2075	/// Set the PVD of the descriptor.
2076	fn set_persisted_validation_data_hash(&mut self, persisted_validation_data_hash: Hash);
2077	/// Set the validation code hash of the descriptor.
2078	fn set_validation_code_hash(&mut self, validation_code_hash: ValidationCodeHash);
2079	/// Set the erasure root of the descriptor.
2080	fn set_erasure_root(&mut self, erasure_root: Hash);
2081	/// Set the para head of the descriptor.
2082	fn set_para_head(&mut self, para_head: Hash);
2083	/// Set the core index of the descriptor.
2084	fn set_core_index(&mut self, core_index: CoreIndex);
2085	/// Set the session index of the descriptor.
2086	fn set_session_index(&mut self, session_index: SessionIndex);
2087	/// Set the reserved2 field of the descriptor.
2088	fn set_reserved2(&mut self, reserved2: [u8; 64]);
2089}
2090
2091#[cfg(feature = "test")]
2092impl<H> MutateDescriptorV2<H> for CandidateDescriptorV2<H> {
2093	fn set_para_id(&mut self, para_id: Id) {
2094		self.para_id = para_id;
2095	}
2096
2097	fn set_relay_parent(&mut self, relay_parent: H) {
2098		self.relay_parent = relay_parent;
2099	}
2100
2101	fn set_pov_hash(&mut self, pov_hash: Hash) {
2102		self.pov_hash = pov_hash;
2103	}
2104
2105	fn set_version(&mut self, version: InternalVersion) {
2106		self.version = version;
2107	}
2108
2109	fn set_core_index(&mut self, core_index: CoreIndex) {
2110		self.core_index = core_index.0 as u16;
2111	}
2112
2113	fn set_session_index(&mut self, session_index: SessionIndex) {
2114		self.session_index = session_index;
2115	}
2116
2117	fn set_persisted_validation_data_hash(&mut self, persisted_validation_data_hash: Hash) {
2118		self.persisted_validation_data_hash = persisted_validation_data_hash;
2119	}
2120
2121	fn set_validation_code_hash(&mut self, validation_code_hash: ValidationCodeHash) {
2122		self.validation_code_hash = validation_code_hash;
2123	}
2124
2125	fn set_erasure_root(&mut self, erasure_root: Hash) {
2126		self.erasure_root = erasure_root;
2127	}
2128
2129	fn set_para_head(&mut self, para_head: Hash) {
2130		self.para_head = para_head;
2131	}
2132
2133	fn set_reserved2(&mut self, reserved2: [u8; 64]) {
2134		self.reserved2 = reserved2;
2135	}
2136}
2137
2138/// A candidate-receipt at version 2.
2139#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo, Debug)]
2140pub struct CandidateReceiptV2<H = Hash> {
2141	/// The descriptor of the candidate.
2142	pub descriptor: CandidateDescriptorV2<H>,
2143	/// The hash of the encoded commitments made as a result of candidate execution.
2144	pub commitments_hash: Hash,
2145}
2146
2147/// A candidate-receipt with commitments directly included.
2148#[derive(PartialEq, Eq, Clone, Encode, Decode, DecodeWithMemTracking, TypeInfo, Debug)]
2149pub struct CommittedCandidateReceiptV2<H = Hash> {
2150	/// The descriptor of the candidate.
2151	pub descriptor: CandidateDescriptorV2<H>,
2152	/// The commitments of the candidate receipt.
2153	pub commitments: CandidateCommitments,
2154}
2155
2156/// An event concerning a candidate.
2157#[derive(Clone, Encode, Decode, TypeInfo, Debug)]
2158#[cfg_attr(feature = "std", derive(PartialEq))]
2159pub enum CandidateEvent<H = Hash> {
2160	/// This candidate receipt was backed in the most recent block.
2161	/// This includes the core index the candidate is now occupying.
2162	#[codec(index = 0)]
2163	CandidateBacked(CandidateReceiptV2<H>, HeadData, CoreIndex, GroupIndex),
2164	/// This candidate receipt was included and became a parablock at the most recent block.
2165	/// This includes the core index the candidate was occupying as well as the group responsible
2166	/// for backing the candidate.
2167	#[codec(index = 1)]
2168	CandidateIncluded(CandidateReceiptV2<H>, HeadData, CoreIndex, GroupIndex),
2169	/// This candidate receipt was not made available in time and timed out.
2170	/// This includes the core index the candidate was occupying.
2171	#[codec(index = 2)]
2172	CandidateTimedOut(CandidateReceiptV2<H>, HeadData, CoreIndex),
2173}
2174
2175impl<H> CandidateReceiptV2<H> {
2176	/// Get a reference to the candidate descriptor.
2177	pub fn descriptor(&self) -> &CandidateDescriptorV2<H> {
2178		&self.descriptor
2179	}
2180
2181	/// Computes the blake2-256 hash of the receipt.
2182	pub fn hash(&self) -> CandidateHash
2183	where
2184		H: Encode,
2185	{
2186		CandidateHash(BlakeTwo256::hash_of(self))
2187	}
2188}
2189
2190impl<H: Clone> CommittedCandidateReceiptV2<H> {
2191	/// Transforms this into a plain `CandidateReceipt`.
2192	pub fn to_plain(&self) -> CandidateReceiptV2<H> {
2193		CandidateReceiptV2 {
2194			descriptor: self.descriptor.clone(),
2195			commitments_hash: self.commitments.hash(),
2196		}
2197	}
2198
2199	/// Computes the hash of the committed candidate receipt.
2200	///
2201	/// This computes the canonical hash, not the hash of the directly encoded data.
2202	/// Thus this is a shortcut for `candidate.to_plain().hash()`.
2203	pub fn hash(&self) -> CandidateHash
2204	where
2205		H: Encode,
2206	{
2207		self.to_plain().hash()
2208	}
2209
2210	/// Does this committed candidate receipt corresponds to the given [`CandidateReceiptV2`]?
2211	pub fn corresponds_to(&self, receipt: &CandidateReceiptV2<H>) -> bool
2212	where
2213		H: PartialEq,
2214	{
2215		receipt.descriptor == self.descriptor && receipt.commitments_hash == self.commitments.hash()
2216	}
2217}
2218
2219impl PartialOrd for CommittedCandidateReceiptV2 {
2220	fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
2221		Some(self.cmp(other))
2222	}
2223}
2224
2225impl Ord for CommittedCandidateReceiptV2 {
2226	fn cmp(&self, other: &Self) -> core::cmp::Ordering {
2227		self.descriptor
2228			.para_id
2229			.cmp(&other.descriptor.para_id)
2230			.then_with(|| self.commitments.head_data.cmp(&other.commitments.head_data))
2231	}
2232}
2233
2234/// A strictly increasing sequence number, typically this would be the least significant byte of the
2235/// block number.
2236#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug, Copy)]
2237pub struct CoreSelector(pub u8);
2238
2239/// An offset in the relay chain claim queue.
2240#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug, Copy)]
2241pub struct ClaimQueueOffset(pub u8);
2242
2243/// Signals that a parachain can send to the relay chain via the UMP queue.
2244#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug)]
2245pub enum UMPSignal {
2246	/// A message sent by a parachain to select the core the candidate is committed to.
2247	/// Relay chain validators, in particular backers, use the `CoreSelector` and
2248	/// `ClaimQueueOffset` to compute the index of the core the candidate has committed to.
2249	SelectCore(CoreSelector, ClaimQueueOffset),
2250	/// A message sent by a parachain to promote the reputation of a given peerid.
2251	ApprovedPeer(ApprovedPeerId),
2252}
2253
2254/// The default claim queue offset to be used if it's not configured/accessible in the parachain
2255/// runtime
2256pub const DEFAULT_CLAIM_QUEUE_OFFSET: u8 = 0;
2257
2258/// Approved PeerId type. PeerIds in polkadot should typically be 32 bytes long but for identity
2259/// multihash can go up to 64. Cannot reuse the PeerId type definition from the networking code as
2260/// it's too generic and extensible.
2261pub type ApprovedPeerId = BoundedVec<u8, ConstU32<64>>;
2262
2263#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug, Default)]
2264/// User-friendly representation of a candidate's UMP signals.
2265pub struct CandidateUMPSignals {
2266	pub(super) select_core: Option<(CoreSelector, ClaimQueueOffset)>,
2267	pub(super) approved_peer: Option<ApprovedPeerId>,
2268}
2269
2270impl CandidateUMPSignals {
2271	/// Get the core selector UMP signal.
2272	pub fn core_selector(&self) -> Option<(CoreSelector, ClaimQueueOffset)> {
2273		self.select_core
2274	}
2275
2276	/// Get a reference to the approved peer UMP signal.
2277	pub fn approved_peer(&self) -> Option<&ApprovedPeerId> {
2278		self.approved_peer.as_ref()
2279	}
2280
2281	/// Returns `true` if UMP signals are empty.
2282	pub fn is_empty(&self) -> bool {
2283		self.select_core.is_none() && self.approved_peer.is_none()
2284	}
2285
2286	fn try_decode_signal(
2287		&mut self,
2288		buffer: &mut impl codec::Input,
2289	) -> Result<(), CommittedCandidateReceiptError> {
2290		match UMPSignal::decode(buffer)
2291			.map_err(|_| CommittedCandidateReceiptError::UmpSignalDecode)?
2292		{
2293			UMPSignal::ApprovedPeer(approved_peer_id) if self.approved_peer.is_none() => {
2294				self.approved_peer = Some(approved_peer_id);
2295			},
2296			UMPSignal::SelectCore(core_selector, cq_offset) if self.select_core.is_none() => {
2297				self.select_core = Some((core_selector, cq_offset));
2298			},
2299			_ => {
2300				// This means that we got duplicate UMP signals.
2301				return Err(CommittedCandidateReceiptError::DuplicateUMPSignal)
2302			},
2303		};
2304
2305		Ok(())
2306	}
2307
2308	#[cfg(feature = "test")]
2309	#[doc(hidden)]
2310	pub fn dummy(
2311		select_core: Option<(CoreSelector, ClaimQueueOffset)>,
2312		approved_peer: Option<ApprovedPeerId>,
2313	) -> Self {
2314		Self { select_core, approved_peer }
2315	}
2316}
2317
2318/// Separator between `XCM` and `UMPSignal`.
2319pub const UMP_SEPARATOR: Vec<u8> = vec![];
2320
2321/// Utility function for skipping the ump signals.
2322pub fn skip_ump_signals<'a>(
2323	upward_messages: impl Iterator<Item = &'a Vec<u8>>,
2324) -> impl Iterator<Item = &'a Vec<u8>> {
2325	upward_messages.take_while(|message| *message != &UMP_SEPARATOR)
2326}
2327
2328impl CandidateCommitments {
2329	/// Returns the ump signals of this candidate, if any, or an error if they violate the expected
2330	/// format.
2331	pub fn ump_signals(&self) -> Result<CandidateUMPSignals, CommittedCandidateReceiptError> {
2332		let mut res = CandidateUMPSignals::default();
2333
2334		let mut signals_iter =
2335			self.upward_messages.iter().skip_while(|message| *message != &UMP_SEPARATOR);
2336
2337		if signals_iter.next().is_none() {
2338			// No UMP separator
2339			return Ok(res)
2340		}
2341
2342		// Process first signal
2343		let Some(first_signal) = signals_iter.next() else { return Ok(res) };
2344		res.try_decode_signal(&mut first_signal.as_slice())?;
2345
2346		// Process second signal
2347		let Some(second_signal) = signals_iter.next() else { return Ok(res) };
2348		res.try_decode_signal(&mut second_signal.as_slice())?;
2349
2350		// At most two signals are allowed
2351		if signals_iter.next().is_some() {
2352			return Err(CommittedCandidateReceiptError::TooManyUMPSignals)
2353		}
2354
2355		Ok(res)
2356	}
2357}
2358
2359/// CommittedCandidateReceiptError construction errors.
2360#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug)]
2361#[cfg_attr(feature = "std", derive(thiserror::Error))]
2362pub enum CommittedCandidateReceiptError {
2363	/// The specified core index is invalid.
2364	#[cfg_attr(feature = "std", error("The specified core index is invalid"))]
2365	InvalidCoreIndex,
2366	/// The core index in commitments doesn't match the one in descriptor
2367	#[cfg_attr(
2368		feature = "std",
2369		error("The core index in commitments ({commitments:?}) doesn't match the one in descriptor ({descriptor:?})")
2370	)]
2371	CoreIndexMismatch {
2372		/// The core index as found in the descriptor.
2373		descriptor: CoreIndex,
2374		/// The core index as found in the commitments.
2375		commitments: CoreIndex,
2376	},
2377	/// The core selector or claim queue offset is invalid.
2378	#[cfg_attr(feature = "std", error("The core selector or claim queue offset is invalid"))]
2379	InvalidSelectedCore,
2380	#[cfg_attr(feature = "std", error("Could not decode UMP signal"))]
2381	/// Could not decode UMP signal.
2382	UmpSignalDecode,
2383	/// The parachain is not assigned to any core at specified claim queue offset.
2384	#[cfg_attr(
2385		feature = "std",
2386		error("The parachain is not assigned to any core at specified claim queue offset")
2387	)]
2388	NoAssignment,
2389	/// Unknown version.
2390	#[cfg_attr(feature = "std", error("Unknown internal version"))]
2391	UnknownVersion(InternalVersion),
2392	/// The allowed number of `UMPSignal` messages in the queue was exceeded.
2393	#[cfg_attr(feature = "std", error("Too many UMP signals"))]
2394	TooManyUMPSignals,
2395	/// Duplicated UMP signal.
2396	#[cfg_attr(feature = "std", error("Duplicate UMP signal"))]
2397	DuplicateUMPSignal,
2398	/// If the parachain runtime started sending ump signals, v1 descriptors are no longer
2399	/// allowed.
2400	#[cfg_attr(feature = "std", error("Version 1 receipt does not support ump signals"))]
2401	UMPSignalWithV1Decriptor,
2402}
2403
2404impl<H: Copy> CommittedCandidateReceiptV2<H> {
2405	/// Performs checks on the UMP signals and returns them.
2406	///
2407	/// Also checks if descriptor core index is equal to the committed core index.
2408	///
2409	/// Params:
2410	/// - `cores_per_para` is a claim queue snapshot at the candidate's relay parent, stored as
2411	/// a mapping between `ParaId` and the cores assigned per depth.
2412	pub fn parse_ump_signals(
2413		&self,
2414		cores_per_para: &TransposedClaimQueue,
2415	) -> Result<CandidateUMPSignals, CommittedCandidateReceiptError> {
2416		let signals = self.commitments.ump_signals()?;
2417
2418		match self.descriptor.version() {
2419			CandidateDescriptorVersion::V1 => {
2420				// If the parachain runtime started sending ump signals, v1 descriptors are no
2421				// longer allowed.
2422				if !signals.is_empty() {
2423					return Err(CommittedCandidateReceiptError::UMPSignalWithV1Decriptor)
2424				} else {
2425					// Nothing else to check for v1 descriptors.
2426					return Ok(CandidateUMPSignals::default())
2427				}
2428			},
2429			CandidateDescriptorVersion::V2 => {},
2430			CandidateDescriptorVersion::Unknown =>
2431				return Err(CommittedCandidateReceiptError::UnknownVersion(self.descriptor.version)),
2432		}
2433
2434		// Check the core index
2435		let (maybe_core_index_selector, cq_offset) = signals
2436			.core_selector()
2437			.map(|(selector, offset)| (Some(selector), offset))
2438			.unwrap_or_else(|| (None, ClaimQueueOffset(DEFAULT_CLAIM_QUEUE_OFFSET)));
2439
2440		self.check_core_index(cores_per_para, maybe_core_index_selector, cq_offset)?;
2441
2442		// Nothing to further check for the approved peer. If everything passed so far, return the
2443		// signals.
2444		Ok(signals)
2445	}
2446
2447	/// Checks if descriptor core index is equal to the committed core index.
2448	/// Input `cores_per_para` is a claim queue snapshot at the candidate's relay parent, stored as
2449	/// a mapping between `ParaId` and the cores assigned per depth.
2450	fn check_core_index(
2451		&self,
2452		cores_per_para: &TransposedClaimQueue,
2453		maybe_core_index_selector: Option<CoreSelector>,
2454		cq_offset: ClaimQueueOffset,
2455	) -> Result<(), CommittedCandidateReceiptError> {
2456		let assigned_cores = cores_per_para
2457			.get(&self.descriptor.para_id())
2458			.ok_or(CommittedCandidateReceiptError::NoAssignment)?
2459			.get(&cq_offset.0)
2460			.ok_or(CommittedCandidateReceiptError::NoAssignment)?;
2461
2462		if assigned_cores.is_empty() {
2463			return Err(CommittedCandidateReceiptError::NoAssignment)
2464		}
2465
2466		let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32);
2467
2468		let core_index_selector = if let Some(core_index_selector) = maybe_core_index_selector {
2469			// We have a committed core selector, we can use it.
2470			core_index_selector
2471		} else if assigned_cores.len() > 1 {
2472			// We got more than one assigned core and no core selector. Special care is needed.
2473			if !assigned_cores.contains(&descriptor_core_index) {
2474				// core index in the descriptor is not assigned to the para. Error.
2475				return Err(CommittedCandidateReceiptError::InvalidCoreIndex)
2476			} else {
2477				// the descriptor core index is indeed assigned to the para. This is the most we can
2478				// check for now
2479				return Ok(())
2480			}
2481		} else {
2482			// No core selector but there's only one assigned core, use it.
2483			CoreSelector(0)
2484		};
2485
2486		let core_index = assigned_cores
2487			.iter()
2488			.nth(core_index_selector.0 as usize % assigned_cores.len())
2489			.ok_or(CommittedCandidateReceiptError::InvalidSelectedCore)
2490			.copied()?;
2491
2492		if core_index != descriptor_core_index {
2493			return Err(CommittedCandidateReceiptError::CoreIndexMismatch {
2494				descriptor: descriptor_core_index,
2495				commitments: core_index,
2496			})
2497		}
2498
2499		Ok(())
2500	}
2501}
2502
2503/// A backed (or backable, depending on context) candidate.
2504#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug, TypeInfo)]
2505pub struct BackedCandidate<H = Hash> {
2506	/// The candidate referred to.
2507	candidate: CommittedCandidateReceiptV2<H>,
2508	/// The validity votes themselves, expressed as signatures.
2509	validity_votes: Vec<ValidityAttestation>,
2510	/// The indices of the validators within the group, expressed as a bitfield. May be extended
2511	/// beyond the backing group size to contain the assigned core index, if ElasticScalingMVP is
2512	/// enabled.
2513	validator_indices: BitVec<u8, bitvec::order::Lsb0>,
2514}
2515
2516/// Parachains inherent-data passed into the runtime by a block author
2517#[derive(Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Debug, TypeInfo)]
2518pub struct InherentData<HDR: HeaderT = Header> {
2519	/// Signed bitfields by validators about availability.
2520	pub bitfields: UncheckedSignedAvailabilityBitfields,
2521	/// Backed candidates for inclusion in the block.
2522	pub backed_candidates: Vec<BackedCandidate<HDR::Hash>>,
2523	/// Sets of dispute votes for inclusion,
2524	pub disputes: MultiDisputeStatementSet,
2525	/// The parent block header. Used for checking state proofs.
2526	pub parent_header: HDR,
2527}
2528
2529impl<H> BackedCandidate<H> {
2530	/// Constructor
2531	pub fn new(
2532		candidate: CommittedCandidateReceiptV2<H>,
2533		validity_votes: Vec<ValidityAttestation>,
2534		validator_indices: BitVec<u8, bitvec::order::Lsb0>,
2535		core_index: CoreIndex,
2536	) -> Self {
2537		let mut instance = Self { candidate, validity_votes, validator_indices };
2538		instance.inject_core_index(core_index);
2539		instance
2540	}
2541
2542	/// Get a reference to the committed candidate receipt of the candidate.
2543	pub fn candidate(&self) -> &CommittedCandidateReceiptV2<H> {
2544		&self.candidate
2545	}
2546
2547	/// Get a mutable reference to the committed candidate receipt of the candidate.
2548	/// Only for testing.
2549	#[cfg(feature = "test")]
2550	pub fn candidate_mut(&mut self) -> &mut CommittedCandidateReceiptV2<H> {
2551		&mut self.candidate
2552	}
2553	/// Get a reference to the descriptor of the candidate.
2554	pub fn descriptor(&self) -> &CandidateDescriptorV2<H> {
2555		&self.candidate.descriptor
2556	}
2557
2558	/// Get a mutable reference to the descriptor of the candidate. Only for testing.
2559	#[cfg(feature = "test")]
2560	pub fn descriptor_mut(&mut self) -> &mut CandidateDescriptorV2<H> {
2561		&mut self.candidate.descriptor
2562	}
2563
2564	/// Get a reference to the validity votes of the candidate.
2565	pub fn validity_votes(&self) -> &[ValidityAttestation] {
2566		&self.validity_votes
2567	}
2568
2569	/// Get a mutable reference to validity votes of the para.
2570	pub fn validity_votes_mut(&mut self) -> &mut Vec<ValidityAttestation> {
2571		&mut self.validity_votes
2572	}
2573
2574	/// Compute this candidate's hash.
2575	pub fn hash(&self) -> CandidateHash
2576	where
2577		H: Clone + Encode,
2578	{
2579		self.candidate.to_plain().hash()
2580	}
2581
2582	/// Get this candidate's receipt.
2583	pub fn receipt(&self) -> CandidateReceiptV2<H>
2584	where
2585		H: Clone,
2586	{
2587		self.candidate.to_plain()
2588	}
2589
2590	/// Get a copy of the raw validator indices.
2591	#[cfg(feature = "test")]
2592	pub fn raw_validator_indices(&self) -> BitVec<u8, bitvec::order::Lsb0> {
2593		self.validator_indices.clone()
2594	}
2595
2596	/// Get a copy of the validator indices and the assumed core index, if any.
2597	pub fn validator_indices_and_core_index(
2598		&self,
2599	) -> (&BitSlice<u8, bitvec::order::Lsb0>, Option<CoreIndex>) {
2600		// `BackedCandidate::validity_indices` are extended to store a 8 bit core index.
2601		let core_idx_offset = self.validator_indices.len().saturating_sub(8);
2602		if core_idx_offset > 0 {
2603			let (validator_indices_slice, core_idx_slice) =
2604				self.validator_indices.split_at(core_idx_offset);
2605			return (validator_indices_slice, Some(CoreIndex(core_idx_slice.load::<u8>() as u32)));
2606		}
2607
2608		(&self.validator_indices, None)
2609	}
2610
2611	/// Inject a core index in the validator_indices bitvec.
2612	fn inject_core_index(&mut self, core_index: CoreIndex) {
2613		let core_index_to_inject: BitVec<u8, bitvec::order::Lsb0> =
2614			BitVec::from_vec(vec![core_index.0 as u8]);
2615		self.validator_indices.extend(core_index_to_inject);
2616	}
2617
2618	/// Update the validator indices and core index in the candidate.
2619	pub fn set_validator_indices_and_core_index(
2620		&mut self,
2621		new_indices: BitVec<u8, bitvec::order::Lsb0>,
2622		maybe_core_index: Option<CoreIndex>,
2623	) {
2624		self.validator_indices = new_indices;
2625
2626		if let Some(core_index) = maybe_core_index {
2627			self.inject_core_index(core_index);
2628		}
2629	}
2630}
2631
2632/// Scraped runtime backing votes and resolved disputes.
2633#[derive(Clone, Encode, Decode, Debug, TypeInfo)]
2634#[cfg_attr(feature = "std", derive(PartialEq))]
2635pub struct ScrapedOnChainVotes<H: Encode + Decode = Hash> {
2636	/// The session in which the block was included.
2637	pub session: SessionIndex,
2638	/// Set of backing validators for each candidate, represented by its candidate
2639	/// receipt.
2640	pub backing_validators_per_candidate:
2641		Vec<(CandidateReceiptV2<H>, Vec<(ValidatorIndex, ValidityAttestation)>)>,
2642	/// On-chain-recorded set of disputes.
2643	/// Note that the above `backing_validators` are
2644	/// unrelated to the backers of the disputes candidates.
2645	pub disputes: MultiDisputeStatementSet,
2646}
2647
2648/// Information about a core which is currently occupied.
2649#[derive(Clone, Encode, Decode, TypeInfo, Debug)]
2650#[cfg_attr(feature = "std", derive(PartialEq))]
2651pub struct OccupiedCore<H = Hash, N = BlockNumber> {
2652	// NOTE: this has no ParaId as it can be deduced from the candidate descriptor.
2653	/// If this core is freed by availability, this is the assignment that is next up on this
2654	/// core, if any. None if there is nothing queued for this core.
2655	pub next_up_on_available: Option<ScheduledCore>,
2656	/// The relay-chain block number this began occupying the core at.
2657	pub occupied_since: N,
2658	/// The relay-chain block this will time-out at, if any.
2659	pub time_out_at: N,
2660	/// If this core is freed by being timed-out, this is the assignment that is next up on this
2661	/// core. None if there is nothing queued for this core or there is no possibility of timing
2662	/// out.
2663	pub next_up_on_time_out: Option<ScheduledCore>,
2664	/// A bitfield with 1 bit for each validator in the set. `1` bits mean that the corresponding
2665	/// validators has attested to availability on-chain. A 2/3+ majority of `1` bits means that
2666	/// this will be available.
2667	pub availability: BitVec<u8, bitvec::order::Lsb0>,
2668	/// The group assigned to distribute availability pieces of this candidate.
2669	pub group_responsible: GroupIndex,
2670	/// The hash of the candidate occupying the core.
2671	pub candidate_hash: CandidateHash,
2672	/// The descriptor of the candidate occupying the core.
2673	pub candidate_descriptor: CandidateDescriptorV2<H>,
2674}
2675
2676impl<H, N> OccupiedCore<H, N> {
2677	/// Get the Para currently occupying this core.
2678	pub fn para_id(&self) -> Id {
2679		self.candidate_descriptor.para_id
2680	}
2681}
2682
2683/// The state of a particular availability core.
2684#[derive(Clone, Encode, Decode, TypeInfo, Debug)]
2685#[cfg_attr(feature = "std", derive(PartialEq))]
2686pub enum CoreState<H = Hash, N = BlockNumber> {
2687	/// The core is currently occupied.
2688	#[codec(index = 0)]
2689	Occupied(OccupiedCore<H, N>),
2690	/// The core is currently free, with a para scheduled and given the opportunity
2691	/// to occupy.
2692	///
2693	/// If a particular Collator is required to author this block, that is also present in this
2694	/// variant.
2695	#[codec(index = 1)]
2696	Scheduled(ScheduledCore),
2697	/// The core is currently free and there is nothing scheduled. This can be the case for
2698	/// parathread cores when there are no parathread blocks queued. Parachain cores will never be
2699	/// left idle.
2700	#[codec(index = 2)]
2701	Free,
2702}
2703
2704impl<N> CoreState<N> {
2705	/// Returns the scheduled `ParaId` for the core or `None` if nothing is scheduled.
2706	///
2707	/// This function is deprecated. `ClaimQueue` should be used to obtain the scheduled `ParaId`s
2708	/// for each core.
2709	#[deprecated(
2710		note = "`para_id` will be removed. Use `ClaimQueue` to query the scheduled `para_id` instead."
2711	)]
2712	pub fn para_id(&self) -> Option<Id> {
2713		match self {
2714			Self::Occupied(ref core) => core.next_up_on_available.as_ref().map(|n| n.para_id),
2715			Self::Scheduled(core) => Some(core.para_id),
2716			Self::Free => None,
2717		}
2718	}
2719
2720	/// Is this core state `Self::Occupied`?
2721	pub fn is_occupied(&self) -> bool {
2722		matches!(self, Self::Occupied(_))
2723	}
2724}
2725
2726/// The claim queue mapped by parachain id.
2727pub type TransposedClaimQueue = BTreeMap<ParaId, BTreeMap<u8, BTreeSet<CoreIndex>>>;
2728
2729/// Returns a mapping between the para id and the core indices assigned at different
2730/// depths in the claim queue.
2731pub fn transpose_claim_queue(
2732	claim_queue: BTreeMap<CoreIndex, VecDeque<Id>>,
2733) -> TransposedClaimQueue {
2734	let mut per_para_claim_queue = BTreeMap::new();
2735
2736	for (core, paras) in claim_queue {
2737		// Iterate paras assigned to this core at each depth.
2738		for (depth, para) in paras.into_iter().enumerate() {
2739			let depths: &mut BTreeMap<u8, BTreeSet<CoreIndex>> =
2740				per_para_claim_queue.entry(para).or_insert_with(|| Default::default());
2741
2742			depths.entry(depth as u8).or_default().insert(core);
2743		}
2744	}
2745
2746	per_para_claim_queue
2747}
2748
2749// Approval Slashes primitives
2750/// Supercedes the old 'SlashingOffenceKind' enum.
2751#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, DecodeWithMemTracking, TypeInfo, Debug)]
2752pub enum DisputeOffenceKind {
2753	/// A severe offence when a validator backed an invalid block
2754	/// (backing only)
2755	#[codec(index = 0)]
2756	ForInvalidBacked,
2757	/// A minor offence when a validator disputed a valid block.
2758	/// (approval checking and dispute vote only)
2759	#[codec(index = 1)]
2760	AgainstValid,
2761	/// A medium offence when a validator approved an invalid block
2762	/// (approval checking and dispute vote only)
2763	#[codec(index = 2)]
2764	ForInvalidApproved,
2765}
2766
2767/// impl for a conversion from SlashingOffenceKind to DisputeOffenceKind
2768/// This creates DisputeOffenceKind that never contains ForInvalidApproved since it was not
2769/// supported in the past
2770impl From<super::v9::slashing::SlashingOffenceKind> for DisputeOffenceKind {
2771	fn from(value: super::v9::slashing::SlashingOffenceKind) -> Self {
2772		match value {
2773			super::v9::slashing::SlashingOffenceKind::ForInvalid => Self::ForInvalidBacked,
2774			super::v9::slashing::SlashingOffenceKind::AgainstValid => Self::AgainstValid,
2775		}
2776	}
2777}
2778
2779/// impl for a tryFrom conversion from DisputeOffenceKind to SlashingOffenceKind
2780impl TryFrom<DisputeOffenceKind> for super::v9::slashing::SlashingOffenceKind {
2781	type Error = ();
2782
2783	fn try_from(value: DisputeOffenceKind) -> Result<Self, Self::Error> {
2784		match value {
2785			DisputeOffenceKind::ForInvalidBacked => Ok(Self::ForInvalid),
2786			DisputeOffenceKind::AgainstValid => Ok(Self::AgainstValid),
2787			DisputeOffenceKind::ForInvalidApproved => Err(()),
2788		}
2789	}
2790}
2791
2792#[cfg(test)]
2793/// Basic tests
2794pub mod tests {
2795	use super::*;
2796
2797	#[test]
2798	fn group_rotation_info_calculations() {
2799		let info =
2800			GroupRotationInfo { session_start_block: 10u32, now: 15, group_rotation_frequency: 5 };
2801
2802		assert_eq!(info.next_rotation_at(), 20);
2803		assert_eq!(info.last_rotation_at(), 15);
2804	}
2805
2806	#[test]
2807	fn group_for_core_is_core_for_group() {
2808		for cores in 1..=256 {
2809			for rotations in 0..(cores * 2) {
2810				let info = GroupRotationInfo {
2811					session_start_block: 0u32,
2812					now: rotations,
2813					group_rotation_frequency: 1,
2814				};
2815
2816				for core in 0..cores {
2817					let group = info.group_for_core(CoreIndex(core), cores as usize);
2818					assert_eq!(info.core_for_group(group, cores as usize).0, core);
2819				}
2820			}
2821		}
2822	}
2823
2824	#[test]
2825	fn test_byzantine_threshold() {
2826		assert_eq!(byzantine_threshold(0), 0);
2827		assert_eq!(byzantine_threshold(1), 0);
2828		assert_eq!(byzantine_threshold(2), 0);
2829		assert_eq!(byzantine_threshold(3), 0);
2830		assert_eq!(byzantine_threshold(4), 1);
2831		assert_eq!(byzantine_threshold(5), 1);
2832		assert_eq!(byzantine_threshold(6), 1);
2833		assert_eq!(byzantine_threshold(7), 2);
2834	}
2835
2836	#[test]
2837	fn test_supermajority_threshold() {
2838		assert_eq!(supermajority_threshold(0), 0);
2839		assert_eq!(supermajority_threshold(1), 1);
2840		assert_eq!(supermajority_threshold(2), 2);
2841		assert_eq!(supermajority_threshold(3), 3);
2842		assert_eq!(supermajority_threshold(4), 3);
2843		assert_eq!(supermajority_threshold(5), 4);
2844		assert_eq!(supermajority_threshold(6), 5);
2845		assert_eq!(supermajority_threshold(7), 5);
2846	}
2847
2848	#[test]
2849	fn balance_bigger_than_usize() {
2850		let zero_b: Balance = 0;
2851		let zero_u: usize = 0;
2852
2853		assert!(zero_b.leading_zeros() >= zero_u.leading_zeros());
2854	}
2855}