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