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