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