From 793142e5c2e97253fe21e1e80217b08e077857bd Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 17 Jul 2024 15:19:14 +0300 Subject: [PATCH 001/130] WIP primitives Signed-off-by: Andrei Sandu --- polkadot/primitives/src/v7/mod.rs | 2 +- polkadot/primitives/src/vstaging/mod.rs | 215 +++++++++++++++++++++++- 2 files changed, 215 insertions(+), 2 deletions(-) diff --git a/polkadot/primitives/src/v7/mod.rs b/polkadot/primitives/src/v7/mod.rs index a729d8cee4c7..18f52951986a 100644 --- a/polkadot/primitives/src/v7/mod.rs +++ b/polkadot/primitives/src/v7/mod.rs @@ -2052,7 +2052,7 @@ pub mod node_features { } #[cfg(test)] -mod tests { +pub mod tests { use super::*; use bitvec::bitvec; use sp_core::sr25519; diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 27296213e611..ff138781153f 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -17,7 +17,11 @@ //! Staging Primitives. // Put any primitives used by staging APIs functions here -use crate::v7::*; +use super::{ + Balance, CoreIndex, CandidateCommitments, Hash, Id, ValidationCode, ValidationCodeHash, + ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, +}; +use sp_std::prelude::*; use codec::{Decode, Encode}; use scale_info::TypeInfo; @@ -98,3 +102,212 @@ impl> Default for SchedulerParams } } } + +/// A unique descriptor of the candidate receipt. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct CandidateDescriptor { + /// The ID of the para this is a candidate for. + pub para_id: Id, + /// The hash of the relay-chain block this is executed in the context of. + pub relay_parent: H, + /// The core index where the candidate is backed. + pub core_index: CoreIndex, + /// Reserved bytes. + pub reserved28b: [u8; 27], + /// The blake2-256 hash of the persisted validation data. This is extra data derived from + /// relay-chain state which may vary based on bitfields included before the candidate. + /// Thus it cannot be derived entirely from the relay-parent. + pub persisted_validation_data_hash: Hash, + /// The blake2-256 hash of the PoV. + pub pov_hash: Hash, + /// The root of a block's erasure encoding Merkle tree. + pub erasure_root: Hash, + /// Reserved bytes. + pub reserved64b: [u8; 64], + /// Hash of the para header that is being generated by this candidate. + pub para_head: Hash, + /// The blake2-256 hash of the validation code bytes. + pub validation_code_hash: ValidationCodeHash, +} + +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub enum ExtendedCommitment { + #[codec(index = 0)] + CoreIndex(CoreIndex), +} + +pub const UMP_SEPARATOR: Vec = vec![]; + + +// /// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation. +// #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +// #[cfg_attr(feature = "std", derive(Default, Hash))] +// pub struct CandidateCommitments { +// /// Messages destined to be interpreted by the Relay chain itself. +// pub upward_messages: UpwardMessages, +// /// Horizontal messages sent by the parachain. +// pub horizontal_messages: HorizontalMessages, +// /// New validation code. +// pub new_validation_code: Option, +// /// The head-data produced as a result of execution. +// pub head_data: HeadData, +// /// The number of messages processed from the DMQ. +// pub processed_downward_messages: u32, +// /// The mark which specifies the block number up to which all inbound HRMP messages are +// /// processed. +// pub hrmp_watermark: N, +// } + +/// A candidate-receipt with commitments directly included. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct CommittedCandidateReceipt { + /// The descriptor of the candidate. + descriptor: CandidateDescriptor, + /// The commitments of the candidate receipt. + commitments: CandidateCommitments, +} + +impl CandidateCommitments { + /// Returns the core index the candidate has commited to. + pub fn core_index(&self) -> Option { + /// We need at least 2 messages for the separator and core index + if self.upward_messages.len() < 2 { + return None + } + + let upward_commitments = self + .upward_messages + .iter() + .cloned() + .rev() + .take_while(|message| message != &UMP_SEPARATOR) + .collect::>(); + + // We didn't find the separator, no core index commitment. + if upward_commitments.len() == self.upward_messages.len() || + upward_commitments.is_empty() + { + return None + } + + // Use first commitment + let Some(message) = upward_commitments.into_iter().rev().next() else { return None }; + + match Commitment::decode(&mut message.as_slice()).ok()? { + Commitment::CoreIndex(core_index) => Some(core_index), + } + } +} + +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub enum CandidateReceiptError { + /// The specified core index is invalid. + InvalidCoreIndex, + /// The core index in commitments doesnt match the one in descriptor + CoreIndexMismatch, +} + +impl CommittedCandidateReceipt { + /// Constructor from descriptor and commitments after sanity checking core index commitments. + pub fn new(descriptor: CandidateDescriptor, commitments: CandidateCommitments, n_cores: u32) -> Result { + // First check if we have a core index commitment + if commitments.core_index() != descriptor.core_index { + return Err(CandidateReceiptError::CoreIndexMismatch) + } + + match descriptor.core_index { + Some(core_index) => { + if core_index.0 > n_cores - 1 { + return Err(CandidateReceiptError::InvalidCoreIndex) + } + + Ok(Self { descriptor, commitments }) + }, + None => Ok(Self { descriptor, commitments }) + } + } + + /// Returns are reference to commitments + pub fn commitments(&self) -> &CandidateCommitments { + &self.commitments + } + + /// Returns a reference to the descriptor + pub fn descriptor(&self) -> &CandidateDescriptor { + &self.descriptor + } + + +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + v7::{ + tests::dummy_committed_candidate_receipt as dummy_old_committed_candidate_receipt, + CandidateReceipt as OldCandidateReceipt, Hash, HeadData, + }, + vstaging::CommittedCandidateReceipt, + }; + + pub fn dummy_committed_candidate_receipt() -> CommittedCandidateReceipt { + let zeros = Hash::zero(); + let reserved64b = [0; 64]; + + CommittedCandidateReceipt { + descriptor: CandidateDescriptor { + para_id: 0.into(), + relay_parent: zeros, + core_index: Some(CoreIndex(123)), + reserved28b: Default::default(), + persisted_validation_data_hash: zeros, + pov_hash: zeros, + erasure_root: zeros, + reserved64b, + para_head: zeros, + validation_code_hash: ValidationCode(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]).hash(), + }, + commitments: CandidateCommitments { + head_data: HeadData(vec![]), + upward_messages: vec![].try_into().expect("empty vec fits within bounds"), + new_validation_code: None, + horizontal_messages: vec![].try_into().expect("empty vec fits within bounds"), + processed_downward_messages: 0, + hrmp_watermark: 0_u32, + }, + } + } + + #[test] + fn is_binary_compatibile() { + let mut old_ccr = dummy_old_committed_candidate_receipt(); + let mut new_ccr = dummy_committed_candidate_receipt(); + + assert_eq!(old_ccr.encoded_size(), new_ccr.encoded_size()); + assert_eq!(new_ccr.commitments().core_index(), None); + } + + #[test] + fn test_ump_commitment() { + let old_ccr = dummy_old_committed_candidate_receipt(); + let mut new_ccr = dummy_committed_candidate_receipt(); + + // XCM messages + new_ccr.commitments.upward_messages.force_push(vec![0u8; 256]); + new_ccr.commitments.upward_messages.force_push(vec![0xff; 256]); + + // separator + new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); + + // CoreIndex commitment + new_ccr + .commitments + .upward_messages + .force_push(Commitment::CoreIndex(CoreIndex(123)).encode()); + + assert_eq!(new_ccr.descriptor.core_index, Some(CoreIndex(123))); + } +} From 3a29fdf3bf05f0558abccfb1a3f6be8c42473918 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 5 Aug 2024 19:43:14 +0300 Subject: [PATCH 002/130] WIP Signed-off-by: Andrei Sandu --- Cargo.lock | 2 + polkadot/primitives/Cargo.toml | 4 + polkadot/primitives/src/vstaging/mod.rs | 489 +++++++++++++++----- polkadot/primitives/test-helpers/src/lib.rs | 69 ++- 4 files changed, 459 insertions(+), 105 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ebacc9ec5a8..8d0aa320c83c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13982,6 +13982,7 @@ dependencies = [ "parity-scale-codec", "polkadot-core-primitives", "polkadot-parachain-primitives", + "polkadot-primitives-test-helpers", "scale-info", "serde", "sp-api", @@ -13995,6 +13996,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "sp-staking", + "sp-std 14.0.0", ] [[package]] diff --git a/polkadot/primitives/Cargo.toml b/polkadot/primitives/Cargo.toml index 8f7ec314ecff..09afc9662d62 100644 --- a/polkadot/primitives/Cargo.toml +++ b/polkadot/primitives/Cargo.toml @@ -28,10 +28,14 @@ sp-consensus-slots = { features = ["serde"], workspace = true } sp-io = { workspace = true } sp-keystore = { optional = true, workspace = true } sp-staking = { features = ["serde"], workspace = true } +sp-std = { workspace = true, optional = true } polkadot-core-primitives = { workspace = true } polkadot-parachain-primitives = { workspace = true } +[dev-dependencies] +polkadot-primitives-test-helpers = { workspace = true } + [features] default = ["std"] std = [ diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index ff138781153f..b259ba022772 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -18,15 +18,18 @@ // Put any primitives used by staging APIs functions here use super::{ - Balance, CoreIndex, CandidateCommitments, Hash, Id, ValidationCode, ValidationCodeHash, + Balance, BlakeTwo256, BlockNumber, CandidateCommitments, CandidateDescriptor, CandidateHash, + CoreIndex, Hash, HashT, Id, Id as ParaId, ValidationCode, ValidationCodeHash, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, }; -use sp_std::prelude::*; +use alloc::collections::{btree_map::BTreeMap, vec_deque::VecDeque}; use codec::{Decode, Encode}; use scale_info::TypeInfo; +use sp_api::Core; use sp_arithmetic::Perbill; use sp_core::RuntimeDebug; +use sp_staking::SessionIndex; /// Scheduler configuration parameters. All coretime/ondemand parameters are here. #[derive( @@ -106,73 +109,312 @@ impl> Default for SchedulerParams /// A unique descriptor of the candidate receipt. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Hash))] -pub struct CandidateDescriptor { +pub struct CandidateDescriptorV2 { /// The ID of the para this is a candidate for. - pub para_id: Id, + para_id: ParaId, /// The hash of the relay-chain block this is executed in the context of. - pub relay_parent: H, + relay_parent: H, /// The core index where the candidate is backed. - pub core_index: CoreIndex, + core_index: u16, + /// The session index of the candidate relay parent. + session_index: SessionIndex, /// Reserved bytes. - pub reserved28b: [u8; 27], + reserved28b: [u8; 26], /// The blake2-256 hash of the persisted validation data. This is extra data derived from /// relay-chain state which may vary based on bitfields included before the candidate. /// Thus it cannot be derived entirely from the relay-parent. - pub persisted_validation_data_hash: Hash, + persisted_validation_data_hash: Hash, /// The blake2-256 hash of the PoV. - pub pov_hash: Hash, + pov_hash: Hash, /// The root of a block's erasure encoding Merkle tree. - pub erasure_root: Hash, + erasure_root: Hash, /// Reserved bytes. - pub reserved64b: [u8; 64], + reserved64b: [u8; 64], /// Hash of the para header that is being generated by this candidate. - pub para_head: Hash, + para_head: Hash, /// The blake2-256 hash of the validation code bytes. - pub validation_code_hash: ValidationCodeHash, + validation_code_hash: ValidationCodeHash, } -#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] -pub enum ExtendedCommitment { - #[codec(index = 0)] - CoreIndex(CoreIndex), +impl CandidateDescriptorV2 { + /// Constructor + pub fn new( + para_id: Id, + relay_parent: H, + core_index: CoreIndex, + session_index: SessionIndex, + persisted_validation_data_hash: Hash, + pov_hash: Hash, + erasure_root: Hash, + para_head: Hash, + validation_code_hash: ValidationCodeHash, + ) -> Self { + Self { + para_id, + relay_parent, + core_index: core_index.0 as u16, + session_index, + reserved28b: [0; 26], + persisted_validation_data_hash, + pov_hash, + erasure_root, + reserved64b: [0; 64], + para_head, + validation_code_hash, + } + } } +/// Version 1 API to access information stored by candidate descriptors. +pub trait CandidateApiV1 { + /// Returns the ID of the para this is a candidate for. + fn para_id(&self) -> Id; -pub const UMP_SEPARATOR: Vec = vec![]; + /// Returns the blake2-256 hash of the persisted validation data. + fn persisted_validation_data_hash(&self) -> Hash; + + /// Returns the blake2-256 hash of the PoV. + fn pov_hash(&self) -> Hash; + + /// Returns the root of a block's erasure encoding Merkle tree. + fn erasure_root(&self) -> Hash; + + /// Returns the hash of the para header generated by this candidate. + fn para_head(&self) -> Hash; + + /// Return the blake2-256 hash of the validation code bytes. + fn validation_code_hash(&self) -> ValidationCodeHash; +} + +/// Version 2 API to access additional information stored by candidate descriptors +pub trait CandidateApiV2 { + /// Returns the core index where the candidate is backed. + fn core_index(&self) -> CoreIndex; + + /// Returns the session index of the candidate relay parent. + fn session_index(&self) -> SessionIndex; +} + +impl CandidateApiV1 for CandidateDescriptor { + fn para_id(&self) -> Id { + self.para_id + } + + fn persisted_validation_data_hash(&self) -> Hash { + self.persisted_validation_data_hash + } + + fn pov_hash(&self) -> Hash { + self.pov_hash + } + + fn erasure_root(&self) -> Hash { + self.erasure_root + } + + fn para_head(&self) -> Hash { + self.para_head + } + + fn validation_code_hash(&self) -> ValidationCodeHash { + self.validation_code_hash + } +} + +impl CandidateApiV1 for CandidateDescriptorV2 { + fn para_id(&self) -> Id { + self.para_id + } + + fn persisted_validation_data_hash(&self) -> Hash { + self.persisted_validation_data_hash + } + fn pov_hash(&self) -> Hash { + self.pov_hash + } + + fn erasure_root(&self) -> Hash { + self.erasure_root + } + + fn para_head(&self) -> Hash { + self.para_head + } + + fn validation_code_hash(&self) -> ValidationCodeHash { + self.validation_code_hash + } +} -// /// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation. -// #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] -// #[cfg_attr(feature = "std", derive(Default, Hash))] -// pub struct CandidateCommitments { -// /// Messages destined to be interpreted by the Relay chain itself. -// pub upward_messages: UpwardMessages, -// /// Horizontal messages sent by the parachain. -// pub horizontal_messages: HorizontalMessages, -// /// New validation code. -// pub new_validation_code: Option, -// /// The head-data produced as a result of execution. -// pub head_data: HeadData, -// /// The number of messages processed from the DMQ. -// pub processed_downward_messages: u32, -// /// The mark which specifies the block number up to which all inbound HRMP messages are -// /// processed. -// pub hrmp_watermark: N, -// } +impl CandidateApiV2 for CandidateDescriptorV2 { + fn core_index(&self) -> CoreIndex { + CoreIndex(self.core_index as u32) + } + + fn session_index(&self) -> SessionIndex { + self.session_index + } +} + +/// A candidate-receipt at version 2. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub struct CandidateReceiptV2 { + /// The descriptor of the candidate. + pub descriptor: CandidateDescriptorV2, + /// The hash of the encoded commitments made as a result of candidate execution. + pub commitments_hash: Hash, +} /// A candidate-receipt with commitments directly included. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Hash))] -pub struct CommittedCandidateReceipt { +pub struct CommittedCandidateReceiptV2 { /// The descriptor of the candidate. - descriptor: CandidateDescriptor, + pub descriptor: CandidateDescriptorV2, /// The commitments of the candidate receipt. - commitments: CandidateCommitments, + pub commitments: CandidateCommitments, } -impl CandidateCommitments { - /// Returns the core index the candidate has commited to. +impl CandidateReceiptV2 { + /// Get a reference to the candidate descriptor. + pub fn descriptor(&self) -> &CandidateDescriptorV2 { + &self.descriptor + } + + /// Computes the blake2-256 hash of the receipt. + pub fn hash(&self) -> CandidateHash + where + H: Encode, + { + CandidateHash(BlakeTwo256::hash_of(self)) + } +} + +impl CommittedCandidateReceiptV2 { + /// Transforms this into a plain `CandidateReceipt`. + pub fn to_plain(&self) -> CandidateReceiptV2 { + CandidateReceiptV2 { + descriptor: self.descriptor.clone(), + commitments_hash: self.commitments.hash(), + } + } + + /// Computes the hash of the committed candidate receipt. + /// + /// This computes the canonical hash, not the hash of the directly encoded data. + /// Thus this is a shortcut for `candidate.to_plain().hash()`. + pub fn hash(&self) -> CandidateHash + where + H: Encode, + { + self.to_plain().hash() + } + + /// Does this committed candidate receipt corresponds to the given [`CandidateReceipt`]? + pub fn corresponds_to(&self, receipt: &CandidateReceiptV2) -> bool + where + H: PartialEq, + { + receipt.descriptor == self.descriptor && receipt.commitments_hash == self.commitments.hash() + } +} + +impl PartialOrd for CommittedCandidateReceiptV2 { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for CommittedCandidateReceiptV2 { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.descriptor() + .para_id + .cmp(&other.descriptor().para_id) + .then_with(|| self.commitments.head_data.cmp(&other.commitments.head_data)) + } +} + +/// A strictly increasing sequence number, tipically this would be the parachain block number. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub struct CoreSelector(pub BlockNumber); + +/// An offset in the relay chain claim queue. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub struct ClaimQueueOffset(pub u8); + +/// Default claim queue offset +pub const DEFAULT_CLAIM_QUEUE_OFFSET: ClaimQueueOffset = ClaimQueueOffset(1); + +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub enum UMPSignal { + /// A message sent by a parachain to select the core the candidate is commited to. + /// Relay chain validators, in particular backers, use the `CoreSelector` and + /// `ClaimQueueOffset` to compute the index of the core the candidate has commited to. + SelectCore(CoreSelector, ClaimQueueOffset), +} +/// Separator between `XCM` and `UMPSignal`. +pub const UMP_SEPARATOR: Vec = vec![]; + +/// A versioned unique descriptor of the candidate receipt. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub enum VersionedCandidateReceipt { + /// Version 1 of candidate receipt. + V1(super::CandidateReceipt), + /// Version 2 of candidate receipts with `core_index` and `session_index`. + V2(CandidateReceiptV2), +} + +/// A versioned unique descriptor of the candidate receipt. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +pub enum VersionedCommittedCandidateReceipt { + V1(super::CommittedCandidateReceipt), + V2(CommittedCandidateReceiptV2), +} + +impl VersionedCandidateReceipt { + /// Returns the core index the candidate has commited to. Returns `None`` if + /// the receipt is version 1. + pub fn core_index(&self) -> Option { + match self { + Self::V1(_receipt_v1) => None, + Self::V2(receipt_v2) => Some(receipt_v2.descriptor.core_index()), + } + } + + /// Returns the session index of the relay parent. Returns `None`` if + /// the receipt is version 1. + pub fn session_index(&self) -> Option { + match self { + Self::V1(_receipt_v1) => None, + Self::V2(receipt_v2) => Some(receipt_v2.descriptor.session_index()), + } + } +} + +impl VersionedCommittedCandidateReceipt { + /// Returns the core index the candidate has commited to. Returns `None`` if + /// the receipt is version 1. pub fn core_index(&self) -> Option { - /// We need at least 2 messages for the separator and core index + match self { + Self::V1(_receipt_v1) => None, + Self::V2(receipt_v2) => Some(receipt_v2.descriptor.core_index()), + } + } + + /// Returns the session index of the relay parent. Returns `None` if + /// the receipt is version 1. + pub fn session_index(&self) -> Option { + match self { + Self::V1(_receipt_v1) => None, + Self::V2(receipt_v2) => Some(receipt_v2.descriptor.session_index()), + } + } +} + +impl CandidateCommitments { + /// Returns the core selector and claim queue offset the candidate has commited to, if any. + pub fn selected_core(&self) -> Option<(CoreSelector, ClaimQueueOffset)> { + // We need at least 2 messages for the separator and core index if self.upward_messages.len() < 2 { return None } @@ -186,60 +428,98 @@ impl CandidateCommitments { .collect::>(); // We didn't find the separator, no core index commitment. - if upward_commitments.len() == self.upward_messages.len() || - upward_commitments.is_empty() - { + if upward_commitments.len() == self.upward_messages.len() || upward_commitments.is_empty() { return None } // Use first commitment let Some(message) = upward_commitments.into_iter().rev().next() else { return None }; - match Commitment::decode(&mut message.as_slice()).ok()? { - Commitment::CoreIndex(core_index) => Some(core_index), + match UMPSignal::decode(&mut message.as_slice()).ok()? { + UMPSignal::SelectCore(core_selector, cq_offset) => Some((core_selector, cq_offset)), } } } +/// CandidateReceipt construction errors. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] pub enum CandidateReceiptError { /// The specified core index is invalid. InvalidCoreIndex, /// The core index in commitments doesnt match the one in descriptor CoreIndexMismatch, + /// The core selector or claim queue offset is invalid. + InvalidSelectedCore, } -impl CommittedCandidateReceipt { - /// Constructor from descriptor and commitments after sanity checking core index commitments. - pub fn new(descriptor: CandidateDescriptor, commitments: CandidateCommitments, n_cores: u32) -> Result { - // First check if we have a core index commitment - if commitments.core_index() != descriptor.core_index { - return Err(CandidateReceiptError::CoreIndexMismatch) - } - - match descriptor.core_index { - Some(core_index) => { - if core_index.0 > n_cores - 1 { - return Err(CandidateReceiptError::InvalidCoreIndex) - } - - Ok(Self { descriptor, commitments }) - }, - None => Ok(Self { descriptor, commitments }) - } +impl CommittedCandidateReceiptV2 { + /// Returns a v2 commited candidate receipt if the committed selected core + /// matches the core index in the descriptor. + pub fn new(descriptor: CandidateDescriptorV2, commitments: CandidateCommitments) -> Self { + Self { descriptor, commitments } } - /// Returns are reference to commitments + /// Returns a reference to commitments pub fn commitments(&self) -> &CandidateCommitments { &self.commitments } /// Returns a reference to the descriptor - pub fn descriptor(&self) -> &CandidateDescriptor { + pub fn descriptor(&self) -> &CandidateDescriptorV2 { &self.descriptor } - + /// Performs a sanity check of the receipt. + /// + /// Returns error if: + /// - descriptor core index is different than the core selected + /// by the commitments + /// - the core index is out of bounds wrt `n_cores`. + pub fn check( + &self, + n_cores: u32, + claimed_cores: Vec, + // TODO: consider promoting `ClaimQueueSnapshot` as primitive + claim_queue: BTreeMap>, + ) -> Result<(), CandidateReceiptError> { + let descriptor_core_index = CoreIndex(descriptor.core_index as u32); + let (core_selector, cq_offset) = self + .commitments + .selected_core() + .ok_or(Err(CandidateReceiptError::InvalidSelectedCore))?; + let para_id = self.descriptor.para_id; + + // TODO: bail out early if cq_offset > depth of claim queue. + + // Get a vec of the core indices the parachain is assigned to at `cq_offset`. + let assigned_cores = claim_queue + .iter() + .filter_map(|(core_index, queue)| { + let queued_para = queue.get(cq_offset)?; + + if queued_para == para_id { + Some(core_index) + } else { + None + } + }) + .cloned() + .collect::>(); + + let core_index = *assigned_cores + .get(core_selector.0 as usize % assigned_cores.len()) + .expect("provided index is always less than queue len; qed"); + + if core_index != Some(descriptor_core_index) { + return Err(CandidateReceiptError::CoreIndexMismatch) + } + + if descriptor_core_index.0 > n_cores - 1 { + return Err(CandidateReceiptError::InvalidCoreIndex) + } + + Ok(()) + } } #[cfg(test)] @@ -248,43 +528,46 @@ mod tests { use crate::{ v7::{ tests::dummy_committed_candidate_receipt as dummy_old_committed_candidate_receipt, - CandidateReceipt as OldCandidateReceipt, Hash, HeadData, + CandidateDescriptor, CandidateReceipt as OldCandidateReceipt, + CommittedCandidateReceipt, Hash, HeadData, }, - vstaging::CommittedCandidateReceipt, + vstaging::CommittedCandidateReceiptV2, }; - - pub fn dummy_committed_candidate_receipt() -> CommittedCandidateReceipt { - let zeros = Hash::zero(); - let reserved64b = [0; 64]; - - CommittedCandidateReceipt { - descriptor: CandidateDescriptor { - para_id: 0.into(), - relay_parent: zeros, - core_index: Some(CoreIndex(123)), - reserved28b: Default::default(), - persisted_validation_data_hash: zeros, - pov_hash: zeros, - erasure_root: zeros, - reserved64b, - para_head: zeros, - validation_code_hash: ValidationCode(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]).hash(), - }, - commitments: CandidateCommitments { - head_data: HeadData(vec![]), - upward_messages: vec![].try_into().expect("empty vec fits within bounds"), - new_validation_code: None, - horizontal_messages: vec![].try_into().expect("empty vec fits within bounds"), - processed_downward_messages: 0, - hrmp_watermark: 0_u32, - }, - } - } + use polkadot_primitives_test_helpers::dummy_committed_candidate_receipt_v2; + + // pub fn dummy_committed_candidate_receipt() -> CommittedCandidateReceiptV2 { + // let zeros = Hash::zero(); + // let reserved64b = [0; 64]; + + // CommittedCandidateReceiptV2 { + // descriptor: CandidateDescriptorV2 { + // para_id: 0.into(), + // relay_parent: zeros, + // core_index: 123, + // session_index: 1, + // reserved28b: Default::default(), + // persisted_validation_data_hash: zeros, + // pov_hash: zeros, + // erasure_root: zeros, + // reserved64b, + // para_head: zeros, + // validation_code_hash: ValidationCode(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]).hash(), + // }, + // commitments: CandidateCommitments { + // head_data: HeadData(vec![]), + // upward_messages: vec![].try_into().expect("empty vec fits within bounds"), + // new_validation_code: None, + // horizontal_messages: vec![].try_into().expect("empty vec fits within bounds"), + // processed_downward_messages: 0, + // hrmp_watermark: 0_u32, + // }, + // } + // } #[test] fn is_binary_compatibile() { let mut old_ccr = dummy_old_committed_candidate_receipt(); - let mut new_ccr = dummy_committed_candidate_receipt(); + let mut new_ccr = dummy_committed_candidate_receipt_v2(Hash::zero()); assert_eq!(old_ccr.encoded_size(), new_ccr.encoded_size()); assert_eq!(new_ccr.commitments().core_index(), None); @@ -292,8 +575,7 @@ mod tests { #[test] fn test_ump_commitment() { - let old_ccr = dummy_old_committed_candidate_receipt(); - let mut new_ccr = dummy_committed_candidate_receipt(); + let mut new_ccr = dummy_committed_candidate_receipt_v2(Hash::zero()); // XCM messages new_ccr.commitments.upward_messages.force_push(vec![0u8; 256]); @@ -306,8 +588,9 @@ mod tests { new_ccr .commitments .upward_messages - .force_push(Commitment::CoreIndex(CoreIndex(123)).encode()); + .force_push(UMPSignal::OnCore(CoreIndex(123)).encode()); - assert_eq!(new_ccr.descriptor.core_index, Some(CoreIndex(123))); + let new_ccr = VersionedCommittedCandidateReceipt::V2(new_ccr); + assert_eq!(new_ccr.core_index(), Some(CoreIndex(123))); } } diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index d43cf3317e57..c06c0420fd70 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -23,9 +23,13 @@ //! Note that `dummy_` prefixed values are meant to be fillers, that should not matter, and will //! contain randomness based data. use polkadot_primitives::{ + vstaging::{ + CandidateDescriptorV2, CandidateReceiptV2, CommittedCandidateReceiptV2, + VersionedCandidateReceipt, + }, CandidateCommitments, CandidateDescriptor, CandidateReceipt, CollatorId, CollatorSignature, - CommittedCandidateReceipt, Hash, HeadData, Id as ParaId, PersistedValidationData, - ValidationCode, ValidationCodeHash, ValidatorId, + CommittedCandidateReceipt, CoreIndex, Hash, HeadData, Id as ParaId, PersistedValidationData, + SessionIndex, ValidationCode, ValidationCodeHash, ValidatorId, }; pub use rand; use sp_application_crypto::sr25519; @@ -42,6 +46,14 @@ pub fn dummy_candidate_receipt>(relay_parent: H) -> CandidateRece } } +/// Creates a v2 candidate receipt with filler data. +pub fn dummy_candidate_receipt_v2>(relay_parent: H) -> CandidateReceiptV2 { + CandidateReceiptV2:: { + commitments_hash: dummy_candidate_commitments(dummy_head_data()).hash(), + descriptor: dummy_candidate_descriptor_v2(relay_parent), + } +} + /// Creates a committed candidate receipt with filler data. pub fn dummy_committed_candidate_receipt>( relay_parent: H, @@ -52,6 +64,14 @@ pub fn dummy_committed_candidate_receipt>( } } +/// Creates a v2 committed candidate receipt with filler data. +pub fn dummy_committed_candidate_receipt_v2(relay_parent: H) -> CommittedCandidateReceiptV2 { + CommittedCandidateReceiptV2 { + descriptor: dummy_candidate_descriptor_v2::(relay_parent), + commitments: dummy_candidate_commitments(dummy_head_data()), + } +} + /// Create a candidate receipt with a bogus signature and filler data. Optionally set the commitment /// hash with the `commitments` arg. pub fn dummy_candidate_receipt_bad_sig( @@ -124,6 +144,23 @@ pub fn dummy_candidate_descriptor>(relay_parent: H) -> CandidateD descriptor } +/// Create a v2 candidate descriptor with filler data. +pub fn dummy_candidate_descriptor_v2(relay_parent: H) -> CandidateDescriptorV2 { + let invalid = Hash::zero(); + let descriptor = make_valid_candidate_descriptor_v2( + 1.into(), + relay_parent, + CoreIndex(1), + 1, + invalid, + invalid, + invalid, + invalid, + invalid, + ); + descriptor +} + /// Create meaningless validation code. pub fn dummy_validation_code() -> ValidationCode { ValidationCode(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]) @@ -232,6 +269,34 @@ pub fn make_valid_candidate_descriptor>( descriptor } +/// Create a v2 candidate descriptor. +pub fn make_valid_candidate_descriptor_v2( + para_id: ParaId, + relay_parent: H, + core_index: CoreIndex, + session_index: SessionIndex, + persisted_validation_data_hash: Hash, + pov_hash: Hash, + validation_code_hash: impl Into, + para_head: Hash, + erasure_root: Hash, +) -> CandidateDescriptorV2 { + let validation_code_hash = validation_code_hash.into(); + + let descriptor = CandidateDescriptorV2::new( + para_id, + relay_parent, + core_index, + session_index, + persisted_validation_data_hash, + pov_hash, + erasure_root, + para_head, + validation_code_hash, + ); + + descriptor +} /// After manually modifying the candidate descriptor, resign with a defined collator key. pub fn resign_candidate_descriptor_with_collator>( descriptor: &mut CandidateDescriptor, From 4a53577abb8234e4174f4ab1545012f7cf066bf0 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 7 Aug 2024 17:01:00 +0300 Subject: [PATCH 003/130] Working version. Signed-off-by: Andrei Sandu --- polkadot/primitives/src/v7/mod.rs | 1 - polkadot/primitives/src/vstaging/mod.rs | 572 +++++++++++++++----- polkadot/primitives/test-helpers/src/lib.rs | 8 +- 3 files changed, 452 insertions(+), 129 deletions(-) diff --git a/polkadot/primitives/src/v7/mod.rs b/polkadot/primitives/src/v7/mod.rs index 18f52951986a..4b7abdb311f5 100644 --- a/polkadot/primitives/src/v7/mod.rs +++ b/polkadot/primitives/src/v7/mod.rs @@ -15,7 +15,6 @@ // along with Polkadot. If not, see . //! `V7` Primitives. - use alloc::{ vec, vec::{IntoIter, Vec}, diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index b259ba022772..749645753991 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -15,18 +15,20 @@ // along with Polkadot. If not, see . //! Staging Primitives. +use crate::{CandidateReceipt, CommittedCandidateReceipt, ValidityAttestation}; // Put any primitives used by staging APIs functions here use super::{ Balance, BlakeTwo256, BlockNumber, CandidateCommitments, CandidateDescriptor, CandidateHash, - CoreIndex, Hash, HashT, Id, Id as ParaId, ValidationCode, ValidationCodeHash, + CollatorId, CollatorSignature, CoreIndex, Hash, HashT, Id, Id as ParaId, ValidationCodeHash, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, }; +use bitvec::prelude::*; +use sp_application_crypto::ByteArray; use alloc::collections::{btree_map::BTreeMap, vec_deque::VecDeque}; use codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_api::Core; use sp_arithmetic::Perbill; use sp_core::RuntimeDebug; use sp_staking::SessionIndex; @@ -119,7 +121,7 @@ pub struct CandidateDescriptorV2 { /// The session index of the candidate relay parent. session_index: SessionIndex, /// Reserved bytes. - reserved28b: [u8; 26], + reserved26b: [u8; 26], /// The blake2-256 hash of the persisted validation data. This is extra data derived from /// relay-chain state which may vary based on bitfields included before the candidate. /// Thus it cannot be derived entirely from the relay-parent. @@ -154,7 +156,7 @@ impl CandidateDescriptorV2 { relay_parent, core_index: core_index.0 as u16, session_index, - reserved28b: [0; 26], + reserved26b: [0; 26], persisted_validation_data_hash, pov_hash, erasure_root, @@ -183,81 +185,37 @@ pub trait CandidateApiV1 { /// Return the blake2-256 hash of the validation code bytes. fn validation_code_hash(&self) -> ValidationCodeHash; + + /// The collator's sr25519 public key. + fn collator(&self) -> Option<&CollatorId>; + + /// The parachain index, the relay parent, the validation data hash, and the `pov_hash`. + fn signature(&self) -> Option<&CollatorSignature>; } /// Version 2 API to access additional information stored by candidate descriptors pub trait CandidateApiV2 { /// Returns the core index where the candidate is backed. - fn core_index(&self) -> CoreIndex; + fn core_index(&self) -> Option; /// Returns the session index of the candidate relay parent. - fn session_index(&self) -> SessionIndex; -} - -impl CandidateApiV1 for CandidateDescriptor { - fn para_id(&self) -> Id { - self.para_id - } - - fn persisted_validation_data_hash(&self) -> Hash { - self.persisted_validation_data_hash - } - - fn pov_hash(&self) -> Hash { - self.pov_hash - } - - fn erasure_root(&self) -> Hash { - self.erasure_root - } - - fn para_head(&self) -> Hash { - self.para_head - } - - fn validation_code_hash(&self) -> ValidationCodeHash { - self.validation_code_hash - } + fn session_index(&self) -> Option; } -impl CandidateApiV1 for CandidateDescriptorV2 { - fn para_id(&self) -> Id { - self.para_id - } - - fn persisted_validation_data_hash(&self) -> Hash { - self.persisted_validation_data_hash - } - - fn pov_hash(&self) -> Hash { - self.pov_hash - } - - fn erasure_root(&self) -> Hash { - self.erasure_root - } - - fn para_head(&self) -> Hash { - self.para_head - } - - fn validation_code_hash(&self) -> ValidationCodeHash { - self.validation_code_hash - } -} impl CandidateApiV2 for CandidateDescriptorV2 { - fn core_index(&self) -> CoreIndex { - CoreIndex(self.core_index as u32) + fn core_index(&self) -> Option { + Some(CoreIndex(self.core_index as u32)) } - fn session_index(&self) -> SessionIndex { - self.session_index + fn session_index(&self) -> Option { + Some(self.session_index) } } /// A candidate-receipt at version 2. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] pub struct CandidateReceiptV2 { /// The descriptor of the candidate. pub descriptor: CandidateDescriptorV2, @@ -356,28 +314,84 @@ pub enum UMPSignal { pub const UMP_SEPARATOR: Vec = vec![]; /// A versioned unique descriptor of the candidate receipt. -#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] -pub enum VersionedCandidateReceipt { +#[derive(PartialEq, Eq, Clone, TypeInfo, RuntimeDebug)] +pub enum VersionedCandidateReceipt { /// Version 1 of candidate receipt. - V1(super::CandidateReceipt), + V1(CandidateReceipt), /// Version 2 of candidate receipts with `core_index` and `session_index`. - V2(CandidateReceiptV2), + V2(CandidateReceiptV2), +} + +impl Encode for VersionedCandidateReceipt { + fn encode(&self) -> Vec { + match self { + VersionedCandidateReceipt::V1(inner) => inner.encode(), + VersionedCandidateReceipt::V2(inner) => inner.encode(), + } + } +} + +impl Decode for VersionedCandidateReceipt { + fn decode(input: &mut I) -> Result { + let descriptor: CandidateDescriptorV2 = Decode::decode(input)?; + let commitments_hash = Hash::decode(input)?; + + // Check if descriptor is v2. + if descriptor.reserved64b == [0u8; 64] && descriptor.reserved26b == [0u8; 26] { + return Ok(VersionedCandidateReceipt::V2(CandidateReceiptV2 { + descriptor, + commitments_hash, + })) + } + + // Fall back to v1. + // TODO: optimize, an additional encode and decode is not nice. + let descriptor = CandidateDescriptor::decode(&mut descriptor.encode().as_slice())?; + + Ok(VersionedCandidateReceipt::V1(CandidateReceipt { descriptor, commitments_hash })) + } +} + +impl Decode for VersionedCommittedCandidateReceipt { + fn decode(input: &mut I) -> Result { + let descriptor = CandidateDescriptorV2::decode(input)?; + let commitments = CandidateCommitments::decode(input)?; + + // Check if descriptor is v2. + if descriptor.reserved64b == [0u8; 64] && descriptor.reserved26b == [0u8; 26] { + return Ok(VersionedCommittedCandidateReceipt::V2(CommittedCandidateReceiptV2 { + descriptor, + commitments, + })) + } + + // Fall back to v1. + // TODO: optimize, an additional encode and decode is not nice. + let descriptor = CandidateDescriptor::decode(&mut descriptor.encode().as_slice())?; + + Ok(VersionedCommittedCandidateReceipt::V1(CommittedCandidateReceipt { + descriptor, + commitments, + })) + } } /// A versioned unique descriptor of the candidate receipt. -#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] -pub enum VersionedCommittedCandidateReceipt { +#[derive(PartialEq, Eq, Clone, TypeInfo, RuntimeDebug)] +pub enum VersionedCommittedCandidateReceipt { + /// Version 1 V1(super::CommittedCandidateReceipt), + /// Version 2 V2(CommittedCandidateReceiptV2), } -impl VersionedCandidateReceipt { +impl VersionedCandidateReceipt { /// Returns the core index the candidate has commited to. Returns `None`` if /// the receipt is version 1. pub fn core_index(&self) -> Option { match self { Self::V1(_receipt_v1) => None, - Self::V2(receipt_v2) => Some(receipt_v2.descriptor.core_index()), + Self::V2(receipt_v2) => receipt_v2.descriptor.core_index(), } } @@ -386,18 +400,29 @@ impl VersionedCandidateReceipt { pub fn session_index(&self) -> Option { match self { Self::V1(_receipt_v1) => None, - Self::V2(receipt_v2) => Some(receipt_v2.descriptor.session_index()), + Self::V2(receipt_v2) => receipt_v2.descriptor.session_index(), + } + } + + /// Computes the blake2-256 hash of the receipt. + pub fn hash(&self) -> CandidateHash + where + H: Encode, + { + match self { + Self::V1(receipt_v1) => receipt_v1.hash(), + Self::V2(receipt_v2) => receipt_v2.hash(), } } } -impl VersionedCommittedCandidateReceipt { +impl VersionedCommittedCandidateReceipt { /// Returns the core index the candidate has commited to. Returns `None`` if /// the receipt is version 1. pub fn core_index(&self) -> Option { match self { Self::V1(_receipt_v1) => None, - Self::V2(receipt_v2) => Some(receipt_v2.descriptor.core_index()), + Self::V2(receipt_v2) => receipt_v2.descriptor.core_index(), } } @@ -406,7 +431,24 @@ impl VersionedCommittedCandidateReceipt { pub fn session_index(&self) -> Option { match self { Self::V1(_receipt_v1) => None, - Self::V2(receipt_v2) => Some(receipt_v2.descriptor.session_index()), + Self::V2(receipt_v2) => receipt_v2.descriptor.session_index(), + } + } + + /// Convert to a plain `CandidateReceipt`. + pub fn to_plain(&self) -> VersionedCandidateReceipt { + match self { + Self::V1(receipt) => VersionedCandidateReceipt::V1(receipt.to_plain()), + Self::V2(receipt) => VersionedCandidateReceipt::V2(receipt.to_plain()), + } + } + + /// Returns the candidate commitments. + /// Convert to a plain `CandidateReceipt`. + pub fn commitments(&self) -> &CandidateCommitments { + match self { + Self::V1(receipt) => &receipt.commitments, + Self::V2(receipt) => &receipt.commitments, } } } @@ -450,6 +492,44 @@ pub enum CandidateReceiptError { CoreIndexMismatch, /// The core selector or claim queue offset is invalid. InvalidSelectedCore, + /// The parachain is not assigned to any core at specified claim queue offset. + NoAssignment, + /// No core was selected. + NoCoreSelected, +} + +macro_rules! impl_candidate_api_v1 { + ($field:ident, $type:ident) => { + fn $field(&self) -> $type { + match self { + Self::V1(receipt) => receipt.descriptor.$field, + Self::V2(receipt) => receipt.descriptor.$field, + } + } + }; +} + +impl CandidateApiV1 for VersionedCommittedCandidateReceipt { + impl_candidate_api_v1!(erasure_root, Hash); + impl_candidate_api_v1!(para_head, Hash); + impl_candidate_api_v1!(para_id, ParaId); + impl_candidate_api_v1!(persisted_validation_data_hash, Hash); + impl_candidate_api_v1!(pov_hash, Hash); + impl_candidate_api_v1!(validation_code_hash, ValidationCodeHash); + + fn collator(&self) -> Option<&CollatorId> { + match self { + Self::V1(receipt) => Some(&receipt.descriptor.collator), + Self::V2(receipt) => None, + } + } + + fn signature(&self) -> Option<&CollatorSignature> { + match self { + Self::V1(receipt) => Some(&receipt.descriptor.signature), + Self::V2(receipt) => None, + } + } } impl CommittedCandidateReceiptV2 { @@ -478,26 +558,35 @@ impl CommittedCandidateReceiptV2 { pub fn check( &self, n_cores: u32, - claimed_cores: Vec, // TODO: consider promoting `ClaimQueueSnapshot` as primitive - claim_queue: BTreeMap>, + claim_queue: &BTreeMap>, ) -> Result<(), CandidateReceiptError> { - let descriptor_core_index = CoreIndex(descriptor.core_index as u32); - let (core_selector, cq_offset) = self - .commitments - .selected_core() - .ok_or(Err(CandidateReceiptError::InvalidSelectedCore))?; + if claim_queue.is_empty() { + return Err(CandidateReceiptError::NoAssignment) + } + + let claim_queue_depth = claim_queue + .first_key_value() + .ok_or(CandidateReceiptError::NoAssignment)? + .1 + .len(); + + let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); + let (core_selector, cq_offset) = + self.commitments.selected_core().ok_or(CandidateReceiptError::NoCoreSelected)?; let para_id = self.descriptor.para_id; - // TODO: bail out early if cq_offset > depth of claim queue. - + if cq_offset.0 as usize >= claim_queue_depth { + return Err(CandidateReceiptError::InvalidSelectedCore) + } + // Get a vec of the core indices the parachain is assigned to at `cq_offset`. let assigned_cores = claim_queue .iter() .filter_map(|(core_index, queue)| { - let queued_para = queue.get(cq_offset)?; + let queued_para = queue.get(cq_offset.0 as usize)?; - if queued_para == para_id { + if queued_para == ¶_id { Some(core_index) } else { None @@ -506,11 +595,15 @@ impl CommittedCandidateReceiptV2 { .cloned() .collect::>(); + if assigned_cores.is_empty() { + return Err(CandidateReceiptError::NoAssignment) + } + let core_index = *assigned_cores .get(core_selector.0 as usize % assigned_cores.len()) .expect("provided index is always less than queue len; qed"); - if core_index != Some(descriptor_core_index) { + if core_index != descriptor_core_index { return Err(CandidateReceiptError::CoreIndexMismatch) } @@ -522,62 +615,230 @@ impl CommittedCandidateReceiptV2 { } } +impl From> for VersionedCommittedCandidateReceipt { + fn from(value: CommittedCandidateReceipt) -> Self { + Self::V1(value) + } +} + +impl From> for VersionedCommittedCandidateReceipt { + fn from(value: CommittedCandidateReceiptV2) -> Self { + Self::V2(value) + } +} + +impl From> for VersionedCandidateReceipt { + fn from(value: CandidateReceipt) -> Self { + Self::V1(value) + } +} + +impl From> for VersionedCandidateReceipt { + fn from(value: CandidateReceiptV2) -> Self { + Self::V2(value) + } +} + +/// A backed (or backable, depending on context) candidate. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct BackedCandidate { + /// The candidate referred to. + candidate: VersionedCommittedCandidateReceipt, + /// The validity votes themselves, expressed as signatures. + validity_votes: Vec, + /// The indices of the validators within the group, expressed as a bitfield. May be extended + /// beyond the backing group size to contain the assigned core index, if ElasticScalingMVP is + /// enabled. + validator_indices: BitVec, +} + +impl BackedCandidate { + /// Constructor + pub fn new( + candidate: VersionedCommittedCandidateReceipt, + validity_votes: Vec, + validator_indices: BitVec, + core_index: Option, + ) -> Self { + let mut instance = Self { candidate, validity_votes, validator_indices }; + if let Some(core_index) = core_index { + instance.inject_core_index(core_index); + } + instance + } + + /// Get a reference to the committed candidate receipt of the candidate. + pub fn candidate(&self) -> &VersionedCommittedCandidateReceipt { + &self.candidate + } + + /// Get a reference to the validity votes of the candidate. + pub fn validity_votes(&self) -> &[ValidityAttestation] { + &self.validity_votes + } + + /// Get a mutable reference to validity votes of the para. + pub fn validity_votes_mut(&mut self) -> &mut Vec { + &mut self.validity_votes + } + + /// Compute this candidate's hash. + pub fn hash(&self) -> CandidateHash + where + H: Clone + Encode, + { + self.candidate.to_plain().hash() + } + + /// Get this candidate's receipt. + pub fn receipt(&self) -> VersionedCandidateReceipt + where + H: Clone, + { + self.candidate.to_plain() + } + + /// Get a copy of the validator indices and the assumed core index, if any. + pub fn validator_indices_and_core_index( + &self, + core_index_enabled: bool, + ) -> (&BitSlice, Option) { + // This flag tells us if the block producers must enable Elastic Scaling MVP hack. + // It extends `BackedCandidate::validity_indices` to store a 8 bit core index. + if core_index_enabled { + let core_idx_offset = self.validator_indices.len().saturating_sub(8); + if core_idx_offset > 0 { + let (validator_indices_slice, core_idx_slice) = + self.validator_indices.split_at(core_idx_offset); + return ( + validator_indices_slice, + Some(CoreIndex(core_idx_slice.load::() as u32)), + ); + } + } + + (&self.validator_indices, None) + } + + /// Inject a core index in the validator_indices bitvec. + fn inject_core_index(&mut self, core_index: CoreIndex) { + let core_index_to_inject: BitVec = + BitVec::from_vec(vec![core_index.0 as u8]); + self.validator_indices.extend(core_index_to_inject); + } + + /// Update the validator indices and core index in the candidate. + pub fn set_validator_indices_and_core_index( + &mut self, + new_indices: BitVec, + maybe_core_index: Option, + ) { + self.validator_indices = new_indices; + + if let Some(core_index) = maybe_core_index { + self.inject_core_index(core_index); + } + } +} + #[cfg(test)] mod tests { + use core::prelude::v1; + use super::*; use crate::{ v7::{ tests::dummy_committed_candidate_receipt as dummy_old_committed_candidate_receipt, CandidateDescriptor, CandidateReceipt as OldCandidateReceipt, - CommittedCandidateReceipt, Hash, HeadData, + CommittedCandidateReceipt, Hash, HeadData, ValidationCode, + }, + vstaging::{ + CandidateApiV1, CandidateApiV2, CandidateDescriptorV2, CommittedCandidateReceiptV2, }, - vstaging::CommittedCandidateReceiptV2, }; - use polkadot_primitives_test_helpers::dummy_committed_candidate_receipt_v2; - - // pub fn dummy_committed_candidate_receipt() -> CommittedCandidateReceiptV2 { - // let zeros = Hash::zero(); - // let reserved64b = [0; 64]; - - // CommittedCandidateReceiptV2 { - // descriptor: CandidateDescriptorV2 { - // para_id: 0.into(), - // relay_parent: zeros, - // core_index: 123, - // session_index: 1, - // reserved28b: Default::default(), - // persisted_validation_data_hash: zeros, - // pov_hash: zeros, - // erasure_root: zeros, - // reserved64b, - // para_head: zeros, - // validation_code_hash: ValidationCode(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]).hash(), - // }, - // commitments: CandidateCommitments { - // head_data: HeadData(vec![]), - // upward_messages: vec![].try_into().expect("empty vec fits within bounds"), - // new_validation_code: None, - // horizontal_messages: vec![].try_into().expect("empty vec fits within bounds"), - // processed_downward_messages: 0, - // hrmp_watermark: 0_u32, - // }, - // } - // } + // use polkadot_primitives_test_helpers::dummy_committed_candidate_receipt_v2; + + pub fn dummy_committed_candidate_receipt_v2() -> CommittedCandidateReceiptV2 { + let zeros = Hash::zero(); + let reserved64b = [0; 64]; + + CommittedCandidateReceiptV2 { + descriptor: CandidateDescriptorV2 { + para_id: 0.into(), + relay_parent: zeros, + core_index: 123, + session_index: 1, + reserved26b: Default::default(), + persisted_validation_data_hash: zeros, + pov_hash: zeros, + erasure_root: zeros, + reserved64b, + para_head: zeros, + validation_code_hash: ValidationCode(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]).hash(), + }, + commitments: CandidateCommitments { + head_data: HeadData(vec![]), + upward_messages: vec![].try_into().expect("empty vec fits within bounds"), + new_validation_code: None, + horizontal_messages: vec![].try_into().expect("empty vec fits within bounds"), + processed_downward_messages: 0, + hrmp_watermark: 0_u32, + }, + } + } #[test] fn is_binary_compatibile() { - let mut old_ccr = dummy_old_committed_candidate_receipt(); - let mut new_ccr = dummy_committed_candidate_receipt_v2(Hash::zero()); + let old_ccr = dummy_old_committed_candidate_receipt(); + let new_ccr = dummy_committed_candidate_receipt_v2(); assert_eq!(old_ccr.encoded_size(), new_ccr.encoded_size()); - assert_eq!(new_ccr.commitments().core_index(), None); + + let encoded_old = old_ccr.encode(); + + // Deserialize from old candidate receipt. + let new_ccr: CommittedCandidateReceiptV2 = + Decode::decode(&mut encoded_old.as_slice()).unwrap(); + + // We get same candidate hash. + assert_eq!(old_ccr.hash(), new_ccr.hash()); } #[test] fn test_ump_commitment() { - let mut new_ccr = dummy_committed_candidate_receipt_v2(Hash::zero()); + let mut new_ccr = dummy_committed_candidate_receipt_v2(); + new_ccr.descriptor.core_index = 123; + new_ccr.descriptor.para_id = ParaId::new(1000); + + // dummy XCM messages + new_ccr.commitments.upward_messages.force_push(vec![0u8; 256]); + new_ccr.commitments.upward_messages.force_push(vec![0xff; 256]); + + // separator + new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); + + // CoreIndex commitment + new_ccr + .commitments + .upward_messages + .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); + + let mut claim_queue = BTreeMap::new(); + claim_queue.insert( + new_ccr.descriptor().core_index().unwrap(), + vec![2.into(), new_ccr.descriptor.para_id, 3.into()].into(), + ); + + assert_eq!(new_ccr.check(200, &claim_queue), Ok(())); + } - // XCM messages + #[test] + fn test_versioned_receipt() { + let mut new_ccr = dummy_committed_candidate_receipt_v2(); + new_ccr.descriptor.core_index = 123; + new_ccr.descriptor.para_id = ParaId::new(1000); + + // dummy XCM messages new_ccr.commitments.upward_messages.force_push(vec![0u8; 256]); new_ccr.commitments.upward_messages.force_push(vec![0xff; 256]); @@ -588,9 +849,70 @@ mod tests { new_ccr .commitments .upward_messages - .force_push(UMPSignal::OnCore(CoreIndex(123)).encode()); + .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); + + let mut claim_queue = BTreeMap::new(); + claim_queue.insert( + new_ccr.descriptor().core_index().unwrap(), + vec![2.into(), new_ccr.descriptor.para_id, 3.into()].into(), + ); + + let encoded_ccr = new_ccr.encode(); + let versioned_ccr = + VersionedCommittedCandidateReceipt::decode(&mut encoded_ccr.as_slice()).unwrap(); + + assert_eq!(versioned_ccr.core_index(), Some(CoreIndex(123))); + + if let VersionedCommittedCandidateReceipt::V2(ref v2_receipt) = versioned_ccr { + assert_eq!(v2_receipt.check(200, &claim_queue), Ok(())); + } + + assert_eq!(new_ccr.hash(), versioned_ccr.to_plain().hash()); + } + + #[test] + fn test_backward_compatible() { + // Testing edge case when collators provide zeroed signature and collator id. + let mut old_ccr = dummy_old_committed_candidate_receipt(); + old_ccr.descriptor.para_id = ParaId::new(1000); + let encoded_ccr: Vec = old_ccr.encode(); + + let versioned_ccr = + VersionedCommittedCandidateReceipt::decode(&mut encoded_ccr.as_slice()).unwrap(); + + // Since collator sig and id are zeroed, it was decoded as V2. + // We expect the check to fail in such case because there will be no `SelectCore` + // commitment. + let mut claim_queue = BTreeMap::new(); + claim_queue.insert( + versioned_ccr.core_index().unwrap(), + vec![2.into(), versioned_ccr.para_id(), 3.into()].into(), + ); + + if let VersionedCommittedCandidateReceipt::V2(ref v2_receipt) = versioned_ccr { + assert_eq!( + v2_receipt.check(200, &claim_queue), + Err(CandidateReceiptError::NoCoreSelected) + ); + } else { + panic!("Should have decoded as V2") + } + + // Adding collator signature should make it decode as v1. + old_ccr.descriptor.signature = + CollatorSignature::from_slice(&vec![99u8; 64]).expect("64 bytes; qed"); + let encoded_ccr: Vec = old_ccr.encode(); + let versioned_ccr = + VersionedCommittedCandidateReceipt::decode(&mut encoded_ccr.as_slice()).unwrap(); + + if let VersionedCommittedCandidateReceipt::V1(ref v1_receipt) = versioned_ccr { + assert_eq!(v1_receipt.descriptor.signature, old_ccr.descriptor.signature); + } else { + panic!("Should have decoded as V1") + } - let new_ccr = VersionedCommittedCandidateReceipt::V2(new_ccr); - assert_eq!(new_ccr.core_index(), Some(CoreIndex(123))); + assert_eq!(versioned_ccr.core_index(), None); + assert_eq!(versioned_ccr.para_id(), ParaId::new(1000)); + assert_eq!(old_ccr.hash(), versioned_ccr.to_plain().hash()); } } diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index c06c0420fd70..c262f16df077 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -65,7 +65,9 @@ pub fn dummy_committed_candidate_receipt>( } /// Creates a v2 committed candidate receipt with filler data. -pub fn dummy_committed_candidate_receipt_v2(relay_parent: H) -> CommittedCandidateReceiptV2 { +pub fn dummy_committed_candidate_receipt_v2>( + relay_parent: H, +) -> CommittedCandidateReceiptV2 { CommittedCandidateReceiptV2 { descriptor: dummy_candidate_descriptor_v2::(relay_parent), commitments: dummy_candidate_commitments(dummy_head_data()), @@ -145,7 +147,7 @@ pub fn dummy_candidate_descriptor>(relay_parent: H) -> CandidateD } /// Create a v2 candidate descriptor with filler data. -pub fn dummy_candidate_descriptor_v2(relay_parent: H) -> CandidateDescriptorV2 { +pub fn dummy_candidate_descriptor_v2>(relay_parent: H) -> CandidateDescriptorV2 { let invalid = Hash::zero(); let descriptor = make_valid_candidate_descriptor_v2( 1.into(), @@ -270,7 +272,7 @@ pub fn make_valid_candidate_descriptor>( } /// Create a v2 candidate descriptor. -pub fn make_valid_candidate_descriptor_v2( +pub fn make_valid_candidate_descriptor_v2>( para_id: ParaId, relay_parent: H, core_index: CoreIndex, From 8285ae79e16e62a373d704fed328abf702ed125e Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 8 Aug 2024 17:09:35 +0300 Subject: [PATCH 004/130] Better version Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 459 +++++++------------- polkadot/primitives/test-helpers/src/lib.rs | 5 +- 2 files changed, 159 insertions(+), 305 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 749645753991..03075e820524 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -15,12 +15,13 @@ // along with Polkadot. If not, see . //! Staging Primitives. -use crate::{CandidateReceipt, CommittedCandidateReceipt, ValidityAttestation}; +use crate::ValidityAttestation; // Put any primitives used by staging APIs functions here use super::{ - Balance, BlakeTwo256, BlockNumber, CandidateCommitments, CandidateDescriptor, CandidateHash, - CollatorId, CollatorSignature, CoreIndex, Hash, HashT, Id, Id as ParaId, ValidationCodeHash, + Balance, BlakeTwo256, BlockNumber, CandidateCommitments, CandidateHash, + CollatorId, CollatorSignature, CoreIndex, Hash, HashT, Header, Id, Id as ParaId, + MultiDisputeStatementSet, UncheckedSignedAvailabilityBitfields, ValidationCodeHash, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, }; use bitvec::prelude::*; @@ -31,6 +32,7 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_arithmetic::Perbill; use sp_core::RuntimeDebug; +use sp_runtime::traits::Header as HeaderT; use sp_staking::SessionIndex; /// Scheduler configuration parameters. All coretime/ondemand parameters are here. @@ -108,6 +110,22 @@ impl> Default for SchedulerParams } } +/// A type representing the version of the candidate descriptor and internal version number. +#[derive(PartialEq, Eq, Encode, Decode, Clone, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub struct InternalVersion(pub u8); + +/// A type representing the version of the candidate descriptor and internal version number. +/// For `V1`` the internal version number stores the first byte of the `CollatorId`. +#[derive(PartialEq, Eq, Clone, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub enum CandidateDescriptorVersion { + /// The old candidate descriptor version. + V1, + /// Introduced with `CandidateDescriptorV2` + V2, +} + /// A unique descriptor of the candidate receipt. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Hash))] @@ -116,12 +134,14 @@ pub struct CandidateDescriptorV2 { para_id: ParaId, /// The hash of the relay-chain block this is executed in the context of. relay_parent: H, + /// Version field + version: InternalVersion, /// The core index where the candidate is backed. core_index: u16, /// The session index of the candidate relay parent. session_index: SessionIndex, /// Reserved bytes. - reserved26b: [u8; 26], + reserved25b: [u8; 25], /// The blake2-256 hash of the persisted validation data. This is extra data derived from /// relay-chain state which may vary based on bitfields included before the candidate. /// Thus it cannot be derived entirely from the relay-parent. @@ -154,9 +174,10 @@ impl CandidateDescriptorV2 { Self { para_id, relay_parent, + version: InternalVersion(0), core_index: core_index.0 as u16, session_index, - reserved26b: [0; 26], + reserved25b: [0; 25], persisted_validation_data_hash, pov_hash, erasure_root, @@ -166,52 +187,6 @@ impl CandidateDescriptorV2 { } } } -/// Version 1 API to access information stored by candidate descriptors. -pub trait CandidateApiV1 { - /// Returns the ID of the para this is a candidate for. - fn para_id(&self) -> Id; - - /// Returns the blake2-256 hash of the persisted validation data. - fn persisted_validation_data_hash(&self) -> Hash; - - /// Returns the blake2-256 hash of the PoV. - fn pov_hash(&self) -> Hash; - - /// Returns the root of a block's erasure encoding Merkle tree. - fn erasure_root(&self) -> Hash; - - /// Returns the hash of the para header generated by this candidate. - fn para_head(&self) -> Hash; - - /// Return the blake2-256 hash of the validation code bytes. - fn validation_code_hash(&self) -> ValidationCodeHash; - - /// The collator's sr25519 public key. - fn collator(&self) -> Option<&CollatorId>; - - /// The parachain index, the relay parent, the validation data hash, and the `pov_hash`. - fn signature(&self) -> Option<&CollatorSignature>; -} - -/// Version 2 API to access additional information stored by candidate descriptors -pub trait CandidateApiV2 { - /// Returns the core index where the candidate is backed. - fn core_index(&self) -> Option; - - /// Returns the session index of the candidate relay parent. - fn session_index(&self) -> Option; -} - - -impl CandidateApiV2 for CandidateDescriptorV2 { - fn core_index(&self) -> Option { - Some(CoreIndex(self.core_index as u32)) - } - - fn session_index(&self) -> Option { - Some(self.session_index) - } -} /// A candidate-receipt at version 2. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] @@ -285,9 +260,9 @@ impl PartialOrd for CommittedCandidateReceiptV2 { impl Ord for CommittedCandidateReceiptV2 { fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.descriptor() + self.descriptor .para_id - .cmp(&other.descriptor().para_id) + .cmp(&other.descriptor.para_id) .then_with(|| self.commitments.head_data.cmp(&other.commitments.head_data)) } } @@ -303,6 +278,7 @@ pub struct ClaimQueueOffset(pub u8); /// Default claim queue offset pub const DEFAULT_CLAIM_QUEUE_OFFSET: ClaimQueueOffset = ClaimQueueOffset(1); +/// Signals that a parachain can send to the relay chain via the UMP queue. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] pub enum UMPSignal { /// A message sent by a parachain to select the core the candidate is commited to. @@ -313,146 +289,6 @@ pub enum UMPSignal { /// Separator between `XCM` and `UMPSignal`. pub const UMP_SEPARATOR: Vec = vec![]; -/// A versioned unique descriptor of the candidate receipt. -#[derive(PartialEq, Eq, Clone, TypeInfo, RuntimeDebug)] -pub enum VersionedCandidateReceipt { - /// Version 1 of candidate receipt. - V1(CandidateReceipt), - /// Version 2 of candidate receipts with `core_index` and `session_index`. - V2(CandidateReceiptV2), -} - -impl Encode for VersionedCandidateReceipt { - fn encode(&self) -> Vec { - match self { - VersionedCandidateReceipt::V1(inner) => inner.encode(), - VersionedCandidateReceipt::V2(inner) => inner.encode(), - } - } -} - -impl Decode for VersionedCandidateReceipt { - fn decode(input: &mut I) -> Result { - let descriptor: CandidateDescriptorV2 = Decode::decode(input)?; - let commitments_hash = Hash::decode(input)?; - - // Check if descriptor is v2. - if descriptor.reserved64b == [0u8; 64] && descriptor.reserved26b == [0u8; 26] { - return Ok(VersionedCandidateReceipt::V2(CandidateReceiptV2 { - descriptor, - commitments_hash, - })) - } - - // Fall back to v1. - // TODO: optimize, an additional encode and decode is not nice. - let descriptor = CandidateDescriptor::decode(&mut descriptor.encode().as_slice())?; - - Ok(VersionedCandidateReceipt::V1(CandidateReceipt { descriptor, commitments_hash })) - } -} - -impl Decode for VersionedCommittedCandidateReceipt { - fn decode(input: &mut I) -> Result { - let descriptor = CandidateDescriptorV2::decode(input)?; - let commitments = CandidateCommitments::decode(input)?; - - // Check if descriptor is v2. - if descriptor.reserved64b == [0u8; 64] && descriptor.reserved26b == [0u8; 26] { - return Ok(VersionedCommittedCandidateReceipt::V2(CommittedCandidateReceiptV2 { - descriptor, - commitments, - })) - } - - // Fall back to v1. - // TODO: optimize, an additional encode and decode is not nice. - let descriptor = CandidateDescriptor::decode(&mut descriptor.encode().as_slice())?; - - Ok(VersionedCommittedCandidateReceipt::V1(CommittedCandidateReceipt { - descriptor, - commitments, - })) - } -} - -/// A versioned unique descriptor of the candidate receipt. -#[derive(PartialEq, Eq, Clone, TypeInfo, RuntimeDebug)] -pub enum VersionedCommittedCandidateReceipt { - /// Version 1 - V1(super::CommittedCandidateReceipt), - /// Version 2 - V2(CommittedCandidateReceiptV2), -} - -impl VersionedCandidateReceipt { - /// Returns the core index the candidate has commited to. Returns `None`` if - /// the receipt is version 1. - pub fn core_index(&self) -> Option { - match self { - Self::V1(_receipt_v1) => None, - Self::V2(receipt_v2) => receipt_v2.descriptor.core_index(), - } - } - - /// Returns the session index of the relay parent. Returns `None`` if - /// the receipt is version 1. - pub fn session_index(&self) -> Option { - match self { - Self::V1(_receipt_v1) => None, - Self::V2(receipt_v2) => receipt_v2.descriptor.session_index(), - } - } - - /// Computes the blake2-256 hash of the receipt. - pub fn hash(&self) -> CandidateHash - where - H: Encode, - { - match self { - Self::V1(receipt_v1) => receipt_v1.hash(), - Self::V2(receipt_v2) => receipt_v2.hash(), - } - } -} - -impl VersionedCommittedCandidateReceipt { - /// Returns the core index the candidate has commited to. Returns `None`` if - /// the receipt is version 1. - pub fn core_index(&self) -> Option { - match self { - Self::V1(_receipt_v1) => None, - Self::V2(receipt_v2) => receipt_v2.descriptor.core_index(), - } - } - - /// Returns the session index of the relay parent. Returns `None` if - /// the receipt is version 1. - pub fn session_index(&self) -> Option { - match self { - Self::V1(_receipt_v1) => None, - Self::V2(receipt_v2) => receipt_v2.descriptor.session_index(), - } - } - - /// Convert to a plain `CandidateReceipt`. - pub fn to_plain(&self) -> VersionedCandidateReceipt { - match self { - Self::V1(receipt) => VersionedCandidateReceipt::V1(receipt.to_plain()), - Self::V2(receipt) => VersionedCandidateReceipt::V2(receipt.to_plain()), - } - } - - /// Returns the candidate commitments. - /// Convert to a plain `CandidateReceipt`. - pub fn commitments(&self) -> &CandidateCommitments { - match self { - Self::V1(receipt) => &receipt.commitments, - Self::V2(receipt) => &receipt.commitments, - } - } -} - impl CandidateCommitments { /// Returns the core selector and claim queue offset the candidate has commited to, if any. pub fn selected_core(&self) -> Option<(CoreSelector, ClaimQueueOffset)> { @@ -498,58 +334,84 @@ pub enum CandidateReceiptError { NoCoreSelected, } -macro_rules! impl_candidate_api_v1 { +macro_rules! impl_getter { ($field:ident, $type:ident) => { fn $field(&self) -> $type { - match self { - Self::V1(receipt) => receipt.descriptor.$field, - Self::V2(receipt) => receipt.descriptor.$field, - } + self.$field } }; } -impl CandidateApiV1 for VersionedCommittedCandidateReceipt { - impl_candidate_api_v1!(erasure_root, Hash); - impl_candidate_api_v1!(para_head, Hash); - impl_candidate_api_v1!(para_id, ParaId); - impl_candidate_api_v1!(persisted_validation_data_hash, Hash); - impl_candidate_api_v1!(pov_hash, Hash); - impl_candidate_api_v1!(validation_code_hash, ValidationCodeHash); - - fn collator(&self) -> Option<&CollatorId> { - match self { - Self::V1(receipt) => Some(&receipt.descriptor.collator), - Self::V2(receipt) => None, +impl CandidateDescriptorV2 { + impl_getter!(erasure_root, Hash); + impl_getter!(para_head, Hash); + impl_getter!(relay_parent, Hash); + impl_getter!(para_id, ParaId); + impl_getter!(persisted_validation_data_hash, Hash); + impl_getter!(pov_hash, Hash); + impl_getter!(validation_code_hash, ValidationCodeHash); + + /// Returns the candidate descriptor version. + /// The candidate is at version 2 if the reserved fields are zeroed out + /// and the internal `version` field is 0. + pub fn version(&self) -> CandidateDescriptorVersion { + if self.reserved64b != [0u8; 64] || self.reserved25b != [0u8; 25] { + return CandidateDescriptorVersion::V1 + } + + match self.version.0 { + 0 => CandidateDescriptorVersion::V2, + _ => CandidateDescriptorVersion::V1, } } - fn signature(&self) -> Option<&CollatorSignature> { - match self { - Self::V1(receipt) => Some(&receipt.descriptor.signature), - Self::V2(receipt) => None, + /// Returns the collator id if this is a v1 `CandidateDescriptor` + pub fn collator(&self) -> Option { + if self.version() == CandidateDescriptorVersion::V1 { + let mut collator_id = vec![self.version.0]; + let core_index: [u8; 2] = unsafe { std::mem::transmute(self.core_index) }; + let session_index: [u8; 4] = unsafe { std::mem::transmute(self.session_index) }; + + collator_id.append(&mut core_index.as_slice().to_vec()); + collator_id.append(&mut session_index.as_slice().to_vec()); + collator_id.append(&mut self.reserved25b.as_slice().to_vec()); + + return Some(CollatorId::from_slice(&collator_id.as_slice()).ok()?) } + + None } -} -impl CommittedCandidateReceiptV2 { - /// Returns a v2 commited candidate receipt if the committed selected core - /// matches the core index in the descriptor. - pub fn new(descriptor: CandidateDescriptorV2, commitments: CandidateCommitments) -> Self { - Self { descriptor, commitments } + /// Returns the collator signature of `V1` candidate descriptors, `None` otherwise. + pub fn signature(&self) -> Option { + if self.version() == CandidateDescriptorVersion::V1 { + return Some(CollatorSignature::from_slice(self.reserved64b.as_slice()).ok()?) + } + + None } - /// Returns a reference to commitments - pub fn commitments(&self) -> &CandidateCommitments { - &self.commitments + /// Returns the `core_index` of `V2` candidate descriptors, `None` otherwise. + pub fn core_index(&self) -> Option { + if self.version() == CandidateDescriptorVersion::V1 { + return None + } + + Some(CoreIndex(self.core_index as u32)) } - /// Returns a reference to the descriptor - pub fn descriptor(&self) -> &CandidateDescriptorV2 { - &self.descriptor + /// Returns the `core_index` of `V2` candidate descriptors, `None` otherwise. + pub fn session_index(&self) -> Option { + if self.version() == CandidateDescriptorVersion::V1 { + return None + } + + Some(self.session_index) } +} - /// Performs a sanity check of the receipt. +impl CommittedCandidateReceiptV2 { + /// Performs a sanity check of the descriptor and commitment. /// /// Returns error if: /// - descriptor core index is different than the core selected @@ -615,35 +477,11 @@ impl CommittedCandidateReceiptV2 { } } -impl From> for VersionedCommittedCandidateReceipt { - fn from(value: CommittedCandidateReceipt) -> Self { - Self::V1(value) - } -} - -impl From> for VersionedCommittedCandidateReceipt { - fn from(value: CommittedCandidateReceiptV2) -> Self { - Self::V2(value) - } -} - -impl From> for VersionedCandidateReceipt { - fn from(value: CandidateReceipt) -> Self { - Self::V1(value) - } -} - -impl From> for VersionedCandidateReceipt { - fn from(value: CandidateReceiptV2) -> Self { - Self::V2(value) - } -} - /// A backed (or backable, depending on context) candidate. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] pub struct BackedCandidate { /// The candidate referred to. - candidate: VersionedCommittedCandidateReceipt, + candidate: CommittedCandidateReceiptV2, /// The validity votes themselves, expressed as signatures. validity_votes: Vec, /// The indices of the validators within the group, expressed as a bitfield. May be extended @@ -652,10 +490,23 @@ pub struct BackedCandidate { validator_indices: BitVec, } +/// Parachains inherent-data passed into the runtime by a block author +#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)] +pub struct InherentData { + /// Signed bitfields by validators about availability. + pub bitfields: UncheckedSignedAvailabilityBitfields, + /// Backed candidates for inclusion in the block. + pub backed_candidates: Vec>, + /// Sets of dispute votes for inclusion, + pub disputes: MultiDisputeStatementSet, + /// The parent block header. Used for checking state proofs. + pub parent_header: HDR, +} + impl BackedCandidate { /// Constructor pub fn new( - candidate: VersionedCommittedCandidateReceipt, + candidate: CommittedCandidateReceiptV2, validity_votes: Vec, validator_indices: BitVec, core_index: Option, @@ -668,7 +519,7 @@ impl BackedCandidate { } /// Get a reference to the committed candidate receipt of the candidate. - pub fn candidate(&self) -> &VersionedCommittedCandidateReceipt { + pub fn candidate(&self) -> &CommittedCandidateReceiptV2 { &self.candidate } @@ -691,7 +542,7 @@ impl BackedCandidate { } /// Get this candidate's receipt. - pub fn receipt(&self) -> VersionedCandidateReceipt + pub fn receipt(&self) -> CandidateReceiptV2 where H: Clone, { @@ -743,20 +594,14 @@ impl BackedCandidate { #[cfg(test)] mod tests { - use core::prelude::v1; - use super::*; use crate::{ v7::{ tests::dummy_committed_candidate_receipt as dummy_old_committed_candidate_receipt, - CandidateDescriptor, CandidateReceipt as OldCandidateReceipt, CommittedCandidateReceipt, Hash, HeadData, ValidationCode, }, - vstaging::{ - CandidateApiV1, CandidateApiV2, CandidateDescriptorV2, CommittedCandidateReceiptV2, - }, + vstaging::{CandidateDescriptorV2, CommittedCandidateReceiptV2}, }; - // use polkadot_primitives_test_helpers::dummy_committed_candidate_receipt_v2; pub fn dummy_committed_candidate_receipt_v2() -> CommittedCandidateReceiptV2 { let zeros = Hash::zero(); @@ -766,9 +611,10 @@ mod tests { descriptor: CandidateDescriptorV2 { para_id: 0.into(), relay_parent: zeros, + version: InternalVersion(0), core_index: 123, session_index: 1, - reserved26b: Default::default(), + reserved25b: Default::default(), persisted_validation_data_hash: zeros, pov_hash: zeros, erasure_root: zeros, @@ -825,7 +671,7 @@ mod tests { let mut claim_queue = BTreeMap::new(); claim_queue.insert( - new_ccr.descriptor().core_index().unwrap(), + new_ccr.descriptor.core_index().unwrap(), vec![2.into(), new_ccr.descriptor.para_id, 3.into()].into(), ); @@ -833,7 +679,7 @@ mod tests { } #[test] - fn test_versioned_receipt() { + fn test_version2_receipts_decoded_as_v1() { let mut new_ccr = dummy_committed_candidate_receipt_v2(); new_ccr.descriptor.core_index = 123; new_ccr.descriptor.para_id = ParaId::new(1000); @@ -853,66 +699,77 @@ mod tests { let mut claim_queue = BTreeMap::new(); claim_queue.insert( - new_ccr.descriptor().core_index().unwrap(), + new_ccr.descriptor.core_index().unwrap(), vec![2.into(), new_ccr.descriptor.para_id, 3.into()].into(), ); let encoded_ccr = new_ccr.encode(); - let versioned_ccr = - VersionedCommittedCandidateReceipt::decode(&mut encoded_ccr.as_slice()).unwrap(); + let decoded_ccr: CommittedCandidateReceipt = + Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); - assert_eq!(versioned_ccr.core_index(), Some(CoreIndex(123))); + assert_eq!(decoded_ccr.descriptor.relay_parent, new_ccr.descriptor.relay_parent()); + assert_eq!(decoded_ccr.descriptor.para_id, new_ccr.descriptor.para_id()); - if let VersionedCommittedCandidateReceipt::V2(ref v2_receipt) = versioned_ccr { - assert_eq!(v2_receipt.check(200, &claim_queue), Ok(())); - } + assert_eq!(new_ccr.hash(), decoded_ccr.hash()); + + // // // Encode v1 and decode as V2 + let encoded_ccr = new_ccr.encode(); + let v2_ccr: CommittedCandidateReceiptV2 = + Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); + + assert_eq!(v2_ccr.descriptor.core_index(), Some(CoreIndex(123))); + assert_eq!(new_ccr.check(200, &claim_queue), Ok(())); + + assert_eq!(new_ccr.hash(), v2_ccr.hash()); + } - assert_eq!(new_ccr.hash(), versioned_ccr.to_plain().hash()); + fn dummy_collator_signature() -> CollatorSignature { + CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) + .expect("64 bytes; qed") + } + + fn dummy_collator_id() -> CollatorId { + CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) + .expect("32 bytes; qed") } #[test] - fn test_backward_compatible() { + fn test_core_select_is_mandatory() { // Testing edge case when collators provide zeroed signature and collator id. let mut old_ccr = dummy_old_committed_candidate_receipt(); old_ccr.descriptor.para_id = ParaId::new(1000); let encoded_ccr: Vec = old_ccr.encode(); - let versioned_ccr = - VersionedCommittedCandidateReceipt::decode(&mut encoded_ccr.as_slice()).unwrap(); + let new_ccr = CommittedCandidateReceiptV2::decode(&mut encoded_ccr.as_slice()).unwrap(); - // Since collator sig and id are zeroed, it was decoded as V2. - // We expect the check to fail in such case because there will be no `SelectCore` - // commitment. + // Since collator sig and id are zeroed, it means that the descriptor uses format + // version 2. let mut claim_queue = BTreeMap::new(); claim_queue.insert( - versioned_ccr.core_index().unwrap(), - vec![2.into(), versioned_ccr.para_id(), 3.into()].into(), + new_ccr.descriptor.core_index().unwrap(), + vec![2.into(), new_ccr.descriptor.para_id(), 3.into()].into(), ); - if let VersionedCommittedCandidateReceipt::V2(ref v2_receipt) = versioned_ccr { - assert_eq!( - v2_receipt.check(200, &claim_queue), - Err(CandidateReceiptError::NoCoreSelected) - ); - } else { - panic!("Should have decoded as V2") - } + // We expect the check to fail in such case because there will be no `SelectCore` + // commitment. + assert_eq!(new_ccr.check(200, &claim_queue), Err(CandidateReceiptError::NoCoreSelected)); // Adding collator signature should make it decode as v1. - old_ccr.descriptor.signature = - CollatorSignature::from_slice(&vec![99u8; 64]).expect("64 bytes; qed"); + old_ccr.descriptor.signature = dummy_collator_signature(); + old_ccr.descriptor.collator = dummy_collator_id(); + + let old_ccr_hash = old_ccr.hash(); + let encoded_ccr: Vec = old_ccr.encode(); - let versioned_ccr = - VersionedCommittedCandidateReceipt::decode(&mut encoded_ccr.as_slice()).unwrap(); - if let VersionedCommittedCandidateReceipt::V1(ref v1_receipt) = versioned_ccr { - assert_eq!(v1_receipt.descriptor.signature, old_ccr.descriptor.signature); - } else { - panic!("Should have decoded as V1") - } + let new_ccr = CommittedCandidateReceiptV2::decode(&mut encoded_ccr.as_slice()).unwrap(); + + assert_eq!(new_ccr.descriptor.signature(), Some(old_ccr.descriptor.signature)); + assert_eq!(new_ccr.descriptor.collator(), Some(old_ccr.descriptor.collator)); + + assert_eq!(new_ccr.descriptor.core_index(), None); + assert_eq!(new_ccr.descriptor.para_id(), ParaId::new(1000)); - assert_eq!(versioned_ccr.core_index(), None); - assert_eq!(versioned_ccr.para_id(), ParaId::new(1000)); - assert_eq!(old_ccr.hash(), versioned_ccr.to_plain().hash()); + assert_eq!(old_ccr_hash, new_ccr.hash()); } } diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index c262f16df077..cb644372f758 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -23,10 +23,7 @@ //! Note that `dummy_` prefixed values are meant to be fillers, that should not matter, and will //! contain randomness based data. use polkadot_primitives::{ - vstaging::{ - CandidateDescriptorV2, CandidateReceiptV2, CommittedCandidateReceiptV2, - VersionedCandidateReceipt, - }, + vstaging::{CandidateDescriptorV2, CandidateReceiptV2, CommittedCandidateReceiptV2}, CandidateCommitments, CandidateDescriptor, CandidateReceipt, CollatorId, CollatorSignature, CommittedCandidateReceipt, CoreIndex, Hash, HeadData, Id as ParaId, PersistedValidationData, SessionIndex, ValidationCode, ValidationCodeHash, ValidatorId, From 2831c5e0cb2f295609a16649a38babc66d36f409 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 8 Aug 2024 23:19:06 +0300 Subject: [PATCH 005/130] Add missing primitives and fix things Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 139 ++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 8 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 03075e820524..f668b3a362bd 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -15,14 +15,14 @@ // along with Polkadot. If not, see . //! Staging Primitives. -use crate::ValidityAttestation; +use crate::{ValidatorIndex, ValidityAttestation}; // Put any primitives used by staging APIs functions here use super::{ Balance, BlakeTwo256, BlockNumber, CandidateCommitments, CandidateHash, CollatorId, CollatorSignature, CoreIndex, Hash, HashT, Header, Id, Id as ParaId, MultiDisputeStatementSet, UncheckedSignedAvailabilityBitfields, ValidationCodeHash, - ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, + ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, HeadData, GroupIndex, async_backing::Constraints, ScheduledCore }; use bitvec::prelude::*; use sp_application_crypto::ByteArray; @@ -158,6 +158,7 @@ pub struct CandidateDescriptorV2 { validation_code_hash: ValidationCodeHash, } + impl CandidateDescriptorV2 { /// Constructor pub fn new( @@ -208,6 +209,27 @@ pub struct CommittedCandidateReceiptV2 { pub commitments: CandidateCommitments, } + + +/// An even concerning a candidate. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum CandidateEvent { + /// This candidate receipt was backed in the most recent block. + /// This includes the core index the candidate is now occupying. + #[codec(index = 0)] + CandidateBacked(CandidateReceiptV2, HeadData, CoreIndex, GroupIndex), + /// This candidate receipt was included and became a parablock at the most recent block. + /// This includes the core index the candidate was occupying as well as the group responsible + /// for backing the candidate. + #[codec(index = 1)] + CandidateIncluded(CandidateReceiptV2, HeadData, CoreIndex, GroupIndex), + /// This candidate receipt was not made available in time and timed out. + /// This includes the core index the candidate was occupying. + #[codec(index = 2)] + CandidateTimedOut(CandidateReceiptV2, HeadData, CoreIndex), +} + impl CandidateReceiptV2 { /// Get a reference to the candidate descriptor. pub fn descriptor(&self) -> &CandidateDescriptorV2 { @@ -336,16 +358,17 @@ pub enum CandidateReceiptError { macro_rules! impl_getter { ($field:ident, $type:ident) => { - fn $field(&self) -> $type { + /// Returns the value of $field field. + pub fn $field(&self) -> $type { self.$field } }; } -impl CandidateDescriptorV2 { +impl CandidateDescriptorV2 { impl_getter!(erasure_root, Hash); impl_getter!(para_head, Hash); - impl_getter!(relay_parent, Hash); + impl_getter!(relay_parent, H); impl_getter!(para_id, ParaId); impl_getter!(persisted_validation_data_hash, Hash); impl_getter!(pov_hash, Hash); @@ -454,18 +477,17 @@ impl CommittedCandidateReceiptV2 { None } }) - .cloned() .collect::>(); if assigned_cores.is_empty() { return Err(CandidateReceiptError::NoAssignment) } - let core_index = *assigned_cores + let core_index = assigned_cores .get(core_selector.0 as usize % assigned_cores.len()) .expect("provided index is always less than queue len; qed"); - if core_index != descriptor_core_index { + if **core_index != descriptor_core_index { return Err(CandidateReceiptError::CoreIndexMismatch) } @@ -523,6 +545,11 @@ impl BackedCandidate { &self.candidate } + /// Get a reference to the descriptor of the candidate. + pub fn descriptor(&self) -> &CandidateDescriptorV2 { + &self.candidate.descriptor + } + /// Get a reference to the validity votes of the candidate. pub fn validity_votes(&self) -> &[ValidityAttestation] { &self.validity_votes @@ -592,6 +619,102 @@ impl BackedCandidate { } } +/// Scraped runtime backing votes and resolved disputes. +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct ScrapedOnChainVotes { + /// The session in which the block was included. + pub session: SessionIndex, + /// Set of backing validators for each candidate, represented by its candidate + /// receipt. + pub backing_validators_per_candidate: + Vec<(CandidateReceiptV2, Vec<(ValidatorIndex, ValidityAttestation)>)>, + /// On-chain-recorded set of disputes. + /// Note that the above `backing_validators` are + /// unrelated to the backers of the disputes candidates. + pub disputes: MultiDisputeStatementSet, +} + + +/// A candidate pending availability. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct CandidatePendingAvailability { + /// The hash of the candidate. + pub candidate_hash: CandidateHash, + /// The candidate's descriptor. + pub descriptor: CandidateDescriptorV2, + /// The commitments of the candidate. + pub commitments: CandidateCommitments, + /// The candidate's relay parent's number. + pub relay_parent_number: N, + /// The maximum Proof-of-Validity size allowed, in bytes. + pub max_pov_size: u32, +} + +/// The per-parachain state of the backing system, including +/// state-machine constraints and candidates pending availability. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct BackingState { + /// The state-machine constraints of the parachain. + pub constraints: Constraints, + /// The candidates pending availability. These should be ordered, i.e. they should form + /// a sub-chain, where the first candidate builds on top of the required parent of the + /// constraints and each subsequent builds on top of the previous head-data. + pub pending_availability: Vec>, +} + + +/// Information about a core which is currently occupied. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct OccupiedCore { + // NOTE: this has no ParaId as it can be deduced from the candidate descriptor. + /// If this core is freed by availability, this is the assignment that is next up on this + /// core, if any. None if there is nothing queued for this core. + pub next_up_on_available: Option, + /// The relay-chain block number this began occupying the core at. + pub occupied_since: N, + /// The relay-chain block this will time-out at, if any. + pub time_out_at: N, + /// If this core is freed by being timed-out, this is the assignment that is next up on this + /// core. None if there is nothing queued for this core or there is no possibility of timing + /// out. + pub next_up_on_time_out: Option, + /// A bitfield with 1 bit for each validator in the set. `1` bits mean that the corresponding + /// validators has attested to availability on-chain. A 2/3+ majority of `1` bits means that + /// this will be available. + pub availability: BitVec, + /// The group assigned to distribute availability pieces of this candidate. + pub group_responsible: GroupIndex, + /// The hash of the candidate occupying the core. + pub candidate_hash: CandidateHash, + /// The descriptor of the candidate occupying the core. + pub candidate_descriptor: CandidateDescriptorV2, +} + + +/// The state of a particular availability core. +#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum CoreState { + /// The core is currently occupied. + #[codec(index = 0)] + Occupied(OccupiedCore), + /// The core is currently free, with a para scheduled and given the opportunity + /// to occupy. + /// + /// If a particular Collator is required to author this block, that is also present in this + /// variant. + #[codec(index = 1)] + Scheduled(ScheduledCore), + /// The core is currently free and there is nothing scheduled. This can be the case for + /// parathread cores when there are no parathread blocks queued. Parachain cores will never be + /// left idle. + #[codec(index = 2)] + Free, +} + + #[cfg(test)] mod tests { use super::*; From c767d60da43a8d6aad953c32752bca772f6da494 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 8 Aug 2024 23:20:06 +0300 Subject: [PATCH 006/130] Implement v2 receipts in polkadot-runtime-parachains Signed-off-by: Andrei Sandu --- .../node/test/client/src/block_builder.rs | 2 +- polkadot/runtime/parachains/src/builder.rs | 4 +-- .../parachains/src/inclusion/migration.rs | 3 +- .../runtime/parachains/src/inclusion/mod.rs | 30 +++++++++---------- .../parachains/src/paras_inherent/mod.rs | 28 ++++++++--------- .../parachains/src/runtime_api_impl/v10.rs | 13 ++++---- .../src/runtime_api_impl/vstaging.rs | 2 +- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/polkadot/node/test/client/src/block_builder.rs b/polkadot/node/test/client/src/block_builder.rs index 71bcdaffac4e..ed24cd55d084 100644 --- a/polkadot/node/test/client/src/block_builder.rs +++ b/polkadot/node/test/client/src/block_builder.rs @@ -16,7 +16,7 @@ use crate::Client; use codec::{Decode, Encode}; -use polkadot_primitives::{Block, InherentData as ParachainsInherentData}; +use polkadot_primitives::{Block, vstaging::InherentData as ParachainsInherentData}; use polkadot_test_runtime::UncheckedExtrinsic; use polkadot_test_service::GetLastTimestamp; use sc_block_builder::{BlockBuilder, BlockBuilderBuilder}; diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index b2a67ee8dd24..86473fafc8b0 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -31,9 +31,9 @@ use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; use polkadot_primitives::{ node_features::FeatureIndex, AvailabilityBitfield, BackedCandidate, CandidateCommitments, - CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, CommittedCandidateReceipt, + vstaging::CandidateDescriptorV2 as CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, - Id as ParaId, IndexedVec, InherentData as ParachainsInherentData, InvalidDisputeStatementKind, + Id as ParaId, IndexedVec, vstaging::InherentData as ParachainsInherentData, InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation, }; diff --git a/polkadot/runtime/parachains/src/inclusion/migration.rs b/polkadot/runtime/parachains/src/inclusion/migration.rs index 36a810d341c6..522d224d00d2 100644 --- a/polkadot/runtime/parachains/src/inclusion/migration.rs +++ b/polkadot/runtime/parachains/src/inclusion/migration.rs @@ -20,8 +20,7 @@ pub mod v0 { use frame_support::{storage_alias, Twox64Concat}; use frame_system::pallet_prelude::BlockNumberFor; use polkadot_primitives::{ - AvailabilityBitfield, CandidateCommitments, CandidateDescriptor, CandidateHash, CoreIndex, - GroupIndex, Id as ParaId, ValidatorIndex, + vstaging::CandidateDescriptorV2 as CandidateDescriptor, AvailabilityBitfield, CandidateCommitments, CandidateHash, CoreIndex, GroupIndex, Id as ParaId, ValidatorIndex }; use scale_info::TypeInfo; diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index 115eee975530..75b80d06fc18 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -45,9 +45,9 @@ use frame_support::{ use frame_system::pallet_prelude::*; use pallet_message_queue::OnQueueChanged; use polkadot_primitives::{ - effective_minimum_backing_votes, supermajority_threshold, well_known_keys, BackedCandidate, - CandidateCommitments, CandidateDescriptor, CandidateHash, CandidateReceipt, - CommittedCandidateReceipt, CoreIndex, GroupIndex, Hash, HeadData, Id as ParaId, + effective_minimum_backing_votes, supermajority_threshold, well_known_keys, vstaging::BackedCandidate, + CandidateCommitments, vstaging::CandidateDescriptorV2 as CandidateDescriptor, CandidateHash, vstaging::CandidateReceiptV2 as CandidateReceipt, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, GroupIndex, Hash, HeadData, Id as ParaId, SignedAvailabilityBitfields, SigningContext, UpwardMessage, ValidatorId, ValidatorIndex, ValidityAttestation, }; @@ -749,7 +749,7 @@ impl Pallet { let mut backers = bitvec::bitvec![u8, BitOrderLsb0; 0; validators.len()]; let signing_context = SigningContext { - parent_hash: backed_candidate.descriptor().relay_parent, + parent_hash: backed_candidate.descriptor().relay_parent(), session_index: shared::CurrentSessionIndex::::get(), }; @@ -870,7 +870,7 @@ impl Pallet { let now = frame_system::Pallet::::block_number(); weight.saturating_add(paras::Pallet::::schedule_code_upgrade( - receipt.descriptor.para_id, + receipt.descriptor.para_id(), new_code, now, &config, @@ -880,19 +880,19 @@ impl Pallet { // enact the messaging facet of the candidate. weight.saturating_accrue(dmp::Pallet::::prune_dmq( - receipt.descriptor.para_id, + receipt.descriptor.para_id(), commitments.processed_downward_messages, )); weight.saturating_accrue(Self::receive_upward_messages( - receipt.descriptor.para_id, + receipt.descriptor.para_id(), commitments.upward_messages.as_slice(), )); weight.saturating_accrue(hrmp::Pallet::::prune_hrmp( - receipt.descriptor.para_id, + receipt.descriptor.para_id(), BlockNumberFor::::from(commitments.hrmp_watermark), )); weight.saturating_accrue(hrmp::Pallet::::queue_outbound_hrmp( - receipt.descriptor.para_id, + receipt.descriptor.para_id(), commitments.horizontal_messages, )); @@ -904,7 +904,7 @@ impl Pallet { )); weight.saturating_add(paras::Pallet::::note_new_head( - receipt.descriptor.para_id, + receipt.descriptor.para_id(), commitments.head_data, relay_parent_number, )) @@ -1242,8 +1242,8 @@ impl CandidateCheckContext { backed_candidate_receipt: &CommittedCandidateReceipt<::Hash>, parent_head_data: HeadData, ) -> Result, Error> { - let para_id = backed_candidate_receipt.descriptor().para_id; - let relay_parent = backed_candidate_receipt.descriptor().relay_parent; + let para_id = backed_candidate_receipt.descriptor.para_id(); + let relay_parent = backed_candidate_receipt.descriptor.relay_parent(); // Check that the relay-parent is one of the allowed relay-parents. let (relay_parent_storage_root, relay_parent_number) = { @@ -1263,7 +1263,7 @@ impl CandidateCheckContext { let expected = persisted_validation_data.hash(); ensure!( - expected == backed_candidate_receipt.descriptor().persisted_validation_data_hash, + expected == backed_candidate_receipt.descriptor.persisted_validation_data_hash(), Error::::ValidationDataHashMismatch, ); } @@ -1272,12 +1272,12 @@ impl CandidateCheckContext { // A candidate for a parachain without current validation code is not scheduled. .ok_or_else(|| Error::::UnscheduledCandidate)?; ensure!( - backed_candidate_receipt.descriptor().validation_code_hash == validation_code_hash, + backed_candidate_receipt.descriptor.validation_code_hash() == validation_code_hash, Error::::InvalidValidationCodeHash, ); ensure!( - backed_candidate_receipt.descriptor().para_head == + backed_candidate_receipt.descriptor.para_head() == backed_candidate_receipt.commitments.head_data.hash(), Error::::ParaHeadMismatch, ); diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 9d27e86ef901..de616ea763b9 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -48,10 +48,10 @@ use frame_support::{ use frame_system::pallet_prelude::*; use pallet_babe::{self, ParentBlockRandomness}; use polkadot_primitives::{ - effective_minimum_backing_votes, node_features::FeatureIndex, BackedCandidate, CandidateHash, - CandidateReceipt, CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CoreIndex, - DisputeStatementSet, HeadData, InherentData as ParachainsInherentData, - MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex, SignedAvailabilityBitfields, + effective_minimum_backing_votes, node_features::FeatureIndex, vstaging::BackedCandidate, CandidateHash, + vstaging::CandidateReceiptV2 as CandidateReceipt, CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CoreIndex, + DisputeStatementSet, HeadData, vstaging::InherentData as ParachainsInherentData, + MultiDisputeStatementSet, vstaging::ScrapedOnChainVotes, SessionIndex, SignedAvailabilityBitfields, SigningContext, UncheckedSignedAvailabilityBitfield, UncheckedSignedAvailabilityBitfields, ValidatorId, ValidatorIndex, ValidityAttestation, PARACHAINS_INHERENT_IDENTIFIER, }; @@ -763,7 +763,7 @@ pub(crate) fn apply_weight_limit( let mut current_para_id = None; for candidate in core::mem::take(candidates).into_iter() { - let candidate_para_id = candidate.descriptor().para_id; + let candidate_para_id = candidate.descriptor().para_id(); if Some(candidate_para_id) == current_para_id { let chain = chained_candidates .last_mut() @@ -965,7 +965,7 @@ fn sanitize_backed_candidates( let mut candidates_per_para: BTreeMap> = BTreeMap::new(); for candidate in backed_candidates { candidates_per_para - .entry(candidate.descriptor().para_id) + .entry(candidate.descriptor().para_id()) .or_default() .push(candidate); } @@ -984,7 +984,7 @@ fn sanitize_backed_candidates( target: LOG_TARGET, "Found backed candidate {:?} which was concluded invalid or is a descendant of a concluded invalid candidate, for paraid {:?}.", candidate.candidate().hash(), - candidate.descriptor().para_id + candidate.descriptor().para_id() ); } keep @@ -1165,13 +1165,13 @@ fn filter_backed_statements_from_disabled_validators< // Get relay parent block number of the candidate. We need this to get the group index // assigned to this core at this block number let relay_parent_block_number = - match allowed_relay_parents.acquire_info(bc.descriptor().relay_parent, None) { + match allowed_relay_parents.acquire_info(bc.descriptor().relay_parent(), None) { Some((_, block_num)) => block_num, None => { log::debug!( target: LOG_TARGET, "Relay parent {:?} for candidate is not in the allowed relay parents. Dropping the candidate.", - bc.descriptor().relay_parent + bc.descriptor().relay_parent() ); return false }, @@ -1372,7 +1372,7 @@ fn map_candidates_to_cores block_num, None => { log::debug!( target: LOG_TARGET, "Relay parent {:?} for candidate {:?} is not in the allowed relay parents.", - candidate.descriptor().relay_parent, + candidate.descriptor().relay_parent(), candidate.candidate().hash(), ); return None diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs index 697890232211..f0107d6f21e2 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs @@ -27,14 +27,15 @@ use frame_support::traits::{GetStorageVersion, StorageVersion}; use frame_system::pallet_prelude::*; use polkadot_primitives::{ async_backing::{ - AsyncBackingParams, BackingState, CandidatePendingAvailability, Constraints, - InboundHrmpLimitations, OutboundHrmpChannelLimitations, + AsyncBackingParams, Constraints, + InboundHrmpLimitations, OutboundHrmpChannelLimitations, }, - slashing, ApprovalVotingParams, AuthorityDiscoveryId, CandidateEvent, CandidateHash, - CommittedCandidateReceipt, CoreIndex, CoreState, DisputeState, ExecutorParams, GroupIndex, + vstaging::{CoreState,OccupiedCore, BackingState, CandidateEvent, ScrapedOnChainVotes, CandidatePendingAvailability, CommittedCandidateReceiptV2 as CommittedCandidateReceipt}, + slashing, ApprovalVotingParams, AuthorityDiscoveryId, CandidateHash, + CoreIndex, DisputeState, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, - NodeFeatures, OccupiedCore, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, - ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, + NodeFeatures, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, + SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; use sp_runtime::traits::One; diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs index 4aa381e33b1b..f110099d968c 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -21,7 +21,7 @@ use alloc::{ collections::{btree_map::BTreeMap, vec_deque::VecDeque}, vec::Vec, }; -use polkadot_primitives::{CommittedCandidateReceipt, CoreIndex, Id as ParaId}; +use polkadot_primitives::{vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, Id as ParaId}; use sp_runtime::traits::One; /// Returns the claimqueue from the scheduler From 96999e31b96f60954bf29f4e7f2db03aa579f0a5 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 15:04:28 +0300 Subject: [PATCH 007/130] add missing stuff Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 176 ++++++++++++++++++++---- 1 file changed, 153 insertions(+), 23 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index f668b3a362bd..9541484d5028 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -19,16 +19,20 @@ use crate::{ValidatorIndex, ValidityAttestation}; // Put any primitives used by staging APIs functions here use super::{ - Balance, BlakeTwo256, BlockNumber, CandidateCommitments, CandidateHash, - CollatorId, CollatorSignature, CoreIndex, Hash, HashT, Header, Id, Id as ParaId, - MultiDisputeStatementSet, UncheckedSignedAvailabilityBitfields, ValidationCodeHash, - ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, HeadData, GroupIndex, async_backing::Constraints, ScheduledCore + async_backing::Constraints, Balance, BlakeTwo256, BlockNumber, CandidateCommitments, + CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, CoreIndex, GroupIndex, Hash, + HashT, HeadData, Header, Id, Id as ParaId, MultiDisputeStatementSet, ScheduledCore, + UncheckedSignedAvailabilityBitfields, ValidationCodeHash, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, }; use bitvec::prelude::*; use sp_application_crypto::ByteArray; -use alloc::collections::{btree_map::BTreeMap, vec_deque::VecDeque}; -use codec::{Decode, Encode}; +use alloc::{ + collections::{btree_map::BTreeMap, vec_deque::VecDeque}, + vec, + vec::Vec, +}; +use codec::{Decode, Encode, WrapperTypeDecode}; use scale_info::TypeInfo; use sp_arithmetic::Perbill; use sp_core::RuntimeDebug; @@ -158,6 +162,21 @@ pub struct CandidateDescriptorV2 { validation_code_hash: ValidationCodeHash, } +impl From> for CandidateDescriptor { + fn from(value: CandidateDescriptorV2) -> Self { + Self { + para_id: value.para_id, + relay_parent: value.relay_parent, + collator: value.rebuild_collator_field(), + persisted_validation_data_hash: value.persisted_validation_data_hash, + pov_hash: value.pov_hash, + erasure_root: value.erasure_root, + signature: value.rebuild_signature_field(), + para_head: value.para_head, + validation_code_hash: value.validation_code_hash, + } + } +} impl CandidateDescriptorV2 { /// Constructor @@ -187,6 +206,11 @@ impl CandidateDescriptorV2 { validation_code_hash, } } + + #[cfg(feature = "test")] + pub fn set_pov_hash(&mut self, pov_hash: Hash) { + self.pov_hash = pov_hash; + } } /// A candidate-receipt at version 2. @@ -209,8 +233,6 @@ pub struct CommittedCandidateReceiptV2 { pub commitments: CandidateCommitments, } - - /// An even concerning a candidate. #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] @@ -230,6 +252,29 @@ pub enum CandidateEvent { CandidateTimedOut(CandidateReceiptV2, HeadData, CoreIndex), } +impl From> for super::v7::CandidateEvent { + fn from(value: CandidateEvent) -> Self { + match value { + CandidateEvent::CandidateBacked(receipt, head_data, core_index, group_index) => + super::v7::CandidateEvent::CandidateBacked( + receipt.into(), + head_data, + core_index, + group_index, + ), + CandidateEvent::CandidateIncluded(receipt, head_data, core_index, group_index) => + super::v7::CandidateEvent::CandidateIncluded( + receipt.into(), + head_data, + core_index, + group_index, + ), + CandidateEvent::CandidateTimedOut(receipt, head_data, core_index) => + super::v7::CandidateEvent::CandidateTimedOut(receipt.into(), head_data, core_index), + } + } +} + impl CandidateReceiptV2 { /// Get a reference to the candidate descriptor. pub fn descriptor(&self) -> &CandidateDescriptorV2 { @@ -289,6 +334,18 @@ impl Ord for CommittedCandidateReceiptV2 { } } +impl From> for super::v7::CommittedCandidateReceipt { + fn from(value: CommittedCandidateReceiptV2) -> Self { + Self { descriptor: value.descriptor.into(), commitments: value.commitments } + } +} + +impl From> for super::v7::CandidateReceipt { + fn from(value: CandidateReceiptV2) -> Self { + Self { descriptor: value.descriptor.into(), commitments_hash: value.commitments_hash } + } +} + /// A strictly increasing sequence number, tipically this would be the parachain block number. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] pub struct CoreSelector(pub BlockNumber); @@ -388,27 +445,36 @@ impl CandidateDescriptorV2 { } } + fn rebuild_collator_field(&self) -> CollatorId { + let mut collator_id = vec![self.version.0]; + let core_index: [u8; 2] = unsafe { core::mem::transmute(self.core_index) }; + let session_index: [u8; 4] = unsafe { core::mem::transmute(self.session_index) }; + + collator_id.append(&mut core_index.as_slice().to_vec()); + collator_id.append(&mut session_index.as_slice().to_vec()); + collator_id.append(&mut self.reserved25b.as_slice().to_vec()); + + CollatorId::from_slice(&collator_id.as_slice()).expect("Slice size is exactly 32 bytes") + } + /// Returns the collator id if this is a v1 `CandidateDescriptor` pub fn collator(&self) -> Option { if self.version() == CandidateDescriptorVersion::V1 { - let mut collator_id = vec![self.version.0]; - let core_index: [u8; 2] = unsafe { std::mem::transmute(self.core_index) }; - let session_index: [u8; 4] = unsafe { std::mem::transmute(self.session_index) }; - - collator_id.append(&mut core_index.as_slice().to_vec()); - collator_id.append(&mut session_index.as_slice().to_vec()); - collator_id.append(&mut self.reserved25b.as_slice().to_vec()); - - return Some(CollatorId::from_slice(&collator_id.as_slice()).ok()?) + Some(self.rebuild_collator_field()) + } else { + None } + } - None + fn rebuild_signature_field(&self) -> CollatorSignature { + CollatorSignature::from_slice(self.reserved64b.as_slice()) + .expect("Slice size is exactly 64 bytes") } /// Returns the collator signature of `V1` candidate descriptors, `None` otherwise. pub fn signature(&self) -> Option { if self.version() == CandidateDescriptorVersion::V1 { - return Some(CollatorSignature::from_slice(self.reserved64b.as_slice()).ok()?) + return Some(self.rebuild_signature_field()) } None @@ -635,6 +701,19 @@ pub struct ScrapedOnChainVotes { pub disputes: MultiDisputeStatementSet, } +impl From> for super::v7::ScrapedOnChainVotes { + fn from(value: ScrapedOnChainVotes) -> Self { + Self { + session: value.session, + backing_validators_per_candidate: value + .backing_validators_per_candidate + .into_iter() + .map(|(receipt, validators)| (receipt.into(), validators)) + .collect::>(), + disputes: value.disputes, + } + } +} /// A candidate pending availability. #[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] @@ -651,6 +730,20 @@ pub struct CandidatePendingAvailability { pub max_pov_size: u32, } +impl From> + for super::async_backing::CandidatePendingAvailability +{ + fn from(value: CandidatePendingAvailability) -> Self { + Self { + candidate_hash: value.candidate_hash, + descriptor: value.descriptor.into(), + commitments: value.commitments, + relay_parent_number: value.relay_parent_number, + max_pov_size: value.max_pov_size, + } + } +} + /// The per-parachain state of the backing system, including /// state-machine constraints and candidates pending availability. #[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] @@ -663,7 +756,18 @@ pub struct BackingState { pub pending_availability: Vec>, } - +impl From> for super::async_backing::BackingState { + fn from(value: BackingState) -> Self { + Self { + constraints: value.constraints, + pending_availability: value + .pending_availability + .into_iter() + .map(|candidate| candidate.into()) + .collect::>(), + } + } +} /// Information about a core which is currently occupied. #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] @@ -692,7 +796,6 @@ pub struct OccupiedCore { pub candidate_descriptor: CandidateDescriptorV2, } - /// The state of a particular availability core. #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] @@ -714,6 +817,31 @@ pub enum CoreState { Free, } +impl From> for super::v7::OccupiedCore { + fn from(value: OccupiedCore) -> Self { + Self { + next_up_on_available: value.next_up_on_available, + occupied_since: value.occupied_since, + time_out_at: value.time_out_at, + next_up_on_time_out: value.next_up_on_time_out, + availability: value.availability, + group_responsible: value.group_responsible, + candidate_hash: value.candidate_hash, + candidate_descriptor: value.candidate_descriptor.into(), + } + } +} + +impl From> for super::v7::CoreState { + fn from(value: CoreState) -> Self { + match value { + CoreState::Free => super::v7::CoreState::Free, + CoreState::Scheduled(core) => super::v7::CoreState::Scheduled(core), + CoreState::Occupied(occupied_core) => + super::v7::CoreState::Occupied(occupied_core.into()), + } + } +} #[cfg(test)] mod tests { @@ -863,7 +991,8 @@ mod tests { old_ccr.descriptor.para_id = ParaId::new(1000); let encoded_ccr: Vec = old_ccr.encode(); - let new_ccr = CommittedCandidateReceiptV2::decode(&mut encoded_ccr.as_slice()).unwrap(); + let new_ccr: CommittedCandidateReceiptV2 = + Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); // Since collator sig and id are zeroed, it means that the descriptor uses format // version 2. @@ -885,7 +1014,8 @@ mod tests { let encoded_ccr: Vec = old_ccr.encode(); - let new_ccr = CommittedCandidateReceiptV2::decode(&mut encoded_ccr.as_slice()).unwrap(); + let new_ccr: CommittedCandidateReceiptV2 = + Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); assert_eq!(new_ccr.descriptor.signature(), Some(old_ccr.descriptor.signature)); assert_eq!(new_ccr.descriptor.collator(), Some(old_ccr.descriptor.collator)); From c5f2dc3237809d6094a3ace158ebde1f9cd1678b Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 15:05:18 +0300 Subject: [PATCH 008/130] Switch parachains runtime to use new primitives Signed-off-by: Andrei Sandu --- .../parachains/src/runtime_api_impl/v10.rs | 21 +++++++++++-------- .../src/runtime_api_impl/vstaging.rs | 4 +++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs index f0107d6f21e2..608db7434b87 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs @@ -27,16 +27,19 @@ use frame_support::traits::{GetStorageVersion, StorageVersion}; use frame_system::pallet_prelude::*; use polkadot_primitives::{ async_backing::{ - AsyncBackingParams, Constraints, - InboundHrmpLimitations, OutboundHrmpChannelLimitations, + AsyncBackingParams, Constraints, InboundHrmpLimitations, OutboundHrmpChannelLimitations, }, - vstaging::{CoreState,OccupiedCore, BackingState, CandidateEvent, ScrapedOnChainVotes, CandidatePendingAvailability, CommittedCandidateReceiptV2 as CommittedCandidateReceipt}, - slashing, ApprovalVotingParams, AuthorityDiscoveryId, CandidateHash, - CoreIndex, DisputeState, ExecutorParams, GroupIndex, - GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, - NodeFeatures, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, - SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, - ValidatorId, ValidatorIndex, ValidatorSignature, + slashing, + vstaging::{ + BackingState, CandidateEvent, CandidatePendingAvailability, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, OccupiedCore, + ScrapedOnChainVotes, + }, + ApprovalVotingParams, AuthorityDiscoveryId, CandidateHash, CoreIndex, DisputeState, + ExecutorParams, GroupIndex, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, + InboundHrmpMessage, NodeFeatures, OccupiedCoreAssumption, PersistedValidationData, + PvfCheckStatement, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, + ValidatorIndex, ValidatorSignature, }; use sp_runtime::traits::One; diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs index f110099d968c..a3440f686e94 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -21,7 +21,9 @@ use alloc::{ collections::{btree_map::BTreeMap, vec_deque::VecDeque}, vec::Vec, }; -use polkadot_primitives::{vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, Id as ParaId}; +use polkadot_primitives::{ + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, Id as ParaId, +}; use sp_runtime::traits::One; /// Returns the claimqueue from the scheduler From dbb0160392fa013acbc6560e4b5737c1476d6ce6 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 15:05:58 +0300 Subject: [PATCH 009/130] use vstaging primitives Signed-off-by: Andrei Sandu --- polkadot/primitives/Cargo.toml | 1 + polkadot/primitives/src/runtime_api.rs | 16 ++-- polkadot/runtime/parachains/Cargo.toml | 4 +- polkadot/runtime/parachains/src/builder.rs | 49 ++++++----- .../parachains/src/inclusion/migration.rs | 10 ++- .../runtime/parachains/src/inclusion/mod.rs | 14 +-- .../runtime/parachains/src/inclusion/tests.rs | 88 ++++--------------- .../parachains/src/paras_inherent/mod.rs | 17 ++-- .../parachains/src/paras_inherent/tests.rs | 68 ++------------ 9 files changed, 95 insertions(+), 172 deletions(-) diff --git a/polkadot/primitives/Cargo.toml b/polkadot/primitives/Cargo.toml index 09afc9662d62..311fc210d42b 100644 --- a/polkadot/primitives/Cargo.toml +++ b/polkadot/primitives/Cargo.toml @@ -64,3 +64,4 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "sp-staking/runtime-benchmarks", ] +test = [] diff --git a/polkadot/primitives/src/runtime_api.rs b/polkadot/primitives/src/runtime_api.rs index b4816ad15075..6412a67b460d 100644 --- a/polkadot/primitives/src/runtime_api.rs +++ b/polkadot/primitives/src/runtime_api.rs @@ -114,11 +114,15 @@ //! separated from the stable primitives. use crate::{ - async_backing, slashing, ApprovalVotingParams, AsyncBackingParams, BlockNumber, - CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreIndex, - CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, NodeFeatures, - OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, - SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, ValidatorSignature, + slashing, + vstaging::{ + self, CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + ApprovalVotingParams, AsyncBackingParams, BlockNumber, CandidateCommitments, CandidateHash, + CoreIndex, DisputeState, ExecutorParams, GroupRotationInfo, Hash, NodeFeatures, + OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, SessionIndex, SessionInfo, + ValidatorId, ValidatorIndex, ValidatorSignature, }; use alloc::{ @@ -260,7 +264,7 @@ sp_api::decl_runtime_apis! { /// Returns the state of parachain backing for a given para. #[api_version(7)] - fn para_backing_state(_: ppp::Id) -> Option>; + fn para_backing_state(_: ppp::Id) -> Option>; /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent. #[api_version(7)] diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml index cfe373e8cba2..59af889fe6e7 100644 --- a/polkadot/runtime/parachains/Cargo.toml +++ b/polkadot/runtime/parachains/Cargo.toml @@ -49,7 +49,7 @@ frame-system = { workspace = true } xcm = { workspace = true } xcm-executor = { workspace = true } -polkadot-primitives = { workspace = true } +polkadot-primitives = { workspace = true, features=["test"] } rand = { workspace = true } rand_chacha = { workspace = true } @@ -59,6 +59,8 @@ polkadot-runtime-metrics = { workspace = true } polkadot-core-primitives = { workspace = true } [dev-dependencies] +polkadot-primitives = { workspace = true } + futures = { workspace = true } hex-literal = { workspace = true, default-features = true } sp-keyring = { workspace = true, default-features = true } diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 86473fafc8b0..c1e7844de470 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -30,12 +30,17 @@ use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; use polkadot_primitives::{ - node_features::FeatureIndex, AvailabilityBitfield, BackedCandidate, CandidateCommitments, - vstaging::CandidateDescriptorV2 as CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, + node_features::FeatureIndex, + vstaging::{ + BackedCandidate, CandidateDescriptorV2 as CandidateDescriptor, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, + InherentData as ParachainsInherentData, + }, + AvailabilityBitfield, CandidateCommitments, CandidateHash, CollatorId, CollatorSignature, CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, - Id as ParaId, IndexedVec, vstaging::InherentData as ParachainsInherentData, InvalidDisputeStatementKind, - PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned, - ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation, + Id as ParaId, IndexedVec, InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, + SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, + ValidatorIndex, ValidityAttestation, }; use sp_core::{sr25519, ByteArray, H256}; use sp_runtime::{ @@ -295,17 +300,17 @@ impl BenchBuilder { } fn candidate_descriptor_mock() -> CandidateDescriptor { - CandidateDescriptor:: { - para_id: 0.into(), - relay_parent: Default::default(), - collator: CollatorId::from(sr25519::Public::from_raw([42u8; 32])), - persisted_validation_data_hash: Default::default(), - pov_hash: Default::default(), - erasure_root: Default::default(), - signature: CollatorSignature::from(sr25519::Signature::from_raw([42u8; 64])), - para_head: Default::default(), - validation_code_hash: mock_validation_code().hash(), - } + CandidateDescriptor::::new( + 0.into(), + Default::default(), + CoreIndex(0), + 1, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + mock_validation_code().hash(), + ) } /// Create a mock of `CandidatePendingAvailability`. @@ -631,17 +636,17 @@ impl BenchBuilder { scheduler::Pallet::::group_validators(group_idx).unwrap(); let candidate = CommittedCandidateReceipt:: { - descriptor: CandidateDescriptor:: { + descriptor: CandidateDescriptor::::new( para_id, relay_parent, - collator: dummy_collator(), + CoreIndex(0), + 1, persisted_validation_data_hash, pov_hash, - erasure_root: Default::default(), - signature: dummy_collator_signature(), - para_head: head_data.hash(), + Default::default(), + head_data.hash(), validation_code_hash, - }, + ), commitments: CandidateCommitments:: { upward_messages: Default::default(), horizontal_messages: Default::default(), diff --git a/polkadot/runtime/parachains/src/inclusion/migration.rs b/polkadot/runtime/parachains/src/inclusion/migration.rs index 522d224d00d2..143c4e7d629a 100644 --- a/polkadot/runtime/parachains/src/inclusion/migration.rs +++ b/polkadot/runtime/parachains/src/inclusion/migration.rs @@ -20,7 +20,8 @@ pub mod v0 { use frame_support::{storage_alias, Twox64Concat}; use frame_system::pallet_prelude::BlockNumberFor; use polkadot_primitives::{ - vstaging::CandidateDescriptorV2 as CandidateDescriptor, AvailabilityBitfield, CandidateCommitments, CandidateHash, CoreIndex, GroupIndex, Id as ParaId, ValidatorIndex + vstaging::CandidateDescriptorV2 as CandidateDescriptor, AvailabilityBitfield, + CandidateCommitments, CandidateHash, CoreIndex, GroupIndex, Id as ParaId, ValidatorIndex, }; use scale_info::TypeInfo; @@ -218,7 +219,8 @@ mod tests { use frame_support::traits::UncheckedOnRuntimeUpgrade; use polkadot_primitives::{AvailabilityBitfield, Id as ParaId}; use polkadot_primitives_test_helpers::{ - dummy_candidate_commitments, dummy_candidate_descriptor, dummy_hash, + dummy_candidate_commitments, dummy_candidate_descriptor, dummy_candidate_descriptor_v2, + dummy_hash, }; #[test] @@ -234,7 +236,7 @@ mod tests { let mut expected = vec![]; for i in 1..5 { - let descriptor = dummy_candidate_descriptor(dummy_hash()); + let descriptor = dummy_candidate_descriptor_v2(dummy_hash()); v0::PendingAvailability::::insert( ParaId::from(i), v0::CandidatePendingAvailability { @@ -284,7 +286,7 @@ mod tests { ParaId::from(6), v0::CandidatePendingAvailability { core: CoreIndex(6), - descriptor: dummy_candidate_descriptor(dummy_hash()), + descriptor: dummy_candidate_descriptor_v2(dummy_hash()), relay_parent_number: 6, hash: CandidateHash(dummy_hash()), availability_votes: Default::default(), diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index 75b80d06fc18..d3edad7b3d6c 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -45,11 +45,15 @@ use frame_support::{ use frame_system::pallet_prelude::*; use pallet_message_queue::OnQueueChanged; use polkadot_primitives::{ - effective_minimum_backing_votes, supermajority_threshold, well_known_keys, vstaging::BackedCandidate, - CandidateCommitments, vstaging::CandidateDescriptorV2 as CandidateDescriptor, CandidateHash, vstaging::CandidateReceiptV2 as CandidateReceipt, - vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, GroupIndex, Hash, HeadData, Id as ParaId, - SignedAvailabilityBitfields, SigningContext, UpwardMessage, ValidatorId, ValidatorIndex, - ValidityAttestation, + effective_minimum_backing_votes, supermajority_threshold, + vstaging::{ + BackedCandidate, CandidateDescriptorV2 as CandidateDescriptor, + CandidateReceiptV2 as CandidateReceipt, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, + }, + well_known_keys, CandidateCommitments, CandidateHash, CoreIndex, GroupIndex, Hash, HeadData, + Id as ParaId, SignedAvailabilityBitfields, SigningContext, UpwardMessage, ValidatorId, + ValidatorIndex, ValidityAttestation, }; use scale_info::TypeInfo; use sp_runtime::{traits::One, DispatchError, SaturatedConversion, Saturating}; diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index 3ead456cde5a..bfb2f228c452 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -26,21 +26,19 @@ use crate::{ shared::AllowedRelayParentsTracker, }; use polkadot_primitives::{ - effective_minimum_backing_votes, AvailabilityBitfield, SignedAvailabilityBitfields, - UncheckedSignedAvailabilityBitfields, + effective_minimum_backing_votes, vstaging::CandidateDescriptorV2, AvailabilityBitfield, + SignedAvailabilityBitfields, UncheckedSignedAvailabilityBitfields, }; use assert_matches::assert_matches; use codec::DecodeAll; use frame_support::assert_noop; use polkadot_primitives::{ - BlockNumber, CandidateCommitments, CandidateDescriptor, CollatorId, - CompactStatement as Statement, Hash, SignedAvailabilityBitfield, SignedStatement, - ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, -}; -use polkadot_primitives_test_helpers::{ - dummy_collator, dummy_collator_signature, dummy_validation_code, + BlockNumber, CandidateCommitments, CollatorId, CompactStatement as Statement, Hash, + SignedAvailabilityBitfield, SignedStatement, ValidationCode, ValidatorId, ValidityAttestation, + PARACHAIN_KEY_TYPE_ID, }; +use polkadot_primitives_test_helpers::dummy_validation_code; use sc_keystore::LocalKeystore; use sp_keyring::Sr25519Keyring; use sp_keystore::{Keystore, KeystorePtr}; @@ -96,24 +94,6 @@ pub(crate) enum BackingKind { Lacking, } -pub(crate) fn collator_sign_candidate( - collator: Sr25519Keyring, - candidate: &mut CommittedCandidateReceipt, -) { - candidate.descriptor.collator = collator.public().into(); - - let payload = polkadot_primitives::collator_signature_payload( - &candidate.descriptor.relay_parent, - &candidate.descriptor.para_id, - &candidate.descriptor.persisted_validation_data_hash, - &candidate.descriptor.pov_hash, - &candidate.descriptor.validation_code_hash, - ); - - candidate.descriptor.signature = collator.sign(&payload[..]).into(); - assert!(candidate.descriptor().check_collator_signature().is_ok()); -} - pub(crate) fn back_candidate( candidate: CommittedCandidateReceipt, validators: &[Sr25519Keyring], @@ -303,17 +283,17 @@ impl std::default::Default for TestCandidateBuilder { impl TestCandidateBuilder { pub(crate) fn build(self) -> CommittedCandidateReceipt { CommittedCandidateReceipt { - descriptor: CandidateDescriptor { - para_id: self.para_id, - pov_hash: self.pov_hash, - relay_parent: self.relay_parent, - persisted_validation_data_hash: self.persisted_validation_data_hash, - validation_code_hash: self.validation_code.hash(), - para_head: self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), - erasure_root: Default::default(), - signature: dummy_collator_signature(), - collator: dummy_collator(), - }, + descriptor: CandidateDescriptorV2::new( + self.para_id, + self.relay_parent, + CoreIndex(0), + 1, + self.persisted_validation_data_hash, + self.pov_hash, + Default::default(), + self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), + self.validation_code.hash(), + ), commitments: CandidateCommitments { head_data: self.head_data, new_validation_code: self.new_validation_code, @@ -1280,10 +1260,6 @@ fn candidate_checks() { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); - collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_b_1); - collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_b_2); - let backed_a = back_candidate( candidate_a, &validators, @@ -1370,7 +1346,6 @@ fn candidate_checks() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_b_3); let backed_b_3 = back_candidate( candidate_b_3, @@ -1404,7 +1379,6 @@ fn candidate_checks() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); // Insufficient backing. let backed = back_candidate( @@ -1477,10 +1451,6 @@ fn candidate_checks() { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); - - collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_b); - let backed_a = back_candidate( candidate_a, &validators, @@ -1530,10 +1500,9 @@ fn candidate_checks() { .build(); assert_eq!(CollatorId::from(Sr25519Keyring::Two.public()), thread_collator); - collator_sign_candidate(Sr25519Keyring::Two, &mut candidate); // change the candidate after signing. - candidate.descriptor.pov_hash = Hash::repeat_byte(2); + candidate.descriptor.set_pov_hash(Hash::repeat_byte(2)); let backed = back_candidate( candidate, @@ -1607,8 +1576,6 @@ fn candidate_checks() { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -1657,8 +1624,6 @@ fn candidate_checks() { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -1695,8 +1660,6 @@ fn candidate_checks() { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -1733,8 +1696,6 @@ fn candidate_checks() { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -1834,7 +1795,6 @@ fn backing_works() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); let mut candidate_b = TestCandidateBuilder { para_id: chain_b, @@ -1845,7 +1805,6 @@ fn backing_works() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_b); let mut candidate_c = TestCandidateBuilder { para_id: thread_a, @@ -1856,7 +1815,6 @@ fn backing_works() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_c); let backed_a = back_candidate( candidate_a.clone(), @@ -1977,7 +1935,7 @@ fn backing_works() { Vec<(ValidatorIndex, ValidityAttestation)>, )>| { candidate_receipts_with_backers.sort_by(|(cr1, _), (cr2, _)| { - cr1.descriptor().para_id.cmp(&cr2.descriptor().para_id) + cr1.descriptor().para_id().cmp(&cr2.descriptor().para_id()) }); candidate_receipts_with_backers }; @@ -2129,7 +2087,6 @@ fn backing_works_with_elastic_scaling_mvp() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); let mut candidate_b_1 = TestCandidateBuilder { para_id: chain_b, @@ -2140,7 +2097,6 @@ fn backing_works_with_elastic_scaling_mvp() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_b_1); // Make candidate b2 a child of b1. let mut candidate_b_2 = TestCandidateBuilder { @@ -2157,7 +2113,6 @@ fn backing_works_with_elastic_scaling_mvp() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_b_2); let backed_a = back_candidate( candidate_a.clone(), @@ -2405,7 +2360,6 @@ fn can_include_candidate_with_ok_code_upgrade() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); let backed_a = back_candidate( candidate_a.clone(), @@ -2568,7 +2522,6 @@ fn check_allowed_relay_parents() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); let signing_context_a = SigningContext { parent_hash: relay_parent_a.1, session_index: 5 }; let mut candidate_b = TestCandidateBuilder { @@ -2584,7 +2537,6 @@ fn check_allowed_relay_parents() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_b); let signing_context_b = SigningContext { parent_hash: relay_parent_b.1, session_index: 5 }; let mut candidate_c = TestCandidateBuilder { @@ -2600,7 +2552,6 @@ fn check_allowed_relay_parents() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_c); let signing_context_c = SigningContext { parent_hash: relay_parent_c.1, session_index: 5 }; let backed_a = back_candidate( @@ -2832,7 +2783,6 @@ fn para_upgrade_delay_scheduled_from_inclusion() { ..Default::default() } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); let backed_a = back_candidate( candidate_a.clone(), diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index de616ea763b9..66330674898b 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -48,12 +48,17 @@ use frame_support::{ use frame_system::pallet_prelude::*; use pallet_babe::{self, ParentBlockRandomness}; use polkadot_primitives::{ - effective_minimum_backing_votes, node_features::FeatureIndex, vstaging::BackedCandidate, CandidateHash, - vstaging::CandidateReceiptV2 as CandidateReceipt, CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CoreIndex, - DisputeStatementSet, HeadData, vstaging::InherentData as ParachainsInherentData, - MultiDisputeStatementSet, vstaging::ScrapedOnChainVotes, SessionIndex, SignedAvailabilityBitfields, - SigningContext, UncheckedSignedAvailabilityBitfield, UncheckedSignedAvailabilityBitfields, - ValidatorId, ValidatorIndex, ValidityAttestation, PARACHAINS_INHERENT_IDENTIFIER, + effective_minimum_backing_votes, + node_features::FeatureIndex, + vstaging::{ + BackedCandidate, CandidateReceiptV2 as CandidateReceipt, + InherentData as ParachainsInherentData, ScrapedOnChainVotes, + }, + CandidateHash, CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CoreIndex, + DisputeStatementSet, HeadData, MultiDisputeStatementSet, SessionIndex, + SignedAvailabilityBitfields, SigningContext, UncheckedSignedAvailabilityBitfield, + UncheckedSignedAvailabilityBitfields, ValidatorId, ValidatorIndex, ValidityAttestation, + PARACHAINS_INHERENT_IDENTIFIER, }; use rand::{seq::SliceRandom, SeedableRng}; use scale_info::TypeInfo; diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 59fbb0948373..eae61f3c57b0 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1381,7 +1381,7 @@ mod enter { // The chained candidates are not picked, instead a single other candidate is picked assert_eq!(backed_candidates.len(), 1); - assert_ne!(backed_candidates[0].descriptor().para_id, ParaId::from(1000)); + assert_ne!(backed_candidates[0].descriptor().para_id(), ParaId::from(1000)); // All bitfields are kept. assert_eq!(bitfields.len(), 150); @@ -1402,9 +1402,9 @@ mod enter { // Only the chained candidates should pass filter. assert_eq!(backed_candidates.len(), 3); // Check the actual candidates - assert_eq!(backed_candidates[0].descriptor().para_id, ParaId::from(1000)); - assert_eq!(backed_candidates[1].descriptor().para_id, ParaId::from(1000)); - assert_eq!(backed_candidates[2].descriptor().para_id, ParaId::from(1000)); + assert_eq!(backed_candidates[0].descriptor().para_id(), ParaId::from(1000)); + assert_eq!(backed_candidates[1].descriptor().para_id(), ParaId::from(1000)); + assert_eq!(backed_candidates[2].descriptor().para_id(), ParaId::from(1000)); // All bitfields are kept. assert_eq!(bitfields.len(), 150); @@ -1481,9 +1481,7 @@ mod sanitizers { use super::*; use crate::{ - inclusion::tests::{ - back_candidate, collator_sign_candidate, BackingKind, TestCandidateBuilder, - }, + inclusion::tests::{back_candidate, BackingKind, TestCandidateBuilder}, mock::new_test_ext, }; use bitvec::order::Lsb0; @@ -1898,8 +1896,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -1932,7 +1928,7 @@ mod sanitizers { let mut expected_backed_candidates_with_core = BTreeMap::new(); for candidate in backed_candidates.iter() { - let para_id = candidate.descriptor().para_id; + let para_id = candidate.descriptor().para_id(); expected_backed_candidates_with_core.entry(para_id).or_insert(vec![]).push(( candidate.clone(), @@ -2136,8 +2132,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let prev_candidate = candidate.clone(); let backed: BackedCandidate = back_candidate( candidate, @@ -2174,8 +2168,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2213,8 +2205,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2252,8 +2242,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2289,8 +2277,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let prev_candidate = candidate.clone(); let backed = back_candidate( candidate, @@ -2325,8 +2311,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2360,8 +2344,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2393,8 +2375,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2426,8 +2406,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2666,8 +2644,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let prev_candidate = candidate.clone(); let prev_backed: BackedCandidate = back_candidate( candidate, @@ -2697,8 +2673,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2732,8 +2706,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_1); - let backed_1: BackedCandidate = back_candidate( candidate_1, &validators, @@ -2770,8 +2742,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_2); - let backed_2 = back_candidate( candidate_2.clone(), &validators, @@ -2801,8 +2771,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate_3); - let backed_3 = back_candidate( candidate_3, &validators, @@ -2835,8 +2803,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let prev_candidate = candidate.clone(); let backed: BackedCandidate = back_candidate( candidate, @@ -2873,8 +2839,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -2913,8 +2877,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed: BackedCandidate = back_candidate( candidate.clone(), &validators, @@ -3169,8 +3131,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let prev_candidate = candidate.clone(); let backed: BackedCandidate = back_candidate( candidate, @@ -3208,8 +3168,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let prev_candidate = candidate.clone(); let backed = back_candidate( candidate, @@ -3241,8 +3199,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -3275,8 +3231,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let prev_candidate = candidate.clone(); let backed: BackedCandidate = back_candidate( candidate, @@ -3314,8 +3268,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let prev_candidate = candidate.clone(); let backed = back_candidate( candidate, @@ -3353,8 +3305,6 @@ mod sanitizers { } .build(); - collator_sign_candidate(Sr25519Keyring::One, &mut candidate); - let backed = back_candidate( candidate, &validators, @@ -3714,9 +3664,9 @@ mod sanitizers { let mut invalid_set = std::collections::BTreeSet::new(); for (idx, backed_candidate) in backed_candidates.iter().enumerate() { - if backed_candidate.descriptor().para_id == ParaId::from(1) && idx == 0 { + if backed_candidate.descriptor().para_id() == ParaId::from(1) && idx == 0 { invalid_set.insert(backed_candidate.hash()); - } else if backed_candidate.descriptor().para_id == ParaId::from(3) { + } else if backed_candidate.descriptor().para_id() == ParaId::from(3) { invalid_set.insert(backed_candidate.hash()); } } @@ -3752,7 +3702,7 @@ mod sanitizers { let mut invalid_set = std::collections::BTreeSet::new(); for (idx, backed_candidate) in backed_candidates.iter().enumerate() { - if backed_candidate.descriptor().para_id == ParaId::from(1) && idx == 1 { + if backed_candidate.descriptor().para_id() == ParaId::from(1) && idx == 1 { invalid_set.insert(backed_candidate.hash()); } } From 5efab68c7d848e09fdcbffc92b1ef385148c1cf0 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 15:06:11 +0300 Subject: [PATCH 010/130] update rococo and westend Signed-off-by: Andrei Sandu --- polkadot/runtime/rococo/src/lib.rs | 18 +++++++++++------- polkadot/runtime/westend/src/lib.rs | 18 +++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 2f23b889916b..5534b86a564d 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -35,12 +35,16 @@ use frame_support::{ }; use pallet_nis::WithMaximumOf; use polkadot_primitives::{ - slashing, AccountId, AccountIndex, ApprovalVotingParams, Balance, BlockNumber, CandidateEvent, - CandidateHash, CommittedCandidateReceipt, CoreIndex, CoreState, DisputeState, ExecutorParams, - GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, - NodeFeatures, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, - SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, - PARACHAIN_KEY_TYPE_ID, + slashing, + vstaging::{ + CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + AccountId, AccountIndex, ApprovalVotingParams, Balance, BlockNumber, CandidateHash, CoreIndex, + DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, + InboundHrmpMessage, Moment, NodeFeatures, Nonce, OccupiedCoreAssumption, + PersistedValidationData, SessionInfo, Signature, ValidationCode, ValidationCodeHash, + ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, }; use polkadot_runtime_common::{ assigned_slots, auctions, claims, crowdloan, identity_migrator, impl_runtime_weights, @@ -2025,7 +2029,7 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::minimum_backing_votes::() } - fn para_backing_state(para_id: ParaId) -> Option { + fn para_backing_state(para_id: ParaId) -> Option { parachains_runtime_api_impl::backing_state::(para_id) } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 838ba17e5613..67c43de8bae7 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -49,12 +49,16 @@ use pallet_identity::legacy::IdentityInfo; use pallet_session::historical as session_historical; use pallet_transaction_payment::{FeeDetails, FungibleAdapter, RuntimeDispatchInfo}; use polkadot_primitives::{ - slashing, AccountId, AccountIndex, ApprovalVotingParams, Balance, BlockNumber, CandidateEvent, - CandidateHash, CommittedCandidateReceipt, CoreIndex, CoreState, DisputeState, ExecutorParams, - GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, - NodeFeatures, Nonce, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, - ScrapedOnChainVotes, SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, - ValidatorIndex, ValidatorSignature, PARACHAIN_KEY_TYPE_ID, + slashing, + vstaging::{ + CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + AccountId, AccountIndex, ApprovalVotingParams, Balance, BlockNumber, CandidateHash, CoreIndex, + DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, + InboundHrmpMessage, Moment, NodeFeatures, Nonce, OccupiedCoreAssumption, + PersistedValidationData, PvfCheckStatement, SessionInfo, Signature, ValidationCode, + ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, PARACHAIN_KEY_TYPE_ID, }; use polkadot_runtime_common::{ assigned_slots, auctions, crowdloan, @@ -2085,7 +2089,7 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::minimum_backing_votes::() } - fn para_backing_state(para_id: ParaId) -> Option { + fn para_backing_state(para_id: ParaId) -> Option { parachains_runtime_api_impl::backing_state::(para_id) } From c2232e425d5b2f8d0a4131963bfe4233193979d3 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 15:06:57 +0300 Subject: [PATCH 011/130] client keeps using the old primitives Signed-off-by: Andrei Sandu --- .../src/lib.rs | 22 ++++++++++-- polkadot/node/service/src/fake_runtime_api.rs | 16 +++++---- .../subsystem-types/src/runtime_client.rs | 34 +++++++++++++++---- .../node/test/client/src/block_builder.rs | 2 +- 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs index 38ba84748c1e..65c0592ff5e5 100644 --- a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs +++ b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs @@ -137,7 +137,11 @@ impl RelayChainInterface for RelayChainInProcessInterface { hash: PHash, para_id: ParaId, ) -> RelayChainResult> { - Ok(self.full_client.runtime_api().candidate_pending_availability(hash, para_id)?) + Ok(self + .full_client + .runtime_api() + .candidate_pending_availability(hash, para_id)? + .map(|receipt| receipt.into())) } async fn session_index_for_child(&self, hash: PHash) -> RelayChainResult { @@ -260,7 +264,13 @@ impl RelayChainInterface for RelayChainInProcessInterface { &self, relay_parent: PHash, ) -> RelayChainResult>> { - Ok(self.full_client.runtime_api().availability_cores(relay_parent)?) + Ok(self + .full_client + .runtime_api() + .availability_cores(relay_parent)? + .into_iter() + .map(|core_state| core_state.into()) + .collect::>()) } async fn candidates_pending_availability( @@ -268,7 +278,13 @@ impl RelayChainInterface for RelayChainInProcessInterface { hash: PHash, para_id: ParaId, ) -> RelayChainResult> { - Ok(self.full_client.runtime_api().candidates_pending_availability(hash, para_id)?) + Ok(self + .full_client + .runtime_api() + .candidates_pending_availability(hash, para_id)? + .into_iter() + .map(|receipt| receipt.into()) + .collect::>()) } } diff --git a/polkadot/node/service/src/fake_runtime_api.rs b/polkadot/node/service/src/fake_runtime_api.rs index cdef39d5bdf1..1f2efdbbb5b3 100644 --- a/polkadot/node/service/src/fake_runtime_api.rs +++ b/polkadot/node/service/src/fake_runtime_api.rs @@ -21,12 +21,16 @@ use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; use polkadot_primitives::{ - runtime_api, slashing, AccountId, AuthorityDiscoveryId, Balance, Block, BlockNumber, - CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreState, - DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, - InboundHrmpMessage, Nonce, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, - ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, - ValidatorId, ValidatorIndex, ValidatorSignature, + runtime_api, slashing, + vstaging::{ + CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + AccountId, AuthorityDiscoveryId, Balance, Block, BlockNumber, CandidateCommitments, + CandidateHash, DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, + InboundDownwardMessage, InboundHrmpMessage, Nonce, OccupiedCoreAssumption, + PersistedValidationData, PvfCheckStatement, SessionIndex, SessionInfo, ValidationCode, + ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; use sp_consensus_beefy::ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}; use sp_consensus_grandpa::AuthorityId as GrandpaId; diff --git a/polkadot/node/subsystem-types/src/runtime_client.rs b/polkadot/node/subsystem-types/src/runtime_client.rs index e5e1e4d24ef9..7938223df23b 100644 --- a/polkadot/node/subsystem-types/src/runtime_client.rs +++ b/polkadot/node/subsystem-types/src/runtime_client.rs @@ -380,7 +380,10 @@ where &self, at: Hash, ) -> Result>, ApiError> { - self.client.runtime_api().availability_cores(at) + self.client + .runtime_api() + .availability_cores(at) + .map(|cores| cores.into_iter().map(|core| core.into()).collect::>()) } async fn persisted_validation_data( @@ -433,7 +436,10 @@ where at: Hash, para_id: Id, ) -> Result>, ApiError> { - self.client.runtime_api().candidate_pending_availability(at, para_id) + self.client + .runtime_api() + .candidate_pending_availability(at, para_id) + .map(|maybe_candidate| maybe_candidate.map(|candidate| candidate.into())) } async fn candidates_pending_availability( @@ -441,11 +447,19 @@ where at: Hash, para_id: Id, ) -> Result>, ApiError> { - self.client.runtime_api().candidates_pending_availability(at, para_id) + self.client + .runtime_api() + .candidates_pending_availability(at, para_id) + .map(|candidates| { + candidates.into_iter().map(|candidate| candidate.into()).collect::>() + }) } async fn candidate_events(&self, at: Hash) -> Result>, ApiError> { - self.client.runtime_api().candidate_events(at) + self.client + .runtime_api() + .candidate_events(at) + .map(|events| events.into_iter().map(|event| event.into()).collect::>()) } async fn dmq_contents( @@ -476,7 +490,10 @@ where &self, at: Hash, ) -> Result>, ApiError> { - self.client.runtime_api().on_chain_votes(at) + self.client + .runtime_api() + .on_chain_votes(at) + .map(|maybe_votes| maybe_votes.map(|votes| votes.into())) } async fn session_executor_params( @@ -588,7 +605,12 @@ where at: Hash, para_id: Id, ) -> Result, ApiError> { - self.client.runtime_api().para_backing_state(at, para_id) + self.client + .runtime_api() + .para_backing_state(at, para_id) + .map(|maybe_backing_state| { + maybe_backing_state.map(|backing_state| backing_state.into()) + }) } async fn async_backing_params( diff --git a/polkadot/node/test/client/src/block_builder.rs b/polkadot/node/test/client/src/block_builder.rs index ed24cd55d084..9375aca6ed73 100644 --- a/polkadot/node/test/client/src/block_builder.rs +++ b/polkadot/node/test/client/src/block_builder.rs @@ -16,7 +16,7 @@ use crate::Client; use codec::{Decode, Encode}; -use polkadot_primitives::{Block, vstaging::InherentData as ParachainsInherentData}; +use polkadot_primitives::{vstaging::InherentData as ParachainsInherentData, Block}; use polkadot_test_runtime::UncheckedExtrinsic; use polkadot_test_service::GetLastTimestamp; use sc_block_builder::{BlockBuilder, BlockBuilderBuilder}; From 87b079f82219d62e4aca3076840583fcabb3e661 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 15:30:16 +0300 Subject: [PATCH 012/130] no unsafe pls Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 9541484d5028..b1f5a8387260 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -32,7 +32,7 @@ use alloc::{ vec, vec::Vec, }; -use codec::{Decode, Encode, WrapperTypeDecode}; +use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_arithmetic::Perbill; use sp_core::RuntimeDebug; @@ -447,8 +447,8 @@ impl CandidateDescriptorV2 { fn rebuild_collator_field(&self) -> CollatorId { let mut collator_id = vec![self.version.0]; - let core_index: [u8; 2] = unsafe { core::mem::transmute(self.core_index) }; - let session_index: [u8; 4] = unsafe { core::mem::transmute(self.session_index) }; + let core_index: [u8; 2] = self.core_index.to_ne_bytes(); + let session_index: [u8; 4] = self.session_index.to_ne_bytes(); collator_id.append(&mut core_index.as_slice().to_vec()); collator_id.append(&mut session_index.as_slice().to_vec()); From 00e8c13133007f1e68879e626bc5e569ff368a3d Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 17:28:50 +0300 Subject: [PATCH 013/130] move async backing primtiives to own file Signed-off-by: Andrei Sandu --- polkadot/primitives/src/runtime_api.rs | 2 +- .../primitives/src/vstaging/async_backing.rs | 76 +++++++++++++++++++ polkadot/primitives/src/vstaging/mod.rs | 55 +------------- .../parachains/src/runtime_api_impl/v10.rs | 2 +- 4 files changed, 80 insertions(+), 55 deletions(-) create mode 100644 polkadot/primitives/src/vstaging/async_backing.rs diff --git a/polkadot/primitives/src/runtime_api.rs b/polkadot/primitives/src/runtime_api.rs index 6412a67b460d..ddebe99e6214 100644 --- a/polkadot/primitives/src/runtime_api.rs +++ b/polkadot/primitives/src/runtime_api.rs @@ -264,7 +264,7 @@ sp_api::decl_runtime_apis! { /// Returns the state of parachain backing for a given para. #[api_version(7)] - fn para_backing_state(_: ppp::Id) -> Option>; + fn para_backing_state(_: ppp::Id) -> Option>; /// Returns candidate's acceptance limitations for asynchronous backing for a relay parent. #[api_version(7)] diff --git a/polkadot/primitives/src/vstaging/async_backing.rs b/polkadot/primitives/src/vstaging/async_backing.rs new file mode 100644 index 000000000000..bdf94e0f00db --- /dev/null +++ b/polkadot/primitives/src/vstaging/async_backing.rs @@ -0,0 +1,76 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use super::*; + +use alloc::vec::Vec; +use codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_core::RuntimeDebug; + +/// A candidate pending availability. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct CandidatePendingAvailability { + /// The hash of the candidate. + pub candidate_hash: CandidateHash, + /// The candidate's descriptor. + pub descriptor: CandidateDescriptorV2, + /// The commitments of the candidate. + pub commitments: CandidateCommitments, + /// The candidate's relay parent's number. + pub relay_parent_number: N, + /// The maximum Proof-of-Validity size allowed, in bytes. + pub max_pov_size: u32, +} + +impl From> + for crate::v7::async_backing::CandidatePendingAvailability +{ + fn from(value: CandidatePendingAvailability) -> Self { + Self { + candidate_hash: value.candidate_hash, + descriptor: value.descriptor.into(), + commitments: value.commitments, + relay_parent_number: value.relay_parent_number, + max_pov_size: value.max_pov_size, + } + } +} + +/// The per-parachain state of the backing system, including +/// state-machine constraints and candidates pending availability. +#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] +pub struct BackingState { + /// The state-machine constraints of the parachain. + pub constraints: Constraints, + /// The candidates pending availability. These should be ordered, i.e. they should form + /// a sub-chain, where the first candidate builds on top of the required parent of the + /// constraints and each subsequent builds on top of the previous head-data. + pub pending_availability: Vec>, +} + +impl From> for crate::v7::async_backing::BackingState { + fn from(value: BackingState) -> Self { + Self { + constraints: value.constraints, + pending_availability: value + .pending_availability + .into_iter() + .map(|candidate| candidate.into()) + .collect::>(), + } + } +} diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index b1f5a8387260..e62e8aa3d760 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -39,6 +39,8 @@ use sp_core::RuntimeDebug; use sp_runtime::traits::Header as HeaderT; use sp_staking::SessionIndex; +pub mod async_backing; + /// Scheduler configuration parameters. All coretime/ondemand parameters are here. #[derive( RuntimeDebug, @@ -715,59 +717,6 @@ impl From> for super::v7::Scra } } -/// A candidate pending availability. -#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] -pub struct CandidatePendingAvailability { - /// The hash of the candidate. - pub candidate_hash: CandidateHash, - /// The candidate's descriptor. - pub descriptor: CandidateDescriptorV2, - /// The commitments of the candidate. - pub commitments: CandidateCommitments, - /// The candidate's relay parent's number. - pub relay_parent_number: N, - /// The maximum Proof-of-Validity size allowed, in bytes. - pub max_pov_size: u32, -} - -impl From> - for super::async_backing::CandidatePendingAvailability -{ - fn from(value: CandidatePendingAvailability) -> Self { - Self { - candidate_hash: value.candidate_hash, - descriptor: value.descriptor.into(), - commitments: value.commitments, - relay_parent_number: value.relay_parent_number, - max_pov_size: value.max_pov_size, - } - } -} - -/// The per-parachain state of the backing system, including -/// state-machine constraints and candidates pending availability. -#[derive(RuntimeDebug, Clone, PartialEq, Encode, Decode, TypeInfo)] -pub struct BackingState { - /// The state-machine constraints of the parachain. - pub constraints: Constraints, - /// The candidates pending availability. These should be ordered, i.e. they should form - /// a sub-chain, where the first candidate builds on top of the required parent of the - /// constraints and each subsequent builds on top of the previous head-data. - pub pending_availability: Vec>, -} - -impl From> for super::async_backing::BackingState { - fn from(value: BackingState) -> Self { - Self { - constraints: value.constraints, - pending_availability: value - .pending_availability - .into_iter() - .map(|candidate| candidate.into()) - .collect::>(), - } - } -} /// Information about a core which is currently occupied. #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs index 608db7434b87..b72b1b550a0b 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs @@ -31,7 +31,7 @@ use polkadot_primitives::{ }, slashing, vstaging::{ - BackingState, CandidateEvent, CandidatePendingAvailability, + async_backing::BackingState, CandidateEvent, async_backing::CandidatePendingAvailability, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, OccupiedCore, ScrapedOnChainVotes, }, From cd4d02f963aed56fe41969191966772be17c353d Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 18:00:54 +0300 Subject: [PATCH 014/130] fix Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 7 +++++-- polkadot/runtime/parachains/src/runtime_api_impl/v10.rs | 6 +++--- polkadot/runtime/rococo/src/lib.rs | 2 +- polkadot/runtime/westend/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index e62e8aa3d760..4f69073648fd 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -39,6 +39,7 @@ use sp_core::RuntimeDebug; use sp_runtime::traits::Header as HeaderT; use sp_staking::SessionIndex; +/// Async backing primitives pub mod async_backing; /// Scheduler configuration parameters. All coretime/ondemand parameters are here. @@ -209,6 +210,7 @@ impl CandidateDescriptorV2 { } } + /// Set the PoV size in the descriptor. Only for tests. #[cfg(feature = "test")] pub fn set_pov_hash(&mut self, pov_hash: Hash) { self.pov_hash = pov_hash; @@ -456,7 +458,8 @@ impl CandidateDescriptorV2 { collator_id.append(&mut session_index.as_slice().to_vec()); collator_id.append(&mut self.reserved25b.as_slice().to_vec()); - CollatorId::from_slice(&collator_id.as_slice()).expect("Slice size is exactly 32 bytes") + CollatorId::from_slice(&collator_id.as_slice()) + .expect("Slice size is exactly 32 bytes; qed") } /// Returns the collator id if this is a v1 `CandidateDescriptor` @@ -470,7 +473,7 @@ impl CandidateDescriptorV2 { fn rebuild_signature_field(&self) -> CollatorSignature { CollatorSignature::from_slice(self.reserved64b.as_slice()) - .expect("Slice size is exactly 64 bytes") + .expect("Slice size is exactly 64 bytes; qed") } /// Returns the collator signature of `V1` candidate descriptors, `None` otherwise. diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs index b72b1b550a0b..ead825b38f07 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs @@ -31,9 +31,9 @@ use polkadot_primitives::{ }, slashing, vstaging::{ - async_backing::BackingState, CandidateEvent, async_backing::CandidatePendingAvailability, - CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, OccupiedCore, - ScrapedOnChainVotes, + async_backing::{BackingState, CandidatePendingAvailability}, + CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + OccupiedCore, ScrapedOnChainVotes, }, ApprovalVotingParams, AuthorityDiscoveryId, CandidateHash, CoreIndex, DisputeState, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 5534b86a564d..688fe6317cc4 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -2029,7 +2029,7 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::minimum_backing_votes::() } - fn para_backing_state(para_id: ParaId) -> Option { + fn para_backing_state(para_id: ParaId) -> Option { parachains_runtime_api_impl::backing_state::(para_id) } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 67c43de8bae7..6f487960b810 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2089,7 +2089,7 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::minimum_backing_votes::() } - fn para_backing_state(para_id: ParaId) -> Option { + fn para_backing_state(para_id: ParaId) -> Option { parachains_runtime_api_impl::backing_state::(para_id) } From 5509e3340810973ea4344466bebb7e2cb5953574 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 18:33:04 +0300 Subject: [PATCH 015/130] fix test build Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/builder.rs | 22 +++------ .../parachains/src/inclusion/migration.rs | 3 +- .../runtime/parachains/src/inclusion/tests.rs | 44 ++++++++--------- .../parachains/src/paras_inherent/tests.rs | 49 +++++++++---------- 4 files changed, 53 insertions(+), 65 deletions(-) diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index c1e7844de470..ebc956a08e67 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -36,29 +36,19 @@ use polkadot_primitives::{ CommittedCandidateReceiptV2 as CommittedCandidateReceipt, InherentData as ParachainsInherentData, }, - AvailabilityBitfield, CandidateCommitments, CandidateHash, CollatorId, CollatorSignature, - CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, - Id as ParaId, IndexedVec, InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, - SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, - ValidatorIndex, ValidityAttestation, + AvailabilityBitfield, CandidateCommitments, CandidateHash, CompactStatement, CoreIndex, + DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, Id as ParaId, IndexedVec, + InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, SigningContext, + UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, + ValidityAttestation, }; -use sp_core::{sr25519, ByteArray, H256}; +use sp_core::H256; use sp_runtime::{ generic::Digest, traits::{Header as HeaderT, One, TrailingZeroInput, Zero}, RuntimeAppPublic, }; -/// Create a null collator id. -pub fn dummy_collator() -> CollatorId { - CollatorId::from_slice(&vec![0u8; 32]).expect("32 bytes; qed") -} - -/// Create a null collator signature. -pub fn dummy_collator_signature() -> CollatorSignature { - CollatorSignature::from_slice(&vec![0u8; 64]).expect("64 bytes; qed") -} - fn mock_validation_code() -> ValidationCode { ValidationCode(vec![1, 2, 3]) } diff --git a/polkadot/runtime/parachains/src/inclusion/migration.rs b/polkadot/runtime/parachains/src/inclusion/migration.rs index 143c4e7d629a..2a215d5d595c 100644 --- a/polkadot/runtime/parachains/src/inclusion/migration.rs +++ b/polkadot/runtime/parachains/src/inclusion/migration.rs @@ -219,8 +219,7 @@ mod tests { use frame_support::traits::UncheckedOnRuntimeUpgrade; use polkadot_primitives::{AvailabilityBitfield, Id as ParaId}; use polkadot_primitives_test_helpers::{ - dummy_candidate_commitments, dummy_candidate_descriptor, dummy_candidate_descriptor_v2, - dummy_hash, + dummy_candidate_commitments, dummy_candidate_descriptor_v2, dummy_hash, }; #[test] diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index bfb2f228c452..2125dffe2592 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -1223,7 +1223,7 @@ fn candidate_checks() { // Check candidate ordering { - let mut candidate_a = TestCandidateBuilder { + let candidate_a = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -1232,7 +1232,7 @@ fn candidate_checks() { ..Default::default() } .build(); - let mut candidate_b_1 = TestCandidateBuilder { + let candidate_b_1 = TestCandidateBuilder { para_id: chain_b, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(2), @@ -1244,7 +1244,7 @@ fn candidate_checks() { .build(); // Make candidate b2 a child of b1. - let mut candidate_b_2 = TestCandidateBuilder { + let candidate_b_2 = TestCandidateBuilder { para_id: chain_b, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(3), @@ -1331,7 +1331,7 @@ fn candidate_checks() { // candidate does not build on top of the latest unincluded head - let mut candidate_b_3 = TestCandidateBuilder { + let candidate_b_3 = TestCandidateBuilder { para_id: chain_b, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(4), @@ -1370,7 +1370,7 @@ fn candidate_checks() { // candidate not backed. { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -1432,7 +1432,7 @@ fn candidate_checks() { let wrong_parent_hash = Hash::repeat_byte(222); assert!(System::parent_hash() != wrong_parent_hash); - let mut candidate_a = TestCandidateBuilder { + let candidate_a = TestCandidateBuilder { para_id: chain_a, relay_parent: wrong_parent_hash, pov_hash: Hash::repeat_byte(1), @@ -1441,7 +1441,7 @@ fn candidate_checks() { } .build(); - let mut candidate_b = TestCandidateBuilder { + let candidate_b = TestCandidateBuilder { para_id: chain_b, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(2), @@ -1565,7 +1565,7 @@ fn candidate_checks() { // interfering code upgrade - reject { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -1614,7 +1614,7 @@ fn candidate_checks() { // Bad validation data hash - reject { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -1649,7 +1649,7 @@ fn candidate_checks() { // bad validation code hash { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -1685,7 +1685,7 @@ fn candidate_checks() { // Para head hash in descriptor doesn't match head data { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -1786,7 +1786,7 @@ fn backing_works() { let chain_b_assignment = (chain_b, CoreIndex::from(1)); let thread_a_assignment = (thread_a, CoreIndex::from(2)); - let mut candidate_a = TestCandidateBuilder { + let candidate_a = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -1796,7 +1796,7 @@ fn backing_works() { } .build(); - let mut candidate_b = TestCandidateBuilder { + let candidate_b = TestCandidateBuilder { para_id: chain_b, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(2), @@ -1806,7 +1806,7 @@ fn backing_works() { } .build(); - let mut candidate_c = TestCandidateBuilder { + let candidate_c = TestCandidateBuilder { para_id: thread_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(3), @@ -2078,7 +2078,7 @@ fn backing_works_with_elastic_scaling_mvp() { let allowed_relay_parents = default_allowed_relay_parent_tracker(); - let mut candidate_a = TestCandidateBuilder { + let candidate_a = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -2088,7 +2088,7 @@ fn backing_works_with_elastic_scaling_mvp() { } .build(); - let mut candidate_b_1 = TestCandidateBuilder { + let candidate_b_1 = TestCandidateBuilder { para_id: chain_b, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(2), @@ -2099,7 +2099,7 @@ fn backing_works_with_elastic_scaling_mvp() { .build(); // Make candidate b2 a child of b1. - let mut candidate_b_2 = TestCandidateBuilder { + let candidate_b_2 = TestCandidateBuilder { para_id: chain_b, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(3), @@ -2350,7 +2350,7 @@ fn can_include_candidate_with_ok_code_upgrade() { let allowed_relay_parents = default_allowed_relay_parent_tracker(); let chain_a_assignment = (chain_a, CoreIndex::from(0)); - let mut candidate_a = TestCandidateBuilder { + let candidate_a = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), @@ -2509,7 +2509,7 @@ fn check_allowed_relay_parents() { let chain_b_assignment = (chain_b, CoreIndex::from(1)); let thread_a_assignment = (thread_a, CoreIndex::from(2)); - let mut candidate_a = TestCandidateBuilder { + let candidate_a = TestCandidateBuilder { para_id: chain_a, relay_parent: relay_parent_a.1, pov_hash: Hash::repeat_byte(1), @@ -2524,7 +2524,7 @@ fn check_allowed_relay_parents() { .build(); let signing_context_a = SigningContext { parent_hash: relay_parent_a.1, session_index: 5 }; - let mut candidate_b = TestCandidateBuilder { + let candidate_b = TestCandidateBuilder { para_id: chain_b, relay_parent: relay_parent_b.1, pov_hash: Hash::repeat_byte(2), @@ -2539,7 +2539,7 @@ fn check_allowed_relay_parents() { .build(); let signing_context_b = SigningContext { parent_hash: relay_parent_b.1, session_index: 5 }; - let mut candidate_c = TestCandidateBuilder { + let candidate_c = TestCandidateBuilder { para_id: thread_a, relay_parent: relay_parent_c.1, pov_hash: Hash::repeat_byte(3), @@ -2773,7 +2773,7 @@ fn para_upgrade_delay_scheduled_from_inclusion() { let allowed_relay_parents = default_allowed_relay_parent_tracker(); let chain_a_assignment = (chain_a, CoreIndex::from(0)); - let mut candidate_a = TestCandidateBuilder { + let candidate_a = TestCandidateBuilder { para_id: chain_a, relay_parent: System::parent_hash(), pov_hash: Hash::repeat_byte(1), diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index eae61f3c57b0..6c82233e0820 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1495,7 +1495,6 @@ mod sanitizers { use crate::mock::Test; use polkadot_primitives::PARACHAIN_KEY_TYPE_ID; use sc_keystore::LocalKeystore; - use sp_keyring::Sr25519Keyring; use sp_keystore::{Keystore, KeystorePtr}; use std::sync::Arc; @@ -1879,7 +1878,7 @@ mod sanitizers { .into_iter() .map(|idx0| { let idx1 = idx0 + 1; - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(idx1), relay_parent, pov_hash: Hash::repeat_byte(idx1 as u8), @@ -2114,7 +2113,7 @@ mod sanitizers { // Para 1 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(1), relay_parent, pov_hash: Hash::repeat_byte(1 as u8), @@ -2150,7 +2149,7 @@ mod sanitizers { .push((backed, CoreIndex(0))); } - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(1), relay_parent, pov_hash: Hash::repeat_byte(2 as u8), @@ -2188,7 +2187,7 @@ mod sanitizers { // Para 2 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(2), relay_parent, pov_hash: Hash::repeat_byte(3 as u8), @@ -2225,7 +2224,7 @@ mod sanitizers { // Para 3 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(3), relay_parent, pov_hash: Hash::repeat_byte(4 as u8), @@ -2260,7 +2259,7 @@ mod sanitizers { // Para 4 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(4), relay_parent, pov_hash: Hash::repeat_byte(5 as u8), @@ -2293,7 +2292,7 @@ mod sanitizers { .or_insert(vec![]) .push((backed, CoreIndex(5))); - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(4), relay_parent, pov_hash: Hash::repeat_byte(6 as u8), @@ -2327,7 +2326,7 @@ mod sanitizers { // Para 6. { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(6), relay_parent, pov_hash: Hash::repeat_byte(3 as u8), @@ -2358,7 +2357,7 @@ mod sanitizers { // Para 7. { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(7), relay_parent, pov_hash: Hash::repeat_byte(3 as u8), @@ -2389,7 +2388,7 @@ mod sanitizers { // Para 8. { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(8), relay_parent, pov_hash: Hash::repeat_byte(3 as u8), @@ -2626,7 +2625,7 @@ mod sanitizers { // Para 1 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(1), relay_parent, pov_hash: Hash::repeat_byte(1 as u8), @@ -2655,7 +2654,7 @@ mod sanitizers { core_index_enabled.then_some(CoreIndex(0 as u32)), ); - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(1), relay_parent, pov_hash: Hash::repeat_byte(2 as u8), @@ -2688,7 +2687,7 @@ mod sanitizers { // Para 2. { - let mut candidate_1 = TestCandidateBuilder { + let candidate_1 = TestCandidateBuilder { para_id: ParaId::from(2), relay_parent, pov_hash: Hash::repeat_byte(3 as u8), @@ -2724,7 +2723,7 @@ mod sanitizers { .push((backed_1, CoreIndex(2))); } - let mut candidate_2 = TestCandidateBuilder { + let candidate_2 = TestCandidateBuilder { para_id: ParaId::from(2), relay_parent, pov_hash: Hash::repeat_byte(4 as u8), @@ -2753,7 +2752,7 @@ mod sanitizers { ); backed_candidates.push(backed_2.clone()); - let mut candidate_3 = TestCandidateBuilder { + let candidate_3 = TestCandidateBuilder { para_id: ParaId::from(2), relay_parent, pov_hash: Hash::repeat_byte(5 as u8), @@ -2785,7 +2784,7 @@ mod sanitizers { // Para 3 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(3), relay_parent, pov_hash: Hash::repeat_byte(6 as u8), @@ -2821,7 +2820,7 @@ mod sanitizers { .push((backed, CoreIndex(5))); } - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(3), relay_parent, pov_hash: Hash::repeat_byte(6 as u8), @@ -2859,7 +2858,7 @@ mod sanitizers { // Para 4 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(4), relay_parent, pov_hash: Hash::repeat_byte(8 as u8), @@ -3113,7 +3112,7 @@ mod sanitizers { // Para 1 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(1), relay_parent, pov_hash: Hash::repeat_byte(1 as u8), @@ -3149,7 +3148,7 @@ mod sanitizers { .push((backed, CoreIndex(0))); } - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(1), relay_parent: prev_relay_parent, pov_hash: Hash::repeat_byte(1 as u8), @@ -3180,7 +3179,7 @@ mod sanitizers { ); backed_candidates.push(backed.clone()); - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(1), relay_parent, pov_hash: Hash::repeat_byte(1 as u8), @@ -3213,7 +3212,7 @@ mod sanitizers { // Para 2 { - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(2), relay_parent: prev_relay_parent, pov_hash: Hash::repeat_byte(2 as u8), @@ -3249,7 +3248,7 @@ mod sanitizers { .push((backed, CoreIndex(3))); } - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(2), relay_parent, pov_hash: Hash::repeat_byte(2 as u8), @@ -3286,7 +3285,7 @@ mod sanitizers { .push((backed, CoreIndex(4))); } - let mut candidate = TestCandidateBuilder { + let candidate = TestCandidateBuilder { para_id: ParaId::from(2), relay_parent, pov_hash: Hash::repeat_byte(2 as u8), From f8b86d26c687a447120122277966dd4322f4b06f Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 12 Aug 2024 23:03:31 +0300 Subject: [PATCH 016/130] fix test-runtime Signed-off-by: Andrei Sandu --- polkadot/runtime/test-runtime/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 8e34320d38f2..26ddf8c90baf 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -59,10 +59,10 @@ use pallet_session::historical as session_historical; use pallet_timestamp::Now; use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; use polkadot_primitives::{ - slashing, AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CandidateHash, - CommittedCandidateReceipt, CoreIndex, CoreState, DisputeState, ExecutorParams, + slashing, AccountId, AccountIndex, Balance, BlockNumber, vstaging::CandidateEvent, CandidateHash, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, vstaging::CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash as HashT, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, - Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes, + Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, vstaging::ScrapedOnChainVotes, SessionInfo as SessionInfoData, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, }; @@ -978,7 +978,7 @@ sp_api::impl_runtime_apis! { runtime_impl::minimum_backing_votes::() } - fn para_backing_state(para_id: ParaId) -> Option { + fn para_backing_state(para_id: ParaId) -> Option { runtime_impl::backing_state::(para_id) } From fe2fbfb6c3b759cfaed13f1ed50425cb4bd14827 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 13 Aug 2024 11:07:39 +0300 Subject: [PATCH 017/130] self review feedback Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 38 ++++++++++++++---------- polkadot/runtime/test-runtime/src/lib.rs | 12 +++++--- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 4f69073648fd..74d75fcc46eb 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -350,9 +350,10 @@ impl From> for super::v7::CandidateReceipt { } } -/// A strictly increasing sequence number, tipically this would be the parachain block number. +/// A strictly increasing sequence number, tipically this would be the least significant byte of the +/// block number. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] -pub struct CoreSelector(pub BlockNumber); +pub struct CoreSelector(pub u8); /// An offset in the relay chain claim queue. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] @@ -375,7 +376,7 @@ pub const UMP_SEPARATOR: Vec = vec![]; impl CandidateCommitments { /// Returns the core selector and claim queue offset the candidate has commited to, if any. pub fn selected_core(&self) -> Option<(CoreSelector, ClaimQueueOffset)> { - // We need at least 2 messages for the separator and core index + // We need at least 2 messages for the separator and core selector if self.upward_messages.len() < 2 { return None } @@ -388,7 +389,7 @@ impl CandidateCommitments { .take_while(|message| message != &UMP_SEPARATOR) .collect::>(); - // We didn't find the separator, no core index commitment. + // Check for UMP separator if upward_commitments.len() == self.upward_messages.len() || upward_commitments.is_empty() { return None } @@ -510,32 +511,43 @@ impl CommittedCandidateReceiptV2 { /// Returns error if: /// - descriptor core index is different than the core selected /// by the commitments - /// - the core index is out of bounds wrt `n_cores`. + /// - the core index is out of bounds pub fn check( &self, n_cores: u32, // TODO: consider promoting `ClaimQueueSnapshot` as primitive claim_queue: &BTreeMap>, ) -> Result<(), CandidateReceiptError> { + // Don't check v1 descriptors. + if self.descriptor.version() == CandidateDescriptorVersion::V1 { + return Ok(()) + } + if claim_queue.is_empty() { return Err(CandidateReceiptError::NoAssignment) } + let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); + if descriptor_core_index.0 > n_cores - 1 { + return Err(CandidateReceiptError::InvalidCoreIndex) + } + + let (core_selector, cq_offset) = + self.commitments.selected_core().ok_or(CandidateReceiptError::NoCoreSelected)?; + + // TODO: double check the invariant of claim queue len == scheduling lookahead. + // What happens when on-demand is used and there is only 1 claim on a core. let claim_queue_depth = claim_queue .first_key_value() .ok_or(CandidateReceiptError::NoAssignment)? .1 .len(); - - let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); - let (core_selector, cq_offset) = - self.commitments.selected_core().ok_or(CandidateReceiptError::NoCoreSelected)?; - let para_id = self.descriptor.para_id; - if cq_offset.0 as usize >= claim_queue_depth { return Err(CandidateReceiptError::InvalidSelectedCore) } + let para_id = self.descriptor.para_id; + // Get a vec of the core indices the parachain is assigned to at `cq_offset`. let assigned_cores = claim_queue .iter() @@ -562,10 +574,6 @@ impl CommittedCandidateReceiptV2 { return Err(CandidateReceiptError::CoreIndexMismatch) } - if descriptor_core_index.0 > n_cores - 1 { - return Err(CandidateReceiptError::InvalidCoreIndex) - } - Ok(()) } } diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 26ddf8c90baf..72d024e9a878 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -59,10 +59,14 @@ use pallet_session::historical as session_historical; use pallet_timestamp::Now; use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; use polkadot_primitives::{ - slashing, AccountId, AccountIndex, Balance, BlockNumber, vstaging::CandidateEvent, CandidateHash, - vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreIndex, vstaging::CoreState, DisputeState, ExecutorParams, - GroupRotationInfo, Hash as HashT, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, - Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, vstaging::ScrapedOnChainVotes, + slashing, + vstaging::{ + CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + AccountId, AccountIndex, Balance, BlockNumber, CandidateHash, CoreIndex, DisputeState, + ExecutorParams, GroupRotationInfo, Hash as HashT, Id as ParaId, InboundDownwardMessage, + InboundHrmpMessage, Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, SessionInfo as SessionInfoData, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, }; From 975e13bafcbaf2c27c5ac5bcb2dafe5f897ca421 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 13 Aug 2024 13:22:27 +0300 Subject: [PATCH 018/130] review feedback Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 9 +++++---- polkadot/runtime/parachains/Cargo.toml | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 74d75fcc46eb..7f438be9434d 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -451,13 +451,14 @@ impl CandidateDescriptorV2 { } fn rebuild_collator_field(&self) -> CollatorId { - let mut collator_id = vec![self.version.0]; + let mut collator_id = Vec::with_capacity(32); let core_index: [u8; 2] = self.core_index.to_ne_bytes(); let session_index: [u8; 4] = self.session_index.to_ne_bytes(); - collator_id.append(&mut core_index.as_slice().to_vec()); - collator_id.append(&mut session_index.as_slice().to_vec()); - collator_id.append(&mut self.reserved25b.as_slice().to_vec()); + collator_id.push(self.version.0); + collator_id.extend_from_slice(core_index.as_slice()); + collator_id.extend_from_slice(session_index.as_slice()); + collator_id.extend_from_slice(self.reserved25b.as_slice()); CollatorId::from_slice(&collator_id.as_slice()) .expect("Slice size is exactly 32 bytes; qed") diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml index 59af889fe6e7..f3123fa554ca 100644 --- a/polkadot/runtime/parachains/Cargo.toml +++ b/polkadot/runtime/parachains/Cargo.toml @@ -49,7 +49,7 @@ frame-system = { workspace = true } xcm = { workspace = true } xcm-executor = { workspace = true } -polkadot-primitives = { workspace = true, features=["test"] } +polkadot-primitives = { workspace = true } rand = { workspace = true } rand_chacha = { workspace = true } @@ -59,7 +59,7 @@ polkadot-runtime-metrics = { workspace = true } polkadot-core-primitives = { workspace = true } [dev-dependencies] -polkadot-primitives = { workspace = true } +polkadot-primitives = { workspace = true, features=["test"] } futures = { workspace = true } hex-literal = { workspace = true, default-features = true } From 1c7ac55b5dce45a2f0a63e55381e0e18d58ac5e1 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 13 Aug 2024 13:39:40 +0300 Subject: [PATCH 019/130] feedback Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 7f438be9434d..8251a32c4aa7 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -122,14 +122,13 @@ impl> Default for SchedulerParams #[cfg_attr(feature = "std", derive(Hash))] pub struct InternalVersion(pub u8); -/// A type representing the version of the candidate descriptor and internal version number. -/// For `V1`` the internal version number stores the first byte of the `CollatorId`. +/// A type representing the version of the candidate descriptor. #[derive(PartialEq, Eq, Clone, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Hash))] pub enum CandidateDescriptorVersion { /// The old candidate descriptor version. V1, - /// Introduced with `CandidateDescriptorV2` + /// The new `CandidateDescriptorV2`. V2, } @@ -141,7 +140,8 @@ pub struct CandidateDescriptorV2 { para_id: ParaId, /// The hash of the relay-chain block this is executed in the context of. relay_parent: H, - /// Version field + /// Version field. The raw value here is not exposed, instead it is used + /// to determine the `CandidateDescriptorVersion`, see `fn version()` version: InternalVersion, /// The core index where the candidate is backed. core_index: u16, @@ -237,7 +237,7 @@ pub struct CommittedCandidateReceiptV2 { pub commitments: CandidateCommitments, } -/// An even concerning a candidate. +/// An event concerning a candidate. #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] pub enum CandidateEvent { @@ -350,7 +350,7 @@ impl From> for super::v7::CandidateReceipt { } } -/// A strictly increasing sequence number, tipically this would be the least significant byte of the +/// A strictly increasing sequence number, typically this would be the least significant byte of the /// block number. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] pub struct CoreSelector(pub u8); @@ -374,7 +374,7 @@ pub enum UMPSignal { pub const UMP_SEPARATOR: Vec = vec![]; impl CandidateCommitments { - /// Returns the core selector and claim queue offset the candidate has commited to, if any. + /// Returns the core selector and claim queue offset the candidate has committed to, if any. pub fn selected_core(&self) -> Option<(CoreSelector, ClaimQueueOffset)> { // We need at least 2 messages for the separator and core selector if self.upward_messages.len() < 2 { From 653873b15819df3cdedb92161cfb19bbbf814420 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 13 Aug 2024 13:51:08 +0300 Subject: [PATCH 020/130] feedback Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 8251a32c4aa7..56e4dcb7054a 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -381,21 +381,11 @@ impl CandidateCommitments { return None } - let upward_commitments = self - .upward_messages - .iter() - .cloned() - .rev() - .take_while(|message| message != &UMP_SEPARATOR) - .collect::>(); - - // Check for UMP separator - if upward_commitments.len() == self.upward_messages.len() || upward_commitments.is_empty() { - return None - } + let separator_pos = + self.upward_messages.iter().rposition(|message| message == &UMP_SEPARATOR)?; // Use first commitment - let Some(message) = upward_commitments.into_iter().rev().next() else { return None }; + let message = self.upward_messages.get(separator_pos + 1)?; match UMPSignal::decode(&mut message.as_slice()).ok()? { UMPSignal::SelectCore(core_selector, cq_offset) => Some((core_selector, cq_offset)), From dc98149924a59162fda79f93eae2836fb545b502 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 13 Aug 2024 13:56:51 +0300 Subject: [PATCH 021/130] clippy Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/paras_inherent/benchmarking.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/benchmarking.rs b/polkadot/runtime/parachains/src/paras_inherent/benchmarking.rs index c5284ba1dd1f..07bdf3d5489c 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/benchmarking.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/benchmarking.rs @@ -141,8 +141,8 @@ benchmarks! { // Traverse candidates and assert descriptors are as expected for (para_id, backing_validators) in vote.backing_validators_per_candidate.iter().enumerate() { let descriptor = backing_validators.0.descriptor(); - assert_eq!(ParaId::from(para_id), descriptor.para_id); - assert_eq!(header.hash(), descriptor.relay_parent); + assert_eq!(ParaId::from(para_id), descriptor.para_id()); + assert_eq!(header.hash(), descriptor.relay_parent()); assert_eq!(backing_validators.1.len(), votes); } @@ -198,8 +198,8 @@ benchmarks! { for (para_id, backing_validators) in vote.backing_validators_per_candidate.iter().enumerate() { let descriptor = backing_validators.0.descriptor(); - assert_eq!(ParaId::from(para_id), descriptor.para_id); - assert_eq!(header.hash(), descriptor.relay_parent); + assert_eq!(ParaId::from(para_id), descriptor.para_id()); + assert_eq!(header.hash(), descriptor.relay_parent()); assert_eq!( backing_validators.1.len(), votes, From 0a6bce3404f3ff91e67ccabf0356c60e19321e4b Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 13 Aug 2024 23:08:03 +0300 Subject: [PATCH 022/130] chores Signed-off-by: Andrei Sandu --- polkadot/primitives/src/v7/mod.rs | 2 +- polkadot/primitives/src/vstaging/mod.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/polkadot/primitives/src/v7/mod.rs b/polkadot/primitives/src/v7/mod.rs index 4b7abdb311f5..7d5d6e093c8f 100644 --- a/polkadot/primitives/src/v7/mod.rs +++ b/polkadot/primitives/src/v7/mod.rs @@ -1153,7 +1153,7 @@ pub enum OccupiedCoreAssumption { Free, } -/// An even concerning a candidate. +/// An event concerning a candidate. #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] pub enum CandidateEvent { diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 56e4dcb7054a..b089fb422f3c 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -539,13 +539,11 @@ impl CommittedCandidateReceiptV2 { let para_id = self.descriptor.para_id; - // Get a vec of the core indices the parachain is assigned to at `cq_offset`. + // Get a sorted vec of the core indices the parachain is assigned to at `cq_offset`. let assigned_cores = claim_queue .iter() .filter_map(|(core_index, queue)| { - let queued_para = queue.get(cq_offset.0 as usize)?; - - if queued_para == ¶_id { + if queue.get(cq_offset.0 as usize)? == ¶_id { Some(core_index) } else { None From 5e4dac2bc9939ddaa759e44738c6a3c5ad4f7ef8 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 14 Aug 2024 15:18:15 +0300 Subject: [PATCH 023/130] Filter v2 candidate descriptors Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 7 ++ polkadot/primitives/test-helpers/src/lib.rs | 8 +- polkadot/runtime/parachains/src/builder.rs | 75 +++++++++++----- .../runtime/parachains/src/inclusion/tests.rs | 29 +++--- .../parachains/src/paras_inherent/mod.rs | 16 +++- .../parachains/src/paras_inherent/tests.rs | 89 ++++++++++++++++++- 6 files changed, 181 insertions(+), 43 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index b089fb422f3c..aec3c7aeb612 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -181,6 +181,13 @@ impl From> for CandidateDescriptor { } } +#[cfg(feature = "test")] +impl From> for CandidateDescriptorV2 { + fn from(value: CandidateDescriptor) -> Self { + Decode::decode(&mut value.encode().as_slice()).unwrap() + } +} + impl CandidateDescriptorV2 { /// Constructor pub fn new( diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index cb644372f758..1adf86624cf8 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -29,7 +29,7 @@ use polkadot_primitives::{ SessionIndex, ValidationCode, ValidationCodeHash, ValidatorId, }; pub use rand; -use sp_application_crypto::sr25519; +use sp_application_crypto::{sr25519, ByteArray}; use sp_keyring::Sr25519Keyring; use sp_runtime::generic::Digest; @@ -172,7 +172,8 @@ pub fn dummy_head_data() -> HeadData { /// Create a meaningless collator id. pub fn dummy_collator() -> CollatorId { - CollatorId::from(sr25519::Public::default()) + CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) + .expect("32 bytes; qed") } /// Create a meaningless validator id. @@ -182,7 +183,8 @@ pub fn dummy_validator() -> ValidatorId { /// Create a meaningless collator signature. pub fn dummy_collator_signature() -> CollatorSignature { - CollatorSignature::from(sr25519::Signature::default()) + CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) + .expect("64 bytes; qed") } /// Create a meaningless persisted validation data. diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index ebc956a08e67..0b64201390a6 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -26,29 +26,30 @@ use alloc::{ vec, vec::Vec, }; + use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; use polkadot_primitives::{ node_features::FeatureIndex, vstaging::{ - BackedCandidate, CandidateDescriptorV2 as CandidateDescriptor, + BackedCandidate, CandidateDescriptorV2, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, InherentData as ParachainsInherentData, }, - AvailabilityBitfield, CandidateCommitments, CandidateHash, CompactStatement, CoreIndex, - DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, Id as ParaId, IndexedVec, - InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, SigningContext, - UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, - ValidityAttestation, + AvailabilityBitfield, CandidateCommitments, CandidateDescriptor, CandidateHash, + CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, + Id as ParaId, IndexedVec, InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, + SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, + ValidatorIndex, ValidityAttestation, }; +use polkadot_primitives_test_helpers::{dummy_collator, dummy_collator_signature}; use sp_core::H256; use sp_runtime::{ generic::Digest, traits::{Header as HeaderT, One, TrailingZeroInput, Zero}, RuntimeAppPublic, }; - fn mock_validation_code() -> ValidationCode { ValidationCode(vec![1, 2, 3]) } @@ -116,6 +117,8 @@ pub(crate) struct BenchBuilder { fill_claimqueue: bool, /// Cores which should not be available when being populated with pending candidates. unavailable_cores: Vec, + /// Use v2 candidate descriptor. + candidate_descriptor_v2: bool, _phantom: core::marker::PhantomData, } @@ -147,6 +150,7 @@ impl BenchBuilder { code_upgrade: None, fill_claimqueue: true, unavailable_cores: vec![], + candidate_descriptor_v2: false, _phantom: core::marker::PhantomData::, } } @@ -254,6 +258,12 @@ impl BenchBuilder { self } + /// Toggle usage of v2 candidate descriptors. + pub(crate) fn set_candidate_descriptor_v2(mut self, enable: bool) -> Self { + self.candidate_descriptor_v2 = enable; + self + } + /// Get the maximum number of validators per core. fn max_validators_per_core(&self) -> u32 { self.max_validators_per_core.unwrap_or(Self::fallback_max_validators_per_core()) @@ -289,18 +299,20 @@ impl BenchBuilder { HeadData(vec![0xFF; max_head_size as usize]) } - fn candidate_descriptor_mock() -> CandidateDescriptor { - CandidateDescriptor::::new( - 0.into(), - Default::default(), - CoreIndex(0), - 1, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - mock_validation_code().hash(), - ) + fn candidate_descriptor_mock() -> CandidateDescriptorV2 { + // Use a v1 descriptor. + CandidateDescriptor:: { + para_id: 0.into(), + relay_parent: Default::default(), + collator: dummy_collator(), + persisted_validation_data_hash: Default::default(), + pov_hash: Default::default(), + erasure_root: Default::default(), + signature: dummy_collator_signature(), + para_head: Default::default(), + validation_code_hash: mock_validation_code().hash(), + } + .into() } /// Create a mock of `CandidatePendingAvailability`. @@ -625,18 +637,35 @@ impl BenchBuilder { let group_validators = scheduler::Pallet::::group_validators(group_idx).unwrap(); - let candidate = CommittedCandidateReceipt:: { - descriptor: CandidateDescriptor::::new( + let descriptor = if self.candidate_descriptor_v2 { + CandidateDescriptorV2::new( para_id, relay_parent, - CoreIndex(0), + core_idx, 1, persisted_validation_data_hash, pov_hash, Default::default(), head_data.hash(), validation_code_hash, - ), + ) + } else { + CandidateDescriptor:: { + para_id, + relay_parent, + collator: dummy_collator(), + persisted_validation_data_hash, + pov_hash, + erasure_root: Default::default(), + signature: dummy_collator_signature(), + para_head: head_data.hash(), + validation_code_hash, + } + .into() + }; + + let candidate = CommittedCandidateReceipt:: { + descriptor, commitments: CandidateCommitments:: { upward_messages: Default::default(), horizontal_messages: Default::default(), diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index 2125dffe2592..7f892a195068 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -26,7 +26,7 @@ use crate::{ shared::AllowedRelayParentsTracker, }; use polkadot_primitives::{ - effective_minimum_backing_votes, vstaging::CandidateDescriptorV2, AvailabilityBitfield, + effective_minimum_backing_votes, AvailabilityBitfield, CandidateDescriptor, SignedAvailabilityBitfields, UncheckedSignedAvailabilityBitfields, }; @@ -38,7 +38,9 @@ use polkadot_primitives::{ SignedAvailabilityBitfield, SignedStatement, ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, }; -use polkadot_primitives_test_helpers::dummy_validation_code; +use polkadot_primitives_test_helpers::{ + dummy_collator, dummy_collator_signature, dummy_validation_code, +}; use sc_keystore::LocalKeystore; use sp_keyring::Sr25519Keyring; use sp_keystore::{Keystore, KeystorePtr}; @@ -283,17 +285,18 @@ impl std::default::Default for TestCandidateBuilder { impl TestCandidateBuilder { pub(crate) fn build(self) -> CommittedCandidateReceipt { CommittedCandidateReceipt { - descriptor: CandidateDescriptorV2::new( - self.para_id, - self.relay_parent, - CoreIndex(0), - 1, - self.persisted_validation_data_hash, - self.pov_hash, - Default::default(), - self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), - self.validation_code.hash(), - ), + descriptor: CandidateDescriptor { + para_id: self.para_id, + pov_hash: self.pov_hash, + relay_parent: self.relay_parent, + persisted_validation_data_hash: self.persisted_validation_data_hash, + validation_code_hash: self.validation_code.hash(), + para_head: self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), + erasure_root: Default::default(), + signature: dummy_collator_signature(), + collator: dummy_collator(), + } + .into(), commitments: CandidateCommitments { head_data: self.head_data, new_validation_code: self.new_validation_code, diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 66330674898b..c00c3dc23130 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -51,7 +51,7 @@ use polkadot_primitives::{ effective_minimum_backing_votes, node_features::FeatureIndex, vstaging::{ - BackedCandidate, CandidateReceiptV2 as CandidateReceipt, + BackedCandidate, CandidateDescriptorVersion, CandidateReceiptV2 as CandidateReceipt, InherentData as ParachainsInherentData, ScrapedOnChainVotes, }, CandidateHash, CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CoreIndex, @@ -575,6 +575,12 @@ impl Pallet { .map(|b| *b) .unwrap_or(false); + let allow_v2_receipts = configuration::ActiveConfig::::get() + .node_features + .get(FeatureIndex::CandidateReceiptV2 as usize) + .map(|b| *b) + .unwrap_or(false); + let mut eligible: BTreeMap> = BTreeMap::new(); let mut total_eligible_cores = 0; @@ -591,6 +597,7 @@ impl Pallet { concluded_invalid_hashes, eligible, core_index_enabled, + allow_v2_receipts, ); let count = count_backed_candidates(&backed_candidates_with_core); @@ -964,11 +971,18 @@ fn sanitize_backed_candidates( concluded_invalid_with_descendants: BTreeSet, scheduled: BTreeMap>, core_index_enabled: bool, + allow_v2_receipts: bool, ) -> BTreeMap, CoreIndex)>> { // Map the candidates to the right paraids, while making sure that the order between candidates // of the same para is preserved. let mut candidates_per_para: BTreeMap> = BTreeMap::new(); for candidate in backed_candidates { + // Drop any v2 candidate receipts if nodes are not allowed to use them. + if !allow_v2_receipts && candidate.descriptor().version() == CandidateDescriptorVersion::V2 + { + continue + } + candidates_per_para .entry(candidate.descriptor().para_id()) .or_default() diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 6c82233e0820..db8e2d9c3d70 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -70,6 +70,7 @@ mod enter { fill_claimqueue: bool, elastic_paras: BTreeMap, unavailable_cores: Vec, + v2_descriptor: bool, } fn make_inherent_data( @@ -82,6 +83,7 @@ mod enter { fill_claimqueue, elastic_paras, unavailable_cores, + v2_descriptor, }: TestConfig, ) -> Bench { let extra_cores = elastic_paras @@ -99,7 +101,8 @@ mod enter { .set_backed_and_concluding_paras(backed_and_concluding.clone()) .set_dispute_sessions(&dispute_sessions[..]) .set_fill_claimqueue(fill_claimqueue) - .set_unavailable_cores(unavailable_cores); + .set_unavailable_cores(unavailable_cores) + .set_candidate_descriptor_v2(v2_descriptor); // Setup some assignments as needed: mock_assigner::Pallet::::set_core_count(builder.max_cores()); @@ -145,6 +148,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); // We expect the scenario to have cores 0 & 1 with pending availability. The backed @@ -240,6 +244,7 @@ mod enter { fill_claimqueue: false, elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -344,6 +349,7 @@ mod enter { fill_claimqueue: true, elastic_paras: [(2, 4)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), + v2_descriptor: false, }); let mut expected_para_inherent_data = scenario.data.clone(); @@ -600,6 +606,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -673,6 +680,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -744,6 +752,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -831,6 +840,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -918,6 +928,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1004,6 +1015,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1111,6 +1123,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1179,6 +1192,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1245,6 +1259,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1348,6 +1363,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let mut para_inherent_data = scenario.data.clone(); @@ -1437,6 +1453,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1465,6 +1482,62 @@ mod enter { assert_eq!(dispatch_error, Error::::InherentOverweight.into()); }); } + + #[test] + fn v2_descriptors_are_filtered() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let mut backed_and_concluding = BTreeMap::new(); + + for i in 0..10 { + backed_and_concluding.insert(i, i); + } + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + fill_claimqueue: false, + elastic_paras: BTreeMap::new(), + unavailable_cores: vec![], + v2_descriptor: true, + }); + + let unfiltered_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 10 backed candidates) + assert_eq!(unfiltered_para_inherent_data.bitfields.len(), 50); + // * 10 v2 candidate descriptors. + assert_eq!(unfiltered_para_inherent_data.backed_candidates.len(), 10); + + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) + .unwrap(); + + // We expect all candidates to be filtered out (including the backed candidates.) + let filtered_para_inherend_data = + Pallet::::create_inherent_inner(&inherent_data).unwrap(); + + assert_eq!(filtered_para_inherend_data.backed_candidates.len(), 0); + + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) + .unwrap(); + let dispatch_error = Pallet::::enter( + frame_system::RawOrigin::None.into(), + expected_para_inherent_data, + ) + .unwrap_err() + .error; + + // We expect `enter` to fail because it contains backed candidates with v2 descriptors. + assert_eq!(dispatch_error, Error::::CandidatesFilteredDuringExecution.into()); + }); + } } fn default_header() -> polkadot_primitives::Header { @@ -3376,7 +3449,8 @@ mod sanitizers { &shared::AllowedRelayParents::::get(), BTreeSet::new(), scheduled, - core_index_enabled + core_index_enabled, + false, ), expected_backed_candidates_with_core, ); @@ -3400,7 +3474,8 @@ mod sanitizers { &shared::AllowedRelayParents::::get(), BTreeSet::new(), scheduled, - core_index_enabled + core_index_enabled, + false, ), expected_backed_candidates_with_core, ); @@ -3425,6 +3500,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ), expected_backed_candidates_with_core ); @@ -3457,6 +3533,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ), expected_backed_candidates_with_core ); @@ -3497,6 +3574,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ); if core_index_enabled { @@ -3567,6 +3645,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ); if core_index_enabled { @@ -3605,6 +3684,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ); assert!(sanitized_backed_candidates.is_empty()); @@ -3641,6 +3721,7 @@ mod sanitizers { set, scheduled, core_index_enabled, + false, ); assert_eq!(sanitized_backed_candidates.len(), backed_candidates.len() / 2); @@ -3678,6 +3759,7 @@ mod sanitizers { invalid_set, scheduled, true, + false, ); // We'll be left with candidates from paraid 2 and 4. @@ -3714,6 +3796,7 @@ mod sanitizers { invalid_set, scheduled, true, + false, ); // Only the second candidate of paraid 1 should be removed. From f12ca7a502edbf0d8849e69919ec8fe174fd3bcf Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 14 Aug 2024 16:52:30 +0300 Subject: [PATCH 024/130] fix Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/tests.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index db8e2d9c3d70..3e04394d9827 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1523,13 +1523,9 @@ mod enter { assert_eq!(filtered_para_inherend_data.backed_candidates.len(), 0); - let mut inherent_data = InherentData::new(); - inherent_data - .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) - .unwrap(); let dispatch_error = Pallet::::enter( frame_system::RawOrigin::None.into(), - expected_para_inherent_data, + unfiltered_para_inherent_data, ) .unwrap_err() .error; From 13734dedfec81602238793901a5614a08c41c1e8 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 14 Aug 2024 19:05:15 +0300 Subject: [PATCH 025/130] fix prospective parachains tests Signed-off-by: Andrei Sandu --- polkadot/primitives/test-helpers/src/lib.rs | 24 +++++++++++++------ polkadot/runtime/parachains/src/builder.rs | 10 ++++---- .../runtime/parachains/src/inclusion/tests.rs | 6 ++--- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index 1adf86624cf8..7aaa8f06160b 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -170,21 +170,31 @@ pub fn dummy_head_data() -> HeadData { HeadData(vec![]) } -/// Create a meaningless collator id. -pub fn dummy_collator() -> CollatorId { +/// Create a meaningless validator id. +pub fn dummy_validator() -> ValidatorId { + ValidatorId::from(sr25519::Public::default()) +} + +/// Create junk non-zeroed collator id. +pub fn junk_collator() -> CollatorId { CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) .expect("32 bytes; qed") } -/// Create a meaningless validator id. -pub fn dummy_validator() -> ValidatorId { - ValidatorId::from(sr25519::Public::default()) +/// Create junk non-zeroed collator signature. +pub fn junk_collator_signature() -> CollatorSignature { + CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) + .expect("64 bytes; qed") +} + +/// Create a meaningless collator id. +pub fn dummy_collator() -> CollatorId { + CollatorId::from(sr25519::Public::default()) } /// Create a meaningless collator signature. pub fn dummy_collator_signature() -> CollatorSignature { - CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) - .expect("64 bytes; qed") + CollatorSignature::from(sr25519::Signature::default()) } /// Create a meaningless persisted validation data. diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 0b64201390a6..432b7777aa9e 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -43,7 +43,7 @@ use polkadot_primitives::{ SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation, }; -use polkadot_primitives_test_helpers::{dummy_collator, dummy_collator_signature}; +use polkadot_primitives_test_helpers::{junk_collator, junk_collator_signature}; use sp_core::H256; use sp_runtime::{ generic::Digest, @@ -304,11 +304,11 @@ impl BenchBuilder { CandidateDescriptor:: { para_id: 0.into(), relay_parent: Default::default(), - collator: dummy_collator(), + collator: junk_collator(), persisted_validation_data_hash: Default::default(), pov_hash: Default::default(), erasure_root: Default::default(), - signature: dummy_collator_signature(), + signature: junk_collator_signature(), para_head: Default::default(), validation_code_hash: mock_validation_code().hash(), } @@ -653,11 +653,11 @@ impl BenchBuilder { CandidateDescriptor:: { para_id, relay_parent, - collator: dummy_collator(), + collator: junk_collator(), persisted_validation_data_hash, pov_hash, erasure_root: Default::default(), - signature: dummy_collator_signature(), + signature: junk_collator_signature(), para_head: head_data.hash(), validation_code_hash, } diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index 7f892a195068..e3c1a9bdefa9 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -39,7 +39,7 @@ use polkadot_primitives::{ PARACHAIN_KEY_TYPE_ID, }; use polkadot_primitives_test_helpers::{ - dummy_collator, dummy_collator_signature, dummy_validation_code, + dummy_validation_code, junk_collator, junk_collator_signature, }; use sc_keystore::LocalKeystore; use sp_keyring::Sr25519Keyring; @@ -293,8 +293,8 @@ impl TestCandidateBuilder { validation_code_hash: self.validation_code.hash(), para_head: self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), erasure_root: Default::default(), - signature: dummy_collator_signature(), - collator: dummy_collator(), + signature: junk_collator_signature(), + collator: junk_collator(), } .into(), commitments: CandidateCommitments { From effb1cc57e040e43724e0027a2b95f4571b74ac7 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 14 Aug 2024 23:06:10 +0300 Subject: [PATCH 026/130] fix fix Signed-off-by: Andrei Sandu --- polkadot/primitives/test-helpers/src/lib.rs | 14 +------------- polkadot/runtime/parachains/src/builder.rs | 17 ++++++++++++++--- .../runtime/parachains/src/inclusion/tests.rs | 13 +++++++------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index 7aaa8f06160b..b0f78717dd97 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -29,7 +29,7 @@ use polkadot_primitives::{ SessionIndex, ValidationCode, ValidationCodeHash, ValidatorId, }; pub use rand; -use sp_application_crypto::{sr25519, ByteArray}; +use sp_application_crypto::sr25519; use sp_keyring::Sr25519Keyring; use sp_runtime::generic::Digest; @@ -175,18 +175,6 @@ pub fn dummy_validator() -> ValidatorId { ValidatorId::from(sr25519::Public::default()) } -/// Create junk non-zeroed collator id. -pub fn junk_collator() -> CollatorId { - CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) - .expect("32 bytes; qed") -} - -/// Create junk non-zeroed collator signature. -pub fn junk_collator_signature() -> CollatorSignature { - CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) - .expect("64 bytes; qed") -} - /// Create a meaningless collator id. pub fn dummy_collator() -> CollatorId { CollatorId::from(sr25519::Public::default()) diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 432b7777aa9e..eaef0d99dccc 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -26,7 +26,7 @@ use alloc::{ vec, vec::Vec, }; - +use sp_core::ByteArray; use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -41,9 +41,8 @@ use polkadot_primitives::{ CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, Id as ParaId, IndexedVec, InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, - ValidatorIndex, ValidityAttestation, + ValidatorIndex, ValidityAttestation, CollatorId, CollatorSignature, }; -use polkadot_primitives_test_helpers::{junk_collator, junk_collator_signature}; use sp_core::H256; use sp_runtime::{ generic::Digest, @@ -54,6 +53,18 @@ fn mock_validation_code() -> ValidationCode { ValidationCode(vec![1, 2, 3]) } +// Create a dummy collator id suitable to be used in a V1 candidate descriptor. +fn junk_collator() -> CollatorId { + CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) + .expect("32 bytes; qed") +} + +// Creates a dummy collator signature suitable to be used in a V1 candidate descriptor. +fn junk_collator_signature() -> CollatorSignature { + CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) + .expect("64 bytes; qed") +} + /// Grab an account, seeded by a name and index. /// /// This is directly from frame-benchmarking. Copy/pasted so we can use it when not compiling with diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index e3c1a9bdefa9..80d6ed752b84 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -36,11 +36,10 @@ use frame_support::assert_noop; use polkadot_primitives::{ BlockNumber, CandidateCommitments, CollatorId, CompactStatement as Statement, Hash, SignedAvailabilityBitfield, SignedStatement, ValidationCode, ValidatorId, ValidityAttestation, - PARACHAIN_KEY_TYPE_ID, -}; -use polkadot_primitives_test_helpers::{ - dummy_validation_code, junk_collator, junk_collator_signature, + PARACHAIN_KEY_TYPE_ID, CollatorSignature, }; +use polkadot_primitives_test_helpers::dummy_validation_code; +use sp_core::ByteArray; use sc_keystore::LocalKeystore; use sp_keyring::Sr25519Keyring; use sp_keystore::{Keystore, KeystorePtr}; @@ -293,8 +292,10 @@ impl TestCandidateBuilder { validation_code_hash: self.validation_code.hash(), para_head: self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), erasure_root: Default::default(), - signature: junk_collator_signature(), - collator: junk_collator(), + signature: CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) + .expect("64 bytes; qed"), + collator: CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) + .expect("32 bytes; qed"), } .into(), commitments: CandidateCommitments { From 3f75cba787c806cc4e15be5bf076d1e83ac32da5 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 14 Aug 2024 23:07:26 +0300 Subject: [PATCH 027/130] fmt Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/builder.rs | 13 ++++++------ .../runtime/parachains/src/inclusion/tests.rs | 20 +++++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index eaef0d99dccc..35835793ce9d 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -26,7 +26,6 @@ use alloc::{ vec, vec::Vec, }; -use sp_core::ByteArray; use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -37,13 +36,13 @@ use polkadot_primitives::{ CommittedCandidateReceiptV2 as CommittedCandidateReceipt, InherentData as ParachainsInherentData, }, - AvailabilityBitfield, CandidateCommitments, CandidateDescriptor, CandidateHash, - CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, - Id as ParaId, IndexedVec, InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, - SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, - ValidatorIndex, ValidityAttestation, CollatorId, CollatorSignature, + AvailabilityBitfield, CandidateCommitments, CandidateDescriptor, CandidateHash, CollatorId, + CollatorSignature, CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, + GroupIndex, HeadData, Id as ParaId, IndexedVec, InvalidDisputeStatementKind, + PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned, + ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation, }; -use sp_core::H256; +use sp_core::{ByteArray, H256}; use sp_runtime::{ generic::Digest, traits::{Header as HeaderT, One, TrailingZeroInput, Zero}, diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index 80d6ed752b84..f17b8ed2e0e9 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -34,13 +34,13 @@ use assert_matches::assert_matches; use codec::DecodeAll; use frame_support::assert_noop; use polkadot_primitives::{ - BlockNumber, CandidateCommitments, CollatorId, CompactStatement as Statement, Hash, - SignedAvailabilityBitfield, SignedStatement, ValidationCode, ValidatorId, ValidityAttestation, - PARACHAIN_KEY_TYPE_ID, CollatorSignature, + BlockNumber, CandidateCommitments, CollatorId, CollatorSignature, + CompactStatement as Statement, Hash, SignedAvailabilityBitfield, SignedStatement, + ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, }; use polkadot_primitives_test_helpers::dummy_validation_code; -use sp_core::ByteArray; use sc_keystore::LocalKeystore; +use sp_core::ByteArray; use sp_keyring::Sr25519Keyring; use sp_keystore::{Keystore, KeystorePtr}; use std::sync::Arc; @@ -292,10 +292,14 @@ impl TestCandidateBuilder { validation_code_hash: self.validation_code.hash(), para_head: self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), erasure_root: Default::default(), - signature: CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) - .expect("64 bytes; qed"), - collator: CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) - .expect("32 bytes; qed"), + signature: CollatorSignature::from_slice( + &mut (0..64).into_iter().collect::>().as_slice(), + ) + .expect("64 bytes; qed"), + collator: CollatorId::from_slice( + &mut (0..32).into_iter().collect::>().as_slice(), + ) + .expect("32 bytes; qed"), } .into(), commitments: CandidateCommitments { From 75a47bb1859e325dda0cee1a1a8e902c5627f972 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 14 Aug 2024 23:10:24 +0300 Subject: [PATCH 028/130] fix comment Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 3e04394d9827..e3b4d8579055 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1517,7 +1517,7 @@ mod enter { .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) .unwrap(); - // We expect all candidates to be filtered out (including the backed candidates.) + // We expect all backed candidates to be filtered out. let filtered_para_inherend_data = Pallet::::create_inherent_inner(&inherent_data).unwrap(); From 12ed853d0641295f1b6262174636da8be3ad97bb Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 14 Aug 2024 23:12:57 +0300 Subject: [PATCH 029/130] another one Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index e3b4d8579055..a5923d68a12a 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1530,7 +1530,7 @@ mod enter { .unwrap_err() .error; - // We expect `enter` to fail because it contains backed candidates with v2 descriptors. + // We expect `enter` to fail because the inherent data contains backed candidates with v2 descriptors. assert_eq!(dispatch_error, Error::::CandidatesFilteredDuringExecution.into()); }); } From f2c0882c8e573166f2ab0f859a2bd0db69dc47d7 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 15 Aug 2024 13:07:41 +0300 Subject: [PATCH 030/130] fix build Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index aec3c7aeb612..8ea628bdc28a 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -181,7 +181,6 @@ impl From> for CandidateDescriptor { } } -#[cfg(feature = "test")] impl From> for CandidateDescriptorV2 { fn from(value: CandidateDescriptor) -> Self { Decode::decode(&mut value.encode().as_slice()).unwrap() From 768e03446a39a454337a158326d1482ba48228af Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 15 Aug 2024 14:05:09 +0300 Subject: [PATCH 031/130] . Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 2 +- polkadot/runtime/parachains/src/paras_inherent/tests.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 8ea628bdc28a..cc97f4a6666c 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -38,7 +38,6 @@ use sp_arithmetic::Perbill; use sp_core::RuntimeDebug; use sp_runtime::traits::Header as HeaderT; use sp_staking::SessionIndex; - /// Async backing primitives pub mod async_backing; @@ -181,6 +180,7 @@ impl From> for CandidateDescriptor { } } +#[cfg(any(feature = "runtime-benchmarks", feature = "test"))] impl From> for CandidateDescriptorV2 { fn from(value: CandidateDescriptor) -> Self { Decode::decode(&mut value.encode().as_slice()).unwrap() diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index a5923d68a12a..39c9fc52d685 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1530,7 +1530,8 @@ mod enter { .unwrap_err() .error; - // We expect `enter` to fail because the inherent data contains backed candidates with v2 descriptors. + // We expect `enter` to fail because the inherent data contains backed candidates with + // v2 descriptors. assert_eq!(dispatch_error, Error::::CandidatesFilteredDuringExecution.into()); }); } From 4bf0706876422e84e80f32fc62b44e23e6fc3c9a Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 15 Aug 2024 17:43:57 +0300 Subject: [PATCH 032/130] improve test and add comment Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 12 ++++++ .../parachains/src/paras_inherent/mod.rs | 13 +++--- .../parachains/src/paras_inherent/tests.rs | 40 ++++++++++++++----- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index cc97f4a6666c..d5e39979ab34 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -221,6 +221,12 @@ impl CandidateDescriptorV2 { pub fn set_pov_hash(&mut self, pov_hash: Hash) { self.pov_hash = pov_hash; } + + /// Set the version in the descriptor. Only for tests. + #[cfg(feature = "test")] + pub fn set_version(&mut self, version: InternalVersion) { + self.version = version; + } } /// A candidate-receipt at version 2. @@ -624,6 +630,12 @@ impl BackedCandidate { &self.candidate.descriptor } + /// Get a mutable reference to the descriptor of the candidate. Only for testing. + #[cfg(feature = "test")] + pub fn descriptor_mut(&mut self) -> &mut CandidateDescriptorV2 { + &mut self.candidate.descriptor + } + /// Get a reference to the validity votes of the candidate. pub fn validity_votes(&self) -> &[ValidityAttestation] { &self.validity_votes diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index c00c3dc23130..7c1b7455de38 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -954,14 +954,15 @@ pub(crate) fn sanitize_bitfields( /// subsequent candidates after the filtered one. /// /// Filter out: -/// 1. any candidates which don't form a chain with the other candidates of the paraid (even if they +/// 1. Candidates that have v2 descriptors if the node `CandidateReceiptV2` feature is not enabled. +/// 2. any candidates which don't form a chain with the other candidates of the paraid (even if they /// do form a chain but are not in the right order). -/// 2. any candidates that have a concluded invalid dispute or who are descendants of a concluded +/// 3. any candidates that have a concluded invalid dispute or who are descendants of a concluded /// invalid candidate. -/// 3. any unscheduled candidates, as well as candidates whose paraid has multiple cores assigned +/// 4. any unscheduled candidates, as well as candidates whose paraid has multiple cores assigned /// but have no injected core index. -/// 4. all backing votes from disabled validators -/// 5. any candidates that end up with less than `effective_minimum_backing_votes` backing votes +/// 5. all backing votes from disabled validators +/// 6. any candidates that end up with less than `effective_minimum_backing_votes` backing votes /// /// Returns the scheduled /// backed candidates which passed filtering, mapped by para id and in the right dependency order. @@ -978,6 +979,8 @@ fn sanitize_backed_candidates( let mut candidates_per_para: BTreeMap> = BTreeMap::new(); for candidate in backed_candidates { // Drop any v2 candidate receipts if nodes are not allowed to use them. + // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure + // any v1 descendants of v2 candidates are dropped. if !allow_v2_receipts && candidate.descriptor().version() == CandidateDescriptorVersion::V2 { continue diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 39c9fc52d685..c0e1636569a8 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -58,7 +58,10 @@ mod enter { use core::panic; use frame_support::assert_ok; use frame_system::limits; - use polkadot_primitives::{vstaging::SchedulerParams, AvailabilityBitfield, UncheckedSigned}; + use polkadot_primitives::{ + vstaging::{InternalVersion, SchedulerParams}, + AvailabilityBitfield, UncheckedSigned, + }; use sp_runtime::Perbill; struct TestConfig { @@ -1485,26 +1488,38 @@ mod enter { #[test] fn v2_descriptors_are_filtered() { - new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::ElasticScalingMVP as u8, + true, + ) + .unwrap(); + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); - for i in 0..10 { - backed_and_concluding.insert(i, i); - } + let unavailable_cores = vec![]; let scenario = make_inherent_data(TestConfig { dispute_statements: BTreeMap::new(), - dispute_sessions: vec![], + dispute_sessions: vec![], // No disputes backed_and_concluding, num_validators_per_core: 5, code_upgrade: None, - fill_claimqueue: false, - elastic_paras: BTreeMap::new(), - unavailable_cores: vec![], + fill_claimqueue: true, + // 8 cores ! + elastic_paras: [(2, 8)].into_iter().collect(), + unavailable_cores: unavailable_cores.clone(), v2_descriptor: true, }); - let unfiltered_para_inherent_data = scenario.data.clone(); + let mut unfiltered_para_inherent_data = scenario.data.clone(); // Check the para inherent data is as expected: // * 1 bitfield per validator (5 validators per core, 10 backed candidates) @@ -1512,6 +1527,11 @@ mod enter { // * 10 v2 candidate descriptors. assert_eq!(unfiltered_para_inherent_data.backed_candidates.len(), 10); + // Make the last candidate look like v1, by using an unknown version. + unfiltered_para_inherent_data.backed_candidates[9] + .descriptor_mut() + .set_version(InternalVersion(123)); + let mut inherent_data = InherentData::new(); inherent_data .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) From 0c83201531b3bc9d40d8f6c1d14cfdc1589cfaa9 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 15 Aug 2024 17:47:48 +0300 Subject: [PATCH 033/130] add log Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 7c1b7455de38..2bcc2d873131 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -983,6 +983,12 @@ fn sanitize_backed_candidates( // any v1 descendants of v2 candidates are dropped. if !allow_v2_receipts && candidate.descriptor().version() == CandidateDescriptorVersion::V2 { + log::debug!( + target: LOG_TARGET, + "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", + candidate.candidate().hash(), + candidate.descriptor().para_id() + ); continue } From 429694215f8ffba2ac3e8639da79df3ec3e32887 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 20 Aug 2024 00:58:10 +0300 Subject: [PATCH 034/130] simplify check() Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 86 ++++--------------------- 1 file changed, 12 insertions(+), 74 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index b089fb422f3c..e2dcf124b545 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -27,11 +27,7 @@ use super::{ use bitvec::prelude::*; use sp_application_crypto::ByteArray; -use alloc::{ - collections::{btree_map::BTreeMap, vec_deque::VecDeque}, - vec, - vec::Vec, -}; +use alloc::{vec, vec::Vec}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_arithmetic::Perbill; @@ -497,69 +493,29 @@ impl CandidateDescriptorV2 { } impl CommittedCandidateReceiptV2 { - /// Performs a sanity check of the descriptor and commitment. - /// - /// Returns error if: - /// - descriptor core index is different than the core selected - /// by the commitments - /// - the core index is out of bounds - pub fn check( - &self, - n_cores: u32, - // TODO: consider promoting `ClaimQueueSnapshot` as primitive - claim_queue: &BTreeMap>, - ) -> Result<(), CandidateReceiptError> { + /// Checks if descriptor core index is equal to the commited core index. + /// Input `assigned_cores` must contain the sorted cores assigned to the para at + /// the committed claim queue offset. + pub fn check(&self, assigned_cores: &Vec) -> Result<(), CandidateReceiptError> { // Don't check v1 descriptors. if self.descriptor.version() == CandidateDescriptorVersion::V1 { return Ok(()) } - if claim_queue.is_empty() { + if assigned_cores.is_empty() { return Err(CandidateReceiptError::NoAssignment) } let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); - if descriptor_core_index.0 > n_cores - 1 { - return Err(CandidateReceiptError::InvalidCoreIndex) - } - let (core_selector, cq_offset) = + let (core_selector, _cq_offset) = self.commitments.selected_core().ok_or(CandidateReceiptError::NoCoreSelected)?; - // TODO: double check the invariant of claim queue len == scheduling lookahead. - // What happens when on-demand is used and there is only 1 claim on a core. - let claim_queue_depth = claim_queue - .first_key_value() - .ok_or(CandidateReceiptError::NoAssignment)? - .1 - .len(); - if cq_offset.0 as usize >= claim_queue_depth { - return Err(CandidateReceiptError::InvalidSelectedCore) - } - - let para_id = self.descriptor.para_id; - - // Get a sorted vec of the core indices the parachain is assigned to at `cq_offset`. - let assigned_cores = claim_queue - .iter() - .filter_map(|(core_index, queue)| { - if queue.get(cq_offset.0 as usize)? == ¶_id { - Some(core_index) - } else { - None - } - }) - .collect::>(); - - if assigned_cores.is_empty() { - return Err(CandidateReceiptError::NoAssignment) - } - let core_index = assigned_cores .get(core_selector.0 as usize % assigned_cores.len()) - .expect("provided index is always less than queue len; qed"); + .ok_or(CandidateReceiptError::InvalidCoreIndex)?; - if **core_index != descriptor_core_index { + if *core_index != descriptor_core_index { return Err(CandidateReceiptError::CoreIndexMismatch) } @@ -869,13 +825,7 @@ mod tests { .upward_messages .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); - let mut claim_queue = BTreeMap::new(); - claim_queue.insert( - new_ccr.descriptor.core_index().unwrap(), - vec![2.into(), new_ccr.descriptor.para_id, 3.into()].into(), - ); - - assert_eq!(new_ccr.check(200, &claim_queue), Ok(())); + assert_eq!(new_ccr.check(&vec![CoreIndex(123)]), Ok(())); } #[test] @@ -897,12 +847,6 @@ mod tests { .upward_messages .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); - let mut claim_queue = BTreeMap::new(); - claim_queue.insert( - new_ccr.descriptor.core_index().unwrap(), - vec![2.into(), new_ccr.descriptor.para_id, 3.into()].into(), - ); - let encoded_ccr = new_ccr.encode(); let decoded_ccr: CommittedCandidateReceipt = Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); @@ -918,7 +862,7 @@ mod tests { Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); assert_eq!(v2_ccr.descriptor.core_index(), Some(CoreIndex(123))); - assert_eq!(new_ccr.check(200, &claim_queue), Ok(())); + assert_eq!(new_ccr.check(&vec![CoreIndex(123)]), Ok(())); assert_eq!(new_ccr.hash(), v2_ccr.hash()); } @@ -945,15 +889,9 @@ mod tests { // Since collator sig and id are zeroed, it means that the descriptor uses format // version 2. - let mut claim_queue = BTreeMap::new(); - claim_queue.insert( - new_ccr.descriptor.core_index().unwrap(), - vec![2.into(), new_ccr.descriptor.para_id(), 3.into()].into(), - ); - // We expect the check to fail in such case because there will be no `SelectCore` // commitment. - assert_eq!(new_ccr.check(200, &claim_queue), Err(CandidateReceiptError::NoCoreSelected)); + assert_eq!(new_ccr.check(&vec![CoreIndex(0)]), Err(CandidateReceiptError::NoCoreSelected)); // Adding collator signature should make it decode as v1. old_ccr.descriptor.signature = dummy_collator_signature(); From 6fb7790eb1aa7aa88acb7f355149f3f70f25b19b Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 20 Aug 2024 18:02:12 +0300 Subject: [PATCH 035/130] impl Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index e2dcf124b545..fe828c02142e 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -492,11 +492,11 @@ impl CandidateDescriptorV2 { } } -impl CommittedCandidateReceiptV2 { +impl CommittedCandidateReceiptV2 { /// Checks if descriptor core index is equal to the commited core index. /// Input `assigned_cores` must contain the sorted cores assigned to the para at /// the committed claim queue offset. - pub fn check(&self, assigned_cores: &Vec) -> Result<(), CandidateReceiptError> { + pub fn check(&self, assigned_cores: &[CoreIndex]) -> Result<(), CandidateReceiptError> { // Don't check v1 descriptors. if self.descriptor.version() == CandidateDescriptorVersion::V1 { return Ok(()) From d0b3961e3c1ab98d9d5bb4506a6af5e9273a1e2c Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 20 Aug 2024 19:19:28 +0300 Subject: [PATCH 036/130] comment Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index fe828c02142e..8503fab2ba70 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -137,7 +137,9 @@ pub struct CandidateDescriptorV2 { /// The hash of the relay-chain block this is executed in the context of. relay_parent: H, /// Version field. The raw value here is not exposed, instead it is used - /// to determine the `CandidateDescriptorVersion`, see `fn version()` + /// to determine the `CandidateDescriptorVersion`, see `fn version()`. + /// For the current version this field is set to `0` and will be incremented + /// by next versions. version: InternalVersion, /// The core index where the candidate is backed. core_index: u16, From 66f7a96d5f6eddb402873b513b4a8ab8b3d57c70 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 21 Aug 2024 02:21:16 +0300 Subject: [PATCH 037/130] add some tests Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 8503fab2ba70..aa47d9cbc3e2 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -808,6 +808,18 @@ mod tests { assert_eq!(old_ccr.hash(), new_ccr.hash()); } + #[test] + fn is_invalid_version_decodes_as_v1() { + let mut new_ccr = dummy_committed_candidate_receipt_v2(); + new_ccr.descriptor.version = InternalVersion(100); + + // Deserialize as V1. + let new_ccr: CommittedCandidateReceiptV2 = + Decode::decode(&mut new_ccr.encode().as_slice()).unwrap(); + + assert_eq!(new_ccr.descriptor.version(), CandidateDescriptorVersion::V1); + } + #[test] fn test_ump_commitment() { let mut new_ccr = dummy_committed_candidate_receipt_v2(); @@ -830,6 +842,34 @@ mod tests { assert_eq!(new_ccr.check(&vec![CoreIndex(123)]), Ok(())); } + #[test] + fn test_invalid_ump_commitment() { + let mut new_ccr = dummy_committed_candidate_receipt_v2(); + new_ccr.descriptor.core_index = 0; + new_ccr.descriptor.para_id = ParaId::new(1000); + + // separator + new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); + + + // The check should fail because no `SelectCore` signal was sent. + assert_eq!(new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), Err(CandidateReceiptError::NoCoreSelected)); + + new_ccr + .commitments + .upward_messages + .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); + // Duplicate + new_ccr + .commitments + .upward_messages + .force_push(UMPSignal::SelectCore(CoreSelector(1), ClaimQueueOffset(1)).encode()); + + // Duplicate doesn't override first signal. + assert_eq!(new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), Ok(())); + + } + #[test] fn test_version2_receipts_decoded_as_v1() { let mut new_ccr = dummy_committed_candidate_receipt_v2(); From 5c0c919114afbc0062e7c2f76af1a47a91faba92 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 21 Aug 2024 02:43:46 +0300 Subject: [PATCH 038/130] update Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 48 +++++++++++++++++-------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index aa47d9cbc3e2..623b0a1a3044 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -761,6 +761,16 @@ mod tests { vstaging::{CandidateDescriptorV2, CommittedCandidateReceiptV2}, }; + fn dummy_collator_signature() -> CollatorSignature { + CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) + .expect("64 bytes; qed") + } + + fn dummy_collator_id() -> CollatorId { + CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) + .expect("32 bytes; qed") + } + pub fn dummy_committed_candidate_receipt_v2() -> CommittedCandidateReceiptV2 { let zeros = Hash::zero(); let reserved64b = [0; 64]; @@ -811,6 +821,7 @@ mod tests { #[test] fn is_invalid_version_decodes_as_v1() { let mut new_ccr = dummy_committed_candidate_receipt_v2(); + // Put some unknown version. new_ccr.descriptor.version = InternalVersion(100); // Deserialize as V1. @@ -848,17 +859,35 @@ mod tests { new_ccr.descriptor.core_index = 0; new_ccr.descriptor.para_id = ParaId::new(1000); - // separator new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); - + new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); // The check should fail because no `SelectCore` signal was sent. - assert_eq!(new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), Err(CandidateReceiptError::NoCoreSelected)); + assert_eq!( + new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), + Err(CandidateReceiptError::NoCoreSelected) + ); + + // Garbage message. + new_ccr.commitments.upward_messages.force_push(vec![0, 13, 200].encode()); + + // No `SelectCore` can be decoded. + assert_eq!(new_ccr.commitments.selected_core(), None); + + // Failure is expected. + assert_eq!( + new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), + Err(CandidateReceiptError::NoCoreSelected) + ); + + new_ccr.commitments.upward_messages.clear(); + new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); new_ccr .commitments .upward_messages .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); + // Duplicate new_ccr .commitments @@ -867,7 +896,6 @@ mod tests { // Duplicate doesn't override first signal. assert_eq!(new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), Ok(())); - } #[test] @@ -898,7 +926,7 @@ mod tests { assert_eq!(new_ccr.hash(), decoded_ccr.hash()); - // // // Encode v1 and decode as V2 + // Encode v1 and decode as V2 let encoded_ccr = new_ccr.encode(); let v2_ccr: CommittedCandidateReceiptV2 = Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); @@ -909,16 +937,6 @@ mod tests { assert_eq!(new_ccr.hash(), v2_ccr.hash()); } - fn dummy_collator_signature() -> CollatorSignature { - CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) - .expect("64 bytes; qed") - } - - fn dummy_collator_id() -> CollatorId { - CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) - .expect("32 bytes; qed") - } - #[test] fn test_core_select_is_mandatory() { // Testing edge case when collators provide zeroed signature and collator id. From 38ce5899bf7c58a02183b0fb227db514609d0d02 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 21 Aug 2024 16:34:56 +0300 Subject: [PATCH 039/130] prdoc Signed-off-by: Andrei Sandu --- prdoc/pr_5322.prdoc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 prdoc/pr_5322.prdoc diff --git a/prdoc/pr_5322.prdoc b/prdoc/pr_5322.prdoc new file mode 100644 index 000000000000..0e262f18bf92 --- /dev/null +++ b/prdoc/pr_5322.prdoc @@ -0,0 +1,33 @@ +title: Elastic scaling: introduce new candidate receipt primitive + +doc: + - audience: [Runtime Dev, Node Dev] + description: | + Introduces `CandidateDescriptorV2` primitive as described in [RFC 103](https://github.com/polkadot-fellows/RFCs/pull/103). + Updates parachains runtime, Westend, Rococo and test runtimes to use the new primitives. + This change does not implement the functionality of the new candidate receipts. + +crates: +- name: polkadot-primitives + bump: minor +- name: polkadot-primitives-test-helpers + bump: minor +- name: polkadot-runtime-parachains + bump: major +- name: rococo-runtime + bump: major +- name: westend-runtime + bump: major +- name: polkadot-test-runtime + bump: major +- name: polkadot-service + bump: patch +- name: polkadot-node-subsystem-types + bump: patch +- name: polkadot-test-client + bump: major +- name: cumulus-relay-chain-inprocess-interface + bump: patch + + + From 9f1d611ee48726993d71b17a473a5ce835e4584e Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 21 Aug 2024 17:04:55 +0300 Subject: [PATCH 040/130] can't be happy if CI is sad Signed-off-by: Andrei Sandu --- polkadot/primitives/Cargo.toml | 1 + polkadot/primitives/src/vstaging/mod.rs | 2 +- polkadot/runtime/parachains/Cargo.toml | 2 +- prdoc/pr_5322.prdoc | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/polkadot/primitives/Cargo.toml b/polkadot/primitives/Cargo.toml index 311fc210d42b..a8cd6cb5f4e0 100644 --- a/polkadot/primitives/Cargo.toml +++ b/polkadot/primitives/Cargo.toml @@ -58,6 +58,7 @@ std = [ "sp-keystore?/std", "sp-runtime/std", "sp-staking/std", + "sp-std/std", ] runtime-benchmarks = [ "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 623b0a1a3044..61a3ddb408b6 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -312,7 +312,7 @@ impl CommittedCandidateReceiptV2 { self.to_plain().hash() } - /// Does this committed candidate receipt corresponds to the given [`CandidateReceipt`]? + /// Does this committed candidate receipt corresponds to the given [`CandidateReceiptV2`]? pub fn corresponds_to(&self, receipt: &CandidateReceiptV2) -> bool where H: PartialEq, diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml index f3123fa554ca..a3eec3f9d961 100644 --- a/polkadot/runtime/parachains/Cargo.toml +++ b/polkadot/runtime/parachains/Cargo.toml @@ -59,7 +59,7 @@ polkadot-runtime-metrics = { workspace = true } polkadot-core-primitives = { workspace = true } [dev-dependencies] -polkadot-primitives = { workspace = true, features=["test"] } +polkadot-primitives = { workspace = true, features = ["test"] } futures = { workspace = true } hex-literal = { workspace = true, default-features = true } diff --git a/prdoc/pr_5322.prdoc b/prdoc/pr_5322.prdoc index 0e262f18bf92..68991ad02c93 100644 --- a/prdoc/pr_5322.prdoc +++ b/prdoc/pr_5322.prdoc @@ -1,4 +1,4 @@ -title: Elastic scaling: introduce new candidate receipt primitive +title: Elastic scaling - introduce new candidate receipt primitive doc: - audience: [Runtime Dev, Node Dev] From 663817dd49bcba63772544b07afbddf79ccf1c54 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 21 Aug 2024 17:08:29 +0300 Subject: [PATCH 041/130] remove newlines Signed-off-by: Andrei Sandu --- prdoc/pr_5322.prdoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/prdoc/pr_5322.prdoc b/prdoc/pr_5322.prdoc index 68991ad02c93..b4cf261f33a4 100644 --- a/prdoc/pr_5322.prdoc +++ b/prdoc/pr_5322.prdoc @@ -28,6 +28,3 @@ crates: bump: major - name: cumulus-relay-chain-inprocess-interface bump: patch - - - From a1dacc1eb24a28c06c67ef8189b202df08717ff0 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 21 Aug 2024 17:10:28 +0300 Subject: [PATCH 042/130] match rfc 103 reserved field naming Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 61a3ddb408b6..af2e17d17ddf 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -146,7 +146,7 @@ pub struct CandidateDescriptorV2 { /// The session index of the candidate relay parent. session_index: SessionIndex, /// Reserved bytes. - reserved25b: [u8; 25], + reserved1: [u8; 25], /// The blake2-256 hash of the persisted validation data. This is extra data derived from /// relay-chain state which may vary based on bitfields included before the candidate. /// Thus it cannot be derived entirely from the relay-parent. @@ -156,7 +156,7 @@ pub struct CandidateDescriptorV2 { /// The root of a block's erasure encoding Merkle tree. erasure_root: Hash, /// Reserved bytes. - reserved64b: [u8; 64], + reserved2: [u8; 64], /// Hash of the para header that is being generated by this candidate. para_head: Hash, /// The blake2-256 hash of the validation code bytes. @@ -198,11 +198,11 @@ impl CandidateDescriptorV2 { version: InternalVersion(0), core_index: core_index.0 as u16, session_index, - reserved25b: [0; 25], + reserved1: [0; 25], persisted_validation_data_hash, pov_hash, erasure_root, - reserved64b: [0; 64], + reserved2: [0; 64], para_head, validation_code_hash, } @@ -428,7 +428,7 @@ impl CandidateDescriptorV2 { /// The candidate is at version 2 if the reserved fields are zeroed out /// and the internal `version` field is 0. pub fn version(&self) -> CandidateDescriptorVersion { - if self.reserved64b != [0u8; 64] || self.reserved25b != [0u8; 25] { + if self.reserved2 != [0u8; 64] || self.reserved1 != [0u8; 25] { return CandidateDescriptorVersion::V1 } @@ -446,7 +446,7 @@ impl CandidateDescriptorV2 { collator_id.push(self.version.0); collator_id.extend_from_slice(core_index.as_slice()); collator_id.extend_from_slice(session_index.as_slice()); - collator_id.extend_from_slice(self.reserved25b.as_slice()); + collator_id.extend_from_slice(self.reserved1.as_slice()); CollatorId::from_slice(&collator_id.as_slice()) .expect("Slice size is exactly 32 bytes; qed") @@ -462,7 +462,7 @@ impl CandidateDescriptorV2 { } fn rebuild_signature_field(&self) -> CollatorSignature { - CollatorSignature::from_slice(self.reserved64b.as_slice()) + CollatorSignature::from_slice(self.reserved2.as_slice()) .expect("Slice size is exactly 64 bytes; qed") } @@ -773,7 +773,7 @@ mod tests { pub fn dummy_committed_candidate_receipt_v2() -> CommittedCandidateReceiptV2 { let zeros = Hash::zero(); - let reserved64b = [0; 64]; + let reserved2 = [0; 64]; CommittedCandidateReceiptV2 { descriptor: CandidateDescriptorV2 { @@ -782,11 +782,11 @@ mod tests { version: InternalVersion(0), core_index: 123, session_index: 1, - reserved25b: Default::default(), + reserved1: Default::default(), persisted_validation_data_hash: zeros, pov_hash: zeros, erasure_root: zeros, - reserved64b, + reserved2, para_head: zeros, validation_code_hash: ValidationCode(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]).hash(), }, From 33b80ea99d4e53d9dd897a90fa3a6e373379825f Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 21 Aug 2024 17:14:39 +0300 Subject: [PATCH 043/130] remove default cq offset Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index af2e17d17ddf..962c9a467fe7 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -357,9 +357,6 @@ pub struct CoreSelector(pub u8); #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] pub struct ClaimQueueOffset(pub u8); -/// Default claim queue offset -pub const DEFAULT_CLAIM_QUEUE_OFFSET: ClaimQueueOffset = ClaimQueueOffset(1); - /// Signals that a parachain can send to the relay chain via the UMP queue. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] pub enum UMPSignal { From 29e4b47355408ff0712f190ee67a0fb0b19a079c Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 16 Aug 2024 18:36:11 +0300 Subject: [PATCH 044/130] Ignore UMP signals when checking and processing UMP queue Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/inclusion/mod.rs | 10 ++++++++++ polkadot/runtime/parachains/src/ump_tests.rs | 12 ++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index d3edad7b3d6c..4dbd0ea638ef 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -925,6 +925,15 @@ impl Pallet { para: ParaId, upward_messages: &[UpwardMessage], ) -> Result<(), UmpAcceptanceCheckErr> { + // Filter any pending UMP signals and the separator. + let upward_messages = if let Some(separator_index) = + upward_messages.iter().rposition(|message| message.is_empty()) + { + upward_messages.split_at(separator_index).0 + } else { + upward_messages + }; + // Cannot send UMP messages while off-boarding. if paras::Pallet::::is_offboarding(para) { ensure!(upward_messages.is_empty(), UmpAcceptanceCheckErr::IsOffboarding); @@ -979,6 +988,7 @@ impl Pallet { pub(crate) fn receive_upward_messages(para: ParaId, upward_messages: &[Vec]) -> Weight { let bounded = upward_messages .iter() + .take_while(|message| !message.is_empty()) .filter_map(|d| { BoundedSlice::try_from(&d[..]) .map_err(|e| { diff --git a/polkadot/runtime/parachains/src/ump_tests.rs b/polkadot/runtime/parachains/src/ump_tests.rs index d914bf8b6661..71494a3faf67 100644 --- a/polkadot/runtime/parachains/src/ump_tests.rs +++ b/polkadot/runtime/parachains/src/ump_tests.rs @@ -141,12 +141,12 @@ mod check_upward_messages { configuration::ActiveConfig::::get().max_upward_message_num_per_candidate; for sent in 0..permitted + 1 { - check(P_0, vec![msg(""); sent as usize], None); + check(P_0, vec![msg("a"); sent as usize], None); } for sent in permitted + 1..permitted + 10 { check( P_0, - vec![msg(""); sent as usize], + vec![msg("a"); sent as usize], Some(UmpAcceptanceCheckErr::MoreMessagesThanPermitted { sent, permitted }), ); } @@ -185,18 +185,18 @@ mod check_upward_messages { let limit = configuration::ActiveConfig::::get().max_upward_queue_count as u64; for _ in 0..limit { - check(P_0, vec![msg("")], None); - queue(P_0, vec![msg("")]); + check(P_0, vec![msg("a")], None); + queue(P_0, vec![msg("a")]); } check( P_0, - vec![msg("")], + vec![msg("a")], Some(UmpAcceptanceCheckErr::CapacityExceeded { count: limit + 1, limit }), ); check( P_0, - vec![msg(""); 2], + vec![msg("a"); 2], Some(UmpAcceptanceCheckErr::CapacityExceeded { count: limit + 2, limit }), ); }); From ab85fe346f94af7927441cadeed3b763f324d92f Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 20 Aug 2024 18:00:34 +0300 Subject: [PATCH 045/130] wip Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/inclusion/mod.rs | 1 + .../parachains/src/paras_inherent/mod.rs | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index 4dbd0ea638ef..f9f54790b570 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -988,6 +988,7 @@ impl Pallet { pub(crate) fn receive_upward_messages(para: ParaId, upward_messages: &[Vec]) -> Weight { let bounded = upward_messages .iter() + // Stop once we hit the `UMPSignal`` separator. .take_while(|message| !message.is_empty()) .filter_map(|d| { BoundedSlice::try_from(&d[..]) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 2bcc2d873131..f191c690a583 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -45,6 +45,7 @@ use frame_support::{ pallet_prelude::*, traits::Randomness, }; + use frame_system::pallet_prelude::*; use pallet_babe::{self, ParentBlockRandomness}; use polkadot_primitives::{ @@ -977,6 +978,9 @@ fn sanitize_backed_candidates( // Map the candidates to the right paraids, while making sure that the order between candidates // of the same para is preserved. let mut candidates_per_para: BTreeMap> = BTreeMap::new(); + + // Get the paras scheduled next on each core. + let scheduled_paras = scheduler::Pallet::::scheduled_paras().collect::>(); for candidate in backed_candidates { // Drop any v2 candidate receipts if nodes are not allowed to use them. // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure @@ -992,6 +996,68 @@ fn sanitize_backed_candidates( continue } + if candidate.descriptor().version() == CandidateDescriptorVersion::V2 { + let current_block_num = frame_system::Pallet::::block_number(); + let Some((_core_selector, cq_offset)) = + candidate.candidate().commitments.selected_core() + else { + log::debug!( + target: LOG_TARGET, + "Dropping candidate {:?} for paraid {:?}, no `CoreSelector` commitment.", + candidate.candidate().hash(), + candidate.descriptor().para_id() + ); + + continue + }; + + // Get the relay parent number for the candidate: + let Some((_state_root, relay_parent_num)) = + allowed_relay_parents.acquire_info(candidate.descriptor().relay_parent(), None) + else { + log::debug!( + target: LOG_TARGET, + "Relay parent {:?} for candidate {:?} is not in the allowed relay parents.", + candidate.descriptor().relay_parent(), + candidate.candidate().hash(), + ); + continue + }; + + let expected_cq_offset = current_block_num - relay_parent_num - One::one(); + // Drop the v2 candidate receipt if the core claim has not reached the top of the + // claim queue. + if expected_cq_offset == (cq_offset.0 as u32).into() { + log::debug!( + target: LOG_TARGET, + "Dropped candidate {:?} of paraid {:?} because the claimed core is not at top \ + of the claim queue, cq_offset: {:?}, relay_parent_num: {:?}", + candidate.candidate().hash(), + candidate.descriptor().para_id(), + cq_offset, + relay_parent_num + ); + } + + let assigned_cores = scheduled_paras + .iter() + .filter(|(core_index, para)| **para == candidate.descriptor().para_id()) + .collect::>(); + + // Check if core index in descriptoir matches the one in commitments + if let Err(err) = candidate.candidate().check(&assigned_cores) { + log::debug!( + target: LOG_TARGET, + "Dropping candidate {:?} for paraid {:?}, {:?}", + candidate.candidate().hash(), + candidate.descriptor().para_id(), + err, + ); + + continue + } + } + candidates_per_para .entry(candidate.descriptor().para_id()) .or_default() From 7d5636bfbb74ca81970a30149a5fcc4859fe5e61 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 20 Aug 2024 18:14:22 +0300 Subject: [PATCH 046/130] refactor a bit Signed-off-by: Andrei Sandu --- .../parachains/src/paras_inherent/mod.rs | 172 ++++++++++-------- 1 file changed, 99 insertions(+), 73 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index f191c690a583..84d4f4a7a234 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -949,6 +949,99 @@ pub(crate) fn sanitize_bitfields( bitfields } +/// Perform required checks for given version 2 candidate receipt. +/// Returns `true` if candidate has passed all checks. +fn sanitize_backed_candidate_v2( + candidate: &BackedCandidate, + allowed_relay_parents: &AllowedRelayParentsTracker>, + scheduled_paras: &BTreeMap, + allow_v2_receipts: bool, +) -> bool { + // Drop any v2 candidate receipts if nodes are not allowed to use them. + // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure + // any v1 descendants of v2 candidates are dropped. + if !allow_v2_receipts && candidate.descriptor().version() == CandidateDescriptorVersion::V2 { + log::debug!( + target: LOG_TARGET, + "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", + candidate.candidate().hash(), + candidate.descriptor().para_id() + ); + return false + } + + if candidate.descriptor().version() == CandidateDescriptorVersion::V1 { + return true; + } + + let current_block_num = frame_system::Pallet::::block_number(); + let Some((_core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() + else { + log::debug!( + target: LOG_TARGET, + "Dropping candidate {:?} for paraid {:?}, no `CoreSelector` commitment.", + candidate.candidate().hash(), + candidate.descriptor().para_id() + ); + + return false + }; + + // Get the relay parent number for the candidate: + let Some((_state_root, relay_parent_num)) = + allowed_relay_parents.acquire_info(candidate.descriptor().relay_parent(), None) + else { + log::debug!( + target: LOG_TARGET, + "Relay parent {:?} for candidate {:?} is not in the allowed relay parents.", + candidate.descriptor().relay_parent(), + candidate.candidate().hash(), + ); + return false + }; + + let expected_cq_offset = current_block_num - relay_parent_num - One::one(); + // Drop the v2 candidate receipt if the core claim has not reached the top of the + // claim queue. + if expected_cq_offset != (cq_offset.0 as u32).into() { + log::debug!( + target: LOG_TARGET, + "Dropped candidate {:?} of paraid {:?} because the claimed core is not at top \ + of the claim queue, cq_offset: {:?}, relay_parent_num: {:?}", + candidate.candidate().hash(), + candidate.descriptor().para_id(), + cq_offset, + relay_parent_num + ); + return false + } + + let assigned_cores = scheduled_paras + .iter() + .filter_map(|(core_index, para)| { + if *para == candidate.descriptor().para_id() { + Some(*core_index) + } else { + None + } + }) + .collect::>(); + + // Check if core index in descriptoir matches the one in commitments + if let Err(err) = candidate.candidate().check(&assigned_cores) { + log::debug!( + target: LOG_TARGET, + "Dropping candidate {:?} for paraid {:?}, {:?}", + candidate.candidate().hash(), + candidate.descriptor().para_id(), + err, + ); + + return false + } + true +} + /// Performs various filtering on the backed candidates inherent data. /// Must maintain the invariant that the returned candidate collection contains the candidates /// sorted in dependency order for each para. When doing any filtering, we must therefore drop any @@ -982,82 +1075,15 @@ fn sanitize_backed_candidates( // Get the paras scheduled next on each core. let scheduled_paras = scheduler::Pallet::::scheduled_paras().collect::>(); for candidate in backed_candidates { - // Drop any v2 candidate receipts if nodes are not allowed to use them. - // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure - // any v1 descendants of v2 candidates are dropped. - if !allow_v2_receipts && candidate.descriptor().version() == CandidateDescriptorVersion::V2 - { - log::debug!( - target: LOG_TARGET, - "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", - candidate.candidate().hash(), - candidate.descriptor().para_id() - ); + if !sanitize_backed_candidate_v2::( + &candidate, + allowed_relay_parents, + &scheduled_paras, + allow_v2_receipts, + ) { continue } - if candidate.descriptor().version() == CandidateDescriptorVersion::V2 { - let current_block_num = frame_system::Pallet::::block_number(); - let Some((_core_selector, cq_offset)) = - candidate.candidate().commitments.selected_core() - else { - log::debug!( - target: LOG_TARGET, - "Dropping candidate {:?} for paraid {:?}, no `CoreSelector` commitment.", - candidate.candidate().hash(), - candidate.descriptor().para_id() - ); - - continue - }; - - // Get the relay parent number for the candidate: - let Some((_state_root, relay_parent_num)) = - allowed_relay_parents.acquire_info(candidate.descriptor().relay_parent(), None) - else { - log::debug!( - target: LOG_TARGET, - "Relay parent {:?} for candidate {:?} is not in the allowed relay parents.", - candidate.descriptor().relay_parent(), - candidate.candidate().hash(), - ); - continue - }; - - let expected_cq_offset = current_block_num - relay_parent_num - One::one(); - // Drop the v2 candidate receipt if the core claim has not reached the top of the - // claim queue. - if expected_cq_offset == (cq_offset.0 as u32).into() { - log::debug!( - target: LOG_TARGET, - "Dropped candidate {:?} of paraid {:?} because the claimed core is not at top \ - of the claim queue, cq_offset: {:?}, relay_parent_num: {:?}", - candidate.candidate().hash(), - candidate.descriptor().para_id(), - cq_offset, - relay_parent_num - ); - } - - let assigned_cores = scheduled_paras - .iter() - .filter(|(core_index, para)| **para == candidate.descriptor().para_id()) - .collect::>(); - - // Check if core index in descriptoir matches the one in commitments - if let Err(err) = candidate.candidate().check(&assigned_cores) { - log::debug!( - target: LOG_TARGET, - "Dropping candidate {:?} for paraid {:?}, {:?}", - candidate.candidate().hash(), - candidate.descriptor().para_id(), - err, - ); - - continue - } - } - candidates_per_para .entry(candidate.descriptor().para_id()) .or_default() From 2954bba27f4de28b8a7d8a760cc14d7e29ed15a5 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 20 Aug 2024 18:45:04 +0300 Subject: [PATCH 047/130] use descriptor core_index in `map_candidates_to_cores` Signed-off-by: Andrei Sandu --- .../parachains/src/paras_inherent/mod.rs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 84d4f4a7a234..44346519490b 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -957,6 +957,10 @@ fn sanitize_backed_candidate_v2( scheduled_paras: &BTreeMap, allow_v2_receipts: bool, ) -> bool { + if candidate.descriptor().version() == CandidateDescriptorVersion::V1 { + return true; + } + // Drop any v2 candidate receipts if nodes are not allowed to use them. // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure // any v1 descendants of v2 candidates are dropped. @@ -970,10 +974,6 @@ fn sanitize_backed_candidate_v2( return false } - if candidate.descriptor().version() == CandidateDescriptorVersion::V1 { - return true; - } - let current_block_num = frame_system::Pallet::::block_number(); let Some((_core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() else { @@ -1496,10 +1496,18 @@ fn map_candidates_to_cores = - get_injected_core_index::(allowed_relay_parents, &candidate); - if let Some(core_index) = maybe_injected_core_index { + // If candidate is v2, use the descriptor core index. We've already checked the + // core index is valid in `sanitize_backed_candidate_v2`. If candidate is v1, + // expect an injected core index. + let maybe_core_index = + if candidate.descriptor().version() == CandidateDescriptorVersion::V2 { + candidate.descriptor().core_index() + } else { + get_injected_core_index::(allowed_relay_parents, &candidate) + }; + + if let Some(core_index) = maybe_core_index { if scheduled_cores.remove(&core_index) { temp_backed_candidates.push((candidate, core_index)); } else { @@ -1508,7 +1516,7 @@ fn map_candidates_to_cores Date: Wed, 21 Aug 2024 02:52:04 +0300 Subject: [PATCH 048/130] nits Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/paras_inherent/mod.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 44346519490b..763464cb8111 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -949,8 +949,14 @@ pub(crate) fn sanitize_bitfields( bitfields } -/// Perform required checks for given version 2 candidate receipt. -/// Returns `true` if candidate has passed all checks. +/// Perform required checks for given candidate receipt. +/// +/// Returns `true` if candidate descriptor is version 1. +/// +/// For version 2 it returns `false` if: +/// - version 2 descriptors are not allowed +/// - the core index doesn't match the one computed from the commitments +/// - the `SelectCore` signal does not refer to a core at the top of claim queue fn sanitize_backed_candidate_v2( candidate: &BackedCandidate, allowed_relay_parents: &AllowedRelayParentsTracker>, @@ -964,7 +970,7 @@ fn sanitize_backed_candidate_v2( // Drop any v2 candidate receipts if nodes are not allowed to use them. // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure // any v1 descendants of v2 candidates are dropped. - if !allow_v2_receipts && candidate.descriptor().version() == CandidateDescriptorVersion::V2 { + if !allow_v2_receipts { log::debug!( target: LOG_TARGET, "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", @@ -1027,7 +1033,7 @@ fn sanitize_backed_candidate_v2( }) .collect::>(); - // Check if core index in descriptoir matches the one in commitments + // Check if core index in descriptor matches the one in the commitments if let Err(err) = candidate.candidate().check(&assigned_cores) { log::debug!( target: LOG_TARGET, From 1db5eb0e1c1c8ec45a320f4cc510543e4129efad Mon Sep 17 00:00:00 2001 From: Andrei Sandu <54316454+sandreim@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:23:49 +0300 Subject: [PATCH 049/130] Para Inherent: filter v2 candidate descriptors (#5362) On top of https://github.com/paritytech/polkadot-sdk/pull/5322 This is an additional check to prevent nodes from passing the v2 candidate descriptors in the runtime until it is enabled via the node feature. TODO: - [ ] PRDoc --------- Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 20 +++- polkadot/primitives/test-helpers/src/lib.rs | 10 +- polkadot/runtime/parachains/src/builder.rs | 87 ++++++++++---- .../runtime/parachains/src/inclusion/tests.rs | 38 +++--- .../parachains/src/paras_inherent/mod.rs | 35 +++++- .../parachains/src/paras_inherent/tests.rs | 108 +++++++++++++++++- 6 files changed, 243 insertions(+), 55 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 962c9a467fe7..8d97ddb57fc5 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -34,7 +34,6 @@ use sp_arithmetic::Perbill; use sp_core::RuntimeDebug; use sp_runtime::traits::Header as HeaderT; use sp_staking::SessionIndex; - /// Async backing primitives pub mod async_backing; @@ -179,6 +178,13 @@ impl From> for CandidateDescriptor { } } +#[cfg(any(feature = "runtime-benchmarks", feature = "test"))] +impl From> for CandidateDescriptorV2 { + fn from(value: CandidateDescriptor) -> Self { + Decode::decode(&mut value.encode().as_slice()).unwrap() + } +} + impl CandidateDescriptorV2 { /// Constructor pub fn new( @@ -213,6 +219,12 @@ impl CandidateDescriptorV2 { pub fn set_pov_hash(&mut self, pov_hash: Hash) { self.pov_hash = pov_hash; } + + /// Set the version in the descriptor. Only for tests. + #[cfg(feature = "test")] + pub fn set_version(&mut self, version: InternalVersion) { + self.version = version; + } } /// A candidate-receipt at version 2. @@ -573,6 +585,12 @@ impl BackedCandidate { &self.candidate.descriptor } + /// Get a mutable reference to the descriptor of the candidate. Only for testing. + #[cfg(feature = "test")] + pub fn descriptor_mut(&mut self) -> &mut CandidateDescriptorV2 { + &mut self.candidate.descriptor + } + /// Get a reference to the validity votes of the candidate. pub fn validity_votes(&self) -> &[ValidityAttestation] { &self.validity_votes diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index cb644372f758..b0f78717dd97 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -170,16 +170,16 @@ pub fn dummy_head_data() -> HeadData { HeadData(vec![]) } -/// Create a meaningless collator id. -pub fn dummy_collator() -> CollatorId { - CollatorId::from(sr25519::Public::default()) -} - /// Create a meaningless validator id. pub fn dummy_validator() -> ValidatorId { ValidatorId::from(sr25519::Public::default()) } +/// Create a meaningless collator id. +pub fn dummy_collator() -> CollatorId { + CollatorId::from(sr25519::Public::default()) +} + /// Create a meaningless collator signature. pub fn dummy_collator_signature() -> CollatorSignature { CollatorSignature::from(sr25519::Signature::default()) diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index ebc956a08e67..35835793ce9d 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -32,27 +32,38 @@ use frame_system::pallet_prelude::*; use polkadot_primitives::{ node_features::FeatureIndex, vstaging::{ - BackedCandidate, CandidateDescriptorV2 as CandidateDescriptor, + BackedCandidate, CandidateDescriptorV2, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, InherentData as ParachainsInherentData, }, - AvailabilityBitfield, CandidateCommitments, CandidateHash, CompactStatement, CoreIndex, - DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, Id as ParaId, IndexedVec, - InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, SigningContext, - UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, - ValidityAttestation, + AvailabilityBitfield, CandidateCommitments, CandidateDescriptor, CandidateHash, CollatorId, + CollatorSignature, CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, + GroupIndex, HeadData, Id as ParaId, IndexedVec, InvalidDisputeStatementKind, + PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned, + ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation, }; -use sp_core::H256; +use sp_core::{ByteArray, H256}; use sp_runtime::{ generic::Digest, traits::{Header as HeaderT, One, TrailingZeroInput, Zero}, RuntimeAppPublic, }; - fn mock_validation_code() -> ValidationCode { ValidationCode(vec![1, 2, 3]) } +// Create a dummy collator id suitable to be used in a V1 candidate descriptor. +fn junk_collator() -> CollatorId { + CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) + .expect("32 bytes; qed") +} + +// Creates a dummy collator signature suitable to be used in a V1 candidate descriptor. +fn junk_collator_signature() -> CollatorSignature { + CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) + .expect("64 bytes; qed") +} + /// Grab an account, seeded by a name and index. /// /// This is directly from frame-benchmarking. Copy/pasted so we can use it when not compiling with @@ -116,6 +127,8 @@ pub(crate) struct BenchBuilder { fill_claimqueue: bool, /// Cores which should not be available when being populated with pending candidates. unavailable_cores: Vec, + /// Use v2 candidate descriptor. + candidate_descriptor_v2: bool, _phantom: core::marker::PhantomData, } @@ -147,6 +160,7 @@ impl BenchBuilder { code_upgrade: None, fill_claimqueue: true, unavailable_cores: vec![], + candidate_descriptor_v2: false, _phantom: core::marker::PhantomData::, } } @@ -254,6 +268,12 @@ impl BenchBuilder { self } + /// Toggle usage of v2 candidate descriptors. + pub(crate) fn set_candidate_descriptor_v2(mut self, enable: bool) -> Self { + self.candidate_descriptor_v2 = enable; + self + } + /// Get the maximum number of validators per core. fn max_validators_per_core(&self) -> u32 { self.max_validators_per_core.unwrap_or(Self::fallback_max_validators_per_core()) @@ -289,18 +309,20 @@ impl BenchBuilder { HeadData(vec![0xFF; max_head_size as usize]) } - fn candidate_descriptor_mock() -> CandidateDescriptor { - CandidateDescriptor::::new( - 0.into(), - Default::default(), - CoreIndex(0), - 1, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - mock_validation_code().hash(), - ) + fn candidate_descriptor_mock() -> CandidateDescriptorV2 { + // Use a v1 descriptor. + CandidateDescriptor:: { + para_id: 0.into(), + relay_parent: Default::default(), + collator: junk_collator(), + persisted_validation_data_hash: Default::default(), + pov_hash: Default::default(), + erasure_root: Default::default(), + signature: junk_collator_signature(), + para_head: Default::default(), + validation_code_hash: mock_validation_code().hash(), + } + .into() } /// Create a mock of `CandidatePendingAvailability`. @@ -625,18 +647,35 @@ impl BenchBuilder { let group_validators = scheduler::Pallet::::group_validators(group_idx).unwrap(); - let candidate = CommittedCandidateReceipt:: { - descriptor: CandidateDescriptor::::new( + let descriptor = if self.candidate_descriptor_v2 { + CandidateDescriptorV2::new( para_id, relay_parent, - CoreIndex(0), + core_idx, 1, persisted_validation_data_hash, pov_hash, Default::default(), head_data.hash(), validation_code_hash, - ), + ) + } else { + CandidateDescriptor:: { + para_id, + relay_parent, + collator: junk_collator(), + persisted_validation_data_hash, + pov_hash, + erasure_root: Default::default(), + signature: junk_collator_signature(), + para_head: head_data.hash(), + validation_code_hash, + } + .into() + }; + + let candidate = CommittedCandidateReceipt:: { + descriptor, commitments: CandidateCommitments:: { upward_messages: Default::default(), horizontal_messages: Default::default(), diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index 2125dffe2592..f17b8ed2e0e9 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -26,7 +26,7 @@ use crate::{ shared::AllowedRelayParentsTracker, }; use polkadot_primitives::{ - effective_minimum_backing_votes, vstaging::CandidateDescriptorV2, AvailabilityBitfield, + effective_minimum_backing_votes, AvailabilityBitfield, CandidateDescriptor, SignedAvailabilityBitfields, UncheckedSignedAvailabilityBitfields, }; @@ -34,12 +34,13 @@ use assert_matches::assert_matches; use codec::DecodeAll; use frame_support::assert_noop; use polkadot_primitives::{ - BlockNumber, CandidateCommitments, CollatorId, CompactStatement as Statement, Hash, - SignedAvailabilityBitfield, SignedStatement, ValidationCode, ValidatorId, ValidityAttestation, - PARACHAIN_KEY_TYPE_ID, + BlockNumber, CandidateCommitments, CollatorId, CollatorSignature, + CompactStatement as Statement, Hash, SignedAvailabilityBitfield, SignedStatement, + ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, }; use polkadot_primitives_test_helpers::dummy_validation_code; use sc_keystore::LocalKeystore; +use sp_core::ByteArray; use sp_keyring::Sr25519Keyring; use sp_keystore::{Keystore, KeystorePtr}; use std::sync::Arc; @@ -283,17 +284,24 @@ impl std::default::Default for TestCandidateBuilder { impl TestCandidateBuilder { pub(crate) fn build(self) -> CommittedCandidateReceipt { CommittedCandidateReceipt { - descriptor: CandidateDescriptorV2::new( - self.para_id, - self.relay_parent, - CoreIndex(0), - 1, - self.persisted_validation_data_hash, - self.pov_hash, - Default::default(), - self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), - self.validation_code.hash(), - ), + descriptor: CandidateDescriptor { + para_id: self.para_id, + pov_hash: self.pov_hash, + relay_parent: self.relay_parent, + persisted_validation_data_hash: self.persisted_validation_data_hash, + validation_code_hash: self.validation_code.hash(), + para_head: self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), + erasure_root: Default::default(), + signature: CollatorSignature::from_slice( + &mut (0..64).into_iter().collect::>().as_slice(), + ) + .expect("64 bytes; qed"), + collator: CollatorId::from_slice( + &mut (0..32).into_iter().collect::>().as_slice(), + ) + .expect("32 bytes; qed"), + } + .into(), commitments: CandidateCommitments { head_data: self.head_data, new_validation_code: self.new_validation_code, diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 66330674898b..2bcc2d873131 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -51,7 +51,7 @@ use polkadot_primitives::{ effective_minimum_backing_votes, node_features::FeatureIndex, vstaging::{ - BackedCandidate, CandidateReceiptV2 as CandidateReceipt, + BackedCandidate, CandidateDescriptorVersion, CandidateReceiptV2 as CandidateReceipt, InherentData as ParachainsInherentData, ScrapedOnChainVotes, }, CandidateHash, CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CoreIndex, @@ -575,6 +575,12 @@ impl Pallet { .map(|b| *b) .unwrap_or(false); + let allow_v2_receipts = configuration::ActiveConfig::::get() + .node_features + .get(FeatureIndex::CandidateReceiptV2 as usize) + .map(|b| *b) + .unwrap_or(false); + let mut eligible: BTreeMap> = BTreeMap::new(); let mut total_eligible_cores = 0; @@ -591,6 +597,7 @@ impl Pallet { concluded_invalid_hashes, eligible, core_index_enabled, + allow_v2_receipts, ); let count = count_backed_candidates(&backed_candidates_with_core); @@ -947,14 +954,15 @@ pub(crate) fn sanitize_bitfields( /// subsequent candidates after the filtered one. /// /// Filter out: -/// 1. any candidates which don't form a chain with the other candidates of the paraid (even if they +/// 1. Candidates that have v2 descriptors if the node `CandidateReceiptV2` feature is not enabled. +/// 2. any candidates which don't form a chain with the other candidates of the paraid (even if they /// do form a chain but are not in the right order). -/// 2. any candidates that have a concluded invalid dispute or who are descendants of a concluded +/// 3. any candidates that have a concluded invalid dispute or who are descendants of a concluded /// invalid candidate. -/// 3. any unscheduled candidates, as well as candidates whose paraid has multiple cores assigned +/// 4. any unscheduled candidates, as well as candidates whose paraid has multiple cores assigned /// but have no injected core index. -/// 4. all backing votes from disabled validators -/// 5. any candidates that end up with less than `effective_minimum_backing_votes` backing votes +/// 5. all backing votes from disabled validators +/// 6. any candidates that end up with less than `effective_minimum_backing_votes` backing votes /// /// Returns the scheduled /// backed candidates which passed filtering, mapped by para id and in the right dependency order. @@ -964,11 +972,26 @@ fn sanitize_backed_candidates( concluded_invalid_with_descendants: BTreeSet, scheduled: BTreeMap>, core_index_enabled: bool, + allow_v2_receipts: bool, ) -> BTreeMap, CoreIndex)>> { // Map the candidates to the right paraids, while making sure that the order between candidates // of the same para is preserved. let mut candidates_per_para: BTreeMap> = BTreeMap::new(); for candidate in backed_candidates { + // Drop any v2 candidate receipts if nodes are not allowed to use them. + // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure + // any v1 descendants of v2 candidates are dropped. + if !allow_v2_receipts && candidate.descriptor().version() == CandidateDescriptorVersion::V2 + { + log::debug!( + target: LOG_TARGET, + "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", + candidate.candidate().hash(), + candidate.descriptor().para_id() + ); + continue + } + candidates_per_para .entry(candidate.descriptor().para_id()) .or_default() diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 6c82233e0820..c0e1636569a8 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -58,7 +58,10 @@ mod enter { use core::panic; use frame_support::assert_ok; use frame_system::limits; - use polkadot_primitives::{vstaging::SchedulerParams, AvailabilityBitfield, UncheckedSigned}; + use polkadot_primitives::{ + vstaging::{InternalVersion, SchedulerParams}, + AvailabilityBitfield, UncheckedSigned, + }; use sp_runtime::Perbill; struct TestConfig { @@ -70,6 +73,7 @@ mod enter { fill_claimqueue: bool, elastic_paras: BTreeMap, unavailable_cores: Vec, + v2_descriptor: bool, } fn make_inherent_data( @@ -82,6 +86,7 @@ mod enter { fill_claimqueue, elastic_paras, unavailable_cores, + v2_descriptor, }: TestConfig, ) -> Bench { let extra_cores = elastic_paras @@ -99,7 +104,8 @@ mod enter { .set_backed_and_concluding_paras(backed_and_concluding.clone()) .set_dispute_sessions(&dispute_sessions[..]) .set_fill_claimqueue(fill_claimqueue) - .set_unavailable_cores(unavailable_cores); + .set_unavailable_cores(unavailable_cores) + .set_candidate_descriptor_v2(v2_descriptor); // Setup some assignments as needed: mock_assigner::Pallet::::set_core_count(builder.max_cores()); @@ -145,6 +151,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); // We expect the scenario to have cores 0 & 1 with pending availability. The backed @@ -240,6 +247,7 @@ mod enter { fill_claimqueue: false, elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -344,6 +352,7 @@ mod enter { fill_claimqueue: true, elastic_paras: [(2, 4)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), + v2_descriptor: false, }); let mut expected_para_inherent_data = scenario.data.clone(); @@ -600,6 +609,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -673,6 +683,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -744,6 +755,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -831,6 +843,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -918,6 +931,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1004,6 +1018,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1111,6 +1126,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1179,6 +1195,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1245,6 +1262,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1348,6 +1366,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let mut para_inherent_data = scenario.data.clone(); @@ -1437,6 +1456,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1465,6 +1485,76 @@ mod enter { assert_eq!(dispatch_error, Error::::InherentOverweight.into()); }); } + + #[test] + fn v2_descriptors_are_filtered() { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::ElasticScalingMVP as u8, + true, + ) + .unwrap(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); + + let unavailable_cores = vec![]; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + fill_claimqueue: true, + // 8 cores ! + elastic_paras: [(2, 8)].into_iter().collect(), + unavailable_cores: unavailable_cores.clone(), + v2_descriptor: true, + }); + + let mut unfiltered_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 10 backed candidates) + assert_eq!(unfiltered_para_inherent_data.bitfields.len(), 50); + // * 10 v2 candidate descriptors. + assert_eq!(unfiltered_para_inherent_data.backed_candidates.len(), 10); + + // Make the last candidate look like v1, by using an unknown version. + unfiltered_para_inherent_data.backed_candidates[9] + .descriptor_mut() + .set_version(InternalVersion(123)); + + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) + .unwrap(); + + // We expect all backed candidates to be filtered out. + let filtered_para_inherend_data = + Pallet::::create_inherent_inner(&inherent_data).unwrap(); + + assert_eq!(filtered_para_inherend_data.backed_candidates.len(), 0); + + let dispatch_error = Pallet::::enter( + frame_system::RawOrigin::None.into(), + unfiltered_para_inherent_data, + ) + .unwrap_err() + .error; + + // We expect `enter` to fail because the inherent data contains backed candidates with + // v2 descriptors. + assert_eq!(dispatch_error, Error::::CandidatesFilteredDuringExecution.into()); + }); + } } fn default_header() -> polkadot_primitives::Header { @@ -3376,7 +3466,8 @@ mod sanitizers { &shared::AllowedRelayParents::::get(), BTreeSet::new(), scheduled, - core_index_enabled + core_index_enabled, + false, ), expected_backed_candidates_with_core, ); @@ -3400,7 +3491,8 @@ mod sanitizers { &shared::AllowedRelayParents::::get(), BTreeSet::new(), scheduled, - core_index_enabled + core_index_enabled, + false, ), expected_backed_candidates_with_core, ); @@ -3425,6 +3517,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ), expected_backed_candidates_with_core ); @@ -3457,6 +3550,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ), expected_backed_candidates_with_core ); @@ -3497,6 +3591,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ); if core_index_enabled { @@ -3567,6 +3662,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ); if core_index_enabled { @@ -3605,6 +3701,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, + false, ); assert!(sanitized_backed_candidates.is_empty()); @@ -3641,6 +3738,7 @@ mod sanitizers { set, scheduled, core_index_enabled, + false, ); assert_eq!(sanitized_backed_candidates.len(), backed_candidates.len() / 2); @@ -3678,6 +3776,7 @@ mod sanitizers { invalid_set, scheduled, true, + false, ); // We'll be left with candidates from paraid 2 and 4. @@ -3714,6 +3813,7 @@ mod sanitizers { invalid_set, scheduled, true, + false, ); // Only the second candidate of paraid 1 should be removed. From cdb49a690efe5b1ad4d62138ff160aaa772309f8 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 22 Aug 2024 14:01:21 +0300 Subject: [PATCH 050/130] increase test coverage Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/builder.rs | 102 +++++++++++----- .../parachains/src/paras_inherent/tests.rs | 115 ++++++++++++++++-- 2 files changed, 175 insertions(+), 42 deletions(-) diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 35835793ce9d..72d93f15c499 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -32,9 +32,9 @@ use frame_system::pallet_prelude::*; use polkadot_primitives::{ node_features::FeatureIndex, vstaging::{ - BackedCandidate, CandidateDescriptorV2, - CommittedCandidateReceiptV2 as CommittedCandidateReceipt, - InherentData as ParachainsInherentData, + BackedCandidate, CandidateDescriptorV2, ClaimQueueOffset, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreSelector, + InherentData as ParachainsInherentData, UMPSignal, UMP_SEPARATOR, }, AvailabilityBitfield, CandidateCommitments, CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, @@ -309,20 +309,34 @@ impl BenchBuilder { HeadData(vec![0xFF; max_head_size as usize]) } - fn candidate_descriptor_mock() -> CandidateDescriptorV2 { - // Use a v1 descriptor. - CandidateDescriptor:: { - para_id: 0.into(), - relay_parent: Default::default(), - collator: junk_collator(), - persisted_validation_data_hash: Default::default(), - pov_hash: Default::default(), - erasure_root: Default::default(), - signature: junk_collator_signature(), - para_head: Default::default(), - validation_code_hash: mock_validation_code().hash(), + fn candidate_descriptor_mock(candidate_descriptor_v2: bool) -> CandidateDescriptorV2 { + if candidate_descriptor_v2 { + CandidateDescriptorV2::new( + 0.into(), + Default::default(), + CoreIndex(200), + 1, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + mock_validation_code().hash(), + ) + } else { + // Convert v1 to v2. + CandidateDescriptor:: { + para_id: 0.into(), + relay_parent: Default::default(), + collator: junk_collator(), + persisted_validation_data_hash: Default::default(), + pov_hash: Default::default(), + erasure_root: Default::default(), + signature: junk_collator_signature(), + para_head: Default::default(), + validation_code_hash: mock_validation_code().hash(), + } + .into() } - .into() } /// Create a mock of `CandidatePendingAvailability`. @@ -332,17 +346,19 @@ impl BenchBuilder { candidate_hash: CandidateHash, availability_votes: BitVec, commitments: CandidateCommitments, + candidate_descriptor_v2: bool, ) -> inclusion::CandidatePendingAvailability> { inclusion::CandidatePendingAvailability::>::new( - core_idx, // core - candidate_hash, // hash - Self::candidate_descriptor_mock(), // candidate descriptor - commitments, // commitments - availability_votes, // availability votes - Default::default(), // backers - Zero::zero(), // relay parent - One::one(), // relay chain block this was backed in - group_idx, // backing group + core_idx, // core + candidate_hash, // hash + Self::candidate_descriptor_mock(candidate_descriptor_v2), // candidate descriptor + commitments, // commitments + availability_votes, // availability votes + Default::default(), // backers + Zero::zero(), // relay parent + One::one(), /* relay chain block this + * was backed in */ + group_idx, // backing group ) } @@ -357,6 +373,7 @@ impl BenchBuilder { group_idx: GroupIndex, availability_votes: BitVec, candidate_hash: CandidateHash, + candidate_descriptor_v2: bool, ) { let commitments = CandidateCommitments:: { upward_messages: Default::default(), @@ -372,6 +389,7 @@ impl BenchBuilder { candidate_hash, availability_votes, commitments, + candidate_descriptor_v2, ); inclusion::PendingAvailability::::mutate(para_id, |maybe_andidates| { if let Some(candidates) = maybe_andidates { @@ -545,6 +563,7 @@ impl BenchBuilder { // No validators have made this candidate available yet. bitvec::bitvec![u8, bitvec::order::Lsb0; 0; validators.len()], CandidateHash(H256::from(byte32_slice_from(current_core_idx))), + self.candidate_descriptor_v2, ); if !self.unavailable_cores.contains(¤t_core_idx) { concluding_cores.insert(current_core_idx); @@ -674,7 +693,7 @@ impl BenchBuilder { .into() }; - let candidate = CommittedCandidateReceipt:: { + let mut candidate = CommittedCandidateReceipt:: { descriptor, commitments: CandidateCommitments:: { upward_messages: Default::default(), @@ -687,6 +706,22 @@ impl BenchBuilder { }, }; + if self.candidate_descriptor_v2 { + // `UMPSignal` separator. + candidate.commitments.upward_messages.force_push(UMP_SEPARATOR); + + // `SelectCore` commitment. + // Claim queue offset must be `0` so this candidate is for the very + // next block. + candidate.commitments.upward_messages.force_push( + UMPSignal::SelectCore( + CoreSelector(chain_idx as u8), + ClaimQueueOffset(0), + ) + .encode(), + ); + } + let candidate_hash = candidate.hash(); let validity_votes: Vec<_> = group_validators @@ -706,12 +741,14 @@ impl BenchBuilder { }) .collect(); - // Check if the elastic scaling bit is set, if so we need to supply the core - // index in the generated candidate. - let core_idx = configuration::ActiveConfig::::get() - .node_features - .get(FeatureIndex::ElasticScalingMVP as usize) - .map(|_the_bit| core_idx); + let core_idx = if self.candidate_descriptor_v2 { + None + } else { + configuration::ActiveConfig::::get() + .node_features + .get(FeatureIndex::ElasticScalingMVP as usize) + .and_then(|the_bit| if *the_bit { Some(core_idx) } else { None }) + }; BackedCandidate::::new( candidate, @@ -764,6 +801,7 @@ impl BenchBuilder { group_idx, Self::validator_availability_votes_yes(validators.len()), candidate_hash, + self.candidate_descriptor_v2, ); let statements_len = diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index c0e1636569a8..ef466491c1ef 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -15,12 +15,15 @@ // along with Polkadot. If not, see . use super::*; +use rstest::rstest; use crate::{ configuration::{self, HostConfiguration}, mock::MockGenesisConfig, }; -use polkadot_primitives::vstaging::SchedulerParams; +use polkadot_primitives::vstaging::{ + ClaimQueueOffset, CoreSelector, SchedulerParams, UMPSignal, UMP_SEPARATOR, +}; fn default_config() -> MockGenesisConfig { MockGenesisConfig { @@ -127,15 +130,25 @@ mod enter { } } - #[test] + #[rstest] + #[case(true)] + #[case(false)] // Validate that if we create 2 backed candidates which are assigned to 2 cores that will be // freed via becoming fully available, the backed candidates will not be filtered out in // `create_inherent` and will not cause `enter` to early. - fn include_backed_candidates() { + fn include_backed_candidates(#[case] v2_descriptor: bool) { let config = MockGenesisConfig::default(); assert!(config.configuration.config.scheduler_params.lookahead > 0); new_test_ext(config).execute_with(|| { + // Enable the v2 receipts. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + v2_descriptor, + ) + .unwrap(); + let dispute_statements = BTreeMap::new(); let mut backed_and_concluding = BTreeMap::new(); @@ -151,7 +164,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], - v2_descriptor: false, + v2_descriptor, }); // We expect the scenario to have cores 0 & 1 with pending availability. The backed @@ -213,8 +226,10 @@ mod enter { }); } - #[test] - fn include_backed_candidates_elastic_scaling() { + #[rstest] + #[case(true)] + #[case(false)] + fn include_backed_candidates_elastic_scaling(#[case] v2_descriptor: bool) { // ParaId 0 has one pending candidate on core 0. // ParaId 1 has one pending candidate on core 1. // ParaId 2 has three pending candidates on cores 2, 3 and 4. @@ -231,6 +246,14 @@ mod enter { ) .unwrap(); + // Enable the v2 receipts. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + v2_descriptor, + ) + .unwrap(); + let dispute_statements = BTreeMap::new(); let mut backed_and_concluding = BTreeMap::new(); @@ -247,7 +270,7 @@ mod enter { fill_claimqueue: false, elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: vec![], - v2_descriptor: false, + v2_descriptor, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1329,6 +1352,15 @@ mod enter { ccr.commitments.processed_downward_messages = idx as u32; let core_index = start_core_index + idx; + // `UMPSignal` separator. + ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); + + // `SelectCore` commitment. + // Claim queue offset must be `0`` so this candidate is for the very next block. + ccr.commitments.upward_messages.force_push( + UMPSignal::SelectCore(CoreSelector(idx as u8), ClaimQueueOffset(0)).encode(), + ); + BackedCandidate::new( ccr.into(), Default::default(), @@ -1341,8 +1373,10 @@ mod enter { // Ensure that overweight parachain inherents are always rejected by the runtime. // Runtime should panic and return `InherentOverweight` error. - #[test] - fn test_backed_candidates_apply_weight_works_for_elastic_scaling() { + #[rstest] + #[case(true)] + #[case(false)] + fn test_backed_candidates_apply_weight_works_for_elastic_scaling(#[case] v2_descriptor: bool) { new_test_ext(MockGenesisConfig::default()).execute_with(|| { let seed = [ 1, 0, 52, 0, 0, 0, 0, 0, 1, 0, 10, 0, 22, 32, 0, 0, 2, 0, 55, 49, 0, 11, 0, 0, 3, @@ -1353,6 +1387,14 @@ mod enter { // Create an overweight inherent and oversized block let mut backed_and_concluding = BTreeMap::new(); + // Enable the v2 receipts. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + v2_descriptor, + ) + .unwrap(); + for i in 0..30 { backed_and_concluding.insert(i, i); } @@ -1366,7 +1408,7 @@ mod enter { fill_claimqueue: false, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], - v2_descriptor: false, + v2_descriptor, }); let mut para_inherent_data = scenario.data.clone(); @@ -1555,6 +1597,59 @@ mod enter { assert_eq!(dispatch_error, Error::::CandidatesFilteredDuringExecution.into()); }); } + + #[test] + fn v2_descriptors_are_accepted() { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::ElasticScalingMVP as u8, + true, + ) + .unwrap(); + + // Enable the v2 receipts. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + true, + ) + .unwrap(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); + + let unavailable_cores = vec![]; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 1, + code_upgrade: None, + fill_claimqueue: true, + // 8 cores ! + elastic_paras: [(2, 3)].into_iter().collect(), + unavailable_cores: unavailable_cores.clone(), + v2_descriptor: false, + }); + + let inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (2 validators per core, 5 backed candidates) + assert_eq!(inherent_data.bitfields.len(), 5); + // * 5 v2 candidate descriptors. + assert_eq!(inherent_data.backed_candidates.len(), 5); + + Pallet::::enter(frame_system::RawOrigin::None.into(), inherent_data).unwrap(); + }); + } } fn default_header() -> polkadot_primitives::Header { From aa925cd40c1cf2af4875acd38a01ee0225e49a72 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 23 Aug 2024 15:26:50 +0300 Subject: [PATCH 051/130] Improve usability of primitives Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 40 ++++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 8d97ddb57fc5..a236f054e1aa 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -398,6 +398,25 @@ impl CandidateCommitments { UMPSignal::SelectCore(core_selector, cq_offset) => Some((core_selector, cq_offset)), } } + + /// Returns the core index determined by `UMPSignal::SelectCore` commitment + /// and `assigned_cores`. + /// + /// Returns `None` if there is no `UMPSignal::SelectCore` commitment or + /// assigned cores is empty. + /// + /// `assigned_cores` must be soted vec of all core indices assigned to a parachain. + pub fn committed_core_index(&self, assigned_cores: &[&CoreIndex]) -> Option { + if assigned_cores.is_empty() { + return None + } + + self.selected_core().and_then(|(core_selector, _cq_offset)| { + let core_index = + **assigned_cores.get(core_selector.0 as usize % assigned_cores.len())?; + Some(core_index) + }) + } } /// CandidateReceipt construction errors. @@ -507,9 +526,11 @@ impl CommittedCandidateReceiptV2 { /// Checks if descriptor core index is equal to the commited core index. /// Input `assigned_cores` must contain the sorted cores assigned to the para at /// the committed claim queue offset. - pub fn check(&self, assigned_cores: &[CoreIndex]) -> Result<(), CandidateReceiptError> { - // Don't check v1 descriptors. - if self.descriptor.version() == CandidateDescriptorVersion::V1 { + pub fn check(&self, assigned_cores: &[&CoreIndex]) -> Result<(), CandidateReceiptError> { + // Don't check v1 descriptors without any `SelectCore` commitments. + if self.descriptor.version() == CandidateDescriptorVersion::V1 && + self.commitments.selected_core().is_none() + { return Ok(()) } @@ -518,15 +539,12 @@ impl CommittedCandidateReceiptV2 { } let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); + let core_index = self + .commitments + .committed_core_index(assigned_cores) + .ok_or(CandidateReceiptError::NoAssignment)?; - let (core_selector, _cq_offset) = - self.commitments.selected_core().ok_or(CandidateReceiptError::NoCoreSelected)?; - - let core_index = assigned_cores - .get(core_selector.0 as usize % assigned_cores.len()) - .ok_or(CandidateReceiptError::InvalidCoreIndex)?; - - if *core_index != descriptor_core_index { + if core_index != descriptor_core_index { return Err(CandidateReceiptError::CoreIndexMismatch) } From 00d7c710c01ae893617b5dfa6211ad9700caea9d Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 23 Aug 2024 15:28:02 +0300 Subject: [PATCH 052/130] use committed core index if available in v1 receipts Signed-off-by: Andrei Sandu --- .../parachains/src/paras_inherent/mod.rs | 114 +++++++++++------- 1 file changed, 71 insertions(+), 43 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 763464cb8111..99ae574a8c99 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -951,11 +951,12 @@ pub(crate) fn sanitize_bitfields( /// Perform required checks for given candidate receipt. /// -/// Returns `true` if candidate descriptor is version 1. +/// Returns `true` if candidate descriptor is version 1 without `UMPSignal` +/// commitments. /// -/// For version 2 it returns `false` if: +/// Otherwise returns `false` if: /// - version 2 descriptors are not allowed -/// - the core index doesn't match the one computed from the commitments +/// - the core index in descriptor doesn't match the one computed from the commitments /// - the `SelectCore` signal does not refer to a core at the top of claim queue fn sanitize_backed_candidate_v2( candidate: &BackedCandidate, @@ -963,37 +964,43 @@ fn sanitize_backed_candidate_v2( scheduled_paras: &BTreeMap, allow_v2_receipts: bool, ) -> bool { - if candidate.descriptor().version() == CandidateDescriptorVersion::V1 { - return true; - } + // We move forward only if the candidate commits to a core selector and claim queue offset. + // If parachain runtime already makes use of `UMPSignal::SelectCore`, and the collator does not, + // we can expect v1 candidate receipts with `UMPSignal::SelectCore` commitments. + // + // It is important that we use these commitments of v1 receipts aand not rely on injected cores. + // Parachain runtime upgrade should be enough to enable both validators and the runtime + // to also validate the core index the candidate has committed to. + let Some((core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() else { + if candidate.descriptor().version() == CandidateDescriptorVersion::V1 { + return true + } - // Drop any v2 candidate receipts if nodes are not allowed to use them. - // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure - // any v1 descendants of v2 candidates are dropped. - if !allow_v2_receipts { log::debug!( target: LOG_TARGET, - "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", + "Dropping V2 candidate receipt {:?} for paraid {:?}, no `SelectCore` commitment.", candidate.candidate().hash(), candidate.descriptor().para_id() ); + return false - } + }; - let current_block_num = frame_system::Pallet::::block_number(); - let Some((_core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() - else { + // Drop any candidate receipts with `UMPSignal::SelectCore` commitments if nodes are not allowed + // to use them. + // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure + // any v1 descendants of v2 candidates are dropped. + if !allow_v2_receipts { log::debug!( target: LOG_TARGET, - "Dropping candidate {:?} for paraid {:?}, no `CoreSelector` commitment.", + "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", candidate.candidate().hash(), candidate.descriptor().para_id() ); - return false - }; + } - // Get the relay parent number for the candidate: + // Get the relay parent number for the candidate let Some((_state_root, relay_parent_num)) = allowed_relay_parents.acquire_info(candidate.descriptor().relay_parent(), None) else { @@ -1006,8 +1013,10 @@ fn sanitize_backed_candidate_v2( return false }; + let current_block_num = frame_system::Pallet::::block_number(); let expected_cq_offset = current_block_num - relay_parent_num - One::one(); - // Drop the v2 candidate receipt if the core claim has not reached the top of the + + // Drop the candidate receipt if the core claim has not reached the top of the // claim queue. if expected_cq_offset != (cq_offset.0 as u32).into() { log::debug!( @@ -1022,25 +1031,30 @@ fn sanitize_backed_candidate_v2( return false } - let assigned_cores = scheduled_paras - .iter() - .filter_map(|(core_index, para)| { - if *para == candidate.descriptor().para_id() { - Some(*core_index) - } else { - None - } - }) - .collect::>(); + let assigned_cores = + scheduled_paras + .iter() + .filter_map(|(core_index, para)| { + if *para == candidate.descriptor().para_id() { + Some(core_index) + } else { + None + } + }) + .collect::>(); + let assigned_cores = assigned_cores.as_slice(); // Check if core index in descriptor matches the one in the commitments - if let Err(err) = candidate.candidate().check(&assigned_cores) { + // No-op for v1 candidate receipts. + if let Err(err) = candidate.candidate().check(assigned_cores) { log::debug!( target: LOG_TARGET, - "Dropping candidate {:?} for paraid {:?}, {:?}", + "Dropping candidate {:?} for paraid {:?}, {:?}, core_selector={:?}, cq_offset={:?}", candidate.candidate().hash(), candidate.descriptor().para_id(), err, + core_selector, + cq_offset, ); return false @@ -1284,6 +1298,7 @@ fn filter_backed_statements_from_disabled_validators< // 1. Core index assigned to the parachain which has produced the candidate // 2. The relay chain block number of the candidate retain_candidates::(backed_candidates_with_core, |para_id, (bc, core_idx)| { + // `CoreIndex` not used, we just need a copy to write it back later. let (validator_indices, maybe_core_index) = bc.validator_indices_and_core_index(core_index_enabled); let mut validator_indices = BitVec::<_>::from(validator_indices); @@ -1491,6 +1506,11 @@ fn map_candidates_to_cores(allowed_relay_parents, &candidate) - }; - - if let Some(core_index) = maybe_core_index { + if let Some(core_index) = + get_core_index::(allowed_relay_parents, &candidate, &assigned_cores) + { if scheduled_cores.remove(&core_index) { temp_backed_candidates.push((candidate, core_index)); } else { @@ -1573,6 +1585,22 @@ fn map_candidates_to_cores( + allowed_relay_parents: &AllowedRelayParentsTracker>, + candidate: &BackedCandidate, + assigned_cores: &BTreeSet, +) -> Option { + // Use the committed core index. It could be available even if descriptor is v1. + // We've already sanitized the candidate so it should be ok to trust it is valid. + // Fall back to injected core index. + candidate + .candidate() + .commitments + .committed_core_index(assigned_cores.iter().collect::>().as_slice()) + .or_else(|| get_injected_core_index::(allowed_relay_parents, &candidate)) +} + fn get_injected_core_index( allowed_relay_parents: &AllowedRelayParentsTracker>, candidate: &BackedCandidate, From af9f5617c40c9380999810f084522cc56e60c302 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 23 Aug 2024 15:29:24 +0300 Subject: [PATCH 053/130] typo Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index a236f054e1aa..9bbc63a31138 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -405,7 +405,7 @@ impl CandidateCommitments { /// Returns `None` if there is no `UMPSignal::SelectCore` commitment or /// assigned cores is empty. /// - /// `assigned_cores` must be soted vec of all core indices assigned to a parachain. + /// `assigned_cores` must be a sorted vec of all core indices assigned to a parachain. pub fn committed_core_index(&self, assigned_cores: &[&CoreIndex]) -> Option { if assigned_cores.is_empty() { return None From fb2cefb31a267f21c27028086bf9ce62fae99837 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 23 Aug 2024 15:33:01 +0300 Subject: [PATCH 054/130] fix check Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 9bbc63a31138..cab5801ade46 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -538,16 +538,20 @@ impl CommittedCandidateReceiptV2 { return Err(CandidateReceiptError::NoAssignment) } - let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); let core_index = self .commitments .committed_core_index(assigned_cores) .ok_or(CandidateReceiptError::NoAssignment)?; - if core_index != descriptor_core_index { - return Err(CandidateReceiptError::CoreIndexMismatch) + // Only check descriptor `core_index` field of v2 descriptors. If it is v1, that field + // will be garbage. + if self.descriptor.version() == CandidateDescriptorVersion::V2 { + let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); + if core_index != descriptor_core_index { + return Err(CandidateReceiptError::CoreIndexMismatch) + } } - + Ok(()) } } From b53787d47a1489df0e01c32e0d3ff63bce7d9c2a Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 23 Aug 2024 15:36:00 +0300 Subject: [PATCH 055/130] typo Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 99ae574a8c99..37d7bcb32ea3 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -968,7 +968,7 @@ fn sanitize_backed_candidate_v2( // If parachain runtime already makes use of `UMPSignal::SelectCore`, and the collator does not, // we can expect v1 candidate receipts with `UMPSignal::SelectCore` commitments. // - // It is important that we use these commitments of v1 receipts aand not rely on injected cores. + // It is important that we use these commitments of v1 receipts and not rely on injected cores. // Parachain runtime upgrade should be enough to enable both validators and the runtime // to also validate the core index the candidate has committed to. let Some((core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() else { From e2ef46ebd9aadb645024343b280c01320c6875f2 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 26 Aug 2024 17:43:05 +0300 Subject: [PATCH 056/130] add test for mixed v1 v2 scenario Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 50 +++++++++++-- polkadot/runtime/parachains/src/builder.rs | 8 +- .../parachains/src/paras_inherent/tests.rs | 73 ++++++++++++++++++- 3 files changed, 118 insertions(+), 13 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index cab5801ade46..e8b51d6b2202 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -534,6 +534,10 @@ impl CommittedCandidateReceiptV2 { return Ok(()) } + if self.commitments.selected_core().is_none() { + return Err(CandidateReceiptError::NoCoreSelected) + } + if assigned_cores.is_empty() { return Err(CandidateReceiptError::NoAssignment) } @@ -551,7 +555,7 @@ impl CommittedCandidateReceiptV2 { return Err(CandidateReceiptError::CoreIndexMismatch) } } - + Ok(()) } } @@ -887,7 +891,7 @@ mod tests { .upward_messages .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); - assert_eq!(new_ccr.check(&vec![CoreIndex(123)]), Ok(())); + assert_eq!(new_ccr.check(&vec![&CoreIndex(123)]), Ok(())); } #[test] @@ -901,7 +905,7 @@ mod tests { // The check should fail because no `SelectCore` signal was sent. assert_eq!( - new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), + new_ccr.check(&vec![&CoreIndex(0), &CoreIndex(100)]), Err(CandidateReceiptError::NoCoreSelected) ); @@ -913,7 +917,7 @@ mod tests { // Failure is expected. assert_eq!( - new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), + new_ccr.check(&vec![&CoreIndex(0), &CoreIndex(100)]), Err(CandidateReceiptError::NoCoreSelected) ); @@ -932,7 +936,7 @@ mod tests { .force_push(UMPSignal::SelectCore(CoreSelector(1), ClaimQueueOffset(1)).encode()); // Duplicate doesn't override first signal. - assert_eq!(new_ccr.check(&vec![CoreIndex(0), CoreIndex(100)]), Ok(())); + assert_eq!(new_ccr.check(&vec![&CoreIndex(0), &CoreIndex(100)]), Ok(())); } #[test] @@ -969,11 +973,43 @@ mod tests { Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); assert_eq!(v2_ccr.descriptor.core_index(), Some(CoreIndex(123))); - assert_eq!(new_ccr.check(&vec![CoreIndex(123)]), Ok(())); + assert_eq!(new_ccr.check(&vec![&CoreIndex(123)]), Ok(())); assert_eq!(new_ccr.hash(), v2_ccr.hash()); } + // Only check descriptor `core_index` field of v2 descriptors. If it is v1, that field + // will be garbage. + #[test] + fn test_v1_descriptors_with_ump_signal() { + let mut ccr = dummy_old_committed_candidate_receipt(); + ccr.descriptor.para_id = ParaId::new(1024); + // Adding collator signature should make it decode as v1. + ccr.descriptor.signature = dummy_collator_signature(); + ccr.descriptor.collator = dummy_collator_id(); + + ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); + ccr.commitments + .upward_messages + .force_push(UMPSignal::SelectCore(CoreSelector(1), ClaimQueueOffset(1)).encode()); + + let encoded_ccr: Vec = ccr.encode(); + + let v1_ccr: CommittedCandidateReceiptV2 = + Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); + + assert_eq!(v1_ccr.descriptor.version(), CandidateDescriptorVersion::V1); + assert!(v1_ccr.commitments.selected_core().is_some()); + assert!(v1_ccr.check(&vec![&CoreIndex(0), &CoreIndex(1)]).is_ok()); + + assert_eq!( + v1_ccr.commitments.committed_core_index(&vec![&CoreIndex(10), &CoreIndex(5)]), + Some(CoreIndex(5)), + ); + + assert_eq!(v1_ccr.descriptor.core_index(), None); + } + #[test] fn test_core_select_is_mandatory() { // Testing edge case when collators provide zeroed signature and collator id. @@ -988,7 +1024,7 @@ mod tests { // version 2. // We expect the check to fail in such case because there will be no `SelectCore` // commitment. - assert_eq!(new_ccr.check(&vec![CoreIndex(0)]), Err(CandidateReceiptError::NoCoreSelected)); + assert_eq!(new_ccr.check(&vec![&CoreIndex(0)]), Err(CandidateReceiptError::NoCoreSelected)); // Adding collator signature should make it decode as v1. old_ccr.descriptor.signature = dummy_collator_signature(); diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 72d93f15c499..7c5e5d7ad307 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -52,14 +52,14 @@ fn mock_validation_code() -> ValidationCode { ValidationCode(vec![1, 2, 3]) } -// Create a dummy collator id suitable to be used in a V1 candidate descriptor. -fn junk_collator() -> CollatorId { +/// Create a dummy collator id suitable to be used in a V1 candidate descriptor. +pub fn junk_collator() -> CollatorId { CollatorId::from_slice(&mut (0..32).into_iter().collect::>().as_slice()) .expect("32 bytes; qed") } -// Creates a dummy collator signature suitable to be used in a V1 candidate descriptor. -fn junk_collator_signature() -> CollatorSignature { +/// Creates a dummy collator signature suitable to be used in a V1 candidate descriptor. +pub fn junk_collator_signature() -> CollatorSignature { CollatorSignature::from_slice(&mut (0..64).into_iter().collect::>().as_slice()) .expect("64 bytes; qed") } diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index ef466491c1ef..6700ab5307bc 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -48,7 +48,7 @@ fn default_config() -> MockGenesisConfig { mod enter { use super::{inclusion::tests::TestCandidateBuilder, *}; use crate::{ - builder::{Bench, BenchBuilder}, + builder::{junk_collator, junk_collator_signature, Bench, BenchBuilder}, mock::{mock_assigner, new_test_ext, BlockLength, BlockWeights, RuntimeOrigin, Test}, scheduler::{ common::{Assignment, AssignmentProvider}, @@ -63,7 +63,7 @@ mod enter { use frame_system::limits; use polkadot_primitives::{ vstaging::{InternalVersion, SchedulerParams}, - AvailabilityBitfield, UncheckedSigned, + AvailabilityBitfield, CandidateDescriptor, UncheckedSigned, }; use sp_runtime::Perbill; @@ -1650,6 +1650,75 @@ mod enter { Pallet::::enter(frame_system::RawOrigin::None.into(), inherent_data).unwrap(); }); } + + // Test when parachain runtime is upgraded to support the new commitments + // but some collators are not and provide v1 descriptors. + #[test] + fn elastic_scaling_mixed_v1_v2_descriptors() { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::ElasticScalingMVP as u8, + true, + ) + .unwrap(); + + // Enable the v2 receipts. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + true, + ) + .unwrap(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); + + let unavailable_cores = vec![]; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 1, + code_upgrade: None, + fill_claimqueue: true, + // 3 cores + elastic_paras: [(2, 3)].into_iter().collect(), + unavailable_cores: unavailable_cores.clone(), + v2_descriptor: false, + }); + + let mut inherent_data = scenario.data.clone(); + let candidate_count = inherent_data.backed_candidates.len(); + + // Make last 2 candidates v1 + for index in candidate_count - 2..candidate_count { + let encoded = inherent_data.backed_candidates[index].descriptor().encode(); + + let mut decoded: CandidateDescriptor = + Decode::decode(&mut encoded.as_slice()).unwrap(); + decoded.collator = junk_collator(); + decoded.signature = junk_collator_signature(); + + *inherent_data.backed_candidates[index].descriptor_mut() = + Decode::decode(&mut encoded.as_slice()).unwrap(); + } + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (2 validators per core, 5 backed candidates) + assert_eq!(inherent_data.bitfields.len(), 5); + // * 5 v2 candidate descriptors. + assert_eq!(inherent_data.backed_candidates.len(), 5); + + Pallet::::enter(frame_system::RawOrigin::None.into(), inherent_data).unwrap(); + }); + } } fn default_header() -> polkadot_primitives::Header { From 2dfc5420a1510bb875c3a4bf56c3058abc384c29 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 26 Aug 2024 17:47:07 +0300 Subject: [PATCH 057/130] comment Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 37d7bcb32ea3..6e52287e4714 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -969,8 +969,8 @@ fn sanitize_backed_candidate_v2( // we can expect v1 candidate receipts with `UMPSignal::SelectCore` commitments. // // It is important that we use these commitments of v1 receipts and not rely on injected cores. - // Parachain runtime upgrade should be enough to enable both validators and the runtime - // to also validate the core index the candidate has committed to. + // Parachain runtime upgrade is enough to enable both validators and the runtime to validate + // the core index the candidate has committed to. let Some((core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() else { if candidate.descriptor().version() == CandidateDescriptorVersion::V1 { return true From a38a2434ad4448ef38312ae910f46055ed510ae2 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 26 Aug 2024 18:34:19 +0300 Subject: [PATCH 058/130] add ump test Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/ump_tests.rs | 41 +++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/ump_tests.rs b/polkadot/runtime/parachains/src/ump_tests.rs index 71494a3faf67..a687515d330e 100644 --- a/polkadot/runtime/parachains/src/ump_tests.rs +++ b/polkadot/runtime/parachains/src/ump_tests.rs @@ -31,7 +31,10 @@ use frame_support::{ traits::{EnqueueMessage, ExecuteOverweightError, ServiceQueues}, weights::Weight, }; -use polkadot_primitives::{well_known_keys, Id as ParaId, UpwardMessage}; +use polkadot_primitives::{ + vstaging::{ClaimQueueOffset, CoreSelector, UMPSignal, UMP_SEPARATOR}, + well_known_keys, Id as ParaId, UpwardMessage, +}; use sp_crypto_hashing::{blake2_256, twox_64}; use sp_runtime::traits::Bounded; @@ -641,6 +644,42 @@ fn cannot_offboard_while_ump_dispatch_queued() { }); } +/// A para-chain cannot send an UMP to the relay chain while it is offboarding. +#[test] +fn enqueue_ump_signals() { + let para = 100.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + register_parachain(para); + run_to_block(5, vec![4, 5]); + + let config = configuration::ActiveConfig::::get(); + let mut messages = (0..config.max_upward_message_num_per_candidate) + .into_iter() + .map(|_| "msg".encode()) + .collect::>(); + let expected_messages = messages.iter().cloned().map(|msg| (para, msg)).collect::>(); + + // `UMPSignals` and separator do not count as XCM messages. The below check must pass. + messages.append(&mut vec![ + UMP_SEPARATOR, + UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(0)).encode(), + ]); + + ParaInclusion::check_upward_messages( + &configuration::ActiveConfig::::get(), + para, + &messages, + ) + .unwrap(); + + // We expect that all messages except UMP signal and separator are processed + ParaInclusion::receive_upward_messages(para, &messages); + MessageQueue::service_queues(Weight::max_value()); + assert_eq!(Processed::take(), expected_messages); + }); +} + /// A para-chain cannot send an UMP to the relay chain while it is offboarding. #[test] fn cannot_enqueue_ump_while_offboarding() { From da381da70f5492af8c8dae308b608940358271f4 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 26 Aug 2024 18:58:05 +0300 Subject: [PATCH 059/130] avoid one storage read Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 6e52287e4714..c5fa5f482a3b 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -1092,8 +1092,13 @@ fn sanitize_backed_candidates( // of the same para is preserved. let mut candidates_per_para: BTreeMap> = BTreeMap::new(); - // Get the paras scheduled next on each core. - let scheduled_paras = scheduler::Pallet::::scheduled_paras().collect::>(); + // Get the eligible paras for each core. + let scheduled_paras = scheduled + .iter() + .map(|(para_id, cores)| cores.iter().map(|core| (*core, *para_id))) + .flatten() + .collect(); + for candidate in backed_candidates { if !sanitize_backed_candidate_v2::( &candidate, From ca5c61832b01d58f70faf7743b3c5f4830b15110 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 27 Aug 2024 23:48:11 +0300 Subject: [PATCH 060/130] store claim queue snapshot in allowed relay parent info Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/shared.rs | 34 +++++++++++++------ .../runtime/parachains/src/shared/tests.rs | 18 +++++----- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index 154b7cfefc3a..7330fcea72c1 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -25,7 +25,7 @@ use alloc::{ }; use frame_support::{pallet_prelude::*, traits::DisabledValidators}; use frame_system::pallet_prelude::BlockNumberFor; -use polkadot_primitives::{SessionIndex, ValidatorId, ValidatorIndex}; +use polkadot_primitives::{CoreIndex, Id, SessionIndex, ValidatorId, ValidatorIndex}; use sp_runtime::traits::AtLeast32BitUnsigned; use rand::{seq::SliceRandom, SeedableRng}; @@ -43,16 +43,25 @@ pub(crate) const SESSION_DELAY: SessionIndex = 2; #[cfg(test)] mod tests; -/// Information about past relay-parents. +/// Information about a relay parent. +#[derive(Encode, Decode, Default, TypeInfo, Debug)] +pub struct RelayParentInfo { + // Relay parent hash + pub relay_parent: Hash, + // The state root at this block + pub state_root: Hash, + // Claim queue snapshot + pub claim_queue: BTreeMap>, +} + +/// Keeps tracks of information about all viable relay parents. #[derive(Encode, Decode, Default, TypeInfo)] pub struct AllowedRelayParentsTracker { - // The past relay parents, paired with state roots, that are viable to build upon. + // Information about past relay parents that are viable to build upon. // // They are in ascending chronologic order, so the newest relay parents are at // the back of the deque. - // - // (relay_parent, state_root) - buffer: VecDeque<(Hash, Hash)>, + buffer: VecDeque>, // The number of the most recent relay-parent, if any. // If the buffer is empty, this value has no meaning and may @@ -70,13 +79,15 @@ impl &mut self, relay_parent: Hash, state_root: Hash, + claim_queue: BTreeMap>, number: BlockNumber, max_ancestry_len: u32, ) { // + 1 for the most recent block, which is always allowed. let buffer_size_limit = max_ancestry_len as usize + 1; - self.buffer.push_back((relay_parent, state_root)); + self.buffer.push_back(RelayParentInfo { relay_parent, state_root, claim_queue }); + self.latest_number = number; while self.buffer.len() > buffer_size_limit { let _ = self.buffer.pop_front(); @@ -96,8 +107,8 @@ impl &self, relay_parent: Hash, prev: Option, - ) -> Option<(Hash, BlockNumber)> { - let pos = self.buffer.iter().position(|(rp, _)| rp == &relay_parent)?; + ) -> Option<(&RelayParentInfo, BlockNumber)> { + let pos = self.buffer.iter().position(|info| info.relay_parent == relay_parent)?; let age = (self.buffer.len() - 1) - pos; let number = self.latest_number - BlockNumber::from(age as u32); @@ -107,7 +118,7 @@ impl } } - Some((self.buffer[pos].1, number)) + Some((&self.buffer[pos], number)) } /// Returns block number of the earliest block the buffer would contain if @@ -263,11 +274,12 @@ impl Pallet { pub(crate) fn add_allowed_relay_parent( relay_parent: T::Hash, state_root: T::Hash, + claim_queue: BTreeMap>, number: BlockNumberFor, max_ancestry_len: u32, ) { AllowedRelayParents::::mutate(|tracker| { - tracker.update(relay_parent, state_root, number, max_ancestry_len) + tracker.update(relay_parent, state_root, claim_queue, number, max_ancestry_len) }) } } diff --git a/polkadot/runtime/parachains/src/shared/tests.rs b/polkadot/runtime/parachains/src/shared/tests.rs index e47d1fd9cfe0..fd4b6555a48c 100644 --- a/polkadot/runtime/parachains/src/shared/tests.rs +++ b/polkadot/runtime/parachains/src/shared/tests.rs @@ -36,19 +36,19 @@ fn tracker_earliest_block_number() { // Push a single block into the tracker, suppose max capacity is 1. let max_ancestry_len = 0; - tracker.update(Hash::zero(), Hash::zero(), 0, max_ancestry_len); + tracker.update(Hash::zero(), Hash::zero(), Default::default(), 0, max_ancestry_len); assert_eq!(tracker.hypothetical_earliest_block_number(now, max_ancestry_len), now); // Test a greater capacity. let max_ancestry_len = 4; let now = 4; for i in 1..now { - tracker.update(Hash::zero(), Hash::zero(), i, max_ancestry_len); + tracker.update(Hash::zero(), Hash::zero(), Default::default(), i, max_ancestry_len); assert_eq!(tracker.hypothetical_earliest_block_number(i + 1, max_ancestry_len), 0); } // Capacity exceeded. - tracker.update(Hash::zero(), Hash::zero(), now, max_ancestry_len); + tracker.update(Hash::zero(), Hash::zero(), Default::default(), now, max_ancestry_len); assert_eq!(tracker.hypothetical_earliest_block_number(now + 1, max_ancestry_len), 1); } @@ -65,20 +65,20 @@ fn tracker_acquire_info() { ]; let (relay_parent, state_root) = blocks[0]; - tracker.update(relay_parent, state_root, 0, max_ancestry_len); + tracker.update(relay_parent, state_root, Default::default(), 0, max_ancestry_len); assert_matches!( tracker.acquire_info(relay_parent, None), - Some((s, b)) if s == state_root && b == 0 + Some((s, b)) if s.state_root == state_root && b == 0 ); let (relay_parent, state_root) = blocks[1]; - tracker.update(relay_parent, state_root, 1u32, max_ancestry_len); + tracker.update(relay_parent, state_root, Default::default(), 1u32, max_ancestry_len); let (relay_parent, state_root) = blocks[2]; - tracker.update(relay_parent, state_root, 2u32, max_ancestry_len); + tracker.update(relay_parent, state_root, Default::default(), 2u32, max_ancestry_len); for (block_num, (rp, state_root)) in blocks.iter().enumerate().take(2) { assert_matches!( tracker.acquire_info(*rp, None), - Some((s, b)) if &s == state_root && b == block_num as u32 + Some((s, b)) if &s.state_root == state_root && b == block_num as u32 ); assert!(tracker.acquire_info(*rp, Some(2)).is_none()); @@ -87,7 +87,7 @@ fn tracker_acquire_info() { for (block_num, (rp, state_root)) in blocks.iter().enumerate().skip(1) { assert_matches!( tracker.acquire_info(*rp, Some(block_num as u32 - 1)), - Some((s, b)) if &s == state_root && b == block_num as u32 + Some((s, b)) if &s.state_root == state_root && b == block_num as u32 ); } } From 4266665728b649853e8dc6b4ebf2cf3f7282d724 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 27 Aug 2024 23:49:07 +0300 Subject: [PATCH 061/130] check v2 receipts using claim queue snapshots Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/inclusion/mod.rs | 6 +- .../runtime/parachains/src/inclusion/tests.rs | 5 +- .../parachains/src/paras_inherent/mod.rs | 101 +++++++----------- .../parachains/src/paras_inherent/tests.rs | 16 +-- 4 files changed, 55 insertions(+), 73 deletions(-) diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index f9f54790b570..4cc21a70a024 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -1261,17 +1261,17 @@ impl CandidateCheckContext { let relay_parent = backed_candidate_receipt.descriptor.relay_parent(); // Check that the relay-parent is one of the allowed relay-parents. - let (relay_parent_storage_root, relay_parent_number) = { + let (state_root, relay_parent_number) = { match allowed_relay_parents.acquire_info(relay_parent, self.prev_context) { None => return Err(Error::::DisallowedRelayParent), - Some(info) => info, + Some((info, relay_parent_number)) => (info.state_root, relay_parent_number), } }; { let persisted_validation_data = make_persisted_validation_data_with_parent::( relay_parent_number, - relay_parent_storage_root, + state_root, parent_head_data, ); diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index f17b8ed2e0e9..ff46ad7fa08e 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -83,7 +83,7 @@ fn default_allowed_relay_parent_tracker() -> AllowedRelayParentsTracker Pallet { let now = frame_system::Pallet::::block_number(); let config = configuration::ActiveConfig::::get(); - // Before anything else, update the allowed relay-parents. - { - let parent_number = now - One::one(); - let parent_storage_root = *parent_header.state_root(); - - shared::AllowedRelayParents::::mutate(|tracker| { - tracker.update( - parent_hash, - parent_storage_root, - parent_number, - config.async_backing_params.allowed_ancestry_len, - ); - }); - } - let allowed_relay_parents = shared::AllowedRelayParents::::get(); - let candidates_weight = backed_candidates_weight::(&backed_candidates); let bitfields_weight = signed_bitfields_weight::(&bitfields); let disputes_weight = multi_dispute_statement_sets_weight::(&disputes); @@ -570,6 +554,29 @@ impl Pallet { METRICS.on_candidates_processed_total(backed_candidates.len() as u64); + // After freeing cores and filling claims, but before processing backed candidates + // we update the allowed relay-parents. + { + let parent_number = now - One::one(); + let parent_storage_root = *parent_header.state_root(); + + shared::AllowedRelayParents::::mutate(|tracker| { + tracker.update( + parent_hash, + parent_storage_root, + scheduler::ClaimQueue::::get() + .into_iter() + .map(|(core_index, paras)| { + (core_index, paras.into_iter().map(|e| e.para_id()).collect()) + }) + .collect(), + parent_number, + config.async_backing_params.allowed_ancestry_len, + ); + }); + } + let allowed_relay_parents = shared::AllowedRelayParents::::get(); + let core_index_enabled = configuration::ActiveConfig::::get() .node_features .get(FeatureIndex::ElasticScalingMVP as usize) @@ -961,7 +968,6 @@ pub(crate) fn sanitize_bitfields( fn sanitize_backed_candidate_v2( candidate: &BackedCandidate, allowed_relay_parents: &AllowedRelayParentsTracker>, - scheduled_paras: &BTreeMap, allow_v2_receipts: bool, ) -> bool { // We move forward only if the candidate commits to a core selector and claim queue offset. @@ -1000,8 +1006,8 @@ fn sanitize_backed_candidate_v2( return false } - // Get the relay parent number for the candidate - let Some((_state_root, relay_parent_num)) = + // Get the claim queue snapshot at the candidate relay paren. + let Some((rp_info, _)) = allowed_relay_parents.acquire_info(candidate.descriptor().relay_parent(), None) else { log::debug!( @@ -1013,35 +1019,19 @@ fn sanitize_backed_candidate_v2( return false }; - let current_block_num = frame_system::Pallet::::block_number(); - let expected_cq_offset = current_block_num - relay_parent_num - One::one(); - - // Drop the candidate receipt if the core claim has not reached the top of the - // claim queue. - if expected_cq_offset != (cq_offset.0 as u32).into() { - log::debug!( - target: LOG_TARGET, - "Dropped candidate {:?} of paraid {:?} because the claimed core is not at top \ - of the claim queue, cq_offset: {:?}, relay_parent_num: {:?}", - candidate.candidate().hash(), - candidate.descriptor().para_id(), - cq_offset, - relay_parent_num - ); - return false - } - - let assigned_cores = - scheduled_paras - .iter() - .filter_map(|(core_index, para)| { - if *para == candidate.descriptor().para_id() { - Some(core_index) - } else { - None - } - }) - .collect::>(); + // The cores assigned to the parachain at the committed claim queue offset. + let assigned_cores = rp_info + .claim_queue + .iter() + .filter_map(move |(core_index, paras)| { + let para_at_offset = *paras.get(cq_offset.0 as usize)?; + if para_at_offset == candidate.descriptor().para_id() { + Some(core_index) + } else { + None + } + }) + .collect::>(); let assigned_cores = assigned_cores.as_slice(); // Check if core index in descriptor matches the one in the commitments @@ -1092,20 +1082,9 @@ fn sanitize_backed_candidates( // of the same para is preserved. let mut candidates_per_para: BTreeMap> = BTreeMap::new(); - // Get the eligible paras for each core. - let scheduled_paras = scheduled - .iter() - .map(|(para_id, cores)| cores.iter().map(|core| (*core, *para_id))) - .flatten() - .collect(); - for candidate in backed_candidates { - if !sanitize_backed_candidate_v2::( - &candidate, - allowed_relay_parents, - &scheduled_paras, - allow_v2_receipts, - ) { + if !sanitize_backed_candidate_v2::(&candidate, allowed_relay_parents, allow_v2_receipts) + { continue } diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 6700ab5307bc..2795130913f1 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -161,7 +161,7 @@ mod enter { backed_and_concluding, num_validators_per_core: 1, code_upgrade: None, - fill_claimqueue: false, + fill_claimqueue: true, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor, @@ -185,9 +185,6 @@ mod enter { .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) .unwrap(); - // The current schedule is empty prior to calling `create_inherent_enter`. - assert!(scheduler::Pallet::::claim_queue_is_empty()); - // Nothing is filtered out (including the backed candidates.) assert_eq!( Pallet::::create_inherent_inner(&inherent_data.clone()).unwrap(), @@ -267,7 +264,7 @@ mod enter { backed_and_concluding, num_validators_per_core: 1, code_upgrade: None, - fill_claimqueue: false, + fill_claimqueue: true, elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: vec![], v2_descriptor, @@ -287,9 +284,6 @@ mod enter { .put_data(PARACHAINS_INHERENT_IDENTIFIER, &expected_para_inherent_data) .unwrap(); - // The current schedule is empty prior to calling `create_inherent_enter`. - assert!(scheduler::Pallet::::claim_queue_is_empty()); - assert!(pallet::OnChainVotes::::get().is_none()); // Nothing is filtered out (including the backed candidates.) @@ -2018,6 +2012,7 @@ mod sanitizers { shared::Pallet::::add_allowed_relay_parent( default_header().hash(), Default::default(), + Default::default(), RELAY_PARENT_NUM, 1, ); @@ -2214,6 +2209,7 @@ mod sanitizers { shared::Pallet::::add_allowed_relay_parent( default_header().hash(), Default::default(), + Default::default(), RELAY_PARENT_NUM, 1, ); @@ -2733,6 +2729,7 @@ mod sanitizers { shared::Pallet::::add_allowed_relay_parent( relay_parent, Default::default(), + Default::default(), RELAY_PARENT_NUM, 1, ); @@ -3233,6 +3230,7 @@ mod sanitizers { shared::Pallet::::add_allowed_relay_parent( prev_relay_parent, Default::default(), + Default::default(), RELAY_PARENT_NUM - 1, 2, ); @@ -3240,6 +3238,7 @@ mod sanitizers { shared::Pallet::::add_allowed_relay_parent( relay_parent, Default::default(), + Default::default(), RELAY_PARENT_NUM, 2, ); @@ -3247,6 +3246,7 @@ mod sanitizers { shared::Pallet::::add_allowed_relay_parent( next_relay_parent, Default::default(), + Default::default(), RELAY_PARENT_NUM + 1, 2, ); From e93b9839a76fcd70b4b3cb0346cf2776ccb94eec Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 27 Aug 2024 23:52:49 +0300 Subject: [PATCH 062/130] typo Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 6e8004101806..b3b7e402f3c4 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -1006,7 +1006,7 @@ fn sanitize_backed_candidate_v2( return false } - // Get the claim queue snapshot at the candidate relay paren. + // Get the claim queue snapshot at the candidate relay parent. let Some((rp_info, _)) = allowed_relay_parents.acquire_info(candidate.descriptor().relay_parent(), None) else { From e01bf53771923338a6a8e4ef72e5742546fb5be9 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 28 Aug 2024 14:03:30 +0300 Subject: [PATCH 063/130] it was a bad idea to process commitments of v1 receipts Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 15 +++----- .../parachains/src/paras_inherent/mod.rs | 38 +++++-------------- 2 files changed, 14 insertions(+), 39 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index e8b51d6b2202..203a0a448bae 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -527,9 +527,8 @@ impl CommittedCandidateReceiptV2 { /// Input `assigned_cores` must contain the sorted cores assigned to the para at /// the committed claim queue offset. pub fn check(&self, assigned_cores: &[&CoreIndex]) -> Result<(), CandidateReceiptError> { - // Don't check v1 descriptors without any `SelectCore` commitments. - if self.descriptor.version() == CandidateDescriptorVersion::V1 && - self.commitments.selected_core().is_none() + // Don't check v1 descriptors. + if self.descriptor.version() == CandidateDescriptorVersion::V1 { return Ok(()) } @@ -547,13 +546,9 @@ impl CommittedCandidateReceiptV2 { .committed_core_index(assigned_cores) .ok_or(CandidateReceiptError::NoAssignment)?; - // Only check descriptor `core_index` field of v2 descriptors. If it is v1, that field - // will be garbage. - if self.descriptor.version() == CandidateDescriptorVersion::V2 { - let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); - if core_index != descriptor_core_index { - return Err(CandidateReceiptError::CoreIndexMismatch) - } + let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); + if core_index != descriptor_core_index { + return Err(CandidateReceiptError::CoreIndexMismatch) } Ok(()) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index b3b7e402f3c4..146bb9c3a3d2 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -958,8 +958,7 @@ pub(crate) fn sanitize_bitfields( /// Perform required checks for given candidate receipt. /// -/// Returns `true` if candidate descriptor is version 1 without `UMPSignal` -/// commitments. +/// Returns `true` if candidate descriptor is version 1. /// /// Otherwise returns `false` if: /// - version 2 descriptors are not allowed @@ -970,18 +969,11 @@ fn sanitize_backed_candidate_v2( allowed_relay_parents: &AllowedRelayParentsTracker>, allow_v2_receipts: bool, ) -> bool { - // We move forward only if the candidate commits to a core selector and claim queue offset. - // If parachain runtime already makes use of `UMPSignal::SelectCore`, and the collator does not, - // we can expect v1 candidate receipts with `UMPSignal::SelectCore` commitments. - // - // It is important that we use these commitments of v1 receipts and not rely on injected cores. - // Parachain runtime upgrade is enough to enable both validators and the runtime to validate - // the core index the candidate has committed to. - let Some((core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() else { - if candidate.descriptor().version() == CandidateDescriptorVersion::V1 { - return true - } + if candidate.descriptor().version() == CandidateDescriptorVersion::V1 { + return true + } + let Some((core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() else { log::debug!( target: LOG_TARGET, "Dropping V2 candidate receipt {:?} for paraid {:?}, no `SelectCore` commitment.", @@ -992,8 +984,6 @@ fn sanitize_backed_candidate_v2( return false }; - // Drop any candidate receipts with `UMPSignal::SelectCore` commitments if nodes are not allowed - // to use them. // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure // any v1 descendants of v2 candidates are dropped. if !allow_v2_receipts { @@ -1034,8 +1024,7 @@ fn sanitize_backed_candidate_v2( .collect::>(); let assigned_cores = assigned_cores.as_slice(); - // Check if core index in descriptor matches the one in the commitments - // No-op for v1 candidate receipts. + // Check if core index in descriptor matches the one in the commitments. if let Err(err) = candidate.candidate().check(assigned_cores) { log::debug!( target: LOG_TARGET, @@ -1490,11 +1479,6 @@ fn map_candidates_to_cores(allowed_relay_parents, &candidate, &assigned_cores) + get_core_index::(allowed_relay_parents, &candidate) { if scheduled_cores.remove(&core_index) { temp_backed_candidates.push((candidate, core_index)); @@ -1573,15 +1557,11 @@ fn map_candidates_to_cores( allowed_relay_parents: &AllowedRelayParentsTracker>, candidate: &BackedCandidate, - assigned_cores: &BTreeSet, ) -> Option { - // Use the committed core index. It could be available even if descriptor is v1. - // We've already sanitized the candidate so it should be ok to trust it is valid. - // Fall back to injected core index. candidate .candidate() - .commitments - .committed_core_index(assigned_cores.iter().collect::>().as_slice()) + .descriptor + .core_index() .or_else(|| get_injected_core_index::(allowed_relay_parents, &candidate)) } From fb9fbe6bdaa8e5773f16eb4fa9272aa0e36ab5f3 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 28 Aug 2024 15:07:12 +0300 Subject: [PATCH 064/130] fmt Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 3 +-- polkadot/runtime/parachains/src/paras_inherent/mod.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 203a0a448bae..79c7a968fa4d 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -528,8 +528,7 @@ impl CommittedCandidateReceiptV2 { /// the committed claim queue offset. pub fn check(&self, assigned_cores: &[&CoreIndex]) -> Result<(), CandidateReceiptError> { // Don't check v1 descriptors. - if self.descriptor.version() == CandidateDescriptorVersion::V1 - { + if self.descriptor.version() == CandidateDescriptorVersion::V1 { return Ok(()) } diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 146bb9c3a3d2..e984470a33e6 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -1491,8 +1491,7 @@ fn map_candidates_to_cores(allowed_relay_parents, &candidate) + if let Some(core_index) = get_core_index::(allowed_relay_parents, &candidate) { if scheduled_cores.remove(&core_index) { temp_backed_candidates.push((candidate, core_index)); From c50748849771c50f02bbaa491865fb9360e7371a Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 28 Aug 2024 15:08:28 +0300 Subject: [PATCH 065/130] remove unused Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 79c7a968fa4d..64b5f8df8814 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -422,8 +422,6 @@ impl CandidateCommitments { /// CandidateReceipt construction errors. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] pub enum CandidateReceiptError { - /// The specified core index is invalid. - InvalidCoreIndex, /// The core index in commitments doesnt match the one in descriptor CoreIndexMismatch, /// The core selector or claim queue offset is invalid. From 178e2018d9162c634276ac248c513289032ee55c Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 28 Aug 2024 18:30:58 +0300 Subject: [PATCH 066/130] Validate session index Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/builder.rs | 4 +- .../runtime/parachains/src/inclusion/mod.rs | 2 +- .../parachains/src/paras_inherent/mod.rs | 24 +++++ .../parachains/src/paras_inherent/tests.rs | 101 +++++++++++++++++- 4 files changed, 125 insertions(+), 6 deletions(-) diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 7c5e5d7ad307..df806ab5940d 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -315,7 +315,7 @@ impl BenchBuilder { 0.into(), Default::default(), CoreIndex(200), - 1, + 2, Default::default(), Default::default(), Default::default(), @@ -671,7 +671,7 @@ impl BenchBuilder { para_id, relay_parent, core_idx, - 1, + 2, persisted_validation_data_hash, pov_hash, Default::default(), diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index 4cc21a70a024..077ac650c559 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -988,7 +988,7 @@ impl Pallet { pub(crate) fn receive_upward_messages(para: ParaId, upward_messages: &[Vec]) -> Weight { let bounded = upward_messages .iter() - // Stop once we hit the `UMPSignal`` separator. + // Stop once we hit the `UMPSignal` separator. .take_while(|message| !message.is_empty()) .filter_map(|d| { BoundedSlice::try_from(&d[..]) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index e984470a33e6..183c47f10568 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -984,6 +984,30 @@ fn sanitize_backed_candidate_v2( return false }; + // Check session index in the receipt. As we drop allowed relay parents at session change + // we only allow here candidates that have the session index equal to the current session. + let Some(session_index) = candidate.descriptor().session_index() else { + log::debug!( + target: LOG_TARGET, + "Invalid V2 candidate receipt {:?} for paraid {:?}, missing session index.", + candidate.candidate().hash(), + candidate.descriptor().para_id(), + ); + return false + }; + + if session_index != shared::CurrentSessionIndex::::get() { + log::debug!( + target: LOG_TARGET, + "Dropping V2 candidate receipt {:?} for paraid {:?}, invalid session index {}, current session {}", + candidate.candidate().hash(), + candidate.descriptor().para_id(), + session_index, + shared::CurrentSessionIndex::::get() + ); + return false + } + // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure // any v1 descendants of v2 candidates are dropped. if !allow_v2_receipts { diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 2795130913f1..78d5c050cf58 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -62,7 +62,9 @@ mod enter { use frame_support::assert_ok; use frame_system::limits; use polkadot_primitives::{ - vstaging::{InternalVersion, SchedulerParams}, + vstaging::{ + CandidateDescriptorV2, CommittedCandidateReceiptV2, InternalVersion, SchedulerParams, + }, AvailabilityBitfield, CandidateDescriptor, UncheckedSigned, }; use sp_runtime::Perbill; @@ -1549,7 +1551,6 @@ mod enter { num_validators_per_core: 5, code_upgrade: None, fill_claimqueue: true, - // 8 cores ! elastic_paras: [(2, 8)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), v2_descriptor: true, @@ -1627,7 +1628,6 @@ mod enter { num_validators_per_core: 1, code_upgrade: None, fill_claimqueue: true, - // 8 cores ! elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), v2_descriptor: false, @@ -1713,6 +1713,101 @@ mod enter { Pallet::::enter(frame_system::RawOrigin::None.into(), inherent_data).unwrap(); }); } + + // A test to ensure that the paras_inherent filters out candidates + // with invalid sesison index in the descriptor. + #[test] + fn invalid_session_index() { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::ElasticScalingMVP as u8, + true, + ) + .unwrap(); + + // Enable the v2 receipts. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + true, + ) + .unwrap(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); + + let unavailable_cores = vec![]; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 1, + code_upgrade: None, + fill_claimqueue: true, + elastic_paras: [(2, 3)].into_iter().collect(), + unavailable_cores, + v2_descriptor: true, + }); + + let mut inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (2 validators per core, 5 backed candidates) + assert_eq!(inherent_data.bitfields.len(), 5); + // * 5 v2 candidate descriptors passed, 1 is invalid + assert_eq!(inherent_data.backed_candidates.len(), 5); + + let index = inherent_data.backed_candidates.len() - 1; + + // Put invalid session index in last candidate + let backed_candidate = inherent_data.backed_candidates[index].clone(); + + let candidate = CommittedCandidateReceiptV2 { + descriptor: CandidateDescriptorV2::new( + backed_candidate.descriptor().para_id(), + backed_candidate.descriptor().relay_parent(), + backed_candidate.descriptor().core_index().unwrap(), + 100, + backed_candidate.descriptor().persisted_validation_data_hash(), + backed_candidate.descriptor().pov_hash(), + backed_candidate.descriptor().erasure_root(), + backed_candidate.descriptor().para_head(), + backed_candidate.descriptor().validation_code_hash(), + ), + commitments: backed_candidate.candidate().commitments.clone(), + }; + + inherent_data.backed_candidates[index] = BackedCandidate::new( + candidate, + backed_candidate.validity_votes().to_vec(), + backed_candidate.validator_indices_and_core_index(false).0.into(), + None, + ); + + let mut expected_inherent_data = inherent_data.clone(); + expected_inherent_data.backed_candidates.truncate(index); + + let mut create_inherent_data = InherentData::new(); + create_inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &inherent_data) + .unwrap(); + + // 1 candidate with invalid session is filtered out + assert_eq!( + Pallet::::create_inherent_inner(&create_inherent_data).unwrap(), + expected_inherent_data + ); + + Pallet::::enter(frame_system::RawOrigin::None.into(), inherent_data).unwrap_err(); + }); + } } fn default_header() -> polkadot_primitives::Header { From 984e8e1c97cf2c8238c6a6ea6b481211db543217 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 29 Aug 2024 11:49:06 +0300 Subject: [PATCH 067/130] add unknown version Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 962c9a467fe7..ccb4c132b0ae 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -126,6 +126,8 @@ pub enum CandidateDescriptorVersion { V1, /// The new `CandidateDescriptorV2`. V2, + /// An unknown version. + Unknown, } /// A unique descriptor of the candidate receipt. @@ -431,7 +433,7 @@ impl CandidateDescriptorV2 { match self.version.0 { 0 => CandidateDescriptorVersion::V2, - _ => CandidateDescriptorVersion::V1, + _ => CandidateDescriptorVersion::Unknown, } } @@ -816,8 +818,9 @@ mod tests { } #[test] - fn is_invalid_version_decodes_as_v1() { + fn invalid_version_descriptor() { let mut new_ccr = dummy_committed_candidate_receipt_v2(); + assert_eq!(new_ccr.descriptor.version(), CandidateDescriptorVersion::V2); // Put some unknown version. new_ccr.descriptor.version = InternalVersion(100); @@ -825,7 +828,7 @@ mod tests { let new_ccr: CommittedCandidateReceiptV2 = Decode::decode(&mut new_ccr.encode().as_slice()).unwrap(); - assert_eq!(new_ccr.descriptor.version(), CandidateDescriptorVersion::V1); + assert_eq!(new_ccr.descriptor.version(), CandidateDescriptorVersion::Unknown); } #[test] From fab215daebc0d1800bb387548c5306d4e54796fb Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 29 Aug 2024 11:56:24 +0300 Subject: [PATCH 068/130] add check for unknown version and test Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index ccb4c132b0ae..1838d94e53b8 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -114,7 +114,7 @@ impl> Default for SchedulerParams } /// A type representing the version of the candidate descriptor and internal version number. -#[derive(PartialEq, Eq, Encode, Decode, Clone, TypeInfo, RuntimeDebug)] +#[derive(PartialEq, Eq, Encode, Decode, Clone, TypeInfo, RuntimeDebug, Copy)] #[cfg_attr(feature = "std", derive(Hash))] pub struct InternalVersion(pub u8); @@ -403,6 +403,8 @@ pub enum CandidateReceiptError { NoAssignment, /// No core was selected. NoCoreSelected, + /// Unknown version. + UnknownVersion(InternalVersion), } macro_rules! impl_getter { @@ -503,6 +505,10 @@ impl CommittedCandidateReceiptV2 { return Ok(()) } + if self.descriptor.version() == CandidateDescriptorVersion::Unknown { + return Err(CandidateReceiptError::UnknownVersion(self.descriptor.version)) + } + if assigned_cores.is_empty() { return Err(CandidateReceiptError::NoAssignment) } @@ -829,6 +835,10 @@ mod tests { Decode::decode(&mut new_ccr.encode().as_slice()).unwrap(); assert_eq!(new_ccr.descriptor.version(), CandidateDescriptorVersion::Unknown); + assert_eq!( + new_ccr.check(&vec![].as_slice()), + Err(CandidateReceiptError::UnknownVersion(InternalVersion(100))) + ) } #[test] From 9bbe2cc788d28d993c73e52b60a4a8c417e10db1 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 29 Aug 2024 15:20:41 +0300 Subject: [PATCH 069/130] typo Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index c01c792c6d89..d154ba11af28 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -407,7 +407,7 @@ impl CandidateCommitments { pub enum CandidateReceiptError { /// The specified core index is invalid. InvalidCoreIndex, - /// The core index in commitments doesnt match the one in descriptor + /// The core index in commitments doesn't match the one in descriptor CoreIndexMismatch, /// The core selector or claim queue offset is invalid. InvalidSelectedCore, From 4dda9dfdf7d88360b5dfd361619e96b39a4e8ae7 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 29 Aug 2024 15:23:01 +0300 Subject: [PATCH 070/130] adjust comments Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 183c47f10568..a445813d984a 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -984,8 +984,6 @@ fn sanitize_backed_candidate_v2( return false }; - // Check session index in the receipt. As we drop allowed relay parents at session change - // we only allow here candidates that have the session index equal to the current session. let Some(session_index) = candidate.descriptor().session_index() else { log::debug!( target: LOG_TARGET, @@ -996,6 +994,7 @@ fn sanitize_backed_candidate_v2( return false }; + // Check if session index is equal to current session index. if session_index != shared::CurrentSessionIndex::::get() { log::debug!( target: LOG_TARGET, From f8ef4ce2486aa32600faab709c2da7bfb6a17e19 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 30 Aug 2024 15:56:01 +0300 Subject: [PATCH 071/130] fix merge damage Signed-off-by: Andrei Sandu --- .../primitives/src/vstaging/async_backing.rs | 4 +-- polkadot/primitives/src/vstaging/mod.rs | 26 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/polkadot/primitives/src/vstaging/async_backing.rs b/polkadot/primitives/src/vstaging/async_backing.rs index bdf94e0f00db..8706214b5a01 100644 --- a/polkadot/primitives/src/vstaging/async_backing.rs +++ b/polkadot/primitives/src/vstaging/async_backing.rs @@ -37,7 +37,7 @@ pub struct CandidatePendingAvailability { } impl From> - for crate::v7::async_backing::CandidatePendingAvailability + for crate::v8::async_backing::CandidatePendingAvailability { fn from(value: CandidatePendingAvailability) -> Self { Self { @@ -62,7 +62,7 @@ pub struct BackingState { pub pending_availability: Vec>, } -impl From> for crate::v7::async_backing::BackingState { +impl From> for crate::v8::async_backing::BackingState { fn from(value: BackingState) -> Self { Self { constraints: value.constraints, diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 8bf098c84a82..95d044762710 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -193,25 +193,25 @@ pub enum CandidateEvent { CandidateTimedOut(CandidateReceiptV2, HeadData, CoreIndex), } -impl From> for super::v7::CandidateEvent { +impl From> for super::v8::CandidateEvent { fn from(value: CandidateEvent) -> Self { match value { CandidateEvent::CandidateBacked(receipt, head_data, core_index, group_index) => - super::v7::CandidateEvent::CandidateBacked( + super::v8::CandidateEvent::CandidateBacked( receipt.into(), head_data, core_index, group_index, ), CandidateEvent::CandidateIncluded(receipt, head_data, core_index, group_index) => - super::v7::CandidateEvent::CandidateIncluded( + super::v8::CandidateEvent::CandidateIncluded( receipt.into(), head_data, core_index, group_index, ), CandidateEvent::CandidateTimedOut(receipt, head_data, core_index) => - super::v7::CandidateEvent::CandidateTimedOut(receipt.into(), head_data, core_index), + super::v8::CandidateEvent::CandidateTimedOut(receipt.into(), head_data, core_index), } } } @@ -275,13 +275,13 @@ impl Ord for CommittedCandidateReceiptV2 { } } -impl From> for super::v7::CommittedCandidateReceipt { +impl From> for super::v8::CommittedCandidateReceipt { fn from(value: CommittedCandidateReceiptV2) -> Self { Self { descriptor: value.descriptor.into(), commitments: value.commitments } } } -impl From> for super::v7::CandidateReceipt { +impl From> for super::v8::CandidateReceipt { fn from(value: CandidateReceiptV2) -> Self { Self { descriptor: value.descriptor.into(), commitments_hash: value.commitments_hash } } @@ -609,7 +609,7 @@ pub struct ScrapedOnChainVotes { pub disputes: MultiDisputeStatementSet, } -impl From> for super::v7::ScrapedOnChainVotes { +impl From> for super::v8::ScrapedOnChainVotes { fn from(value: ScrapedOnChainVotes) -> Self { Self { session: value.session, @@ -672,7 +672,7 @@ pub enum CoreState { Free, } -impl From> for super::v7::OccupiedCore { +impl From> for super::v8::OccupiedCore { fn from(value: OccupiedCore) -> Self { Self { next_up_on_available: value.next_up_on_available, @@ -687,13 +687,13 @@ impl From> for super::v7::OccupiedCore { } } -impl From> for super::v7::CoreState { +impl From> for super::v8::CoreState { fn from(value: CoreState) -> Self { match value { - CoreState::Free => super::v7::CoreState::Free, - CoreState::Scheduled(core) => super::v7::CoreState::Scheduled(core), + CoreState::Free => super::v8::CoreState::Free, + CoreState::Scheduled(core) => super::v8::CoreState::Scheduled(core), CoreState::Occupied(occupied_core) => - super::v7::CoreState::Occupied(occupied_core.into()), + super::v8::CoreState::Occupied(occupied_core.into()), } } } @@ -702,7 +702,7 @@ impl From> for super::v7::CoreState { mod tests { use super::*; use crate::{ - v7::{ + v8::{ tests::dummy_committed_candidate_receipt as dummy_old_committed_candidate_receipt, CommittedCandidateReceipt, Hash, HeadData, ValidationCode, }, From 04e31a191201eb928796a14c94be8de2e67cf09e Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 30 Aug 2024 15:58:20 +0300 Subject: [PATCH 072/130] unused Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 95d044762710..57cba85c10d9 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -19,10 +19,10 @@ use crate::{ValidatorIndex, ValidityAttestation}; // Put any primitives used by staging APIs functions here use super::{ - async_backing::Constraints, Balance, BlakeTwo256, BlockNumber, CandidateCommitments, + async_backing::Constraints, BlakeTwo256, BlockNumber, CandidateCommitments, CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, CoreIndex, GroupIndex, Hash, HashT, HeadData, Header, Id, Id as ParaId, MultiDisputeStatementSet, ScheduledCore, - UncheckedSignedAvailabilityBitfields, ValidationCodeHash, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, + UncheckedSignedAvailabilityBitfields, ValidationCodeHash, }; use bitvec::prelude::*; use sp_application_crypto::ByteArray; @@ -30,7 +30,6 @@ use sp_application_crypto::ByteArray; use alloc::{vec, vec::Vec}; use codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_arithmetic::Perbill; use sp_core::RuntimeDebug; use sp_runtime::traits::Header as HeaderT; use sp_staking::SessionIndex; From 5fd127949c93ff1d28cb455d78d54ebe7e54cc1a Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 30 Aug 2024 17:38:46 +0300 Subject: [PATCH 073/130] fix Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/tests.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 0097c1267383..2675ece471cf 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -58,7 +58,7 @@ mod enter { use core::panic; use frame_support::assert_ok; use frame_system::limits; - use polkadot_primitives::{AvailabilityBitfield, SchedulerParams, UncheckedSigned}; + use polkadot_primitives::{AvailabilityBitfield, SchedulerParams, UncheckedSigned, vstaging::InternalVersion}; use sp_runtime::Perbill; struct TestConfig { @@ -988,6 +988,7 @@ mod enter { fill_claimqueue: true, elastic_paras: BTreeMap::new(), unavailable_cores: vec![], + v2_descriptor: false, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1633,7 +1634,7 @@ mod sanitizers { use bitvec::order::Lsb0; use polkadot_primitives::{ AvailabilityBitfield, GroupIndex, Hash, Id as ParaId, SignedAvailabilityBitfield, - ValidatorIndex, + ValidatorIndex }; use rstest::rstest; use sp_core::crypto::UncheckedFrom; From 19d6f325b9168908f98d474a0dc3c92223c25048 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 2 Sep 2024 15:33:17 +0300 Subject: [PATCH 074/130] fix benchmark build Signed-off-by: Andrei Sandu --- .../parachains/src/inclusion/benchmarking.rs | 27 +++++++++---------- .../parachains/src/paras_inherent/tests.rs | 6 +++-- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/polkadot/runtime/parachains/src/inclusion/benchmarking.rs b/polkadot/runtime/parachains/src/inclusion/benchmarking.rs index 978ef718ea40..cb6329bf88ea 100644 --- a/polkadot/runtime/parachains/src/inclusion/benchmarking.rs +++ b/polkadot/runtime/parachains/src/inclusion/benchmarking.rs @@ -25,10 +25,9 @@ use bitvec::{bitvec, prelude::Lsb0}; use frame_benchmarking::benchmarks; use pallet_message_queue as mq; use polkadot_primitives::{ - CandidateCommitments, CollatorId, CollatorSignature, CommittedCandidateReceipt, HrmpChannelId, - OutboundHrmpMessage, SessionIndex, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CandidateCommitments, + HrmpChannelId, OutboundHrmpMessage, SessionIndex, }; -use sp_core::sr25519; fn create_candidate_commitments( para_id: ParaId, @@ -124,17 +123,17 @@ benchmarks! { let core_index = CoreIndex::from(0); let backing_group = GroupIndex::from(0); - let descriptor = CandidateDescriptor:: { - para_id: para, - relay_parent: Default::default(), - collator: CollatorId::from(sr25519::Public::from_raw([42u8; 32])), - persisted_validation_data_hash: Default::default(), - pov_hash: Default::default(), - erasure_root: Default::default(), - signature: CollatorSignature::from(sr25519::Signature::from_raw([42u8; 64])), - para_head: Default::default(), - validation_code_hash: ValidationCode(vec![1, 2, 3]).hash(), - }; + let descriptor = CandidateDescriptor::::new( + para, + Default::default(), + CoreIndex(0), + 1, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ValidationCode(vec![1, 2, 3]).hash(), + ); let receipt = CommittedCandidateReceipt:: { descriptor, diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 2675ece471cf..ac42ac1611df 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -58,7 +58,9 @@ mod enter { use core::panic; use frame_support::assert_ok; use frame_system::limits; - use polkadot_primitives::{AvailabilityBitfield, SchedulerParams, UncheckedSigned, vstaging::InternalVersion}; + use polkadot_primitives::{ + vstaging::InternalVersion, AvailabilityBitfield, SchedulerParams, UncheckedSigned, + }; use sp_runtime::Perbill; struct TestConfig { @@ -1634,7 +1636,7 @@ mod sanitizers { use bitvec::order::Lsb0; use polkadot_primitives::{ AvailabilityBitfield, GroupIndex, Hash, Id as ParaId, SignedAvailabilityBitfield, - ValidatorIndex + ValidatorIndex, }; use rstest::rstest; use sp_core::crypto::UncheckedFrom; From 4ec3fc8f9588d46ac928474300056b5bbe5691d9 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 2 Sep 2024 19:31:41 +0300 Subject: [PATCH 075/130] typos Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index d9d5a07fc92c..93589ecfae0a 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -298,9 +298,9 @@ pub struct ClaimQueueOffset(pub u8); /// Signals that a parachain can send to the relay chain via the UMP queue. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] pub enum UMPSignal { - /// A message sent by a parachain to select the core the candidate is commited to. + /// A message sent by a parachain to select the core the candidate is committed to. /// Relay chain validators, in particular backers, use the `CoreSelector` and - /// `ClaimQueueOffset` to compute the index of the core the candidate has commited to. + /// `ClaimQueueOffset` to compute the index of the core the candidate has committed to. SelectCore(CoreSelector, ClaimQueueOffset), } /// Separator between `XCM` and `UMPSignal`. @@ -451,7 +451,7 @@ impl CandidateDescriptorV2 { } impl CommittedCandidateReceiptV2 { - /// Checks if descriptor core index is equal to the commited core index. + /// Checks if descriptor core index is equal to the committed core index. /// Input `assigned_cores` must contain the sorted cores assigned to the para at /// the committed claim queue offset. pub fn check(&self, assigned_cores: &[&CoreIndex]) -> Result<(), CandidateReceiptError> { From 2ba0a276bc7ae7fa38cb1c7bd0bd40d50df09e82 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 2 Sep 2024 19:31:59 +0300 Subject: [PATCH 076/130] fmt Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 3 ++- .../runtime/parachains/src/paras_inherent/tests.rs | 10 ++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 93589ecfae0a..ddad8170aecc 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -459,7 +459,8 @@ impl CommittedCandidateReceiptV2 { // Don't check v1 descriptors. CandidateDescriptorVersion::V1 => return Ok(()), CandidateDescriptorVersion::V2 => {}, - CandidateDescriptorVersion::Unknown => return Err(CandidateReceiptError::UnknownVersion(self.descriptor.version)), + CandidateDescriptorVersion::Unknown => + return Err(CandidateReceiptError::UnknownVersion(self.descriptor.version)), } if self.commitments.selected_core().is_none() { diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index b57811d61dbc..d31d4bd2a734 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -21,10 +21,10 @@ use crate::{ configuration::{self, HostConfiguration}, mock::MockGenesisConfig, }; -use polkadot_primitives::vstaging::{ - ClaimQueueOffset, CoreSelector, UMPSignal, UMP_SEPARATOR, +use polkadot_primitives::{ + vstaging::{ClaimQueueOffset, CoreSelector, UMPSignal, UMP_SEPARATOR}, + SchedulerParams, }; -use polkadot_primitives::SchedulerParams; fn default_config() -> MockGenesisConfig { MockGenesisConfig { @@ -63,9 +63,7 @@ mod enter { use frame_support::assert_ok; use frame_system::limits; use polkadot_primitives::{ - vstaging::{ - CandidateDescriptorV2, CommittedCandidateReceiptV2, InternalVersion, - }, + vstaging::{CandidateDescriptorV2, CommittedCandidateReceiptV2, InternalVersion}, AvailabilityBitfield, CandidateDescriptor, UncheckedSigned, }; use sp_runtime::Perbill; From e468d62166e4ad264ab79e3346e908ecb1d7e8d7 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 2 Sep 2024 19:36:49 +0300 Subject: [PATCH 077/130] fix comment Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/ump_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/ump_tests.rs b/polkadot/runtime/parachains/src/ump_tests.rs index a687515d330e..571fc5ab2271 100644 --- a/polkadot/runtime/parachains/src/ump_tests.rs +++ b/polkadot/runtime/parachains/src/ump_tests.rs @@ -644,7 +644,7 @@ fn cannot_offboard_while_ump_dispatch_queued() { }); } -/// A para-chain cannot send an UMP to the relay chain while it is offboarding. +/// Test UMP signals are filtered out and don't consume `max_upward_message_num_per_candidate`. #[test] fn enqueue_ump_signals() { let para = 100.into(); From 18a0496807fe9f4a2c5ba657d9f157d4af6f6de4 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 4 Sep 2024 13:53:26 +0300 Subject: [PATCH 078/130] mixed v1, v2, v2 without select core tests, plus some benchbuilder improvements Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 148 +++++++++++++----- polkadot/runtime/parachains/src/builder.rs | 23 ++- .../parachains/src/paras_inherent/mod.rs | 47 ++---- .../parachains/src/paras_inherent/tests.rs | 106 ++++++++++++- 4 files changed, 245 insertions(+), 79 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index ddad8170aecc..e8598aa87600 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -24,12 +24,15 @@ use super::{ HashT, HeadData, Header, Id, Id as ParaId, MultiDisputeStatementSet, ScheduledCore, UncheckedSignedAvailabilityBitfields, ValidationCodeHash, }; +use alloc::{ + collections::{BTreeMap, VecDeque}, + vec, + vec::Vec, +}; use bitvec::prelude::*; -use sp_application_crypto::ByteArray; - -use alloc::{vec, vec::Vec}; use codec::{Decode, Encode}; use scale_info::TypeInfo; +use sp_application_crypto::ByteArray; use sp_core::RuntimeDebug; use sp_runtime::traits::Header as HeaderT; use sp_staking::SessionIndex; @@ -334,8 +337,10 @@ impl CandidateCommitments { /// `assigned_cores` must be a sorted vec of all core indices assigned to a parachain. pub fn committed_core_index(&self, assigned_cores: &[&CoreIndex]) -> Option { if assigned_cores.is_empty() { + println!("Assigned cores empty"); return None } + println!("Selected core: {:?}", self.selected_core()); self.selected_core().and_then(|(core_selector, _cq_offset)| { let core_index = @@ -356,7 +361,8 @@ pub enum CandidateReceiptError { InvalidSelectedCore, /// The parachain is not assigned to any core at specified claim queue offset. NoAssignment, - /// No core was selected. + /// No core was selected. The `SelectCore` commitment is mandatory for + /// v2 receipts if parachains has multiple cores assigned. NoCoreSelected, /// Unknown version. UnknownVersion(InternalVersion), @@ -452,9 +458,12 @@ impl CandidateDescriptorV2 { impl CommittedCandidateReceiptV2 { /// Checks if descriptor core index is equal to the committed core index. - /// Input `assigned_cores` must contain the sorted cores assigned to the para at - /// the committed claim queue offset. - pub fn check(&self, assigned_cores: &[&CoreIndex]) -> Result<(), CandidateReceiptError> { + /// Input `claim_queue` must contain a snapshot of the claim queue at the + /// candidate relay parent. + pub fn check( + &self, + claim_queue: &BTreeMap>, + ) -> Result<(), CandidateReceiptError> { match self.descriptor.version() { // Don't check v1 descriptors. CandidateDescriptorVersion::V1 => return Ok(()), @@ -463,18 +472,48 @@ impl CommittedCandidateReceiptV2 { return Err(CandidateReceiptError::UnknownVersion(self.descriptor.version)), } - if self.commitments.selected_core().is_none() { - return Err(CandidateReceiptError::NoCoreSelected) - } - - if assigned_cores.is_empty() { + if claim_queue.is_empty() { + println!("cq empty"); return Err(CandidateReceiptError::NoAssignment) } - let core_index = self - .commitments - .committed_core_index(assigned_cores) - .ok_or(CandidateReceiptError::NoAssignment)?; + let (offset, core_selected) = + if let Some((_core_selector, cq_offset)) = self.commitments.selected_core() { + (cq_offset.0 as usize, true) + } else { + // If no core has been selected then we use offset 0 (top of claim queue) + (0, false) + }; + + // The cores assigned to the parachain at above computed offset. + // + // TODO: this might be inneficient to do for each candidate. + // A BTreeMap> can be computed + // once per relay chain block, making this search here much faster. + let assigned_cores = claim_queue + .iter() + .filter_map(move |(core_index, paras)| { + let para_at_offset = *paras.get(offset)?; + if para_at_offset == self.descriptor.para_id() { + Some(core_index) + } else { + None + } + }) + .collect::>(); + + let core_index = if core_selected { + self.commitments + .committed_core_index(assigned_cores.as_slice()) + .ok_or(CandidateReceiptError::NoAssignment)? + } else { + // `SelectCore` commitment is mandatory for elastic scaling parachains. + if assigned_cores.len() > 1 { + return Err(CandidateReceiptError::NoCoreSelected) + } + + **assigned_cores.get(0).ok_or(CandidateReceiptError::NoAssignment)? + }; let descriptor_core_index = CoreIndex(self.descriptor.core_index as u32); if core_index != descriptor_core_index { @@ -531,6 +570,12 @@ impl BackedCandidate { &self.candidate } + /// Get a mutable reference to the committed candidate receipt of the candidate. + /// Only for testing. + #[cfg(feature = "test")] + pub fn candidate_mut(&mut self) -> &mut CommittedCandidateReceiptV2 { + &mut self.candidate + } /// Get a reference to the descriptor of the candidate. pub fn descriptor(&self) -> &CandidateDescriptorV2 { &self.candidate.descriptor @@ -797,7 +842,7 @@ mod tests { assert_eq!(new_ccr.descriptor.version(), CandidateDescriptorVersion::Unknown); assert_eq!( - new_ccr.check(&vec![].as_slice()), + new_ccr.check(&BTreeMap::new()), Err(CandidateReceiptError::UnknownVersion(InternalVersion(100))) ) } @@ -821,7 +866,13 @@ mod tests { .upward_messages .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); - assert_eq!(new_ccr.check(&vec![&CoreIndex(123)]), Ok(())); + let mut cq = BTreeMap::new(); + cq.insert( + CoreIndex(123), + vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), + ); + + assert_eq!(new_ccr.check(&cq), Ok(())); } #[test] @@ -833,11 +884,12 @@ mod tests { new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); - // The check should fail because no `SelectCore` signal was sent. - assert_eq!( - new_ccr.check(&vec![&CoreIndex(0), &CoreIndex(100)]), - Err(CandidateReceiptError::NoCoreSelected) - ); + let mut cq = BTreeMap::new(); + cq.insert(CoreIndex(0), vec![new_ccr.descriptor.para_id()].into()); + + // The check should not fail because no `SelectCore` signal was sent. + // The message is optional. + assert!(new_ccr.check(&cq).is_ok()); // Garbage message. new_ccr.commitments.upward_messages.force_push(vec![0, 13, 200].encode()); @@ -845,12 +897,18 @@ mod tests { // No `SelectCore` can be decoded. assert_eq!(new_ccr.commitments.selected_core(), None); - // Failure is expected. - assert_eq!( - new_ccr.check(&vec![&CoreIndex(0), &CoreIndex(100)]), - Err(CandidateReceiptError::NoCoreSelected) + let mut cq = BTreeMap::new(); + cq.insert( + CoreIndex(0), + vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), + ); + cq.insert( + CoreIndex(100), + vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); + assert_eq!(new_ccr.check(&cq), Err(CandidateReceiptError::NoCoreSelected)); + new_ccr.commitments.upward_messages.clear(); new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); @@ -866,7 +924,7 @@ mod tests { .force_push(UMPSignal::SelectCore(CoreSelector(1), ClaimQueueOffset(1)).encode()); // Duplicate doesn't override first signal. - assert_eq!(new_ccr.check(&vec![&CoreIndex(0), &CoreIndex(100)]), Ok(())); + assert_eq!(new_ccr.check(&cq), Ok(())); } #[test] @@ -903,7 +961,14 @@ mod tests { Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); assert_eq!(v2_ccr.descriptor.core_index(), Some(CoreIndex(123))); - assert_eq!(new_ccr.check(&vec![&CoreIndex(123)]), Ok(())); + + let mut cq = BTreeMap::new(); + cq.insert( + CoreIndex(123), + vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), + ); + + assert_eq!(new_ccr.check(&cq), Ok(())); assert_eq!(new_ccr.hash(), v2_ccr.hash()); } @@ -930,7 +995,12 @@ mod tests { assert_eq!(v1_ccr.descriptor.version(), CandidateDescriptorVersion::V1); assert!(v1_ccr.commitments.selected_core().is_some()); - assert!(v1_ccr.check(&vec![&CoreIndex(0), &CoreIndex(1)]).is_ok()); + + let mut cq = BTreeMap::new(); + cq.insert(CoreIndex(0), vec![v1_ccr.descriptor.para_id()].into()); + cq.insert(CoreIndex(1), vec![v1_ccr.descriptor.para_id()].into()); + + assert!(v1_ccr.check(&cq).is_ok()); assert_eq!( v1_ccr.commitments.committed_core_index(&vec![&CoreIndex(10), &CoreIndex(5)]), @@ -941,7 +1011,7 @@ mod tests { } #[test] - fn test_core_select_is_mandatory() { + fn test_core_select_is_optional() { // Testing edge case when collators provide zeroed signature and collator id. let mut old_ccr = dummy_old_committed_candidate_receipt(); old_ccr.descriptor.para_id = ParaId::new(1000); @@ -950,11 +1020,19 @@ mod tests { let new_ccr: CommittedCandidateReceiptV2 = Decode::decode(&mut encoded_ccr.as_slice()).unwrap(); + let mut cq = BTreeMap::new(); + cq.insert(CoreIndex(0), vec![new_ccr.descriptor.para_id()].into()); + // Since collator sig and id are zeroed, it means that the descriptor uses format - // version 2. - // We expect the check to fail in such case because there will be no `SelectCore` - // commitment. - assert_eq!(new_ccr.check(&vec![&CoreIndex(0)]), Err(CandidateReceiptError::NoCoreSelected)); + // version 2. Should still pass checks without core selector. + assert!(new_ccr.check(&cq).is_ok()); + + let mut cq = BTreeMap::new(); + cq.insert(CoreIndex(0), vec![new_ccr.descriptor.para_id()].into()); + cq.insert(CoreIndex(1), vec![new_ccr.descriptor.para_id()].into()); + + // Should fail because 2 cores are assigned, + assert_eq!(new_ccr.check(&cq), Err(CandidateReceiptError::NoCoreSelected)); // Adding collator signature should make it decode as v1. old_ccr.descriptor.signature = dummy_collator_signature(); diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index ca6c088860c9..b12637da2e42 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -144,9 +144,14 @@ pub(crate) struct BenchBuilder { unavailable_cores: Vec, /// Use v2 candidate descriptor. candidate_descriptor_v2: bool, + /// Apply custom changes to generated candidates + candidate_modifier: Option>, _phantom: core::marker::PhantomData, } +pub type CandidateModifier = + fn(CommittedCandidateReceipt) -> CommittedCandidateReceipt; + /// Paras inherent `enter` benchmark scenario. #[cfg(any(feature = "runtime-benchmarks", test))] pub(crate) struct Bench { @@ -176,6 +181,7 @@ impl BenchBuilder { fill_claimqueue: true, unavailable_cores: vec![], candidate_descriptor_v2: false, + candidate_modifier: None, _phantom: core::marker::PhantomData::, } } @@ -290,6 +296,15 @@ impl BenchBuilder { self } + /// Set the candidate modifier. + pub(crate) fn set_candidate_modifier( + mut self, + modifier: Option>, + ) -> Self { + self.candidate_modifier = modifier; + self + } + /// Get the maximum number of validators per core. fn max_validators_per_core(&self) -> u32 { self.max_validators_per_core.unwrap_or(Self::fallback_max_validators_per_core()) @@ -725,6 +740,11 @@ impl BenchBuilder { ); } + // Maybe apply the candidate modifier + if let Some(modifier) = self.candidate_modifier { + candidate = modifier(candidate); + } + let candidate_hash = candidate.hash(); let validity_votes: Vec<_> = group_validators @@ -744,7 +764,8 @@ impl BenchBuilder { }) .collect(); - let core_idx = if self.candidate_descriptor_v2 { + // Don't inject core when it is available in descriptor. + let core_idx = if candidate.descriptor.core_index().is_some() { None } else { configuration::ActiveConfig::::get() diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 0cb2574f82a2..fced2ad8a512 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -997,16 +997,17 @@ fn sanitize_backed_candidate_v2( return true } - let Some((core_selector, cq_offset)) = candidate.candidate().commitments.selected_core() else { + // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure + // any v1 descendants of v2 candidates are dropped. + if !allow_v2_receipts { log::debug!( target: LOG_TARGET, - "Dropping V2 candidate receipt {:?} for paraid {:?}, no `SelectCore` commitment.", + "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", candidate.candidate().hash(), candidate.descriptor().para_id() ); - return false - }; + } let Some(session_index) = candidate.descriptor().session_index() else { log::debug!( @@ -1031,18 +1032,6 @@ fn sanitize_backed_candidate_v2( return false } - // It is mandatory to filter these before calling `filter_unchained_candidates` to ensure - // any v1 descendants of v2 candidates are dropped. - if !allow_v2_receipts { - log::debug!( - target: LOG_TARGET, - "V2 candidate descriptors not allowed. Dropping candidate {:?} for paraid {:?}.", - candidate.candidate().hash(), - candidate.descriptor().para_id() - ); - return false - } - // Get the claim queue snapshot at the candidate relay parent. let Some((rp_info, _)) = allowed_relay_parents.acquire_info(candidate.descriptor().relay_parent(), None) @@ -1056,31 +1045,14 @@ fn sanitize_backed_candidate_v2( return false }; - // The cores assigned to the parachain at the committed claim queue offset. - let assigned_cores = rp_info - .claim_queue - .iter() - .filter_map(move |(core_index, paras)| { - let para_at_offset = *paras.get(cq_offset.0 as usize)?; - if para_at_offset == candidate.descriptor().para_id() { - Some(core_index) - } else { - None - } - }) - .collect::>(); - let assigned_cores = assigned_cores.as_slice(); - - // Check if core index in descriptor matches the one in the commitments. - if let Err(err) = candidate.candidate().check(assigned_cores) { + // Check validity of `core_index` and `session_index`. + if let Err(err) = candidate.candidate().check(&rp_info.claim_queue) { log::debug!( target: LOG_TARGET, - "Dropping candidate {:?} for paraid {:?}, {:?}, core_selector={:?}, cq_offset={:?}", + "Dropping candidate {:?} for paraid {:?}, {:?}", candidate.candidate().hash(), candidate.descriptor().para_id(), err, - core_selector, - cq_offset, ); return false @@ -1540,6 +1512,7 @@ fn map_candidates_to_cores(allowed_relay_parents, &candidate) { + println!("Core index: {:?}", core_index); if scheduled_cores.remove(&core_index) { temp_backed_candidates.push((candidate, core_index)); } else { @@ -1563,7 +1536,7 @@ fn map_candidates_to_cores MockGenesisConfig { mod enter { use super::{inclusion::tests::TestCandidateBuilder, *}; use crate::{ - builder::{junk_collator, junk_collator_signature, Bench, BenchBuilder}, + builder::{junk_collator, junk_collator_signature, Bench, BenchBuilder, CandidateModifier}, mock::{mock_assigner, new_test_ext, BlockLength, BlockWeights, RuntimeOrigin, Test}, scheduler::{ common::{Assignment, AssignmentProvider}, @@ -78,6 +78,7 @@ mod enter { elastic_paras: BTreeMap, unavailable_cores: Vec, v2_descriptor: bool, + candidate_modifier: Option::Hash>>, } fn make_inherent_data( @@ -91,6 +92,7 @@ mod enter { elastic_paras, unavailable_cores, v2_descriptor, + candidate_modifier, }: TestConfig, ) -> Bench { let extra_cores = elastic_paras @@ -109,7 +111,8 @@ mod enter { .set_dispute_sessions(&dispute_sessions[..]) .set_fill_claimqueue(fill_claimqueue) .set_unavailable_cores(unavailable_cores) - .set_candidate_descriptor_v2(v2_descriptor); + .set_candidate_descriptor_v2(v2_descriptor) + .set_candidate_modifier(candidate_modifier); // Setup some assignments as needed: mock_assigner::Pallet::::set_core_count(builder.max_cores()); @@ -166,6 +169,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor, + candidate_modifier: None, }); // We expect the scenario to have cores 0 & 1 with pending availability. The backed @@ -269,6 +273,7 @@ mod enter { elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: vec![], v2_descriptor, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -371,6 +376,7 @@ mod enter { elastic_paras: [(2, 4)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), v2_descriptor: false, + candidate_modifier: None, }); let mut expected_para_inherent_data = scenario.data.clone(); @@ -628,6 +634,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -702,6 +709,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -774,6 +782,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -862,6 +871,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -950,6 +960,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1010,6 +1021,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1097,6 +1109,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1205,6 +1218,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1274,6 +1288,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1341,6 +1356,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1464,6 +1480,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor, + candidate_modifier: None, }); let mut para_inherent_data = scenario.data.clone(); @@ -1554,6 +1571,7 @@ mod enter { elastic_paras: BTreeMap::new(), unavailable_cores: vec![], v2_descriptor: false, + candidate_modifier: None, }); let expected_para_inherent_data = scenario.data.clone(); @@ -1613,6 +1631,7 @@ mod enter { elastic_paras: [(2, 8)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), v2_descriptor: true, + candidate_modifier: None, }); let mut unfiltered_para_inherent_data = scenario.data.clone(); @@ -1690,6 +1709,7 @@ mod enter { elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), v2_descriptor: false, + candidate_modifier: None, }); let inherent_data = scenario.data.clone(); @@ -1741,10 +1761,10 @@ mod enter { num_validators_per_core: 1, code_upgrade: None, fill_claimqueue: true, - // 3 cores elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), - v2_descriptor: false, + v2_descriptor: true, + candidate_modifier: None, }); let mut inherent_data = scenario.data.clone(); @@ -1773,8 +1793,81 @@ mod enter { }); } - // A test to ensure that the paras_inherent filters out candidates - // with invalid sesison index in the descriptor. + // Mixed test with v1, v2 with/without `UMPSignal::SelectCore` + #[test] + fn mixed_v1_and_v2_optional_commitments() { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::ElasticScalingMVP as u8, + true, + ) + .unwrap(); + + // Enable the v2 receipts. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + true, + ) + .unwrap(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); + backed_and_concluding.insert(3, 1); + backed_and_concluding.insert(4, 1); + + let unavailable_cores = vec![]; + + let candidate_modifier = |mut candidate: CommittedCandidateReceiptV2| { + // first candidate has v2 descriptor with no commitments + if candidate.descriptor.para_id() == ParaId::from(0) { + candidate.commitments.upward_messages.clear(); + } + + if candidate.descriptor.para_id() > ParaId::from(2) { + let mut v1: CandidateDescriptor = candidate.descriptor.into(); + + v1.collator = junk_collator(); + v1.signature = junk_collator_signature(); + + candidate.descriptor = v1.into(); + } + candidate + }; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 1, + code_upgrade: None, + fill_claimqueue: true, + elastic_paras: Default::default(), + unavailable_cores: unavailable_cores.clone(), + v2_descriptor: true, + candidate_modifier: Some(candidate_modifier), + }); + + let inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (2 validators per core, 5 backed candidates) + assert_eq!(inherent_data.bitfields.len(), 5); + // * 5 v2 candidate descriptors. + assert_eq!(inherent_data.backed_candidates.len(), 5); + + Pallet::::enter(frame_system::RawOrigin::None.into(), inherent_data).unwrap(); + }); + } + + // A test to ensure that the `paras_inherent`` filters out candidates with invalid + // session index in the descriptor. #[test] fn invalid_session_index() { let config = default_config(); @@ -1813,6 +1906,7 @@ mod enter { elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores, v2_descriptor: true, + candidate_modifier: None, }); let mut inherent_data = scenario.data.clone(); From d3202699a4c37e3e2748f885a8be797c3255f082 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 4 Sep 2024 18:24:18 +0300 Subject: [PATCH 079/130] Add allowed relay parents storage migration Signed-off-by: Andrei Sandu --- .../parachains/src/paras_inherent/mod.rs | 1 - polkadot/runtime/parachains/src/shared.rs | 4 + .../parachains/src/shared/migration.rs | 174 ++++++++++++++++++ polkadot/runtime/rococo/src/lib.rs | 1 + polkadot/runtime/westend/src/lib.rs | 1 + 5 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 polkadot/runtime/parachains/src/shared/migration.rs diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index fced2ad8a512..554ba505abf8 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -1512,7 +1512,6 @@ fn map_candidates_to_cores(allowed_relay_parents, &candidate) { - println!("Core index: {:?}", core_index); if scheduled_cores.remove(&core_index) { temp_backed_candidates.push((candidate, core_index)); } else { diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index 7330fcea72c1..4e877607d92e 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -40,9 +40,13 @@ pub use pallet::*; // which guarantees that at least one full session has passed before any changes are applied. pub(crate) const SESSION_DELAY: SessionIndex = 2; +const LOG_TARGET: &str = "runtime::inclusion"; + #[cfg(test)] mod tests; +mod migration; + /// Information about a relay parent. #[derive(Encode, Decode, Default, TypeInfo, Debug)] pub struct RelayParentInfo { diff --git a/polkadot/runtime/parachains/src/shared/migration.rs b/polkadot/runtime/parachains/src/shared/migration.rs new file mode 100644 index 000000000000..46ee89912e8b --- /dev/null +++ b/polkadot/runtime/parachains/src/shared/migration.rs @@ -0,0 +1,174 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +use super::*; +use codec::{Decode, Encode}; +use frame_support::{ + pallet_prelude::ValueQuery, traits::UncheckedOnRuntimeUpgrade, weights::Weight, +}; +pub use v1::MigrateToV1; + +pub mod v0 { + use super::*; + use alloc::collections::vec_deque::VecDeque; + + #[derive(Encode, Decode, Default, TypeInfo)] + pub struct AllowedRelayParentsTracker { + // The past relay parents, paired with state roots, that are viable to build upon. + // + // They are in ascending chronologic order, so the newest relay parents are at + // the back of the deque. + // + // (relay_parent, state_root) + pub buffer: VecDeque<(Hash, Hash)>, + + // The number of the most recent relay-parent, if any. + // If the buffer is empty, this value has no meaning and may + // be nonsensical. + pub latest_number: BlockNumber, + } + + impl From> + for super::AllowedRelayParentsTracker + { + fn from(value: AllowedRelayParentsTracker) -> Self { + Self { + latest_number: value.latest_number, + buffer: value + .buffer + .into_iter() + .map(|(relay_parent, state_root)| super::RelayParentInfo { + relay_parent, + state_root, + claim_queue: Default::default(), + }) + .collect(), + } + } + } +} + +mod v1 { + use super::*; + use alloc::vec::Vec; + + use codec::Decode; + #[cfg(feature = "try-runtime")] + use frame_support::{ + ensure, + traits::{GetStorageVersion, StorageVersion}, + }; + + use frame_support::storage_alias; + + /// All allowed relay-parents storage at version 0. + #[storage_alias] + pub(crate) type AllowedRelayParents = StorageValue< + Pallet, + super::v0::AllowedRelayParentsTracker<::Hash, BlockNumberFor>, + ValueQuery, + >; + + pub struct VersionUncheckedMigrateToV1(core::marker::PhantomData); + + impl UncheckedOnRuntimeUpgrade for VersionUncheckedMigrateToV1 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + log::trace!(target: crate::shared::LOG_TARGET, "Running pre_upgrade() for inclusion MigrateToV1"); + let bytes = u32::to_ne_bytes(AllowedRelayParents::::get().buffer.len() as u32); + + Ok(bytes.to_vec()) + } + + fn on_runtime_upgrade() -> Weight { + let mut weight: Weight = Weight::zero(); + + // Read old storage. + let old_rp_tracker = AllowedRelayParents::::take(); + + super::AllowedRelayParents::::set(old_rp_tracker.into()); + + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + + weight + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + log::trace!(target: crate::shared::LOG_TARGET, "Running post_upgrade() for inclusion MigrateToV1"); + ensure!( + Pallet::::on_chain_storage_version() >= StorageVersion::new(1), + "Storage version should be >= 1 after the migration" + ); + + let relay_parent_count = + u32::decode(&mut &state[..]).expect("Was properly encoded") as usize; + + let rp_tracker = AllowedRelayParents::::get(); + + ensure!( + relay_parent_count == rp_tracker.buffer.len(), + "Number of allowed relay parents should be the same as the one before the upgrade." + ); + + Ok(()) + } + } + + /// Migrate shared module storage to v1. + pub type MigrateToV1 = frame_support::migrations::VersionedMigration< + 0, + 1, + VersionUncheckedMigrateToV1, + Pallet, + ::DbWeight, + >; +} + +#[cfg(test)] +mod tests { + use super::{v1::VersionUncheckedMigrateToV1, *}; + use crate::mock::{new_test_ext, MockGenesisConfig, Test}; + use frame_support::traits::UncheckedOnRuntimeUpgrade; + use polkadot_primitives::Hash; + + #[test] + fn migrate_to_v1() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let rp_tracker = v0::AllowedRelayParentsTracker { + latest_number: 9, + buffer: (0..10u64) + .into_iter() + .map(|idx| (Hash::from_low_u64_ne(idx), Hash::from_low_u64_ne(2 * idx))) + .collect::>(), + }; + + v1::AllowedRelayParents::::put(rp_tracker); + + as UncheckedOnRuntimeUpgrade>::on_runtime_upgrade(); + + let rp_tracker = AllowedRelayParents::::get(); + + for idx in 0..10u64 { + let relay_parent = Hash::from_low_u64_ne(idx); + let state_root = Hash::from_low_u64_ne(2 * idx); + let (info, block_num) = rp_tracker.acquire_info(relay_parent, None).unwrap(); + + assert!(info.claim_queue.is_empty()); + assert_eq!(info.relay_parent, relay_parent); + assert_eq!(info.state_root, state_root); + assert_eq!(block_num as u64, idx); + } + }); + } +} diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 6b046e190830..bae376bc49a0 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1679,6 +1679,7 @@ pub mod migrations { // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, parachains_inclusion::migration::MigrateToV1, + parachains_shared::migration::MigrateToV1, ); } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index b02c2d8c671e..e2c334e4edb4 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1786,6 +1786,7 @@ pub mod migrations { Runtime, MaxAgentsToMigrate, >, + parachains_shared::migration::MigrateToV1, ); } From 8490488088e735fa5940c6bf2dbf8b4a20eeabf0 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 15:34:08 +0300 Subject: [PATCH 080/130] fix migration Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 3 -- polkadot/runtime/parachains/src/shared.rs | 7 +++-- .../parachains/src/shared/migration.rs | 28 ++++++++++--------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index e8598aa87600..cd6f1b85cfe0 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -337,10 +337,8 @@ impl CandidateCommitments { /// `assigned_cores` must be a sorted vec of all core indices assigned to a parachain. pub fn committed_core_index(&self, assigned_cores: &[&CoreIndex]) -> Option { if assigned_cores.is_empty() { - println!("Assigned cores empty"); return None } - println!("Selected core: {:?}", self.selected_core()); self.selected_core().and_then(|(core_selector, _cq_offset)| { let core_index = @@ -473,7 +471,6 @@ impl CommittedCandidateReceiptV2 { } if claim_queue.is_empty() { - println!("cq empty"); return Err(CandidateReceiptError::NoAssignment) } diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index 4e877607d92e..f9d534660b7c 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -40,12 +40,10 @@ pub use pallet::*; // which guarantees that at least one full session has passed before any changes are applied. pub(crate) const SESSION_DELAY: SessionIndex = 2; -const LOG_TARGET: &str = "runtime::inclusion"; - #[cfg(test)] mod tests; -mod migration; +pub mod migration; /// Information about a relay parent. #[derive(Encode, Decode, Default, TypeInfo, Debug)] @@ -142,8 +140,11 @@ impl pub mod pallet { use super::*; + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + #[pallet::pallet] #[pallet::without_storage_info] + #[pallet::storage_version(STORAGE_VERSION)] pub struct Pallet(_); #[pallet::config] diff --git a/polkadot/runtime/parachains/src/shared/migration.rs b/polkadot/runtime/parachains/src/shared/migration.rs index 46ee89912e8b..77c646ed0aa3 100644 --- a/polkadot/runtime/parachains/src/shared/migration.rs +++ b/polkadot/runtime/parachains/src/shared/migration.rs @@ -16,7 +16,9 @@ use codec::{Decode, Encode}; use frame_support::{ pallet_prelude::ValueQuery, traits::UncheckedOnRuntimeUpgrade, weights::Weight, }; -pub use v1::MigrateToV1; + +#[cfg(feature = "try-runtime")] +const LOG_TARGET: &str = "runtime::shared"; pub mod v0 { use super::*; @@ -60,8 +62,8 @@ pub mod v0 { mod v1 { use super::*; - use alloc::vec::Vec; + #[cfg(feature = "try-runtime")] use codec::Decode; #[cfg(feature = "try-runtime")] use frame_support::{ @@ -84,7 +86,7 @@ mod v1 { impl UncheckedOnRuntimeUpgrade for VersionUncheckedMigrateToV1 { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { - log::trace!(target: crate::shared::LOG_TARGET, "Running pre_upgrade() for inclusion MigrateToV1"); + log::trace!(LOG_TARGET, "Running pre_upgrade() for inclusion MigrateToV1"); let bytes = u32::to_ne_bytes(AllowedRelayParents::::get().buffer.len() as u32); Ok(bytes.to_vec()) @@ -105,7 +107,7 @@ mod v1 { #[cfg(feature = "try-runtime")] fn post_upgrade(state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { - log::trace!(target: crate::shared::LOG_TARGET, "Running post_upgrade() for inclusion MigrateToV1"); + log::trace!(target: LOG_TARGET, "Running post_upgrade() for inclusion MigrateToV1"); ensure!( Pallet::::on_chain_storage_version() >= StorageVersion::new(1), "Storage version should be >= 1 after the migration" @@ -124,17 +126,17 @@ mod v1 { Ok(()) } } - - /// Migrate shared module storage to v1. - pub type MigrateToV1 = frame_support::migrations::VersionedMigration< - 0, - 1, - VersionUncheckedMigrateToV1, - Pallet, - ::DbWeight, - >; } +/// Migrate shared module storage to v1. +pub type MigrateToV1 = frame_support::migrations::VersionedMigration< + 0, + 1, + v1::VersionUncheckedMigrateToV1, + Pallet, + ::DbWeight, +>; + #[cfg(test)] mod tests { use super::{v1::VersionUncheckedMigrateToV1, *}; From db6748630f4d2a91006f8ff3ac5dc6352db99291 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 15:46:14 +0300 Subject: [PATCH 081/130] fix Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/shared/migration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/shared/migration.rs b/polkadot/runtime/parachains/src/shared/migration.rs index 77c646ed0aa3..0126f817e0da 100644 --- a/polkadot/runtime/parachains/src/shared/migration.rs +++ b/polkadot/runtime/parachains/src/shared/migration.rs @@ -86,7 +86,7 @@ mod v1 { impl UncheckedOnRuntimeUpgrade for VersionUncheckedMigrateToV1 { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { - log::trace!(LOG_TARGET, "Running pre_upgrade() for inclusion MigrateToV1"); + log::trace!(target: LOG_TARGET, "Running pre_upgrade() for inclusion MigrateToV1"); let bytes = u32::to_ne_bytes(AllowedRelayParents::::get().buffer.len() as u32); Ok(bytes.to_vec()) From 03cf8c1d405ecee7e19eaa04bc95c13156a50d2f Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 16:11:43 +0300 Subject: [PATCH 082/130] clippy Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/tests.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 1a0078e62d29..b411e71d532c 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -15,16 +15,12 @@ // along with Polkadot. If not, see . use super::*; -use rstest::rstest; use crate::{ configuration::{self, HostConfiguration}, mock::MockGenesisConfig, }; -use polkadot_primitives::{ - vstaging::{ClaimQueueOffset, CoreSelector, UMPSignal, UMP_SEPARATOR}, - SchedulerParams, -}; +use polkadot_primitives::SchedulerParams; fn default_config() -> MockGenesisConfig { MockGenesisConfig { @@ -48,6 +44,9 @@ fn default_config() -> MockGenesisConfig { #[cfg(not(feature = "runtime-benchmarks"))] mod enter { use super::{inclusion::tests::TestCandidateBuilder, *}; + use polkadot_primitives::vstaging::{ClaimQueueOffset, CoreSelector, UMPSignal, UMP_SEPARATOR}; + use rstest::rstest; + use crate::{ builder::{junk_collator, junk_collator_signature, Bench, BenchBuilder, CandidateModifier}, mock::{mock_assigner, new_test_ext, BlockLength, BlockWeights, RuntimeOrigin, Test}, From 43f6de755895d5c683c9b18abc9275abb2bcbe96 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 16:17:33 +0300 Subject: [PATCH 083/130] feedback Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 20 +++++++++---------- .../parachains/src/paras_inherent/mod.rs | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index cd6f1b85cfe0..23bb19a2f85d 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -458,7 +458,7 @@ impl CommittedCandidateReceiptV2 { /// Checks if descriptor core index is equal to the committed core index. /// Input `claim_queue` must contain a snapshot of the claim queue at the /// candidate relay parent. - pub fn check( + pub fn check_core_index( &self, claim_queue: &BTreeMap>, ) -> Result<(), CandidateReceiptError> { @@ -839,7 +839,7 @@ mod tests { assert_eq!(new_ccr.descriptor.version(), CandidateDescriptorVersion::Unknown); assert_eq!( - new_ccr.check(&BTreeMap::new()), + new_ccr.check_core_index(&BTreeMap::new()), Err(CandidateReceiptError::UnknownVersion(InternalVersion(100))) ) } @@ -869,7 +869,7 @@ mod tests { vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); - assert_eq!(new_ccr.check(&cq), Ok(())); + assert_eq!(new_ccr.check_core_index(&cq), Ok(())); } #[test] @@ -886,7 +886,7 @@ mod tests { // The check should not fail because no `SelectCore` signal was sent. // The message is optional. - assert!(new_ccr.check(&cq).is_ok()); + assert!(new_ccr.check_core_index(&cq).is_ok()); // Garbage message. new_ccr.commitments.upward_messages.force_push(vec![0, 13, 200].encode()); @@ -904,7 +904,7 @@ mod tests { vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); - assert_eq!(new_ccr.check(&cq), Err(CandidateReceiptError::NoCoreSelected)); + assert_eq!(new_ccr.check_core_index(&cq), Err(CandidateReceiptError::NoCoreSelected)); new_ccr.commitments.upward_messages.clear(); new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); @@ -921,7 +921,7 @@ mod tests { .force_push(UMPSignal::SelectCore(CoreSelector(1), ClaimQueueOffset(1)).encode()); // Duplicate doesn't override first signal. - assert_eq!(new_ccr.check(&cq), Ok(())); + assert_eq!(new_ccr.check_core_index(&cq), Ok(())); } #[test] @@ -965,7 +965,7 @@ mod tests { vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); - assert_eq!(new_ccr.check(&cq), Ok(())); + assert_eq!(new_ccr.check_core_index(&cq), Ok(())); assert_eq!(new_ccr.hash(), v2_ccr.hash()); } @@ -997,7 +997,7 @@ mod tests { cq.insert(CoreIndex(0), vec![v1_ccr.descriptor.para_id()].into()); cq.insert(CoreIndex(1), vec![v1_ccr.descriptor.para_id()].into()); - assert!(v1_ccr.check(&cq).is_ok()); + assert!(v1_ccr.check_core_index(&cq).is_ok()); assert_eq!( v1_ccr.commitments.committed_core_index(&vec![&CoreIndex(10), &CoreIndex(5)]), @@ -1022,14 +1022,14 @@ mod tests { // Since collator sig and id are zeroed, it means that the descriptor uses format // version 2. Should still pass checks without core selector. - assert!(new_ccr.check(&cq).is_ok()); + assert!(new_ccr.check_core_index(&cq).is_ok()); let mut cq = BTreeMap::new(); cq.insert(CoreIndex(0), vec![new_ccr.descriptor.para_id()].into()); cq.insert(CoreIndex(1), vec![new_ccr.descriptor.para_id()].into()); // Should fail because 2 cores are assigned, - assert_eq!(new_ccr.check(&cq), Err(CandidateReceiptError::NoCoreSelected)); + assert_eq!(new_ccr.check_core_index(&cq), Err(CandidateReceiptError::NoCoreSelected)); // Adding collator signature should make it decode as v1. old_ccr.descriptor.signature = dummy_collator_signature(); diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 554ba505abf8..8ffbc635fae2 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -1045,8 +1045,8 @@ fn sanitize_backed_candidate_v2( return false }; - // Check validity of `core_index` and `session_index`. - if let Err(err) = candidate.candidate().check(&rp_info.claim_queue) { + // Check validity of `core_index`. + if let Err(err) = candidate.candidate().check_core_index(&rp_info.claim_queue) { log::debug!( target: LOG_TARGET, "Dropping candidate {:?} for paraid {:?}, {:?}", From 70e48d2e83eb4177661d38f6f7054c64fb2337a0 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 19:09:16 +0300 Subject: [PATCH 084/130] sir, make it faster Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 26 ++++------ polkadot/runtime/parachains/src/shared.rs | 28 +++++++++-- .../runtime/parachains/src/shared/tests.rs | 49 +++++++++++++++++++ 3 files changed, 82 insertions(+), 21 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 23bb19a2f85d..83ddd64587a6 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -25,7 +25,7 @@ use super::{ UncheckedSignedAvailabilityBitfields, ValidationCodeHash, }; use alloc::{ - collections::{BTreeMap, VecDeque}, + collections::{BTreeMap, BTreeSet, VecDeque}, vec, vec::Vec, }; @@ -460,7 +460,7 @@ impl CommittedCandidateReceiptV2 { /// candidate relay parent. pub fn check_core_index( &self, - claim_queue: &BTreeMap>, + cores_per_para: &BTreeMap>>, ) -> Result<(), CandidateReceiptError> { match self.descriptor.version() { // Don't check v1 descriptors. @@ -470,7 +470,7 @@ impl CommittedCandidateReceiptV2 { return Err(CandidateReceiptError::UnknownVersion(self.descriptor.version)), } - if claim_queue.is_empty() { + if cores_per_para.is_empty() { return Err(CandidateReceiptError::NoAssignment) } @@ -483,20 +483,12 @@ impl CommittedCandidateReceiptV2 { }; // The cores assigned to the parachain at above computed offset. - // - // TODO: this might be inneficient to do for each candidate. - // A BTreeMap> can be computed - // once per relay chain block, making this search here much faster. - let assigned_cores = claim_queue - .iter() - .filter_map(move |(core_index, paras)| { - let para_at_offset = *paras.get(offset)?; - if para_at_offset == self.descriptor.para_id() { - Some(core_index) - } else { - None - } - }) + let assigned_cores = cores_per_para + .get(&self.descriptor.para_id()) + .ok_or(CandidateReceiptError::NoAssignment)? + .get(offset) + .ok_or(CandidateReceiptError::NoAssignment)? + .into_iter() .collect::>(); let core_index = if core_selected { diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index f9d534660b7c..511a6aff4258 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -20,7 +20,7 @@ //! dependent on any of the other pallets. use alloc::{ - collections::{btree_map::BTreeMap, vec_deque::VecDeque}, + collections::{btree_map::BTreeMap, btree_set::BTreeSet, vec_deque::VecDeque}, vec::Vec, }; use frame_support::{pallet_prelude::*, traits::DisabledValidators}; @@ -52,8 +52,9 @@ pub struct RelayParentInfo { pub relay_parent: Hash, // The state root at this block pub state_root: Hash, - // Claim queue snapshot - pub claim_queue: BTreeMap>, + // Claim queue snapshot, optimized for accessing the assignments by `ParaId`. + // For each para we store the cores assigned per depth. + pub claim_queue: BTreeMap>>, } /// Keeps tracks of information about all viable relay parents. @@ -85,10 +86,29 @@ impl number: BlockNumber, max_ancestry_len: u32, ) { + let mut per_para_claim_queue = BTreeMap::new(); + + // Re-map the claim queue by `ParaId`. + for (core, paras) in claim_queue { + // Iterate paras assigned to this core at each depth. + for (depth, para) in paras.into_iter().enumerate() { + let depths: &mut VecDeque> = + per_para_claim_queue.entry(para).or_default(); + let initialize_count = depth.saturating_sub(depths.len()) + 1; + depths.extend((0..initialize_count).into_iter().map(|_| BTreeSet::new())); + + depths[depth].insert(core); + } + } + // + 1 for the most recent block, which is always allowed. let buffer_size_limit = max_ancestry_len as usize + 1; - self.buffer.push_back(RelayParentInfo { relay_parent, state_root, claim_queue }); + self.buffer.push_back(RelayParentInfo { + relay_parent, + state_root, + claim_queue: per_para_claim_queue, + }); self.latest_number = number; while self.buffer.len() > buffer_size_limit { diff --git a/polkadot/runtime/parachains/src/shared/tests.rs b/polkadot/runtime/parachains/src/shared/tests.rs index fd4b6555a48c..32e6afa4f21b 100644 --- a/polkadot/runtime/parachains/src/shared/tests.rs +++ b/polkadot/runtime/parachains/src/shared/tests.rs @@ -52,6 +52,55 @@ fn tracker_earliest_block_number() { assert_eq!(tracker.hypothetical_earliest_block_number(now + 1, max_ancestry_len), 1); } +#[test] +fn tracker_claim_queue_remap() { + let mut tracker = AllowedRelayParentsTracker::::default(); + + let mut claim_queue = BTreeMap::new(); + claim_queue.insert(CoreIndex(0), vec![Id::from(0), Id::from(1), Id::from(2)].into()); + claim_queue.insert(CoreIndex(1), vec![Id::from(0), Id::from(0), Id::from(100)].into()); + claim_queue.insert(CoreIndex(2), vec![Id::from(1), Id::from(2), Id::from(100)].into()); + + tracker.update(Hash::zero(), Hash::zero(), claim_queue, 1u32, 3u32); + + let (info, _block_num) = tracker.acquire_info(Hash::zero(), None).unwrap(); + assert_eq!( + info.claim_queue.get(&Id::from(0)).unwrap()[0], + vec![CoreIndex(0), CoreIndex(1)].into_iter().collect::>() + ); + assert_eq!( + info.claim_queue.get(&Id::from(1)).unwrap()[0], + vec![CoreIndex(2)].into_iter().collect::>() + ); + assert_eq!(info.claim_queue.get(&Id::from(2)).unwrap()[0], BTreeSet::new()); + assert_eq!(info.claim_queue.get(&Id::from(100)).unwrap()[0], BTreeSet::new()); + + assert_eq!( + info.claim_queue.get(&Id::from(0)).unwrap()[1], + vec![CoreIndex(0)].into_iter().collect::>() + ); + assert_eq!( + info.claim_queue.get(&Id::from(1)).unwrap()[1], + vec![CoreIndex(1)].into_iter().collect::>() + ); + assert_eq!( + info.claim_queue.get(&Id::from(2)).unwrap()[1], + vec![CoreIndex(2)].into_iter().collect::>() + ); + assert_eq!(info.claim_queue.get(&Id::from(100)).unwrap()[1], BTreeSet::new()); + + assert_eq!(info.claim_queue.get(&Id::from(0)).unwrap()[1], BTreeSet::new()); + assert_eq!(info.claim_queue.get(&Id::from(1)).unwrap()[1], BTreeSet::new()); + assert_eq!( + info.claim_queue.get(&Id::from(2)).unwrap()[1], + vec![CoreIndex(0)].into_iter().collect::>() + ); + assert_eq!( + info.claim_queue.get(&Id::from(100)).unwrap()[1], + vec![CoreIndex(1), CoreIndex(1)].into_iter().collect::>() + ); +} + #[test] fn tracker_acquire_info() { let mut tracker = AllowedRelayParentsTracker::::default(); From 1e26c7315b7124db20df1a350e61c7df6f419b55 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 19:09:54 +0300 Subject: [PATCH 085/130] fix Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/shared/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/runtime/parachains/src/shared/tests.rs b/polkadot/runtime/parachains/src/shared/tests.rs index 32e6afa4f21b..936f21694ac9 100644 --- a/polkadot/runtime/parachains/src/shared/tests.rs +++ b/polkadot/runtime/parachains/src/shared/tests.rs @@ -77,11 +77,11 @@ fn tracker_claim_queue_remap() { assert_eq!( info.claim_queue.get(&Id::from(0)).unwrap()[1], - vec![CoreIndex(0)].into_iter().collect::>() + vec![CoreIndex(1)].into_iter().collect::>() ); assert_eq!( info.claim_queue.get(&Id::from(1)).unwrap()[1], - vec![CoreIndex(1)].into_iter().collect::>() + vec![CoreIndex(0)].into_iter().collect::>() ); assert_eq!( info.claim_queue.get(&Id::from(2)).unwrap()[1], From f4e3fb5873e790a55680b4f02bcfcfad22f440f4 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 19:11:18 +0300 Subject: [PATCH 086/130] one last fix Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/shared/tests.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/polkadot/runtime/parachains/src/shared/tests.rs b/polkadot/runtime/parachains/src/shared/tests.rs index 936f21694ac9..a78610903eaf 100644 --- a/polkadot/runtime/parachains/src/shared/tests.rs +++ b/polkadot/runtime/parachains/src/shared/tests.rs @@ -89,15 +89,15 @@ fn tracker_claim_queue_remap() { ); assert_eq!(info.claim_queue.get(&Id::from(100)).unwrap()[1], BTreeSet::new()); - assert_eq!(info.claim_queue.get(&Id::from(0)).unwrap()[1], BTreeSet::new()); - assert_eq!(info.claim_queue.get(&Id::from(1)).unwrap()[1], BTreeSet::new()); + assert_eq!(info.claim_queue.get(&Id::from(0)).unwrap()[2], BTreeSet::new()); + assert_eq!(info.claim_queue.get(&Id::from(1)).unwrap()[2], BTreeSet::new()); assert_eq!( - info.claim_queue.get(&Id::from(2)).unwrap()[1], + info.claim_queue.get(&Id::from(2)).unwrap()[2], vec![CoreIndex(0)].into_iter().collect::>() ); assert_eq!( - info.claim_queue.get(&Id::from(100)).unwrap()[1], - vec![CoreIndex(1), CoreIndex(1)].into_iter().collect::>() + info.claim_queue.get(&Id::from(100)).unwrap()[2], + vec![CoreIndex(1), CoreIndex(2)].into_iter().collect::>() ); } From 2e87ad3979f22167fd75a7a5852d7b22c4da5678 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 23:34:50 +0300 Subject: [PATCH 087/130] fixes Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 45 +++++++++++++++---- polkadot/runtime/parachains/src/shared.rs | 25 +++-------- .../runtime/parachains/src/shared/tests.rs | 4 +- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 83ddd64587a6..a21f2fa00392 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -750,6 +750,29 @@ impl From> for super::v8::CoreState { } } +/// Returns a mapping between the para id and the core indices assigned at different +/// depths in the claim queue. +pub fn remap_claim_queue( + claim_queue: BTreeMap>, +) -> BTreeMap>> { + let mut per_para_claim_queue = BTreeMap::new(); + + for (core, paras) in claim_queue { + // Iterate paras assigned to this core at each depth. + for (depth, para) in paras.into_iter().enumerate() { + let depths: &mut VecDeque> = + per_para_claim_queue.entry(para).or_insert_with(|| Default::default()); + + let initialize_count = (depth + 1).saturating_sub(depths.len()); + depths.extend((0..initialize_count).into_iter().map(|_| BTreeSet::new())); + depths[depth].insert(core); + } + } + + println!("Remaped CQ: {:?}", per_para_claim_queue); + per_para_claim_queue +} + #[cfg(test)] mod tests { use super::*; @@ -861,7 +884,7 @@ mod tests { vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); - assert_eq!(new_ccr.check_core_index(&cq), Ok(())); + assert_eq!(new_ccr.check_core_index(&remap_claim_queue(cq)), Ok(())); } #[test] @@ -878,7 +901,7 @@ mod tests { // The check should not fail because no `SelectCore` signal was sent. // The message is optional. - assert!(new_ccr.check_core_index(&cq).is_ok()); + assert!(new_ccr.check_core_index(&remap_claim_queue(cq)).is_ok()); // Garbage message. new_ccr.commitments.upward_messages.force_push(vec![0, 13, 200].encode()); @@ -896,7 +919,10 @@ mod tests { vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); - assert_eq!(new_ccr.check_core_index(&cq), Err(CandidateReceiptError::NoCoreSelected)); + assert_eq!( + new_ccr.check_core_index(&remap_claim_queue(cq.clone())), + Err(CandidateReceiptError::NoCoreSelected) + ); new_ccr.commitments.upward_messages.clear(); new_ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); @@ -913,7 +939,7 @@ mod tests { .force_push(UMPSignal::SelectCore(CoreSelector(1), ClaimQueueOffset(1)).encode()); // Duplicate doesn't override first signal. - assert_eq!(new_ccr.check_core_index(&cq), Ok(())); + assert_eq!(new_ccr.check_core_index(&remap_claim_queue(cq)), Ok(())); } #[test] @@ -957,7 +983,7 @@ mod tests { vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); - assert_eq!(new_ccr.check_core_index(&cq), Ok(())); + assert_eq!(new_ccr.check_core_index(&remap_claim_queue(cq)), Ok(())); assert_eq!(new_ccr.hash(), v2_ccr.hash()); } @@ -989,7 +1015,7 @@ mod tests { cq.insert(CoreIndex(0), vec![v1_ccr.descriptor.para_id()].into()); cq.insert(CoreIndex(1), vec![v1_ccr.descriptor.para_id()].into()); - assert!(v1_ccr.check_core_index(&cq).is_ok()); + assert!(v1_ccr.check_core_index(&remap_claim_queue(cq)).is_ok()); assert_eq!( v1_ccr.commitments.committed_core_index(&vec![&CoreIndex(10), &CoreIndex(5)]), @@ -1014,14 +1040,17 @@ mod tests { // Since collator sig and id are zeroed, it means that the descriptor uses format // version 2. Should still pass checks without core selector. - assert!(new_ccr.check_core_index(&cq).is_ok()); + assert!(new_ccr.check_core_index(&remap_claim_queue(cq)).is_ok()); let mut cq = BTreeMap::new(); cq.insert(CoreIndex(0), vec![new_ccr.descriptor.para_id()].into()); cq.insert(CoreIndex(1), vec![new_ccr.descriptor.para_id()].into()); // Should fail because 2 cores are assigned, - assert_eq!(new_ccr.check_core_index(&cq), Err(CandidateReceiptError::NoCoreSelected)); + assert_eq!( + new_ccr.check_core_index(&remap_claim_queue(cq)), + Err(CandidateReceiptError::NoCoreSelected) + ); // Adding collator signature should make it decode as v1. old_ccr.descriptor.signature = dummy_collator_signature(); diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index 511a6aff4258..4e982313791c 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -25,7 +25,9 @@ use alloc::{ }; use frame_support::{pallet_prelude::*, traits::DisabledValidators}; use frame_system::pallet_prelude::BlockNumberFor; -use polkadot_primitives::{CoreIndex, Id, SessionIndex, ValidatorId, ValidatorIndex}; +use polkadot_primitives::{ + vstaging::remap_claim_queue, CoreIndex, Id, SessionIndex, ValidatorId, ValidatorIndex, +}; use sp_runtime::traits::AtLeast32BitUnsigned; use rand::{seq::SliceRandom, SeedableRng}; @@ -86,29 +88,12 @@ impl number: BlockNumber, max_ancestry_len: u32, ) { - let mut per_para_claim_queue = BTreeMap::new(); - - // Re-map the claim queue by `ParaId`. - for (core, paras) in claim_queue { - // Iterate paras assigned to this core at each depth. - for (depth, para) in paras.into_iter().enumerate() { - let depths: &mut VecDeque> = - per_para_claim_queue.entry(para).or_default(); - let initialize_count = depth.saturating_sub(depths.len()) + 1; - depths.extend((0..initialize_count).into_iter().map(|_| BTreeSet::new())); - - depths[depth].insert(core); - } - } + let claim_queue = remap_claim_queue(claim_queue); // + 1 for the most recent block, which is always allowed. let buffer_size_limit = max_ancestry_len as usize + 1; - self.buffer.push_back(RelayParentInfo { - relay_parent, - state_root, - claim_queue: per_para_claim_queue, - }); + self.buffer.push_back(RelayParentInfo { relay_parent, state_root, claim_queue }); self.latest_number = number; while self.buffer.len() > buffer_size_limit { diff --git a/polkadot/runtime/parachains/src/shared/tests.rs b/polkadot/runtime/parachains/src/shared/tests.rs index a78610903eaf..fb04db5d79bb 100644 --- a/polkadot/runtime/parachains/src/shared/tests.rs +++ b/polkadot/runtime/parachains/src/shared/tests.rs @@ -89,8 +89,8 @@ fn tracker_claim_queue_remap() { ); assert_eq!(info.claim_queue.get(&Id::from(100)).unwrap()[1], BTreeSet::new()); - assert_eq!(info.claim_queue.get(&Id::from(0)).unwrap()[2], BTreeSet::new()); - assert_eq!(info.claim_queue.get(&Id::from(1)).unwrap()[2], BTreeSet::new()); + assert_eq!(info.claim_queue.get(&Id::from(0)).unwrap().get(2), None); + assert_eq!(info.claim_queue.get(&Id::from(1)).unwrap().get(2), None); assert_eq!( info.claim_queue.get(&Id::from(2)).unwrap()[2], vec![CoreIndex(0)].into_iter().collect::>() From 54432becf69429854ab46e21268df011f7498370 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 5 Sep 2024 23:36:05 +0300 Subject: [PATCH 088/130] remove println Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index a21f2fa00392..1a08aa691687 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -769,7 +769,6 @@ pub fn remap_claim_queue( } } - println!("Remaped CQ: {:?}", per_para_claim_queue); per_para_claim_queue } From cfbecb0e16c8b92878562558f195e13e21fe8603 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 6 Sep 2024 18:09:47 +0300 Subject: [PATCH 089/130] add prdoc Signed-off-by: Andrei Sandu --- prdoc/pr_5423.prdoc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 prdoc/pr_5423.prdoc diff --git a/prdoc/pr_5423.prdoc b/prdoc/pr_5423.prdoc new file mode 100644 index 000000000000..ee75b3d7849a --- /dev/null +++ b/prdoc/pr_5423.prdoc @@ -0,0 +1,18 @@ +title: Runtime support for candidate receipt v2 (RFC103) + +doc: + - audience: [Runtime Dev, Node Dev] + description: | + Implementation of [RFC103](https://github.com/polkadot-fellows/RFCs/pull/103) in the relay chain runtime. + The runtime will accept and validate the new receipts only if the `FeatureIndex::CandidateReceiptV2` + feature bit is enabled. + +crates: + - name: polkadot-primitives + bump: major + - name: polkadot-runtime-parachains + bump: patch + - name: rococo-runtime + bump: patch + - name: westend-runtime + bump: patch \ No newline at end of file From 3a518f25066a18b750ae8a3b5eaaf80fa4a13ee4 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 6 Sep 2024 18:16:21 +0300 Subject: [PATCH 090/130] fix comment Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 1a08aa691687..6bdbfc632705 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -456,8 +456,8 @@ impl CandidateDescriptorV2 { impl CommittedCandidateReceiptV2 { /// Checks if descriptor core index is equal to the committed core index. - /// Input `claim_queue` must contain a snapshot of the claim queue at the - /// candidate relay parent. + /// Input `cores_per_para` is a claim queue snapshot stored as a mapping + /// between `ParaId` and the cores assigned per depth. pub fn check_core_index( &self, cores_per_para: &BTreeMap>>, From 54106e254fb753307376d26e6645a9eab2300565 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 6 Sep 2024 19:01:45 +0300 Subject: [PATCH 091/130] refactor map_candidates_to_cores Signed-off-by: Andrei Sandu --- .../parachains/src/paras_inherent/mod.rs | 175 +++++++++--------- 1 file changed, 84 insertions(+), 91 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 8ffbc635fae2..3db9cee6db31 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -1467,104 +1467,96 @@ fn map_candidates_to_cores= 1 && core_index_enabled { - // We must preserve the dependency order given in the input. - let mut temp_backed_candidates = Vec::with_capacity(scheduled_cores.len()); - - for candidate in backed_candidates { - if scheduled_cores.len() == 0 { - // We've got candidates for all of this para's assigned cores. Move on to - // the next para. - log::debug!( - target: LOG_TARGET, - "Found enough candidates for paraid: {:?}.", - candidate.descriptor().para_id() - ); - break; - } - - if let Some(core_index) = get_core_index::(allowed_relay_parents, &candidate) - { - if scheduled_cores.remove(&core_index) { - temp_backed_candidates.push((candidate, core_index)); - } else { - // if we got a candidate for a core index which is not scheduled, stop - // the work for this para. the already processed candidate chain in - // temp_backed_candidates is still fine though. - log::debug!( - target: LOG_TARGET, - "Found a backed candidate {:?} with core index {}, which is not scheduled for paraid {:?}.", - candidate.candidate().hash(), - core_index.0, - candidate.descriptor().para_id() - ); - - break; - } - } else { - // if we got a candidate which does not contain its core index, stop the - // work for this para. the already processed candidate chain in - // temp_backed_candidates is still fine though. - - log::debug!( - target: LOG_TARGET, - "Found a backed candidate {:?} without core index informationm, but paraid {:?} has multiple scheduled cores.", - candidate.candidate().hash(), - candidate.descriptor().para_id() - ); - - break; - } - } + if let Some(core_index) = + get_core_index::(core_index_enabled, allowed_relay_parents, &candidate) + { + if scheduled_cores.remove(&core_index) { + temp_backed_candidates.push((candidate, core_index)); + } else { + // if we got a candidate for a core index which is not scheduled, stop + // the work for this para. the already processed candidate chain in + // temp_backed_candidates is still fine though. + log::debug!( + target: LOG_TARGET, + "Found a backed candidate {:?} with core index {}, which is not scheduled for paraid {:?}.", + candidate.candidate().hash(), + core_index.0, + candidate.descriptor().para_id() + ); - if !temp_backed_candidates.is_empty() { - backed_candidates_with_core - .entry(para_id) - .or_insert_with(|| vec![]) - .extend(temp_backed_candidates); + break; } } else { - log::warn!( + // No core index is fine, if para has just 1 core assigned. + if scheduled_cores.len() == 1 { + backed_candidates_with_core.insert( + para_id, + vec![( + // We need the first one here, as we assume candidates of a + // para are in dependency order. + candidate, + scheduled_cores.pop_first().expect("Length is 1"), + )], + ); + break; + } + + // if we got a candidate which does not contain its core index, stop the + // work for this para. the already processed candidate chain in + // temp_backed_candidates is still fine though. + + log::debug!( target: LOG_TARGET, - "Found a paraid {:?} which has multiple scheduled cores but ElasticScalingMVP feature is not enabled: {:?}", - para_id, - scheduled_cores + "Found a backed candidate {:?} without core index informationm, but paraid {:?} has multiple scheduled cores.", + candidate.candidate().hash(), + candidate.descriptor().para_id() ); + + break; } - } else { - log::debug!( - target: LOG_TARGET, - "Paraid: {:?} has no entry in scheduled cores but {} candidates were supplied.", - para_id, - backed_candidates.len() - ); + } + + if !temp_backed_candidates.is_empty() { + backed_candidates_with_core + .entry(para_id) + .or_insert_with(|| vec![]) + .extend(temp_backed_candidates); } } @@ -1573,24 +1565,25 @@ fn map_candidates_to_cores( + core_index_enabled: bool, allowed_relay_parents: &AllowedRelayParentsTracker>, candidate: &BackedCandidate, ) -> Option { - candidate - .candidate() - .descriptor - .core_index() - .or_else(|| get_injected_core_index::(allowed_relay_parents, &candidate)) + candidate.candidate().descriptor.core_index().or_else(|| { + get_injected_core_index::(core_index_enabled, allowed_relay_parents, &candidate) + }) } fn get_injected_core_index( + core_index_enabled: bool, allowed_relay_parents: &AllowedRelayParentsTracker>, candidate: &BackedCandidate, ) -> Option { // After stripping the 8 bit extensions, the `validator_indices` field length is expected // to be equal to backing group size. If these don't match, the `CoreIndex` is badly encoded, // or not supported. - let (validator_indices, maybe_core_idx) = candidate.validator_indices_and_core_index(true); + let (validator_indices, maybe_core_idx) = + candidate.validator_indices_and_core_index(core_index_enabled); let Some(core_idx) = maybe_core_idx else { return None }; From b44a6043d339624e03c01afe024184b6fafdefdb Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 9 Sep 2024 14:14:42 +0300 Subject: [PATCH 092/130] doc updates Signed-off-by: Andrei Sandu --- .../src/node/utility/candidate-validation.md | 2 +- polkadot/roadmap/implementers-guide/src/runtime/inclusion.md | 2 +- polkadot/runtime/parachains/src/paras_inherent/mod.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/candidate-validation.md b/polkadot/roadmap/implementers-guide/src/node/utility/candidate-validation.md index 1a3ff1c6aff0..aad77de0aded 100644 --- a/polkadot/roadmap/implementers-guide/src/node/utility/candidate-validation.md +++ b/polkadot/roadmap/implementers-guide/src/node/utility/candidate-validation.md @@ -85,7 +85,7 @@ state. Once we have all parameters, we can spin up a background task to perform the validation in a way that doesn't hold up the entire event loop. Before invoking the validation function itself, this should first do some basic checks: - * The collator signature is valid + * The collator signature is valid (only if `CandidateDescriptor` has version 1) * The PoV provided matches the `pov_hash` field of the descriptor For more details please see [PVF Host and Workers](pvf-host-and-workers.md). diff --git a/polkadot/roadmap/implementers-guide/src/runtime/inclusion.md b/polkadot/roadmap/implementers-guide/src/runtime/inclusion.md index 5031433cf5a1..48909db07ba5 100644 --- a/polkadot/roadmap/implementers-guide/src/runtime/inclusion.md +++ b/polkadot/roadmap/implementers-guide/src/runtime/inclusion.md @@ -109,7 +109,7 @@ All failed checks should lead to an unrecoverable error making the block invalid 1. Ensure that any code upgrade scheduled by the candidate does not happen within `config.validation_upgrade_cooldown` of `Paras::last_code_upgrade(para_id, true)`, if any, comparing against the value of `Paras::FutureCodeUpgrades` for the given para ID. - 1. Check the collator's signature on the candidate data. + 1. Check the collator's signature on the candidate data (only if `CandidateDescriptor` is version 1) 1. check the backing of the candidate using the signatures and the bitfields, comparing against the validators assigned to the groups, fetched with the `group_validators` lookup, while group indices are computed by `Scheduler` according to group rotation info. diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 3db9cee6db31..f571dba314a5 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -1448,8 +1448,8 @@ fn filter_unchained_candidates Date: Wed, 11 Sep 2024 15:32:59 +0300 Subject: [PATCH 093/130] switch nodes to vstaging primitives Signed-off-by: Andrei Sandu --- .../consensus/aura/src/collators/mod.rs | 2 +- cumulus/client/network/src/lib.rs | 12 +- cumulus/client/pov-recovery/src/lib.rs | 6 +- .../src/lib.rs | 2 +- .../client/relay-chain-interface/src/lib.rs | 5 +- .../src/blockchain_rpc_client.rs | 21 ++-- .../relay-chain-rpc-interface/src/lib.rs | 5 +- .../src/rpc_client.rs | 19 ++-- polkadot/node/collation-generation/src/lib.rs | 10 +- .../approval-voting/src/approval_db/v1/mod.rs | 4 +- .../approval-voting/src/approval_db/v2/mod.rs | 4 +- .../approval-voting/src/approval_db/v3/mod.rs | 4 +- .../node/core/approval-voting/src/import.rs | 5 +- polkadot/node/core/approval-voting/src/lib.rs | 28 +++-- polkadot/node/core/approval-voting/src/ops.rs | 4 +- .../approval-voting/src/persisted_entries.rs | 4 +- polkadot/node/core/av-store/src/lib.rs | 4 +- polkadot/node/core/backing/src/error.rs | 2 +- polkadot/node/core/backing/src/lib.rs | 46 ++++---- .../node/core/bitfield-signing/src/lib.rs | 2 +- .../node/core/candidate-validation/src/lib.rs | 34 +++--- .../core/dispute-coordinator/src/db/v1.rs | 5 +- .../core/dispute-coordinator/src/import.rs | 6 +- .../dispute-coordinator/src/initialized.rs | 15 +-- .../node/core/dispute-coordinator/src/lib.rs | 2 +- .../src/participation/mod.rs | 7 +- .../src/participation/queues/mod.rs | 5 +- .../dispute-coordinator/src/scraping/mod.rs | 5 +- .../node/core/parachains-inherent/src/lib.rs | 2 +- .../src/fragment_chain/mod.rs | 20 ++-- .../core/prospective-parachains/src/lib.rs | 13 ++- polkadot/node/core/provisioner/src/lib.rs | 21 ++-- polkadot/node/core/runtime-api/src/cache.rs | 22 ++-- .../src/requester/fetch_task/mod.rs | 12 +- .../src/requester/mod.rs | 2 +- .../network/availability-recovery/src/lib.rs | 8 +- .../src/collator_side/collation.rs | 4 +- .../src/collator_side/mod.rs | 15 +-- .../src/validator_side/collation.rs | 16 +-- .../src/validator_side/mod.rs | 26 ++--- .../src/receiver/batches/batch.rs | 2 +- .../src/receiver/batches/mod.rs | 2 +- .../dispute-distribution/src/receiver/mod.rs | 2 +- .../src/sender/send_task.rs | 2 +- .../protocol/src/request_response/v1.rs | 7 +- .../protocol/src/request_response/v2.rs | 4 +- .../src/legacy_v1/mod.rs | 9 +- .../src/legacy_v1/requester.rs | 4 +- .../src/legacy_v1/responder.rs | 4 +- .../src/v2/candidates.rs | 12 +- .../statement-distribution/src/v2/mod.rs | 16 +-- .../statement-distribution/src/v2/requests.rs | 12 +- .../node/primitives/src/disputes/message.rs | 3 +- polkadot/node/primitives/src/disputes/mod.rs | 6 +- polkadot/node/primitives/src/lib.rs | 8 +- polkadot/node/subsystem-types/src/messages.rs | 36 +++--- .../subsystem-types/src/runtime_client.rs | 56 ++++------ .../src/inclusion_emulator/mod.rs | 4 +- polkadot/node/subsystem-util/src/lib.rs | 15 ++- .../node/subsystem-util/src/runtime/mod.rs | 12 +- polkadot/primitives/src/v8/mod.rs | 2 +- polkadot/primitives/src/vstaging/mod.rs | 104 +++++++++++++++++- polkadot/primitives/test-helpers/src/lib.rs | 10 +- polkadot/statement-table/src/lib.rs | 4 +- 64 files changed, 460 insertions(+), 305 deletions(-) diff --git a/cumulus/client/consensus/aura/src/collators/mod.rs b/cumulus/client/consensus/aura/src/collators/mod.rs index 7d430ecdc727..7432a24bfbce 100644 --- a/cumulus/client/consensus/aura/src/collators/mod.rs +++ b/cumulus/client/consensus/aura/src/collators/mod.rs @@ -29,7 +29,7 @@ use cumulus_primitives_aura::{AuraUnincludedSegmentApi, Slot}; use cumulus_primitives_core::{relay_chain::Hash as ParaHash, BlockT}; use cumulus_relay_chain_interface::RelayChainInterface; use polkadot_primitives::{ - AsyncBackingParams, CoreIndex, CoreState, Hash as RelayHash, Id as ParaId, + vstaging::CoreState, AsyncBackingParams, CoreIndex, Hash as RelayHash, Id as ParaId, OccupiedCoreAssumption, ValidationCodeHash, }; use sc_consensus_aura::{standalone as aura_internal, AuraApi}; diff --git a/cumulus/client/network/src/lib.rs b/cumulus/client/network/src/lib.rs index dab15bba590a..9903720f05c6 100644 --- a/cumulus/client/network/src/lib.rs +++ b/cumulus/client/network/src/lib.rs @@ -32,8 +32,8 @@ use polkadot_node_primitives::{CollationSecondedSignal, Statement}; use polkadot_node_subsystem::messages::RuntimeApiRequest; use polkadot_parachain_primitives::primitives::HeadData; use polkadot_primitives::{ - CandidateReceipt, CompactStatement, Hash as PHash, Id as ParaId, OccupiedCoreAssumption, - SigningContext, UncheckedSigned, + vstaging::CandidateReceiptV2 as CandidateReceipt, CompactStatement, Hash as PHash, + Id as ParaId, OccupiedCoreAssumption, SigningContext, UncheckedSigned, }; use codec::{Decode, DecodeAll, Encode}; @@ -79,7 +79,7 @@ impl Decode for BlockAnnounceData { let relay_parent = match PHash::decode(input) { Ok(p) => p, // For being backwards compatible, we support missing relay-chain parent. - Err(_) => receipt.descriptor.relay_parent, + Err(_) => receipt.descriptor.relay_parent(), }; Ok(Self { receipt, statement, relay_parent }) @@ -108,7 +108,7 @@ impl BlockAnnounceData { return Err(Validation::Failure { disconnect: true }) } - if HeadData(encoded_header).hash() != self.receipt.descriptor.para_head { + if HeadData(encoded_header).hash() != self.receipt.descriptor.para_head() { tracing::debug!( target: LOG_TARGET, "Receipt para head hash doesn't match the hash of the header in the block announcement", @@ -302,7 +302,7 @@ where } .map_err(|e| Box::new(BlockAnnounceError(format!("{:?}", e))) as Box<_>)?; - Ok(candidate_receipts.into_iter().map(|cr| cr.descriptor.para_head)) + Ok(candidate_receipts.into_iter().map(|cr| cr.descriptor.para_head())) } /// Handle a block announcement with empty data (no statement) attached to it. @@ -399,7 +399,7 @@ where return Ok(e) } - let relay_parent = block_announce_data.receipt.descriptor.relay_parent; + let relay_parent = block_announce_data.receipt.descriptor.relay_parent(); relay_chain_interface .wait_for_block(relay_parent) diff --git a/cumulus/client/pov-recovery/src/lib.rs b/cumulus/client/pov-recovery/src/lib.rs index 6ace18155e87..6ceb24b8a657 100644 --- a/cumulus/client/pov-recovery/src/lib.rs +++ b/cumulus/client/pov-recovery/src/lib.rs @@ -56,7 +56,11 @@ use polkadot_node_primitives::{PoV, POV_BOMB_LIMIT}; use polkadot_node_subsystem::messages::{AvailabilityRecoveryMessage, RuntimeApiRequest}; use polkadot_overseer::Handle as OverseerHandle; use polkadot_primitives::{ - CandidateReceipt, CommittedCandidateReceipt, Id as ParaId, SessionIndex, + vstaging::{ + CandidateReceiptV2 as CandidateReceipt, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, + }, + Id as ParaId, SessionIndex, }; use cumulus_primitives_core::ParachainBlockData; diff --git a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs index 629fa728be37..c7bba6884421 100644 --- a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs +++ b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs @@ -20,7 +20,7 @@ use async_trait::async_trait; use cumulus_primitives_core::{ relay_chain::{ runtime_api::ParachainHost, Block as PBlock, BlockId, BlockNumber, - CommittedCandidateReceipt, CoreState, Hash as PHash, Header as PHeader, InboundHrmpMessage, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, vstaging::CoreState, Hash as PHash, Header as PHeader, InboundHrmpMessage, OccupiedCoreAssumption, SessionIndex, ValidationCodeHash, ValidatorId, }, InboundDownwardMessage, ParaId, PersistedValidationData, diff --git a/cumulus/client/relay-chain-interface/src/lib.rs b/cumulus/client/relay-chain-interface/src/lib.rs index d02035e84e92..13811b48a128 100644 --- a/cumulus/client/relay-chain-interface/src/lib.rs +++ b/cumulus/client/relay-chain-interface/src/lib.rs @@ -29,8 +29,9 @@ use sp_api::ApiError; use cumulus_primitives_core::relay_chain::BlockId; pub use cumulus_primitives_core::{ relay_chain::{ - BlockNumber, CommittedCandidateReceipt, CoreState, Hash as PHash, Header as PHeader, - InboundHrmpMessage, OccupiedCoreAssumption, SessionIndex, ValidationCodeHash, ValidatorId, + vstaging::{CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState}, + BlockNumber, Hash as PHash, Header as PHeader, InboundHrmpMessage, OccupiedCoreAssumption, + SessionIndex, ValidationCodeHash, ValidatorId, }, InboundDownwardMessage, ParaId, PersistedValidationData, }; diff --git a/cumulus/client/relay-chain-minimal-node/src/blockchain_rpc_client.rs b/cumulus/client/relay-chain-minimal-node/src/blockchain_rpc_client.rs index 06f19941165a..3bc8e1efa5ac 100644 --- a/cumulus/client/relay-chain-minimal-node/src/blockchain_rpc_client.rs +++ b/cumulus/client/relay-chain-minimal-node/src/blockchain_rpc_client.rs @@ -25,8 +25,8 @@ use futures::{Stream, StreamExt}; use polkadot_core_primitives::{Block, BlockNumber, Hash, Header}; use polkadot_overseer::{ChainApiBackend, RuntimeApiSubsystemClient}; use polkadot_primitives::{ - async_backing::{AsyncBackingParams, BackingState}, - slashing, ApprovalVotingParams, CoreIndex, NodeFeatures, + async_backing::AsyncBackingParams, slashing, vstaging::async_backing::BackingState, + ApprovalVotingParams, CoreIndex, NodeFeatures, }; use sc_authority_discovery::{AuthorityDiscovery, Error as AuthorityDiscoveryError}; use sc_client_api::AuxStore; @@ -143,7 +143,7 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient { &self, at: Hash, ) -> Result< - Vec>, + Vec>, sp_api::ApiError, > { Ok(self.rpc_client.parachain_host_availability_cores(at).await?) @@ -226,7 +226,10 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient { &self, at: Hash, para_id: cumulus_primitives_core::ParaId, - ) -> Result>, sp_api::ApiError> { + ) -> Result< + Option>, + sp_api::ApiError, + > { Ok(self .rpc_client .parachain_host_candidate_pending_availability(at, para_id) @@ -236,7 +239,7 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient { async fn candidate_events( &self, at: Hash, - ) -> Result>, sp_api::ApiError> { + ) -> Result>, sp_api::ApiError> { Ok(self.rpc_client.parachain_host_candidate_events(at).await?) } @@ -284,7 +287,8 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient { async fn on_chain_votes( &self, at: Hash, - ) -> Result>, sp_api::ApiError> { + ) -> Result>, sp_api::ApiError> + { Ok(self.rpc_client.parachain_host_on_chain_votes(at).await?) } @@ -456,7 +460,10 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient { &self, at: Hash, para_id: cumulus_primitives_core::ParaId, - ) -> Result>, sp_api::ApiError> { + ) -> Result< + Vec>, + sp_api::ApiError, + > { Ok(self .rpc_client .parachain_host_candidates_pending_availability(at, para_id) diff --git a/cumulus/client/relay-chain-rpc-interface/src/lib.rs b/cumulus/client/relay-chain-rpc-interface/src/lib.rs index e32ec6a41a4b..4c48b4cd0dc9 100644 --- a/cumulus/client/relay-chain-rpc-interface/src/lib.rs +++ b/cumulus/client/relay-chain-rpc-interface/src/lib.rs @@ -18,8 +18,9 @@ use async_trait::async_trait; use core::time::Duration; use cumulus_primitives_core::{ relay_chain::{ - CommittedCandidateReceipt, Hash as RelayHash, Header as RelayHeader, InboundHrmpMessage, - OccupiedCoreAssumption, SessionIndex, ValidationCodeHash, ValidatorId, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, Hash as RelayHash, + Header as RelayHeader, InboundHrmpMessage, OccupiedCoreAssumption, SessionIndex, + ValidationCodeHash, ValidatorId, }, InboundDownwardMessage, ParaId, PersistedValidationData, }; diff --git a/cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs b/cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs index c7eaa45958b0..a27b135841cd 100644 --- a/cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs +++ b/cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs @@ -31,13 +31,18 @@ use codec::{Decode, Encode}; use cumulus_primitives_core::{ relay_chain::{ - async_backing::{AsyncBackingParams, BackingState}, - slashing, ApprovalVotingParams, BlockNumber, CandidateCommitments, CandidateEvent, - CandidateHash, CommittedCandidateReceipt, CoreIndex, CoreState, DisputeState, - ExecutorParams, GroupRotationInfo, Hash as RelayHash, Header as RelayHeader, - InboundHrmpMessage, NodeFeatures, OccupiedCoreAssumption, PvfCheckStatement, - ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, - ValidatorId, ValidatorIndex, ValidatorSignature, + async_backing::AsyncBackingParams, + slashing, + vstaging::{ + async_backing::BackingState, CandidateEvent, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + ApprovalVotingParams, BlockNumber, CandidateCommitments, CandidateHash, CoreIndex, + DisputeState, ExecutorParams, GroupRotationInfo, Hash as RelayHash, Header as RelayHeader, + InboundHrmpMessage, NodeFeatures, OccupiedCoreAssumption, PvfCheckStatement, SessionIndex, + SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, + ValidatorSignature, }, InboundDownwardMessage, ParaId, PersistedValidationData, }; diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs index 50adbddea413..a9b812f6673b 100644 --- a/polkadot/node/collation-generation/src/lib.rs +++ b/polkadot/node/collation-generation/src/lib.rs @@ -48,9 +48,10 @@ use polkadot_node_subsystem_util::{ request_validators, runtime::fetch_claim_queue, }; use polkadot_primitives::{ - collator_signature_payload, CandidateCommitments, CandidateDescriptor, CandidateReceipt, - CollatorPair, CoreIndex, CoreState, Hash, Id as ParaId, OccupiedCoreAssumption, - PersistedValidationData, ScheduledCore, ValidationCodeHash, + collator_signature_payload, + vstaging::{CandidateDescriptorV2, CandidateReceiptV2 as CandidateReceipt, CoreState}, + CandidateCommitments, CandidateDescriptor, CollatorPair, CoreIndex, Hash, Id as ParaId, + OccupiedCoreAssumption, PersistedValidationData, ScheduledCore, ValidationCodeHash, }; use sp_core::crypto::Pair; use std::sync::Arc; @@ -607,7 +608,8 @@ async fn construct_and_distribute_receipt( erasure_root, para_head: commitments.head_data.hash(), validation_code_hash, - }, + } + .into(), }; gum::debug!( diff --git a/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs b/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs index 53e9db64f636..87a1d20b92f5 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs @@ -25,8 +25,8 @@ use codec::{Decode, Encode}; use polkadot_node_primitives::approval::v1::{AssignmentCert, DelayTranche}; use polkadot_primitives::{ - BlockNumber, CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, Hash, SessionIndex, - ValidatorIndex, ValidatorSignature, + vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, CoreIndex, + GroupIndex, Hash, SessionIndex, ValidatorIndex, ValidatorSignature, }; use sp_consensus_slots::Slot; use std::collections::BTreeMap; diff --git a/polkadot/node/core/approval-voting/src/approval_db/v2/mod.rs b/polkadot/node/core/approval-voting/src/approval_db/v2/mod.rs index cd9256a5d47e..63c6cbf40b89 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v2/mod.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v2/mod.rs @@ -21,8 +21,8 @@ use polkadot_node_primitives::approval::{v1::DelayTranche, v2::AssignmentCertV2} use polkadot_node_subsystem::{SubsystemError, SubsystemResult}; use polkadot_node_subsystem_util::database::{DBTransaction, Database}; use polkadot_primitives::{ - BlockNumber, CandidateHash, CandidateIndex, CandidateReceipt, CoreIndex, GroupIndex, Hash, - SessionIndex, ValidatorIndex, ValidatorSignature, + vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, CandidateIndex, + CoreIndex, GroupIndex, Hash, SessionIndex, ValidatorIndex, ValidatorSignature, }; use sp_consensus_slots::Slot; diff --git a/polkadot/node/core/approval-voting/src/approval_db/v3/mod.rs b/polkadot/node/core/approval-voting/src/approval_db/v3/mod.rs index 7118fb6770fd..bc34f88af80a 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v3/mod.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v3/mod.rs @@ -25,8 +25,8 @@ use polkadot_node_subsystem::SubsystemResult; use polkadot_node_subsystem_util::database::{DBTransaction, Database}; use polkadot_overseer::SubsystemError; use polkadot_primitives::{ - BlockNumber, CandidateHash, CandidateIndex, CandidateReceipt, CoreIndex, GroupIndex, Hash, - SessionIndex, ValidatorIndex, ValidatorSignature, + vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, CandidateIndex, + CoreIndex, GroupIndex, Hash, SessionIndex, ValidatorIndex, ValidatorSignature, }; use sp_consensus_slots::Slot; diff --git a/polkadot/node/core/approval-voting/src/import.rs b/polkadot/node/core/approval-voting/src/import.rs index b163d718eb25..e1ff46168e73 100644 --- a/polkadot/node/core/approval-voting/src/import.rs +++ b/polkadot/node/core/approval-voting/src/import.rs @@ -45,8 +45,9 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_util::{determine_new_blocks, runtime::RuntimeInfo}; use polkadot_primitives::{ - node_features, BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, ConsensusLog, - CoreIndex, GroupIndex, Hash, Header, SessionIndex, + node_features, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt}, + BlockNumber, CandidateHash, ConsensusLog, CoreIndex, GroupIndex, Hash, Header, SessionIndex, }; use sc_keystore::LocalKeystore; use sp_consensus_slots::Slot; diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index 942922cba6df..87386ea06d46 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -55,9 +55,10 @@ use polkadot_node_subsystem_util::{ TimeoutExt, }; use polkadot_primitives::{ - ApprovalVoteMultipleCandidates, ApprovalVotingParams, BlockNumber, CandidateHash, - CandidateIndex, CandidateReceipt, CoreIndex, ExecutorParams, GroupIndex, Hash, PvfExecKind, - SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature, + vstaging::CandidateReceiptV2 as CandidateReceipt, ApprovalVoteMultipleCandidates, + ApprovalVotingParams, BlockNumber, CandidateHash, CandidateIndex, CoreIndex, ExecutorParams, + GroupIndex, Hash, PvfExecKind, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, + ValidatorPair, ValidatorSignature, }; use sc_keystore::LocalKeystore; use sp_application_crypto::Pair; @@ -2810,7 +2811,7 @@ where target: LOG_TARGET, validator_index = approval.validator.0, candidate_hash = ?approved_candidate_hash, - para_id = ?candidate_entry.candidate_receipt().descriptor.para_id, + para_id = ?candidate_entry.candidate_receipt().descriptor.para_id(), "Importing approval vote", ); @@ -2909,7 +2910,7 @@ where let block_hash = block_entry.block_hash(); let block_number = block_entry.block_number(); let session_index = block_entry.session(); - let para_id = candidate_entry.candidate_receipt().descriptor().para_id; + let para_id = candidate_entry.candidate_receipt().descriptor().para_id(); let tick_now = state.clock.tick_now(); let (is_approved, status) = if let Some((approval_entry, status)) = state @@ -3218,7 +3219,7 @@ async fn process_wakeup( gum::trace!( target: LOG_TARGET, ?candidate_hash, - para_id = ?candidate_receipt.descriptor.para_id, + para_id = ?candidate_receipt.descriptor.para_id(), block_hash = ?relay_block, "Launching approval work.", ); @@ -3344,7 +3345,7 @@ async fn launch_approval( } let candidate_hash = candidate.hash(); - let para_id = candidate.descriptor.para_id; + let para_id = candidate.descriptor.para_id(); gum::trace!(target: LOG_TARGET, ?candidate_hash, ?para_id, "Recovering data."); let request_validation_data_span = span @@ -3373,7 +3374,10 @@ async fn launch_approval( ctx.send_message(RuntimeApiMessage::Request( block_hash, - RuntimeApiRequest::ValidationCodeByHash(candidate.descriptor.validation_code_hash, code_tx), + RuntimeApiRequest::ValidationCodeByHash( + candidate.descriptor.validation_code_hash(), + code_tx, + ), )) .await; @@ -3395,7 +3399,7 @@ async fn launch_approval( ?para_id, ?candidate_hash, "Data unavailable for candidate {:?}", - (candidate_hash, candidate.descriptor.para_id), + (candidate_hash, candidate.descriptor.para_id()), ); // do nothing. we'll just be a no-show and that'll cause others to rise up. metrics_guard.take().on_approval_unavailable(); @@ -3406,7 +3410,7 @@ async fn launch_approval( ?para_id, ?candidate_hash, "Channel closed while recovering data for candidate {:?}", - (candidate_hash, candidate.descriptor.para_id), + (candidate_hash, candidate.descriptor.para_id()), ); // do nothing. we'll just be a no-show and that'll cause others to rise up. metrics_guard.take().on_approval_unavailable(); @@ -3417,7 +3421,7 @@ async fn launch_approval( ?para_id, ?candidate_hash, "Data recovery invalid for candidate {:?}", - (candidate_hash, candidate.descriptor.para_id), + (candidate_hash, candidate.descriptor.para_id()), ); issue_local_invalid_statement( &mut sender, @@ -3441,7 +3445,7 @@ async fn launch_approval( gum::warn!( target: LOG_TARGET, "Validation code unavailable for block {:?} in the state of block {:?} (a recent descendant)", - candidate.descriptor.relay_parent, + candidate.descriptor.relay_parent(), block_hash, ); diff --git a/polkadot/node/core/approval-voting/src/ops.rs b/polkadot/node/core/approval-voting/src/ops.rs index 2a8fdba5aa36..f105580009fa 100644 --- a/polkadot/node/core/approval-voting/src/ops.rs +++ b/polkadot/node/core/approval-voting/src/ops.rs @@ -20,7 +20,9 @@ use polkadot_node_subsystem::{SubsystemError, SubsystemResult}; use bitvec::order::Lsb0 as BitOrderLsb0; -use polkadot_primitives::{BlockNumber, CandidateHash, CandidateReceipt, GroupIndex, Hash}; +use polkadot_primitives::{ + vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, GroupIndex, Hash, +}; use std::collections::{hash_map::Entry, BTreeMap, HashMap}; diff --git a/polkadot/node/core/approval-voting/src/persisted_entries.rs b/polkadot/node/core/approval-voting/src/persisted_entries.rs index 16e231aa1a2d..d891af01c3ab 100644 --- a/polkadot/node/core/approval-voting/src/persisted_entries.rs +++ b/polkadot/node/core/approval-voting/src/persisted_entries.rs @@ -26,8 +26,8 @@ use polkadot_node_primitives::approval::{ v2::{AssignmentCertV2, CandidateBitfield}, }; use polkadot_primitives::{ - BlockNumber, CandidateHash, CandidateIndex, CandidateReceipt, CoreIndex, GroupIndex, Hash, - SessionIndex, ValidatorIndex, ValidatorSignature, + vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, CandidateIndex, + CoreIndex, GroupIndex, Hash, SessionIndex, ValidatorIndex, ValidatorSignature, }; use sp_consensus_slots::Slot; diff --git a/polkadot/node/core/av-store/src/lib.rs b/polkadot/node/core/av-store/src/lib.rs index 7b245c9e3c52..00397c8c7f48 100644 --- a/polkadot/node/core/av-store/src/lib.rs +++ b/polkadot/node/core/av-store/src/lib.rs @@ -48,8 +48,8 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_util as util; use polkadot_primitives::{ - BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, ChunkIndex, CoreIndex, Hash, - Header, NodeFeatures, ValidatorIndex, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt}, + BlockNumber, CandidateHash, ChunkIndex, CoreIndex, Hash, Header, NodeFeatures, ValidatorIndex, }; use util::availability_chunks::availability_chunk_indices; diff --git a/polkadot/node/core/backing/src/error.rs b/polkadot/node/core/backing/src/error.rs index 568f71402644..e09d8425f78a 100644 --- a/polkadot/node/core/backing/src/error.rs +++ b/polkadot/node/core/backing/src/error.rs @@ -24,7 +24,7 @@ use polkadot_node_subsystem::{ RuntimeApiError, SubsystemError, }; use polkadot_node_subsystem_util::{runtime, Error as UtilError}; -use polkadot_primitives::{BackedCandidate, ValidationCodeHash}; +use polkadot_primitives::{vstaging::BackedCandidate, ValidationCodeHash}; use crate::{ParaId, LOG_TARGET}; diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs index f276321c87ed..c71f8183c721 100644 --- a/polkadot/node/core/backing/src/lib.rs +++ b/polkadot/node/core/backing/src/lib.rs @@ -106,11 +106,15 @@ use polkadot_node_subsystem_util::{ Validator, }; use polkadot_primitives::{ - node_features::FeatureIndex, BackedCandidate, CandidateCommitments, CandidateHash, - CandidateReceipt, CommittedCandidateReceipt, CoreIndex, CoreState, ExecutorParams, GroupIndex, - GroupRotationInfo, Hash, Id as ParaId, IndexedVec, NodeFeatures, PersistedValidationData, - PvfExecKind, SessionIndex, SigningContext, ValidationCode, ValidatorId, ValidatorIndex, - ValidatorSignature, ValidityAttestation, + node_features::FeatureIndex, + vstaging::{ + BackedCandidate, CandidateReceiptV2 as CandidateReceipt, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + }, + CandidateCommitments, CandidateHash, CoreIndex, ExecutorParams, GroupIndex, GroupRotationInfo, + Hash, Id as ParaId, IndexedVec, NodeFeatures, PersistedValidationData, PvfExecKind, + SessionIndex, SigningContext, ValidationCode, ValidatorId, ValidatorIndex, ValidatorSignature, + ValidityAttestation, }; use polkadot_statement_table::{ generic::AttestedCandidate as TableAttestedCandidate, @@ -685,7 +689,7 @@ async fn validate_and_make_available( } = params; let validation_code = { - let validation_code_hash = candidate.descriptor().validation_code_hash; + let validation_code_hash = candidate.descriptor().validation_code_hash(); let (tx, rx) = oneshot::channel(); sender .send_message(RuntimeApiMessage::Request( @@ -718,7 +722,7 @@ async fn validate_and_make_available( &mut sender, relay_parent, from_validator, - candidate.descriptor.para_id, + candidate.descriptor.para_id(), candidate_hash, pov_hash, ) @@ -765,7 +769,7 @@ async fn validate_and_make_available( pov.clone(), candidate.hash(), validation_data.clone(), - candidate.descriptor.erasure_root, + candidate.descriptor.erasure_root(), core_index, node_features, ) @@ -1047,7 +1051,7 @@ fn core_index_from_statement( } if let StatementWithPVD::Seconded(candidate, _pvd) = statement.payload() { - let candidate_para_id = candidate.descriptor.para_id; + let candidate_para_id = candidate.descriptor.para_id(); let mut assigned_paras = claim_queue.iter_claims_for_core(&core_index); if !assigned_paras.any(|id| id == &candidate_para_id) { @@ -1438,14 +1442,14 @@ async fn handle_validated_candidate_command( let candidate_hash = candidate.hash(); gum::debug!( target: LOG_TARGET, - relay_parent = ?candidate.descriptor().relay_parent, + relay_parent = ?candidate.descriptor().relay_parent(), ?candidate_hash, "Attempted to second candidate but was rejected by prospective parachains", ); // Ensure the collator is reported. ctx.send_message(CollatorProtocolMessage::Invalid( - candidate.descriptor().relay_parent, + candidate.descriptor().relay_parent(), candidate, )) .await; @@ -1480,7 +1484,7 @@ async fn handle_validated_candidate_command( Some(d) => d, }; - leaf_data.add_seconded_candidate(candidate.descriptor().para_id); + leaf_data.add_seconded_candidate(candidate.descriptor().para_id()); } rp_state.issued_statements.insert(candidate_hash); @@ -1629,7 +1633,7 @@ async fn import_statement( let (tx, rx) = oneshot::channel(); ctx.send_message(ProspectiveParachainsMessage::IntroduceSecondedCandidate( IntroduceSecondedCandidateRequest { - candidate_para: candidate.descriptor().para_id, + candidate_para: candidate.descriptor.para_id(), candidate_receipt: candidate.clone(), persisted_validation_data: pvd.clone(), }, @@ -1658,7 +1662,7 @@ async fn import_statement( persisted_validation_data: pvd.clone(), // This is set after importing when seconding locally. seconded_locally: false, - relay_parent: candidate.descriptor().relay_parent, + relay_parent: candidate.descriptor.relay_parent(), }, ); } @@ -1702,7 +1706,7 @@ async fn post_import_statement_actions( &rp_state.table_context, rp_state.inject_core_index, ) { - let para_id = backed.candidate().descriptor.para_id; + let para_id = backed.candidate().descriptor.para_id(); gum::debug!( target: LOG_TARGET, candidate_hash = ?candidate_hash, @@ -1960,7 +1964,7 @@ async fn maybe_validate_and_import( .get_candidate(&candidate_hash) .ok_or(Error::CandidateNotFound)? .to_plain(), - pov_hash: receipt.descriptor.pov_hash, + pov_hash: receipt.descriptor.pov_hash(), from_validator: statement.validator_index(), backing: Vec::new(), }; @@ -2061,9 +2065,9 @@ async fn handle_second_message( let _timer = metrics.time_process_second(); let candidate_hash = candidate.hash(); - let relay_parent = candidate.descriptor().relay_parent; + let relay_parent = candidate.descriptor().relay_parent(); - if candidate.descriptor().persisted_validation_data_hash != persisted_validation_data.hash() { + if candidate.descriptor().persisted_validation_data_hash() != persisted_validation_data.hash() { gum::warn!( target: LOG_TARGET, ?candidate_hash, @@ -2097,12 +2101,12 @@ async fn handle_second_message( let assigned_paras = rp_state.assigned_core.and_then(|core| rp_state.claim_queue.0.get(&core)); // Sanity check that candidate is from our assignment. - if !matches!(assigned_paras, Some(paras) if paras.contains(&candidate.descriptor().para_id)) { + if !matches!(assigned_paras, Some(paras) if paras.contains(&candidate.descriptor().para_id())) { gum::debug!( target: LOG_TARGET, our_assignment_core = ?rp_state.assigned_core, our_assignment_paras = ?assigned_paras, - collation = ?candidate.descriptor().para_id, + collation = ?candidate.descriptor().para_id(), "Subsystem asked to second for para outside of our assignment", ); return Ok(()); @@ -2112,7 +2116,7 @@ async fn handle_second_message( target: LOG_TARGET, our_assignment_core = ?rp_state.assigned_core, our_assignment_paras = ?assigned_paras, - collation = ?candidate.descriptor().para_id, + collation = ?candidate.descriptor().para_id(), "Current assignments vs collation", ); diff --git a/polkadot/node/core/bitfield-signing/src/lib.rs b/polkadot/node/core/bitfield-signing/src/lib.rs index e3effb7949ea..024fce981380 100644 --- a/polkadot/node/core/bitfield-signing/src/lib.rs +++ b/polkadot/node/core/bitfield-signing/src/lib.rs @@ -35,7 +35,7 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_util::{ self as util, request_availability_cores, runtime::recv_runtime, Validator, }; -use polkadot_primitives::{AvailabilityBitfield, CoreState, Hash, ValidatorIndex}; +use polkadot_primitives::{vstaging::CoreState, AvailabilityBitfield, Hash, ValidatorIndex}; use sp_keystore::{Error as KeystoreError, KeystorePtr}; use std::{collections::HashMap, time::Duration}; use wasm_timer::{Delay, Instant}; diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index a9732e934414..204cf53401c0 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -45,9 +45,13 @@ use polkadot_primitives::{ DEFAULT_APPROVAL_EXECUTION_TIMEOUT, DEFAULT_BACKING_EXECUTION_TIMEOUT, DEFAULT_LENIENT_PREPARATION_TIMEOUT, DEFAULT_PRECHECK_PREPARATION_TIMEOUT, }, - AuthorityDiscoveryId, CandidateCommitments, CandidateDescriptor, CandidateEvent, - CandidateReceipt, ExecutorParams, Hash, OccupiedCoreAssumption, PersistedValidationData, - PvfExecKind, PvfPrepKind, SessionIndex, ValidationCode, ValidationCodeHash, ValidatorId, + vstaging::{ + CandidateDescriptorV2 as CandidateDescriptor, CandidateEvent, + CandidateReceiptV2 as CandidateReceipt, + }, + AuthorityDiscoveryId, CandidateCommitments, ExecutorParams, Hash, OccupiedCoreAssumption, + PersistedValidationData, PvfExecKind, PvfPrepKind, SessionIndex, ValidationCode, + ValidationCodeHash, ValidatorId, }; use sp_application_crypto::{AppCrypto, ByteArray}; use sp_keystore::KeystorePtr; @@ -461,7 +465,7 @@ where .into_iter() .filter_map(|e| match e { CandidateEvent::CandidateBacked(receipt, ..) => { - let h = receipt.descriptor.validation_code_hash; + let h = receipt.descriptor.validation_code_hash(); if already_prepared.contains(&h) { None } else { @@ -676,8 +680,8 @@ where let (tx, rx) = oneshot::channel(); let d = runtime_api_request( sender, - descriptor.relay_parent, - RuntimeApiRequest::PersistedValidationData(descriptor.para_id, assumption, tx), + descriptor.relay_parent(), + RuntimeApiRequest::PersistedValidationData(descriptor.para_id(), assumption, tx), rx, ) .await; @@ -690,12 +694,12 @@ where let persisted_validation_data_hash = validation_data.hash(); - if descriptor.persisted_validation_data_hash == persisted_validation_data_hash { + if descriptor.persisted_validation_data_hash() == persisted_validation_data_hash { let (code_tx, code_rx) = oneshot::channel(); let validation_code = runtime_api_request( sender, - descriptor.relay_parent, - RuntimeApiRequest::ValidationCode(descriptor.para_id, assumption, code_tx), + descriptor.relay_parent(), + RuntimeApiRequest::ValidationCode(descriptor.para_id(), assumption, code_tx), code_rx, ) .await; @@ -801,9 +805,9 @@ where let (tx, rx) = oneshot::channel(); match runtime_api_request( sender, - candidate_receipt.descriptor.relay_parent, + candidate_receipt.descriptor.relay_parent(), RuntimeApiRequest::CheckValidationOutputs( - candidate_receipt.descriptor.para_id, + candidate_receipt.descriptor.para_id(), outputs.clone(), tx, ), @@ -834,7 +838,7 @@ async fn validate_candidate_exhaustive( let _timer = metrics.time_validate_candidate_exhaustive(); let validation_code_hash = validation_code.hash(); - let para_id = candidate_receipt.descriptor.para_id; + let para_id = candidate_receipt.descriptor.para_id(); gum::debug!( target: LOG_TARGET, ?validation_code_hash, @@ -933,7 +937,7 @@ async fn validate_candidate_exhaustive( Err(ValidationFailed(e.to_string())) }, Ok(res) => - if res.head_data.hash() != candidate_receipt.descriptor.para_head { + if res.head_data.hash() != candidate_receipt.descriptor.para_head() { gum::info!(target: LOG_TARGET, ?para_id, "Invalid candidate (para_head)"); Ok(ValidationResult::Invalid(InvalidCandidate::ParaHeadHashMismatch)) } else { @@ -1168,11 +1172,11 @@ fn perform_basic_checks( return Err(InvalidCandidate::ParamsTooLarge(encoded_pov_size as u64)) } - if pov_hash != candidate.pov_hash { + if pov_hash != candidate.pov_hash() { return Err(InvalidCandidate::PoVHashMismatch) } - if *validation_code_hash != candidate.validation_code_hash { + if *validation_code_hash != candidate.validation_code_hash() { return Err(InvalidCandidate::CodeHashMismatch) } diff --git a/polkadot/node/core/dispute-coordinator/src/db/v1.rs b/polkadot/node/core/dispute-coordinator/src/db/v1.rs index 0101791550ee..f3df6b6091b1 100644 --- a/polkadot/node/core/dispute-coordinator/src/db/v1.rs +++ b/polkadot/node/core/dispute-coordinator/src/db/v1.rs @@ -25,8 +25,9 @@ use polkadot_node_primitives::DisputeStatus; use polkadot_node_subsystem_util::database::{DBTransaction, Database}; use polkadot_primitives::{ - CandidateHash, CandidateReceipt, Hash, InvalidDisputeStatementKind, SessionIndex, - ValidDisputeStatementKind, ValidatorIndex, ValidatorSignature, + vstaging::CandidateReceiptV2 as CandidateReceipt, CandidateHash, Hash, + InvalidDisputeStatementKind, SessionIndex, ValidDisputeStatementKind, ValidatorIndex, + ValidatorSignature, }; use std::sync::Arc; diff --git a/polkadot/node/core/dispute-coordinator/src/import.rs b/polkadot/node/core/dispute-coordinator/src/import.rs index d3a4625f0d24..4263dda54b9b 100644 --- a/polkadot/node/core/dispute-coordinator/src/import.rs +++ b/polkadot/node/core/dispute-coordinator/src/import.rs @@ -34,9 +34,9 @@ use polkadot_node_primitives::{ use polkadot_node_subsystem::overseer; use polkadot_node_subsystem_util::runtime::RuntimeInfo; use polkadot_primitives::{ - CandidateHash, CandidateReceipt, DisputeStatement, ExecutorParams, Hash, IndexedVec, - SessionIndex, SessionInfo, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, - ValidatorPair, ValidatorSignature, + vstaging::CandidateReceiptV2 as CandidateReceipt, CandidateHash, DisputeStatement, + ExecutorParams, Hash, IndexedVec, SessionIndex, SessionInfo, ValidDisputeStatementKind, + ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature, }; use sc_keystore::LocalKeystore; diff --git a/polkadot/node/core/dispute-coordinator/src/initialized.rs b/polkadot/node/core/dispute-coordinator/src/initialized.rs index 5096fe5e6891..4dd13fa38cbf 100644 --- a/polkadot/node/core/dispute-coordinator/src/initialized.rs +++ b/polkadot/node/core/dispute-coordinator/src/initialized.rs @@ -43,9 +43,10 @@ use polkadot_node_subsystem_util::runtime::{ self, key_ownership_proof, submit_report_dispute_lost, RuntimeInfo, }; use polkadot_primitives::{ - slashing, BlockNumber, CandidateHash, CandidateReceipt, CompactStatement, DisputeStatement, - DisputeStatementSet, Hash, ScrapedOnChainVotes, SessionIndex, ValidDisputeStatementKind, - ValidatorId, ValidatorIndex, + slashing, + vstaging::{CandidateReceiptV2 as CandidateReceipt, ScrapedOnChainVotes}, + BlockNumber, CandidateHash, CompactStatement, DisputeStatement, DisputeStatementSet, Hash, + SessionIndex, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, }; use schnellru::{LruMap, UnlimitedCompact}; @@ -598,7 +599,7 @@ impl Initialized { // the new active leaf as if we received them via gossip. for (candidate_receipt, backers) in backing_validators_per_candidate { // Obtain the session info, for sake of `ValidatorId`s - let relay_parent = candidate_receipt.descriptor.relay_parent; + let relay_parent = candidate_receipt.descriptor.relay_parent(); let session_info = match self .runtime_info .get_session_info_by_index(ctx.sender(), relay_parent, session) @@ -949,9 +950,9 @@ impl Initialized { let votes_in_db = overlay_db.load_candidate_votes(session, &candidate_hash)?; let relay_parent = match &candidate_receipt { MaybeCandidateReceipt::Provides(candidate_receipt) => - candidate_receipt.descriptor().relay_parent, + candidate_receipt.descriptor().relay_parent(), MaybeCandidateReceipt::AssumeBackingVotePresent(candidate_hash) => match &votes_in_db { - Some(votes) => votes.candidate_receipt.descriptor().relay_parent, + Some(votes) => votes.candidate_receipt.descriptor().relay_parent(), None => { gum::warn!( target: LOG_TARGET, @@ -1430,7 +1431,7 @@ impl Initialized { ctx, &mut self.runtime_info, session, - candidate_receipt.descriptor.relay_parent, + candidate_receipt.descriptor.relay_parent(), self.offchain_disabled_validators.iter(session), ) .await diff --git a/polkadot/node/core/dispute-coordinator/src/lib.rs b/polkadot/node/core/dispute-coordinator/src/lib.rs index 34d9ddf3a97c..865a0c86533e 100644 --- a/polkadot/node/core/dispute-coordinator/src/lib.rs +++ b/polkadot/node/core/dispute-coordinator/src/lib.rs @@ -46,7 +46,7 @@ use polkadot_node_subsystem_util::{ runtime::{Config as RuntimeInfoConfig, RuntimeInfo}, }; use polkadot_primitives::{ - DisputeStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidatorIndex, + vstaging::ScrapedOnChainVotes, DisputeStatement, SessionIndex, SessionInfo, ValidatorIndex, }; use crate::{ diff --git a/polkadot/node/core/dispute-coordinator/src/participation/mod.rs b/polkadot/node/core/dispute-coordinator/src/participation/mod.rs index b58ce570f8ff..b8f5ed472a6b 100644 --- a/polkadot/node/core/dispute-coordinator/src/participation/mod.rs +++ b/polkadot/node/core/dispute-coordinator/src/participation/mod.rs @@ -32,7 +32,8 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_util::runtime::get_validation_code_by_hash; use polkadot_primitives::{ - BlockNumber, CandidateHash, CandidateReceipt, Hash, PvfExecKind, SessionIndex, + vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, Hash, + PvfExecKind, SessionIndex, }; use crate::LOG_TARGET; @@ -350,7 +351,7 @@ async fn participate( let validation_code = match get_validation_code_by_hash( &mut sender, block_hash, - req.candidate_receipt().descriptor.validation_code_hash, + req.candidate_receipt().descriptor.validation_code_hash(), ) .await { @@ -359,7 +360,7 @@ async fn participate( gum::warn!( target: LOG_TARGET, "Validation code unavailable for code hash {:?} in the state of block {:?}", - req.candidate_receipt().descriptor.validation_code_hash, + req.candidate_receipt().descriptor.validation_code_hash(), block_hash, ); diff --git a/polkadot/node/core/dispute-coordinator/src/participation/queues/mod.rs b/polkadot/node/core/dispute-coordinator/src/participation/queues/mod.rs index d9e86def168c..4d317d38590a 100644 --- a/polkadot/node/core/dispute-coordinator/src/participation/queues/mod.rs +++ b/polkadot/node/core/dispute-coordinator/src/participation/queues/mod.rs @@ -22,7 +22,8 @@ use std::{ use futures::channel::oneshot; use polkadot_node_subsystem::{messages::ChainApiMessage, overseer}; use polkadot_primitives::{ - BlockNumber, CandidateHash, CandidateReceipt, ExecutorParams, Hash, SessionIndex, + vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, ExecutorParams, + Hash, SessionIndex, }; use crate::{ @@ -405,7 +406,7 @@ impl CandidateComparator { candidate: &CandidateReceipt, ) -> FatalResult { let candidate_hash = candidate.hash(); - let n = get_block_number(sender, candidate.descriptor().relay_parent).await?; + let n = get_block_number(sender, candidate.descriptor().relay_parent()).await?; if n.is_none() { gum::warn!( diff --git a/polkadot/node/core/dispute-coordinator/src/scraping/mod.rs b/polkadot/node/core/dispute-coordinator/src/scraping/mod.rs index 4c45d9dcc220..9aaad9d1c528 100644 --- a/polkadot/node/core/dispute-coordinator/src/scraping/mod.rs +++ b/polkadot/node/core/dispute-coordinator/src/scraping/mod.rs @@ -28,8 +28,9 @@ use polkadot_node_subsystem_util::runtime::{ self, get_candidate_events, get_on_chain_votes, get_unapplied_slashes, }; use polkadot_primitives::{ - slashing::PendingSlashes, BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, Hash, - ScrapedOnChainVotes, SessionIndex, + slashing::PendingSlashes, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt, ScrapedOnChainVotes}, + BlockNumber, CandidateHash, Hash, SessionIndex, }; use crate::{ diff --git a/polkadot/node/core/parachains-inherent/src/lib.rs b/polkadot/node/core/parachains-inherent/src/lib.rs index 1de3cab32bed..5f3092f6a881 100644 --- a/polkadot/node/core/parachains-inherent/src/lib.rs +++ b/polkadot/node/core/parachains-inherent/src/lib.rs @@ -29,7 +29,7 @@ use futures::{select, FutureExt}; use polkadot_node_subsystem::{ errors::SubsystemError, messages::ProvisionerMessage, overseer::Handle, }; -use polkadot_primitives::{Block, Hash, InherentData as ParachainsInherentData}; +use polkadot_primitives::{vstaging::InherentData as ParachainsInherentData, Block, Hash}; use std::{sync::Arc, time}; pub(crate) const LOG_TARGET: &str = "parachain::parachains-inherent"; diff --git a/polkadot/node/core/prospective-parachains/src/fragment_chain/mod.rs b/polkadot/node/core/prospective-parachains/src/fragment_chain/mod.rs index b060897d4391..265d1498ee96 100644 --- a/polkadot/node/core/prospective-parachains/src/fragment_chain/mod.rs +++ b/polkadot/node/core/prospective-parachains/src/fragment_chain/mod.rs @@ -136,8 +136,9 @@ use polkadot_node_subsystem_util::inclusion_emulator::{ ProspectiveCandidate, RelayChainBlockInfo, }; use polkadot_primitives::{ - BlockNumber, CandidateCommitments, CandidateHash, CommittedCandidateReceipt, Hash, HeadData, - PersistedValidationData, ValidationCodeHash, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, BlockNumber, + CandidateCommitments, CandidateHash, Hash, HeadData, PersistedValidationData, + ValidationCodeHash, }; use thiserror::Error; @@ -371,7 +372,8 @@ impl CandidateEntry { persisted_validation_data: PersistedValidationData, state: CandidateState, ) -> Result { - if persisted_validation_data.hash() != candidate.descriptor.persisted_validation_data_hash { + if persisted_validation_data.hash() != candidate.descriptor.persisted_validation_data_hash() + { return Err(CandidateEntryError::PersistedValidationDataMismatch) } @@ -386,13 +388,13 @@ impl CandidateEntry { candidate_hash, parent_head_data_hash, output_head_data_hash, - relay_parent: candidate.descriptor.relay_parent, + relay_parent: candidate.descriptor.relay_parent(), state, candidate: Arc::new(ProspectiveCandidate { commitments: candidate.commitments, persisted_validation_data, - pov_hash: candidate.descriptor.pov_hash, - validation_code_hash: candidate.descriptor.validation_code_hash, + pov_hash: candidate.descriptor.pov_hash(), + validation_code_hash: candidate.descriptor.validation_code_hash(), }), }) } @@ -407,8 +409,8 @@ impl HypotheticalOrConcreteCandidate for CandidateEntry { Some(&self.candidate.persisted_validation_data) } - fn validation_code_hash(&self) -> Option<&ValidationCodeHash> { - Some(&self.candidate.validation_code_hash) + fn validation_code_hash(&self) -> Option { + Some(self.candidate.validation_code_hash) } fn parent_head_data_hash(&self) -> Hash { @@ -1090,7 +1092,7 @@ impl FragmentChain { &relay_parent, &constraints, commitments, - validation_code_hash, + &validation_code_hash, pvd, ) .map_err(Error::CheckAgainstConstraints)?; diff --git a/polkadot/node/core/prospective-parachains/src/lib.rs b/polkadot/node/core/prospective-parachains/src/lib.rs index b8b5f159e71c..34c1d8823bfc 100644 --- a/polkadot/node/core/prospective-parachains/src/lib.rs +++ b/polkadot/node/core/prospective-parachains/src/lib.rs @@ -49,9 +49,11 @@ use polkadot_node_subsystem_util::{ runtime::{fetch_claim_queue, prospective_parachains_mode, ProspectiveParachainsMode}, }; use polkadot_primitives::{ - async_backing::CandidatePendingAvailability, BlockNumber, CandidateHash, - CommittedCandidateReceipt, CoreState, Hash, HeadData, Header, Id as ParaId, - PersistedValidationData, + vstaging::{ + async_backing::CandidatePendingAvailability, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + }, + BlockNumber, CandidateHash, Hash, HeadData, Header, Id as ParaId, PersistedValidationData, }; use crate::{ @@ -453,12 +455,13 @@ async fn preprocess_candidates_pending_availability( for (i, pending) in pending_availability.into_iter().enumerate() { let Some(relay_parent) = - fetch_block_info(ctx, cache, pending.descriptor.relay_parent).await? + fetch_block_info(ctx, cache, pending.descriptor.relay_parent()).await? else { + let para_id = pending.descriptor.para_id(); gum::debug!( target: LOG_TARGET, ?pending.candidate_hash, - ?pending.descriptor.para_id, + ?para_id, index = ?i, ?expected_count, "Had to stop processing pending candidates early due to missing info.", diff --git a/polkadot/node/core/provisioner/src/lib.rs b/polkadot/node/core/provisioner/src/lib.rs index ffc5859b7756..c8dbdfd4b6db 100644 --- a/polkadot/node/core/provisioner/src/lib.rs +++ b/polkadot/node/core/provisioner/src/lib.rs @@ -42,9 +42,10 @@ use polkadot_node_subsystem_util::{ TimeoutExt, }; use polkadot_primitives::{ - node_features::FeatureIndex, BackedCandidate, BlockNumber, CandidateHash, CandidateReceipt, - CoreIndex, CoreState, Hash, Id as ParaId, NodeFeatures, OccupiedCoreAssumption, SessionIndex, - SignedAvailabilityBitfield, ValidatorIndex, + node_features::FeatureIndex, + vstaging::{BackedCandidate, CandidateReceiptV2 as CandidateReceipt, CoreState}, + BlockNumber, CandidateHash, CoreIndex, Hash, Id as ParaId, NodeFeatures, + OccupiedCoreAssumption, SessionIndex, SignedAvailabilityBitfield, ValidatorIndex, }; use std::collections::{BTreeMap, HashMap}; @@ -370,13 +371,13 @@ fn note_provisionable_data( gum::trace!( target: LOG_TARGET, ?candidate_hash, - para = ?backed_candidate.descriptor().para_id, + para = ?backed_candidate.descriptor().para_id(), "noted backed candidate", ); let _span = span .child("provisionable-backed") .with_candidate(candidate_hash) - .with_para_id(backed_candidate.descriptor().para_id); + .with_para_id(backed_candidate.descriptor().para_id()); per_relay_parent.backed_candidates.push(backed_candidate); }, // We choose not to punish these forms of misbehavior for the time being. @@ -662,22 +663,22 @@ async fn select_candidate_hashes_from_tracked( // selection criteria if let Some(candidate) = candidates.iter().find(|backed_candidate| { let descriptor = &backed_candidate.descriptor; - descriptor.para_id == scheduled_core.para_id && - descriptor.persisted_validation_data_hash == computed_validation_data_hash + descriptor.para_id() == scheduled_core.para_id && + descriptor.persisted_validation_data_hash() == computed_validation_data_hash }) { let candidate_hash = candidate.hash(); gum::trace!( target: LOG_TARGET, leaf_hash=?relay_parent, ?candidate_hash, - para = ?candidate.descriptor.para_id, + para = ?candidate.descriptor.para_id(), core = core_idx, "Selected candidate receipt", ); selected_candidates.insert( - candidate.descriptor.para_id, - vec![(candidate_hash, candidate.descriptor.relay_parent)], + candidate.descriptor.para_id(), + vec![(candidate_hash, candidate.descriptor.relay_parent())], ); } } diff --git a/polkadot/node/core/runtime-api/src/cache.rs b/polkadot/node/core/runtime-api/src/cache.rs index 05efbc533d02..7246010711e4 100644 --- a/polkadot/node/core/runtime-api/src/cache.rs +++ b/polkadot/node/core/runtime-api/src/cache.rs @@ -20,12 +20,16 @@ use schnellru::{ByLength, LruMap}; use sp_consensus_babe::Epoch; use polkadot_primitives::{ - async_backing, slashing, ApprovalVotingParams, AuthorityDiscoveryId, BlockNumber, - CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreIndex, - CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, + async_backing, slashing, vstaging, + vstaging::{ + CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + ApprovalVotingParams, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateHash, + CoreIndex, DisputeState, ExecutorParams, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, NodeFeatures, OccupiedCoreAssumption, - PersistedValidationData, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, - ValidationCodeHash, ValidatorId, ValidatorIndex, + PersistedValidationData, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, + ValidatorId, ValidatorIndex, }; /// For consistency we have the same capacity for all caches. We use 128 as we'll only need that @@ -66,7 +70,7 @@ pub(crate) struct RequestResultCache { key_ownership_proof: LruMap<(Hash, ValidatorId), Option>, minimum_backing_votes: LruMap, disabled_validators: LruMap>, - para_backing_state: LruMap<(Hash, ParaId), Option>, + para_backing_state: LruMap<(Hash, ParaId), Option>, async_backing_params: LruMap, node_features: LruMap, approval_voting_params: LruMap, @@ -499,14 +503,14 @@ impl RequestResultCache { pub(crate) fn para_backing_state( &mut self, key: (Hash, ParaId), - ) -> Option<&Option> { + ) -> Option<&Option> { self.para_backing_state.get(&key).map(|v| &*v) } pub(crate) fn cache_para_backing_state( &mut self, key: (Hash, ParaId), - value: Option, + value: Option, ) { self.para_backing_state.insert(key, value); } @@ -601,7 +605,7 @@ pub(crate) enum RequestResult { SubmitReportDisputeLost(Option<()>), ApprovalVotingParams(Hash, SessionIndex, ApprovalVotingParams), DisabledValidators(Hash, Vec), - ParaBackingState(Hash, ParaId, Option), + ParaBackingState(Hash, ParaId, Option), AsyncBackingParams(Hash, async_backing::AsyncBackingParams), NodeFeatures(SessionIndex, NodeFeatures), ClaimQueue(Hash, BTreeMap>), diff --git a/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs b/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs index 278608cc858d..6abe5df9f1d9 100644 --- a/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs +++ b/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs @@ -36,8 +36,8 @@ use polkadot_node_subsystem::{ overseer, }; use polkadot_primitives::{ - AuthorityDiscoveryId, BlakeTwo256, CandidateHash, ChunkIndex, GroupIndex, Hash, HashT, - OccupiedCore, SessionIndex, + vstaging::OccupiedCore, AuthorityDiscoveryId, BlakeTwo256, CandidateHash, ChunkIndex, + GroupIndex, Hash, HashT, SessionIndex, }; use sc_network::ProtocolName; @@ -165,8 +165,8 @@ impl FetchTaskConfig { .with_validator_index(session_info.our_index) .with_chunk_index(chunk_index) .with_uint_tag("group-index", core.group_responsible.0 as u64) - .with_relay_parent(core.candidate_descriptor.relay_parent) - .with_string_tag("pov-hash", format!("{:?}", core.candidate_descriptor.pov_hash)) + .with_relay_parent(core.candidate_descriptor.relay_parent()) + .with_string_tag("pov-hash", format!("{:?}", core.candidate_descriptor.pov_hash())) .with_stage(jaeger::Stage::AvailabilityDistribution); let live_in = vec![leaf].into_iter().collect(); @@ -186,8 +186,8 @@ impl FetchTaskConfig { candidate_hash: core.candidate_hash, index: session_info.our_index, }, - erasure_root: core.candidate_descriptor.erasure_root, - relay_parent: core.candidate_descriptor.relay_parent, + erasure_root: core.candidate_descriptor.erasure_root(), + relay_parent: core.candidate_descriptor.relay_parent(), metrics, sender, span, diff --git a/polkadot/node/network/availability-distribution/src/requester/mod.rs b/polkadot/node/network/availability-distribution/src/requester/mod.rs index 0175161af70d..b6c8a4a1aba5 100644 --- a/polkadot/node/network/availability-distribution/src/requester/mod.rs +++ b/polkadot/node/network/availability-distribution/src/requester/mod.rs @@ -40,7 +40,7 @@ use polkadot_node_subsystem_util::{ runtime::{get_occupied_cores, RuntimeInfo}, }; use polkadot_primitives::{ - BlockNumber, CandidateHash, CoreIndex, Hash, OccupiedCore, SessionIndex, + vstaging::OccupiedCore, BlockNumber, CandidateHash, CoreIndex, Hash, SessionIndex, }; use super::{FatalError, Metrics, Result, LOG_TARGET}; diff --git a/polkadot/node/network/availability-recovery/src/lib.rs b/polkadot/node/network/availability-recovery/src/lib.rs index 167125f987ab..ff98d02019f5 100644 --- a/polkadot/node/network/availability-recovery/src/lib.rs +++ b/polkadot/node/network/availability-recovery/src/lib.rs @@ -67,8 +67,8 @@ use polkadot_node_subsystem_util::{ runtime::{ExtendedSessionInfo, RuntimeInfo}, }; use polkadot_primitives::{ - node_features, BlockNumber, CandidateHash, CandidateReceipt, ChunkIndex, CoreIndex, GroupIndex, - Hash, SessionIndex, ValidatorIndex, + node_features, vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, + ChunkIndex, CoreIndex, GroupIndex, Hash, SessionIndex, ValidatorIndex, }; mod error; @@ -546,11 +546,11 @@ async fn handle_recover( threshold: recovery_threshold(n_validators)?, systematic_threshold, candidate_hash, - erasure_root: receipt.descriptor.erasure_root, + erasure_root: receipt.descriptor.erasure_root(), metrics: metrics.clone(), bypass_availability_store, post_recovery_check, - pov_hash: receipt.descriptor.pov_hash, + pov_hash: receipt.descriptor.pov_hash(), req_v1_protocol_name, req_v2_protocol_name, chunk_mapping_enabled, diff --git a/polkadot/node/network/collator-protocol/src/collator_side/collation.rs b/polkadot/node/network/collator-protocol/src/collator_side/collation.rs index 57e1479a449b..6a570331f710 100644 --- a/polkadot/node/network/collator-protocol/src/collator_side/collation.rs +++ b/polkadot/node/network/collator-protocol/src/collator_side/collation.rs @@ -28,7 +28,9 @@ use polkadot_node_network_protocol::{ }; use polkadot_node_primitives::PoV; use polkadot_node_subsystem::messages::ParentHeadData; -use polkadot_primitives::{CandidateHash, CandidateReceipt, Hash, Id as ParaId}; +use polkadot_primitives::{ + vstaging::CandidateReceiptV2 as CandidateReceipt, CandidateHash, Hash, Id as ParaId, +}; /// The status of a collation as seen from the collator. pub enum CollationStatus { diff --git a/polkadot/node/network/collator-protocol/src/collator_side/mod.rs b/polkadot/node/network/collator-protocol/src/collator_side/mod.rs index 97bc66d6058c..cfe0ed278fc9 100644 --- a/polkadot/node/network/collator-protocol/src/collator_side/mod.rs +++ b/polkadot/node/network/collator-protocol/src/collator_side/mod.rs @@ -55,8 +55,9 @@ use polkadot_node_subsystem_util::{ TimeoutExt, }; use polkadot_primitives::{ - AuthorityDiscoveryId, CandidateHash, CandidateReceipt, CollatorPair, CoreIndex, CoreState, - GroupIndex, Hash, HeadData, Id as ParaId, SessionIndex, + vstaging::{CandidateReceiptV2 as CandidateReceipt, CoreState}, + AuthorityDiscoveryId, CandidateHash, CollatorPair, CoreIndex, GroupIndex, Hash, HeadData, + Id as ParaId, SessionIndex, }; use super::LOG_TARGET; @@ -379,7 +380,7 @@ async fn distribute_collation( result_sender: Option>, core_index: CoreIndex, ) -> Result<()> { - let candidate_relay_parent = receipt.descriptor.relay_parent; + let candidate_relay_parent = receipt.descriptor.relay_parent(); let candidate_hash = receipt.hash(); let per_relay_parent = match state.per_relay_parent.get_mut(&candidate_relay_parent) { @@ -856,17 +857,17 @@ async fn process_msg( } => { let _span1 = state .span_per_relay_parent - .get(&candidate_receipt.descriptor.relay_parent) + .get(&candidate_receipt.descriptor.relay_parent()) .map(|s| s.child("distributing-collation")); let _span2 = jaeger::Span::new(&pov, "distributing-collation"); match state.collating_on { - Some(id) if candidate_receipt.descriptor.para_id != id => { + Some(id) if candidate_receipt.descriptor.para_id() != id => { // If the ParaId of a collation requested to be distributed does not match // the one we expect, we ignore the message. gum::warn!( target: LOG_TARGET, - para_id = %candidate_receipt.descriptor.para_id, + para_id = %candidate_receipt.descriptor.para_id(), collating_on = %id, "DistributeCollation for unexpected para_id", ); @@ -890,7 +891,7 @@ async fn process_msg( None => { gum::warn!( target: LOG_TARGET, - para_id = %candidate_receipt.descriptor.para_id, + para_id = %candidate_receipt.descriptor.para_id(), "DistributeCollation message while not collating on any", ); }, diff --git a/polkadot/node/network/collator-protocol/src/validator_side/collation.rs b/polkadot/node/network/collator-protocol/src/validator_side/collation.rs index 96ffe9f13db3..9cbccbf55824 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/collation.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/collation.rs @@ -41,8 +41,8 @@ use polkadot_node_subsystem_util::{ metrics::prometheus::prometheus::HistogramTimer, runtime::ProspectiveParachainsMode, }; use polkadot_primitives::{ - CandidateHash, CandidateReceipt, CollatorId, Hash, HeadData, Id as ParaId, - PersistedValidationData, + vstaging::CandidateReceiptV2 as CandidateReceipt, CandidateHash, CollatorId, Hash, HeadData, + Id as ParaId, PersistedValidationData, }; use tokio_util::sync::CancellationToken; @@ -73,17 +73,19 @@ pub struct FetchedCollation { /// Candidate hash. pub candidate_hash: CandidateHash, /// Id of the collator the collation was fetched from. - pub collator_id: CollatorId, + /// This will be missing when we create the struct from + /// a v2 candidate receipt. instance + pub collator_id: Option, } impl From<&CandidateReceipt> for FetchedCollation { fn from(receipt: &CandidateReceipt) -> Self { let descriptor = receipt.descriptor(); Self { - relay_parent: descriptor.relay_parent, - para_id: descriptor.para_id, + relay_parent: descriptor.relay_parent(), + para_id: descriptor.para_id(), candidate_hash: receipt.hash(), - collator_id: descriptor.collator.clone(), + collator_id: descriptor.collator(), } } } @@ -142,7 +144,7 @@ pub fn fetched_collation_sanity_check( persisted_validation_data: &PersistedValidationData, maybe_parent_head_and_hash: Option<(HeadData, Hash)>, ) -> Result<(), SecondingError> { - if persisted_validation_data.hash() != fetched.descriptor().persisted_validation_data_hash { + if persisted_validation_data.hash() != fetched.descriptor().persisted_validation_data_hash() { Err(SecondingError::PersistedValidationDataMismatch) } else if advertised .prospective_candidate diff --git a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs index cbf00a9e119d..72172557fd90 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs @@ -53,8 +53,8 @@ use polkadot_node_subsystem_util::{ runtime::{fetch_claim_queue, prospective_parachains_mode, ProspectiveParachainsMode}, }; use polkadot_primitives::{ - CandidateHash, CollatorId, CoreState, Hash, HeadData, Id as ParaId, OccupiedCoreAssumption, - PersistedValidationData, + vstaging::CoreState, CandidateHash, CollatorId, Hash, HeadData, Id as ParaId, + OccupiedCoreAssumption, PersistedValidationData, }; use crate::error::{Error, FetchError, Result, SecondingError}; @@ -1029,7 +1029,7 @@ async fn second_unblocked_collations( for mut unblocked_collation in unblocked_collations { unblocked_collation.maybe_parent_head_data = Some(head_data.clone()); let peer_id = unblocked_collation.collation_event.pending_collation.peer_id; - let relay_parent = unblocked_collation.candidate_receipt.descriptor.relay_parent; + let relay_parent = unblocked_collation.candidate_receipt.descriptor.relay_parent(); if let Err(err) = kick_off_seconding(ctx, state, unblocked_collation).await { gum::warn!( @@ -1347,7 +1347,7 @@ where collations.retain(|collation| { state .per_relay_parent - .contains_key(&collation.candidate_receipt.descriptor.relay_parent) + .contains_key(&collation.candidate_receipt.descriptor.relay_parent()) }); !collations.is_empty() @@ -1489,7 +1489,7 @@ async fn process_msg( }, }; let output_head_data = receipt.commitments.head_data.clone(); - let output_head_data_hash = receipt.descriptor.para_head; + let output_head_data_hash = receipt.descriptor.para_head(); let fetched_collation = FetchedCollation::from(&receipt.to_plain()); if let Some(CollationEvent { collator_id, pending_collation, .. }) = state.fetched_candidates.remove(&fetched_collation) @@ -1550,8 +1550,8 @@ async fn process_msg( Invalid(parent, candidate_receipt) => { // Remove collations which were blocked from seconding and had this candidate as parent. state.blocked_from_seconding.remove(&BlockedCollationId { - para_id: candidate_receipt.descriptor.para_id, - parent_head_data_hash: candidate_receipt.descriptor.para_head, + para_id: candidate_receipt.descriptor.para_id(), + parent_head_data_hash: candidate_receipt.descriptor.para_head(), }); let fetched_collation = FetchedCollation::from(&candidate_receipt); @@ -1862,8 +1862,8 @@ async fn kick_off_seconding( (CollationVersion::V2, Some(_)) | (CollationVersion::V1, _) => { let pvd = request_persisted_validation_data( ctx.sender(), - candidate_receipt.descriptor().relay_parent, - candidate_receipt.descriptor().para_id, + candidate_receipt.descriptor().relay_parent(), + candidate_receipt.descriptor().para_id(), ) .await?; ( @@ -1893,14 +1893,14 @@ async fn kick_off_seconding( gum::debug!( target: LOG_TARGET, candidate_hash = ?blocked_collation.candidate_receipt.hash(), - relay_parent = ?blocked_collation.candidate_receipt.descriptor.relay_parent, + relay_parent = ?blocked_collation.candidate_receipt.descriptor.relay_parent(), "Collation having parent head data hash {} is blocked from seconding. Waiting on its parent to be validated.", parent_head_data_hash ); state .blocked_from_seconding .entry(BlockedCollationId { - para_id: blocked_collation.candidate_receipt.descriptor.para_id, + para_id: blocked_collation.candidate_receipt.descriptor.para_id(), parent_head_data_hash, }) .or_insert_with(Vec::new) @@ -2048,11 +2048,11 @@ async fn handle_collation_fetch_response( Ok( request_v1::CollationFetchingResponse::Collation(receipt, _) | request_v1::CollationFetchingResponse::CollationWithParentHeadData { receipt, .. }, - ) if receipt.descriptor().para_id != pending_collation.para_id => { + ) if receipt.descriptor().para_id() != pending_collation.para_id => { gum::debug!( target: LOG_TARGET, expected_para_id = ?pending_collation.para_id, - got_para_id = ?receipt.descriptor().para_id, + got_para_id = ?receipt.descriptor().para_id(), peer_id = ?pending_collation.peer_id, "Got wrong para ID for requested collation." ); diff --git a/polkadot/node/network/dispute-distribution/src/receiver/batches/batch.rs b/polkadot/node/network/dispute-distribution/src/receiver/batches/batch.rs index 11380b7c072e..c911b4bc4ae6 100644 --- a/polkadot/node/network/dispute-distribution/src/receiver/batches/batch.rs +++ b/polkadot/node/network/dispute-distribution/src/receiver/batches/batch.rs @@ -22,7 +22,7 @@ use polkadot_node_network_protocol::{ PeerId, }; use polkadot_node_primitives::SignedDisputeStatement; -use polkadot_primitives::{CandidateReceipt, ValidatorIndex}; +use polkadot_primitives::{vstaging::CandidateReceiptV2 as CandidateReceipt, ValidatorIndex}; use crate::receiver::{BATCH_COLLECTING_INTERVAL, MIN_KEEP_BATCH_ALIVE_VOTES}; diff --git a/polkadot/node/network/dispute-distribution/src/receiver/batches/mod.rs b/polkadot/node/network/dispute-distribution/src/receiver/batches/mod.rs index 76c7683d1574..13b42aff1f30 100644 --- a/polkadot/node/network/dispute-distribution/src/receiver/batches/mod.rs +++ b/polkadot/node/network/dispute-distribution/src/receiver/batches/mod.rs @@ -22,7 +22,7 @@ use std::{ use futures::future::pending; use polkadot_node_network_protocol::request_response::DISPUTE_REQUEST_TIMEOUT; -use polkadot_primitives::{CandidateHash, CandidateReceipt}; +use polkadot_primitives::{vstaging::CandidateReceiptV2 as CandidateReceipt, CandidateHash}; use crate::{ receiver::batches::{batch::TickResult, waiting_queue::PendingWake}, diff --git a/polkadot/node/network/dispute-distribution/src/receiver/mod.rs b/polkadot/node/network/dispute-distribution/src/receiver/mod.rs index 77c1e41aac05..b21965fc7004 100644 --- a/polkadot/node/network/dispute-distribution/src/receiver/mod.rs +++ b/polkadot/node/network/dispute-distribution/src/receiver/mod.rs @@ -334,7 +334,7 @@ where .runtime .get_session_info_by_index( &mut self.sender, - payload.0.candidate_receipt.descriptor.relay_parent, + payload.0.candidate_receipt.descriptor.relay_parent(), payload.0.session_index, ) .await?; diff --git a/polkadot/node/network/dispute-distribution/src/sender/send_task.rs b/polkadot/node/network/dispute-distribution/src/sender/send_task.rs index 54ccd10789d0..f607c9431513 100644 --- a/polkadot/node/network/dispute-distribution/src/sender/send_task.rs +++ b/polkadot/node/network/dispute-distribution/src/sender/send_task.rs @@ -234,7 +234,7 @@ impl SendTask { runtime: &mut RuntimeInfo, active_sessions: &HashMap, ) -> Result> { - let ref_head = self.request.0.candidate_receipt.descriptor.relay_parent; + let ref_head = self.request.0.candidate_receipt.descriptor.relay_parent(); // Retrieve all authorities which participated in the parachain consensus of the session // in which the candidate was backed. let info = runtime diff --git a/polkadot/node/network/protocol/src/request_response/v1.rs b/polkadot/node/network/protocol/src/request_response/v1.rs index 80721f1884af..4f28d4cbf2d8 100644 --- a/polkadot/node/network/protocol/src/request_response/v1.rs +++ b/polkadot/node/network/protocol/src/request_response/v1.rs @@ -22,8 +22,11 @@ use polkadot_node_primitives::{ AvailableData, DisputeMessage, ErasureChunk, PoV, Proof, UncheckedDisputeMessage, }; use polkadot_primitives::{ - CandidateHash, CandidateReceipt, CommittedCandidateReceipt, Hash, HeadData, Id as ParaId, - ValidatorIndex, + vstaging::{ + CandidateReceiptV2 as CandidateReceipt, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, + }, + CandidateHash, Hash, HeadData, Id as ParaId, ValidatorIndex, }; use super::{IsRequest, Protocol}; diff --git a/polkadot/node/network/protocol/src/request_response/v2.rs b/polkadot/node/network/protocol/src/request_response/v2.rs index ae65b39cd406..834870e5b908 100644 --- a/polkadot/node/network/protocol/src/request_response/v2.rs +++ b/polkadot/node/network/protocol/src/request_response/v2.rs @@ -20,8 +20,8 @@ use codec::{Decode, Encode}; use polkadot_node_primitives::ErasureChunk; use polkadot_primitives::{ - CandidateHash, CommittedCandidateReceipt, Hash, Id as ParaId, PersistedValidationData, - UncheckedSignedStatement, ValidatorIndex, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CandidateHash, Hash, + Id as ParaId, PersistedValidationData, UncheckedSignedStatement, ValidatorIndex, }; use super::{v1, IsRequest, Protocol}; diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/mod.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/mod.rs index 264333435a00..a86745e1dcb1 100644 --- a/polkadot/node/network/statement-distribution/src/legacy_v1/mod.rs +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/mod.rs @@ -38,9 +38,10 @@ use polkadot_node_subsystem::{ overseer, ActivatedLeaf, PerLeafSpan, StatementDistributionSenderTrait, }; use polkadot_primitives::{ - AuthorityDiscoveryId, CandidateHash, CommittedCandidateReceipt, CompactStatement, Hash, - Id as ParaId, IndexedVec, OccupiedCoreAssumption, PersistedValidationData, SignedStatement, - SigningContext, UncheckedSignedStatement, ValidatorId, ValidatorIndex, ValidatorSignature, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, AuthorityDiscoveryId, + CandidateHash, CompactStatement, Hash, Id as ParaId, IndexedVec, OccupiedCoreAssumption, + PersistedValidationData, SignedStatement, SigningContext, UncheckedSignedStatement, + ValidatorId, ValidatorIndex, ValidatorSignature, }; use futures::{ @@ -1659,7 +1660,7 @@ async fn handle_incoming_message<'a, Context>( // In case of `Valid` we should have it cached prior, therefore this performs // no Runtime API calls and always returns `Ok(Some(_))`. let pvd = if let Statement::Seconded(receipt) = statement.payload() { - let para_id = receipt.descriptor.para_id; + let para_id = receipt.descriptor.para_id(); // Either call the Runtime API or check that validation data is cached. let result = active_head .fetch_persisted_validation_data(ctx.sender(), relay_parent, para_id) diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/requester.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/requester.rs index 8a8a8f3d624a..a52c348b8618 100644 --- a/polkadot/node/network/statement-distribution/src/legacy_v1/requester.rs +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/requester.rs @@ -30,7 +30,9 @@ use polkadot_node_network_protocol::{ }; use polkadot_node_subsystem::{Span, Stage}; use polkadot_node_subsystem_util::TimeoutExt; -use polkadot_primitives::{CandidateHash, CommittedCandidateReceipt, Hash}; +use polkadot_primitives::{ + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CandidateHash, Hash, +}; use crate::{ legacy_v1::{COST_WRONG_HASH, LOG_TARGET}, diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/responder.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/responder.rs index 8d1683759a03..03e1dc059989 100644 --- a/polkadot/node/network/statement-distribution/src/legacy_v1/responder.rs +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/responder.rs @@ -29,7 +29,9 @@ use polkadot_node_network_protocol::{ }, PeerId, UnifiedReputationChange as Rep, }; -use polkadot_primitives::{CandidateHash, CommittedCandidateReceipt, Hash}; +use polkadot_primitives::{ + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CandidateHash, Hash, +}; use crate::LOG_TARGET; diff --git a/polkadot/node/network/statement-distribution/src/v2/candidates.rs b/polkadot/node/network/statement-distribution/src/v2/candidates.rs index a4f2455c2840..1a37d2ea086a 100644 --- a/polkadot/node/network/statement-distribution/src/v2/candidates.rs +++ b/polkadot/node/network/statement-distribution/src/v2/candidates.rs @@ -28,8 +28,8 @@ use polkadot_node_network_protocol::PeerId; use polkadot_node_subsystem::messages::HypotheticalCandidate; use polkadot_primitives::{ - CandidateHash, CommittedCandidateReceipt, GroupIndex, Hash, Id as ParaId, - PersistedValidationData, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CandidateHash, GroupIndex, + Hash, Id as ParaId, PersistedValidationData, }; use std::{ @@ -154,8 +154,8 @@ impl Candidates { assigned_group: GroupIndex, ) -> Option { let parent_hash = persisted_validation_data.parent_head.hash(); - let relay_parent = candidate_receipt.descriptor().relay_parent; - let para_id = candidate_receipt.descriptor().para_id; + let relay_parent = candidate_receipt.descriptor.relay_parent(); + let para_id = candidate_receipt.descriptor.para_id(); let prev_state = self.candidates.insert( candidate_hash, @@ -530,12 +530,12 @@ pub struct ConfirmedCandidate { impl ConfirmedCandidate { /// Get the relay-parent of the candidate. pub fn relay_parent(&self) -> Hash { - self.receipt.descriptor().relay_parent + self.receipt.descriptor.relay_parent() } /// Get the para-id of the candidate. pub fn para_id(&self) -> ParaId { - self.receipt.descriptor().para_id + self.receipt.descriptor.para_id() } /// Get the underlying candidate receipt. diff --git a/polkadot/node/network/statement-distribution/src/v2/mod.rs b/polkadot/node/network/statement-distribution/src/v2/mod.rs index f9c2d0ddbae8..c79ae3953ad9 100644 --- a/polkadot/node/network/statement-distribution/src/v2/mod.rs +++ b/polkadot/node/network/statement-distribution/src/v2/mod.rs @@ -50,9 +50,9 @@ use polkadot_node_subsystem_util::{ }, }; use polkadot_primitives::{ - AuthorityDiscoveryId, CandidateHash, CompactStatement, CoreIndex, CoreState, GroupIndex, - GroupRotationInfo, Hash, Id as ParaId, IndexedVec, SessionIndex, SessionInfo, SignedStatement, - SigningContext, UncheckedSignedStatement, ValidatorId, ValidatorIndex, + vstaging::CoreState, AuthorityDiscoveryId, CandidateHash, CompactStatement, CoreIndex, + GroupIndex, GroupRotationInfo, Hash, Id as ParaId, IndexedVec, SessionIndex, SessionInfo, + SignedStatement, SigningContext, UncheckedSignedStatement, ValidatorId, ValidatorIndex, }; use sp_keystore::KeystorePtr; @@ -1201,7 +1201,7 @@ pub(crate) async fn share_local_statement( // have the candidate. Sanity: check the para-id is valid. let expected = match statement.payload() { FullStatementWithPVD::Seconded(ref c, _) => - Some((c.descriptor().para_id, c.descriptor().relay_parent)), + Some((c.descriptor.para_id(), c.descriptor.relay_parent())), FullStatementWithPVD::Valid(hash) => state.candidates.get_confirmed(&hash).map(|c| (c.para_id(), c.relay_parent())), }; @@ -2277,13 +2277,13 @@ async fn fragment_chain_update_inner( } = hypo { let confirmed_candidate = state.candidates.get_confirmed(&candidate_hash); - let prs = state.per_relay_parent.get_mut(&receipt.descriptor().relay_parent); + let prs = state.per_relay_parent.get_mut(&receipt.descriptor.relay_parent()); if let (Some(confirmed), Some(prs)) = (confirmed_candidate, prs) { let per_session = state.per_session.get(&prs.session); let group_index = confirmed.group_index(); // Sanity check if group_index is valid for this para at relay parent. - let Some(expected_groups) = prs.groups_per_para.get(&receipt.descriptor().para_id) + let Some(expected_groups) = prs.groups_per_para.get(&receipt.descriptor.para_id()) else { continue }; @@ -2296,7 +2296,7 @@ async fn fragment_chain_update_inner( ctx, candidate_hash, confirmed.group_index(), - &receipt.descriptor().relay_parent, + &receipt.descriptor.relay_parent(), prs, confirmed, per_session, @@ -2888,7 +2888,7 @@ pub(crate) async fn handle_backed_candidate_message( ctx, state, confirmed.para_id(), - confirmed.candidate_receipt().descriptor().para_head, + confirmed.candidate_receipt().descriptor.para_head(), ) .await; } diff --git a/polkadot/node/network/statement-distribution/src/v2/requests.rs b/polkadot/node/network/statement-distribution/src/v2/requests.rs index b8ed34d26c8a..4e48f5c4dd50 100644 --- a/polkadot/node/network/statement-distribution/src/v2/requests.rs +++ b/polkadot/node/network/statement-distribution/src/v2/requests.rs @@ -47,9 +47,9 @@ use polkadot_node_network_protocol::{ PeerId, UnifiedReputationChange as Rep, }; use polkadot_primitives::{ - CandidateHash, CommittedCandidateReceipt, CompactStatement, GroupIndex, Hash, Id as ParaId, - PersistedValidationData, SessionIndex, SignedStatement, SigningContext, ValidatorId, - ValidatorIndex, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CandidateHash, + CompactStatement, GroupIndex, Hash, Id as ParaId, PersistedValidationData, SessionIndex, + SignedStatement, SigningContext, ValidatorId, ValidatorIndex, }; use futures::{future::BoxFuture, prelude::*, stream::FuturesUnordered}; @@ -696,18 +696,18 @@ fn validate_complete_response( // sanity-check candidate response. // note: roughly ascending cost of operations { - if response.candidate_receipt.descriptor.relay_parent != identifier.relay_parent { + if response.candidate_receipt.descriptor.relay_parent() != identifier.relay_parent { return invalid_candidate_output() } - if response.candidate_receipt.descriptor.persisted_validation_data_hash != + if response.candidate_receipt.descriptor.persisted_validation_data_hash() != response.persisted_validation_data.hash() { return invalid_candidate_output() } if !allowed_para_lookup( - response.candidate_receipt.descriptor.para_id, + response.candidate_receipt.descriptor.para_id(), identifier.group_index, ) { return invalid_candidate_output() diff --git a/polkadot/node/primitives/src/disputes/message.rs b/polkadot/node/primitives/src/disputes/message.rs index f9dec073bf50..d32ed4dadb6e 100644 --- a/polkadot/node/primitives/src/disputes/message.rs +++ b/polkadot/node/primitives/src/disputes/message.rs @@ -25,7 +25,8 @@ use codec::{Decode, Encode}; use super::{InvalidDisputeVote, SignedDisputeStatement, ValidDisputeVote}; use polkadot_primitives::{ - CandidateReceipt, DisputeStatement, SessionIndex, SessionInfo, ValidatorIndex, + vstaging::CandidateReceiptV2 as CandidateReceipt, DisputeStatement, SessionIndex, SessionInfo, + ValidatorIndex, }; /// A dispute initiating/participating message that have been built from signed diff --git a/polkadot/node/primitives/src/disputes/mod.rs b/polkadot/node/primitives/src/disputes/mod.rs index 0f08b4733654..71e2f0b16be3 100644 --- a/polkadot/node/primitives/src/disputes/mod.rs +++ b/polkadot/node/primitives/src/disputes/mod.rs @@ -25,9 +25,9 @@ use sp_application_crypto::AppCrypto; use sp_keystore::{Error as KeystoreError, KeystorePtr}; use polkadot_primitives::{ - CandidateHash, CandidateReceipt, CompactStatement, DisputeStatement, EncodeAs, - InvalidDisputeStatementKind, SessionIndex, SigningContext, UncheckedSigned, - ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature, + vstaging::CandidateReceiptV2 as CandidateReceipt, CandidateHash, CompactStatement, + DisputeStatement, EncodeAs, InvalidDisputeStatementKind, SessionIndex, SigningContext, + UncheckedSigned, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature, }; /// `DisputeMessage` and related types. diff --git a/polkadot/node/primitives/src/lib.rs b/polkadot/node/primitives/src/lib.rs index 685a9fd337df..bce1550b96f6 100644 --- a/polkadot/node/primitives/src/lib.rs +++ b/polkadot/node/primitives/src/lib.rs @@ -30,10 +30,10 @@ use futures::Future; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use polkadot_primitives::{ - BlakeTwo256, BlockNumber, CandidateCommitments, CandidateHash, ChunkIndex, CollatorPair, - CommittedCandidateReceipt, CompactStatement, CoreIndex, EncodeAs, Hash, HashT, HeadData, - Id as ParaId, PersistedValidationData, SessionIndex, Signed, UncheckedSigned, ValidationCode, - ValidationCodeHash, MAX_CODE_SIZE, MAX_POV_SIZE, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, BlakeTwo256, BlockNumber, + CandidateCommitments, CandidateHash, ChunkIndex, CollatorPair, CompactStatement, CoreIndex, + EncodeAs, Hash, HashT, HeadData, Id as ParaId, PersistedValidationData, SessionIndex, Signed, + UncheckedSigned, ValidationCode, ValidationCodeHash, MAX_CODE_SIZE, MAX_POV_SIZE, }; pub use sp_consensus_babe::{ AllowedSlots as BabeAllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch, diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index 854a9da158be..41691a83c4aa 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -42,14 +42,18 @@ use polkadot_node_primitives::{ ValidationResult, }; use polkadot_primitives::{ - async_backing, slashing, ApprovalVotingParams, AuthorityDiscoveryId, BackedCandidate, - BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash, CandidateIndex, - CandidateReceipt, CollatorId, CommittedCandidateReceipt, CoreIndex, CoreState, DisputeState, - ExecutorParams, GroupIndex, GroupRotationInfo, Hash, HeadData, Header as BlockHeader, - Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet, - NodeFeatures, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, PvfExecKind, - SessionIndex, SessionInfo, SignedAvailabilityBitfield, SignedAvailabilityBitfields, - ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, + async_backing, slashing, vstaging, + vstaging::{ + BackedCandidate, CandidateReceiptV2 as CandidateReceipt, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + }, + ApprovalVotingParams, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateHash, + CandidateIndex, CollatorId, CoreIndex, DisputeState, ExecutorParams, GroupIndex, + GroupRotationInfo, Hash, HeadData, Header as BlockHeader, Id as ParaId, InboundDownwardMessage, + InboundHrmpMessage, MultiDisputeStatementSet, NodeFeatures, OccupiedCoreAssumption, + PersistedValidationData, PvfCheckStatement, PvfExecKind, SessionIndex, SessionInfo, + SignedAvailabilityBitfield, SignedAvailabilityBitfields, ValidationCode, ValidationCodeHash, + ValidatorId, ValidatorIndex, ValidatorSignature, }; use polkadot_statement_table::v2::Misbehavior; use std::{ @@ -689,7 +693,7 @@ pub enum RuntimeApiRequest { CandidatePendingAvailability(ParaId, RuntimeApiSender>), /// Get all events concerning candidates (backing, inclusion, time-out) in the parent of /// the block in whose state this request is executed. - CandidateEvents(RuntimeApiSender>), + CandidateEvents(RuntimeApiSender>), /// Get the execution environment parameter set by session index SessionExecutorParams(SessionIndex, RuntimeApiSender>), /// Get the session info for the given session, if stored. @@ -705,7 +709,7 @@ pub enum RuntimeApiRequest { /// Get information about the BABE epoch the block was included in. CurrentBabeEpoch(RuntimeApiSender), /// Get all disputes in relation to a relay parent. - FetchOnChainVotes(RuntimeApiSender>), + FetchOnChainVotes(RuntimeApiSender>), /// Submits a PVF pre-checking statement into the transaction pool. SubmitPvfCheckStatement(PvfCheckStatement, ValidatorSignature, RuntimeApiSender<()>), /// Returns code hashes of PVFs that require pre-checking by validators in the active set. @@ -740,7 +744,7 @@ pub enum RuntimeApiRequest { /// Returns all disabled validators at a given block height. DisabledValidators(RuntimeApiSender>), /// Get the backing state of the given para. - ParaBackingState(ParaId, RuntimeApiSender>), + ParaBackingState(ParaId, RuntimeApiSender>), /// Get candidate's acceptance limitations for asynchronous backing for a relay parent. /// /// If it's not supported by the Runtime, the async backing is said to be disabled. @@ -1140,7 +1144,7 @@ impl HypotheticalCandidate { /// Get the `ParaId` of the hypothetical candidate. pub fn candidate_para(&self) -> ParaId { match *self { - HypotheticalCandidate::Complete { ref receipt, .. } => receipt.descriptor().para_id, + HypotheticalCandidate::Complete { ref receipt, .. } => receipt.descriptor.para_id(), HypotheticalCandidate::Incomplete { candidate_para, .. } => candidate_para, } } @@ -1159,7 +1163,7 @@ impl HypotheticalCandidate { pub fn relay_parent(&self) -> Hash { match *self { HypotheticalCandidate::Complete { ref receipt, .. } => - receipt.descriptor().relay_parent, + receipt.descriptor.relay_parent(), HypotheticalCandidate::Incomplete { candidate_relay_parent, .. } => candidate_relay_parent, } @@ -1169,7 +1173,7 @@ impl HypotheticalCandidate { pub fn output_head_data_hash(&self) -> Option { match *self { HypotheticalCandidate::Complete { ref receipt, .. } => - Some(receipt.descriptor.para_head), + Some(receipt.descriptor.para_head()), HypotheticalCandidate::Incomplete { .. } => None, } } @@ -1192,10 +1196,10 @@ impl HypotheticalCandidate { } /// Get the validation code hash, if the candidate is complete. - pub fn validation_code_hash(&self) -> Option<&ValidationCodeHash> { + pub fn validation_code_hash(&self) -> Option { match *self { HypotheticalCandidate::Complete { ref receipt, .. } => - Some(&receipt.descriptor.validation_code_hash), + Some(receipt.descriptor.validation_code_hash()), HypotheticalCandidate::Incomplete { .. } => None, } } diff --git a/polkadot/node/subsystem-types/src/runtime_client.rs b/polkadot/node/subsystem-types/src/runtime_client.rs index 7938223df23b..5dd7c97a9fdc 100644 --- a/polkadot/node/subsystem-types/src/runtime_client.rs +++ b/polkadot/node/subsystem-types/src/runtime_client.rs @@ -16,12 +16,18 @@ use async_trait::async_trait; use polkadot_primitives::{ - async_backing, runtime_api::ParachainHost, slashing, ApprovalVotingParams, Block, BlockNumber, - CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreIndex, - CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Hash, Header, Id, - InboundDownwardMessage, InboundHrmpMessage, NodeFeatures, OccupiedCoreAssumption, - PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, - ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, + async_backing, + runtime_api::ParachainHost, + slashing, vstaging, + vstaging::{ + CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + ApprovalVotingParams, Block, BlockNumber, CandidateCommitments, CandidateHash, CoreIndex, + DisputeState, ExecutorParams, GroupRotationInfo, Hash, Header, Id, InboundDownwardMessage, + InboundHrmpMessage, NodeFeatures, OccupiedCoreAssumption, PersistedValidationData, + PvfCheckStatement, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, + ValidatorIndex, ValidatorSignature, }; use sc_client_api::{AuxStore, HeaderBackend}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; @@ -311,7 +317,7 @@ pub trait RuntimeApiSubsystemClient { &self, at: Hash, para_id: Id, - ) -> Result, ApiError>; + ) -> Result, ApiError>; // === v8 === @@ -380,10 +386,7 @@ where &self, at: Hash, ) -> Result>, ApiError> { - self.client - .runtime_api() - .availability_cores(at) - .map(|cores| cores.into_iter().map(|core| core.into()).collect::>()) + self.client.runtime_api().availability_cores(at) } async fn persisted_validation_data( @@ -436,10 +439,7 @@ where at: Hash, para_id: Id, ) -> Result>, ApiError> { - self.client - .runtime_api() - .candidate_pending_availability(at, para_id) - .map(|maybe_candidate| maybe_candidate.map(|candidate| candidate.into())) + self.client.runtime_api().candidate_pending_availability(at, para_id) } async fn candidates_pending_availability( @@ -447,19 +447,11 @@ where at: Hash, para_id: Id, ) -> Result>, ApiError> { - self.client - .runtime_api() - .candidates_pending_availability(at, para_id) - .map(|candidates| { - candidates.into_iter().map(|candidate| candidate.into()).collect::>() - }) + self.client.runtime_api().candidates_pending_availability(at, para_id) } async fn candidate_events(&self, at: Hash) -> Result>, ApiError> { - self.client - .runtime_api() - .candidate_events(at) - .map(|events| events.into_iter().map(|event| event.into()).collect::>()) + self.client.runtime_api().candidate_events(at) } async fn dmq_contents( @@ -490,10 +482,7 @@ where &self, at: Hash, ) -> Result>, ApiError> { - self.client - .runtime_api() - .on_chain_votes(at) - .map(|maybe_votes| maybe_votes.map(|votes| votes.into())) + self.client.runtime_api().on_chain_votes(at) } async fn session_executor_params( @@ -604,13 +593,8 @@ where &self, at: Hash, para_id: Id, - ) -> Result, ApiError> { - self.client - .runtime_api() - .para_backing_state(at, para_id) - .map(|maybe_backing_state| { - maybe_backing_state.map(|backing_state| backing_state.into()) - }) + ) -> Result, ApiError> { + self.client.runtime_api().para_backing_state(at, para_id) } async fn async_backing_params( diff --git a/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs b/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs index 0c3b40743495..a2a6095b765c 100644 --- a/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs +++ b/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs @@ -770,7 +770,7 @@ pub trait HypotheticalOrConcreteCandidate { /// Return a reference to the persisted validation data, if present. fn persisted_validation_data(&self) -> Option<&PersistedValidationData>; /// Return a reference to the validation code hash, if present. - fn validation_code_hash(&self) -> Option<&ValidationCodeHash>; + fn validation_code_hash(&self) -> Option; /// Return the parent head hash. fn parent_head_data_hash(&self) -> Hash; /// Return the output head hash, if present. @@ -790,7 +790,7 @@ impl HypotheticalOrConcreteCandidate for HypotheticalCandidate { self.persisted_validation_data() } - fn validation_code_hash(&self) -> Option<&ValidationCodeHash> { + fn validation_code_hash(&self) -> Option { self.validation_code_hash() } diff --git a/polkadot/node/subsystem-util/src/lib.rs b/polkadot/node/subsystem-util/src/lib.rs index 4bab4e80fe50..3bed18558941 100644 --- a/polkadot/node/subsystem-util/src/lib.rs +++ b/polkadot/node/subsystem-util/src/lib.rs @@ -41,12 +41,15 @@ use codec::Encode; use futures::channel::{mpsc, oneshot}; use polkadot_primitives::{ - async_backing::BackingState, slashing, AsyncBackingParams, AuthorityDiscoveryId, - CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreIndex, CoreState, EncodeAs, - ExecutorParams, GroupIndex, GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption, - PersistedValidationData, ScrapedOnChainVotes, SessionIndex, SessionInfo, Signed, - SigningContext, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, - ValidatorSignature, + slashing, + vstaging::{ + async_backing::BackingState, CandidateEvent, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, ScrapedOnChainVotes, + }, + AsyncBackingParams, AuthorityDiscoveryId, CandidateHash, CoreIndex, EncodeAs, ExecutorParams, + GroupIndex, GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption, + PersistedValidationData, SessionIndex, SessionInfo, Signed, SigningContext, ValidationCode, + ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; pub use rand; use runtime::get_disabled_validators_with_fallback; diff --git a/polkadot/node/subsystem-util/src/runtime/mod.rs b/polkadot/node/subsystem-util/src/runtime/mod.rs index 2f9d3ed7b4f4..d84951ae1366 100644 --- a/polkadot/node/subsystem-util/src/runtime/mod.rs +++ b/polkadot/node/subsystem-util/src/runtime/mod.rs @@ -30,11 +30,13 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_types::UnpinHandle; use polkadot_primitives::{ - node_features::FeatureIndex, slashing, AsyncBackingParams, CandidateEvent, CandidateHash, - CoreIndex, CoreState, EncodeAs, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, - Id as ParaId, IndexedVec, NodeFeatures, OccupiedCore, ScrapedOnChainVotes, SessionIndex, - SessionInfo, Signed, SigningContext, UncheckedSigned, ValidationCode, ValidationCodeHash, - ValidatorId, ValidatorIndex, LEGACY_MIN_BACKING_VOTES, + node_features::FeatureIndex, + slashing, + vstaging::{CandidateEvent, CoreState, OccupiedCore, ScrapedOnChainVotes}, + AsyncBackingParams, CandidateHash, CoreIndex, EncodeAs, ExecutorParams, GroupIndex, + GroupRotationInfo, Hash, Id as ParaId, IndexedVec, NodeFeatures, SessionIndex, SessionInfo, + Signed, SigningContext, UncheckedSigned, ValidationCode, ValidationCodeHash, ValidatorId, + ValidatorIndex, LEGACY_MIN_BACKING_VOTES, }; use std::collections::{BTreeMap, VecDeque}; diff --git a/polkadot/primitives/src/v8/mod.rs b/polkadot/primitives/src/v8/mod.rs index a51ee0bd99bf..f908632a01cb 100644 --- a/polkadot/primitives/src/v8/mod.rs +++ b/polkadot/primitives/src/v8/mod.rs @@ -484,7 +484,7 @@ pub fn collator_signature_payload>( payload } -fn check_collator_signature>( +pub(crate) fn check_collator_signature>( relay_parent: &H, para_id: &Id, persisted_validation_data_hash: &Hash, diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 6bdbfc632705..adde11486b4f 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -107,14 +107,42 @@ impl From> for CandidateDescriptor { } } -#[cfg(any(feature = "runtime-benchmarks", feature = "test"))] -impl From> for CandidateDescriptorV2 { +fn clone_into_array(slice: &[T]) -> A +where + A: Default + AsMut<[T]>, + T: Clone, +{ + let mut a = A::default(); + >::as_mut(&mut a).clone_from_slice(slice); + a +} + +impl From> for CandidateDescriptorV2 { fn from(value: CandidateDescriptor) -> Self { - Decode::decode(&mut value.encode().as_slice()).unwrap() + let collator = value.collator.as_slice(); + + Self { + para_id: value.para_id, + relay_parent: value.relay_parent, + // Use first byte of the `collator` field. + version: InternalVersion(collator[0]), + // Use next 2 bytes of the `collator` field. + core_index: u16::from_ne_bytes(clone_into_array(&collator[1..=2])), + // Use next 4 bytes of the `collator` field. + session_index: SessionIndex::from_ne_bytes(clone_into_array(&collator[3..=6])), + // Use remaing 25 bytes of the `collator` field. + reserved1: clone_into_array(&collator[7..]), + persisted_validation_data_hash: value.persisted_validation_data_hash, + pov_hash: value.pov_hash, + erasure_root: value.erasure_root, + reserved2: value.signature.into_inner().0, + para_head: value.para_head, + validation_code_hash: value.validation_code_hash, + } } } -impl CandidateDescriptorV2 { +impl> CandidateDescriptorV2 { /// Constructor pub fn new( para_id: Id, @@ -154,6 +182,24 @@ impl CandidateDescriptorV2 { pub fn set_version(&mut self, version: InternalVersion) { self.version = version; } + + /// Check the signature of the collator within this descriptor. + pub fn check_collator_signature(&self) -> Result<(), ()> { + // Return `Ok` if collator signature is not included (v2+ descriptor). + let Some(collator) = self.collator() else { return Ok(()) }; + + let Some(signature) = self.signature() else { return Ok(()) }; + + super::v8::check_collator_signature( + &self.relay_parent, + &self.para_id, + &self.persisted_validation_data_hash, + &self.pov_hash, + &self.validation_code_hash, + &collator, + &signature, + ) + } } /// A candidate-receipt at version 2. @@ -703,6 +749,13 @@ pub struct OccupiedCore { pub candidate_descriptor: CandidateDescriptorV2, } +impl OccupiedCore { + /// Get the Para currently occupying this core. + pub fn para_id(&self) -> Id { + self.candidate_descriptor.para_id + } +} + /// The state of a particular availability core. #[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] @@ -724,6 +777,28 @@ pub enum CoreState { Free, } +impl CoreState { + /// Returns the scheduled `ParaId` for the core or `None` if nothing is scheduled. + /// + /// This function is deprecated. `ClaimQueue` should be used to obtain the scheduled `ParaId`s + /// for each core. + #[deprecated( + note = "`para_id` will be removed. Use `ClaimQueue` to query the scheduled `para_id` instead." + )] + pub fn para_id(&self) -> Option { + match self { + Self::Occupied(ref core) => core.next_up_on_available.as_ref().map(|n| n.para_id), + Self::Scheduled(core) => Some(core.para_id), + Self::Free => None, + } + } + + /// Is this core state `Self::Occupied`? + pub fn is_occupied(&self) -> bool { + matches!(self, Self::Occupied(_)) + } +} + impl From> for super::v8::OccupiedCore { fn from(value: OccupiedCore) -> Self { Self { @@ -774,6 +849,8 @@ pub fn remap_claim_queue( #[cfg(test)] mod tests { + use std::hash::DefaultHasher; + use super::*; use crate::{ v8::{ @@ -840,6 +917,25 @@ mod tests { assert_eq!(old_ccr.hash(), new_ccr.hash()); } + #[test] + fn test_from_v1_descriptor() { + let mut old_ccr = dummy_old_committed_candidate_receipt().to_plain(); + old_ccr.descriptor.collator = dummy_collator_id(); + old_ccr.descriptor.signature = dummy_collator_signature(); + + let mut new_ccr = dummy_committed_candidate_receipt_v2().to_plain(); + + // Override descriptor from old candidate receipt. + new_ccr.descriptor = old_ccr.descriptor.clone().into(); + + // We get same candidate hash. + assert_eq!(old_ccr.hash(), new_ccr.hash()); + + assert_eq!(new_ccr.descriptor.version(), CandidateDescriptorVersion::V1); + assert_eq!(old_ccr.descriptor.collator, new_ccr.descriptor.collator().unwrap()); + assert_eq!(old_ccr.descriptor.signature, new_ccr.descriptor.signature().unwrap()); + } + #[test] fn invalid_version_descriptor() { let mut new_ccr = dummy_committed_candidate_receipt_v2(); diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index b0f78717dd97..b62c6cc6a903 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -44,7 +44,7 @@ pub fn dummy_candidate_receipt>(relay_parent: H) -> CandidateRece } /// Creates a v2 candidate receipt with filler data. -pub fn dummy_candidate_receipt_v2>(relay_parent: H) -> CandidateReceiptV2 { +pub fn dummy_candidate_receipt_v2 + Copy>(relay_parent: H) -> CandidateReceiptV2 { CandidateReceiptV2:: { commitments_hash: dummy_candidate_commitments(dummy_head_data()).hash(), descriptor: dummy_candidate_descriptor_v2(relay_parent), @@ -62,7 +62,7 @@ pub fn dummy_committed_candidate_receipt>( } /// Creates a v2 committed candidate receipt with filler data. -pub fn dummy_committed_candidate_receipt_v2>( +pub fn dummy_committed_candidate_receipt_v2 + Copy>( relay_parent: H, ) -> CommittedCandidateReceiptV2 { CommittedCandidateReceiptV2 { @@ -144,7 +144,9 @@ pub fn dummy_candidate_descriptor>(relay_parent: H) -> CandidateD } /// Create a v2 candidate descriptor with filler data. -pub fn dummy_candidate_descriptor_v2>(relay_parent: H) -> CandidateDescriptorV2 { +pub fn dummy_candidate_descriptor_v2 + Copy>( + relay_parent: H, +) -> CandidateDescriptorV2 { let invalid = Hash::zero(); let descriptor = make_valid_candidate_descriptor_v2( 1.into(), @@ -269,7 +271,7 @@ pub fn make_valid_candidate_descriptor>( } /// Create a v2 candidate descriptor. -pub fn make_valid_candidate_descriptor_v2>( +pub fn make_valid_candidate_descriptor_v2 + Copy>( para_id: ParaId, relay_parent: H, core_index: CoreIndex, diff --git a/polkadot/statement-table/src/lib.rs b/polkadot/statement-table/src/lib.rs index 469c877eafc9..68febf76feb3 100644 --- a/polkadot/statement-table/src/lib.rs +++ b/polkadot/statement-table/src/lib.rs @@ -35,8 +35,8 @@ pub use generic::{Config, Context, Table}; pub mod v2 { use crate::generic; use polkadot_primitives::{ - CandidateHash, CommittedCandidateReceipt, CompactStatement as PrimitiveStatement, - CoreIndex, ValidatorIndex, ValidatorSignature, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CandidateHash, + CompactStatement as PrimitiveStatement, CoreIndex, ValidatorIndex, ValidatorSignature, }; /// Statements about candidates on the network. From f9ddb152c72087849d9bd05c5f518869f0547991 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 11 Sep 2024 17:34:16 +0300 Subject: [PATCH 094/130] test fixes Signed-off-by: Andrei Sandu --- polkadot/node/collation-generation/src/lib.rs | 2 +- polkadot/node/core/backing/src/tests/mod.rs | 6 +++--- .../src/tests/prospective_parachains.rs | 2 +- polkadot/node/malus/src/variants/common.rs | 6 ++++-- .../src/variants/suggest_garbage_candidate.rs | 9 +++++---- .../node/overseer/examples/minimal-example.rs | 4 ++-- polkadot/node/overseer/src/tests.rs | 19 ++++++++++--------- .../node/service/src/parachains_db/upgrade.rs | 2 +- .../src/lib/approval/helpers.rs | 12 +++++++----- .../src/lib/approval/message_generator.rs | 4 ++-- .../subsystem-bench/src/lib/approval/mod.rs | 5 +++-- .../src/lib/availability/mod.rs | 2 +- .../src/lib/availability/test_state.rs | 10 +++++++--- .../src/lib/mock/runtime_api.rs | 7 ++++--- .../src/lib/statement/test_state.rs | 13 ++++++++----- .../test-parachains/adder/collator/src/lib.rs | 2 +- .../undying/collator/src/lib.rs | 2 +- polkadot/primitives/src/vstaging/mod.rs | 4 +--- polkadot/primitives/test-helpers/src/lib.rs | 18 ++++++++++++++++++ 19 files changed, 80 insertions(+), 49 deletions(-) diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs index a9b812f6673b..f04f69cbd380 100644 --- a/polkadot/node/collation-generation/src/lib.rs +++ b/polkadot/node/collation-generation/src/lib.rs @@ -49,7 +49,7 @@ use polkadot_node_subsystem_util::{ }; use polkadot_primitives::{ collator_signature_payload, - vstaging::{CandidateDescriptorV2, CandidateReceiptV2 as CandidateReceipt, CoreState}, + vstaging::{CandidateReceiptV2 as CandidateReceipt, CoreState}, CandidateCommitments, CandidateDescriptor, CollatorPair, CoreIndex, Hash, Id as ParaId, OccupiedCoreAssumption, PersistedValidationData, ScheduledCore, ValidationCodeHash, }; diff --git a/polkadot/node/core/backing/src/tests/mod.rs b/polkadot/node/core/backing/src/tests/mod.rs index 10eb45b82d12..417c13b51a4f 100644 --- a/polkadot/node/core/backing/src/tests/mod.rs +++ b/polkadot/node/core/backing/src/tests/mod.rs @@ -433,7 +433,7 @@ async fn assert_validate_from_exhaustive( }, ) if validation_data == *assert_pvd && validation_code == *assert_validation_code && - *pov == *assert_pov && &candidate_receipt.descriptor == assert_candidate.descriptor() && + *pov == *assert_pov && &candidate_receipt.descriptor == assert_candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate_receipt.commitments_hash == assert_candidate.commitments.hash() => { @@ -2210,7 +2210,7 @@ fn retry_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor() && + *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate.commitments.hash() == candidate_receipt.commitments_hash ); @@ -2752,7 +2752,7 @@ fn validator_ignores_statements_from_disabled_validators() { } ) if validation_data == pvd && validation_code == expected_validation_code && - *pov == expected_pov && &candidate_receipt.descriptor == candidate.descriptor() && + *pov == expected_pov && &candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate_commitments_hash == candidate_receipt.commitments_hash => { diff --git a/polkadot/node/core/backing/src/tests/prospective_parachains.rs b/polkadot/node/core/backing/src/tests/prospective_parachains.rs index 15bc0b4a1139..6a36375b6525 100644 --- a/polkadot/node/core/backing/src/tests/prospective_parachains.rs +++ b/polkadot/node/core/backing/src/tests/prospective_parachains.rs @@ -275,7 +275,7 @@ async fn assert_validate_seconded_candidate( }) if &validation_data == assert_pvd && &validation_code == assert_validation_code && &*pov == assert_pov && - &candidate_receipt.descriptor == candidate.descriptor() && + &candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate.commitments.hash() == candidate_receipt.commitments_hash => { diff --git a/polkadot/node/malus/src/variants/common.rs b/polkadot/node/malus/src/variants/common.rs index eb6988f81811..1b6ac9a2d186 100644 --- a/polkadot/node/malus/src/variants/common.rs +++ b/polkadot/node/malus/src/variants/common.rs @@ -25,8 +25,10 @@ use polkadot_node_core_candidate_validation::find_validation_data; use polkadot_node_primitives::{InvalidCandidate, ValidationResult}; use polkadot_primitives::{ - CandidateCommitments, CandidateDescriptor, CandidateReceipt, PersistedValidationData, - PvfExecKind, + vstaging::{ + CandidateDescriptorV2 as CandidateDescriptor, CandidateReceiptV2 as CandidateReceipt, + }, + CandidateCommitments, PersistedValidationData, PvfExecKind, }; use futures::channel::oneshot; diff --git a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs index 6921352cdfc2..f3900ee76a1a 100644 --- a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs +++ b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs @@ -32,7 +32,7 @@ use polkadot_cli::{ }; use polkadot_node_primitives::{AvailableData, BlockData, PoV}; use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; -use polkadot_primitives::{CandidateDescriptor, CandidateReceipt}; +use polkadot_primitives::{vstaging::CandidateReceiptV2, CandidateDescriptor, CandidateReceipt}; use polkadot_node_subsystem_util::request_validators; use sp_core::traits::SpawnNamed; @@ -227,9 +227,9 @@ where &malicious_available_data.validation_data, ); - let malicious_candidate = CandidateReceipt { + let malicious_candidate = CandidateReceiptV2 { descriptor: CandidateDescriptor { - para_id: candidate.descriptor().para_id, + para_id: candidate.descriptor.para_id(), relay_parent, collator: collator_id, persisted_validation_data_hash: validation_data_hash, @@ -238,7 +238,8 @@ where signature: collator_signature, para_head: malicious_commitments.head_data.hash(), validation_code_hash, - }, + } + .into(), commitments_hash: malicious_commitments.hash(), }; let malicious_candidate_hash = malicious_candidate.hash(); diff --git a/polkadot/node/overseer/examples/minimal-example.rs b/polkadot/node/overseer/examples/minimal-example.rs index 86a1801a5f2d..b00b98d8db68 100644 --- a/polkadot/node/overseer/examples/minimal-example.rs +++ b/polkadot/node/overseer/examples/minimal-example.rs @@ -31,7 +31,7 @@ use polkadot_overseer::{ gen::{FromOrchestra, SpawnedSubsystem}, HeadSupportsParachains, SubsystemError, }; -use polkadot_primitives::{CandidateReceipt, Hash, PvfExecKind}; +use polkadot_primitives::{vstaging::CandidateReceiptV2 as CandidateReceipt, Hash, PvfExecKind}; use polkadot_primitives_test_helpers::{dummy_candidate_descriptor, dummy_hash}; struct AlwaysSupportsParachains; @@ -69,7 +69,7 @@ impl Subsystem1 { let (tx, _) = oneshot::channel(); let candidate_receipt = CandidateReceipt { - descriptor: dummy_candidate_descriptor(dummy_hash()), + descriptor: dummy_candidate_descriptor(dummy_hash()).into(), commitments_hash: Hash::zero(), }; diff --git a/polkadot/node/overseer/src/tests.rs b/polkadot/node/overseer/src/tests.rs index 8e78d8fc8921..3792165c7658 100644 --- a/polkadot/node/overseer/src/tests.rs +++ b/polkadot/node/overseer/src/tests.rs @@ -28,11 +28,12 @@ use polkadot_node_subsystem_types::messages::{ NetworkBridgeEvent, ReportPeerMessage, RuntimeApiRequest, }; use polkadot_primitives::{ - CandidateHash, CandidateReceipt, CollatorPair, Id as ParaId, InvalidDisputeStatementKind, - PvfExecKind, SessionIndex, ValidDisputeStatementKind, ValidatorIndex, + vstaging::CandidateReceiptV2, CandidateHash, CandidateReceipt, CollatorPair, Id as ParaId, + InvalidDisputeStatementKind, PvfExecKind, SessionIndex, ValidDisputeStatementKind, + ValidatorIndex, }; use polkadot_primitives_test_helpers::{ - dummy_candidate_descriptor, dummy_candidate_receipt, dummy_hash, + dummy_candidate_descriptor, dummy_candidate_receipt, dummy_candidate_receipt_v2, dummy_hash, }; use crate::{ @@ -98,8 +99,8 @@ where let mut c: usize = 0; loop { if c < 10 { - let candidate_receipt = CandidateReceipt { - descriptor: dummy_candidate_descriptor(dummy_hash()), + let candidate_receipt = CandidateReceiptV2 { + descriptor: dummy_candidate_descriptor(dummy_hash()).into(), commitments_hash: dummy_hash(), }; @@ -797,8 +798,8 @@ where fn test_candidate_validation_msg() -> CandidateValidationMessage { let (response_sender, _) = oneshot::channel(); let pov = Arc::new(PoV { block_data: BlockData(Vec::new()) }); - let candidate_receipt = CandidateReceipt { - descriptor: dummy_candidate_descriptor(dummy_hash()), + let candidate_receipt = CandidateReceiptV2 { + descriptor: dummy_candidate_descriptor(dummy_hash()).into(), commitments_hash: Hash::zero(), }; @@ -855,7 +856,7 @@ fn test_statement_distribution_msg() -> StatementDistributionMessage { fn test_availability_recovery_msg() -> AvailabilityRecoveryMessage { let (sender, _) = oneshot::channel(); AvailabilityRecoveryMessage::RecoverAvailableData( - dummy_candidate_receipt(dummy_hash()), + dummy_candidate_receipt_v2(dummy_hash()), Default::default(), None, None, @@ -914,7 +915,7 @@ fn test_dispute_coordinator_msg() -> DisputeCoordinatorMessage { fn test_dispute_distribution_msg() -> DisputeDistributionMessage { let dummy_dispute_message = UncheckedDisputeMessage { - candidate_receipt: dummy_candidate_receipt(dummy_hash()), + candidate_receipt: dummy_candidate_receipt_v2(dummy_hash()), session_index: 0, invalid_vote: InvalidDisputeVote { validator_index: ValidatorIndex(0), diff --git a/polkadot/node/service/src/parachains_db/upgrade.rs b/polkadot/node/service/src/parachains_db/upgrade.rs index 808acf04b4e7..a82d751dff93 100644 --- a/polkadot/node/service/src/parachains_db/upgrade.rs +++ b/polkadot/node/service/src/parachains_db/upgrade.rs @@ -617,7 +617,7 @@ mod tests { assert_eq!(db.num_columns(), super::columns::v3::NUM_COLUMNS as u32); let db = DbAdapter::new(db, columns::v3::ORDERED_COL); // Fill the approval voting column with test data. - v1_fill_test_data(std::sync::Arc::new(db), approval_cfg, dummy_candidate_receipt) + v1_fill_test_data(std::sync::Arc::new(db), approval_cfg, dummy_candidate_receipt_v2) .unwrap() }; diff --git a/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs b/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs index 4b2b91696824..de811e510c23 100644 --- a/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs +++ b/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs @@ -26,10 +26,12 @@ use polkadot_node_subsystem_types::messages::{ }; use polkadot_overseer::AllMessages; use polkadot_primitives::{ - BlockNumber, CandidateEvent, CandidateReceipt, CoreIndex, GroupIndex, Hash, Header, - Id as ParaId, Slot, ValidatorIndex, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt}, + BlockNumber, CoreIndex, GroupIndex, Hash, Header, Id as ParaId, Slot, ValidatorIndex, +}; +use polkadot_primitives_test_helpers::{ + dummy_candidate_receipt_bad_sig, dummy_candidate_receipt_v2_bad_sig, }; -use polkadot_primitives_test_helpers::dummy_candidate_receipt_bad_sig; use rand::{seq::SliceRandom, SeedableRng}; use rand_chacha::ChaCha20Rng; use sc_network_types::PeerId; @@ -168,9 +170,9 @@ pub fn make_header(parent_hash: Hash, slot: Slot, number: u32) -> Header { /// Helper function to create a candidate receipt. fn make_candidate(para_id: ParaId, hash: &Hash) -> CandidateReceipt { - let mut r = dummy_candidate_receipt_bad_sig(*hash, Some(Default::default())); + let mut r = dummy_candidate_receipt_v2_bad_sig(*hash, Some(Default::default())); r.descriptor.para_id = para_id; - r + r.descriptor } /// Helper function to create a list of candidates that are included in the block diff --git a/polkadot/node/subsystem-bench/src/lib/approval/message_generator.rs b/polkadot/node/subsystem-bench/src/lib/approval/message_generator.rs index da25a3bf3b79..bc54fb430cb4 100644 --- a/polkadot/node/subsystem-bench/src/lib/approval/message_generator.rs +++ b/polkadot/node/subsystem-bench/src/lib/approval/message_generator.rs @@ -40,8 +40,8 @@ use polkadot_node_primitives::approval::{ v2::{CoreBitfield, IndirectAssignmentCertV2, IndirectSignedApprovalVoteV2}, }; use polkadot_primitives::{ - ApprovalVoteMultipleCandidates, CandidateEvent, CandidateHash, CandidateIndex, CoreIndex, Hash, - SessionInfo, Slot, ValidatorId, ValidatorIndex, ASSIGNMENT_KEY_TYPE_ID, + vstaging::CandidateEvent, ApprovalVoteMultipleCandidates, CandidateHash, CandidateIndex, + CoreIndex, Hash, SessionInfo, Slot, ValidatorId, ValidatorIndex, ASSIGNMENT_KEY_TYPE_ID, }; use rand::{seq::SliceRandom, RngCore, SeedableRng}; use rand_chacha::ChaCha20Rng; diff --git a/polkadot/node/subsystem-bench/src/lib/approval/mod.rs b/polkadot/node/subsystem-bench/src/lib/approval/mod.rs index f05d061f3fde..20931933f10b 100644 --- a/polkadot/node/subsystem-bench/src/lib/approval/mod.rs +++ b/polkadot/node/subsystem-bench/src/lib/approval/mod.rs @@ -65,8 +65,9 @@ use polkadot_node_subsystem_types::messages::{ApprovalDistributionMessage, Appro use polkadot_node_subsystem_util::metrics::Metrics; use polkadot_overseer::Handle as OverseerHandleReal; use polkadot_primitives::{ - BlockNumber, CandidateEvent, CandidateIndex, CandidateReceipt, Hash, Header, Slot, ValidatorId, - ValidatorIndex, ASSIGNMENT_KEY_TYPE_ID, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt}, + BlockNumber, CandidateIndex, Hash, Header, Slot, ValidatorId, ValidatorIndex, + ASSIGNMENT_KEY_TYPE_ID, }; use prometheus::Registry; use sc_keystore::LocalKeystore; diff --git a/polkadot/node/subsystem-bench/src/lib/availability/mod.rs b/polkadot/node/subsystem-bench/src/lib/availability/mod.rs index 32dc8ae2c8dc..a975ccbab36c 100644 --- a/polkadot/node/subsystem-bench/src/lib/availability/mod.rs +++ b/polkadot/node/subsystem-bench/src/lib/availability/mod.rs @@ -394,7 +394,7 @@ pub async fn benchmark_availability_write( candidate_hash: backed_candidate.hash(), n_validators: config.n_validators as u32, available_data, - expected_erasure_root: backed_candidate.descriptor().erasure_root, + expected_erasure_root: backed_candidate.descriptor().erasure_root(), tx, core_index: CoreIndex(core_index as u32), node_features: node_features_with_chunk_mapping_enabled(), diff --git a/polkadot/node/subsystem-bench/src/lib/availability/test_state.rs b/polkadot/node/subsystem-bench/src/lib/availability/test_state.rs index 173b23f6b76e..d42f8fd80a9c 100644 --- a/polkadot/node/subsystem-bench/src/lib/availability/test_state.rs +++ b/polkadot/node/subsystem-bench/src/lib/availability/test_state.rs @@ -34,8 +34,9 @@ use polkadot_node_subsystem_test_helpers::{ use polkadot_node_subsystem_util::availability_chunks::availability_chunk_indices; use polkadot_overseer::BlockInfo; use polkadot_primitives::{ - AvailabilityBitfield, BlockNumber, CandidateHash, CandidateReceipt, ChunkIndex, CoreIndex, - Hash, HeadData, Header, PersistedValidationData, Signed, SigningContext, ValidatorIndex, + vstaging::CandidateReceiptV2 as CandidateReceipt, AvailabilityBitfield, BlockNumber, + CandidateHash, ChunkIndex, CoreIndex, Hash, HeadData, Header, PersistedValidationData, Signed, + SigningContext, ValidatorIndex, }; use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; use sp_core::H256; @@ -148,7 +149,10 @@ impl TestState { test_state.chunks.push(new_chunks); test_state.available_data.push(new_available_data); test_state.pov_size_to_candidate.insert(pov_size, index); - test_state.candidate_receipt_templates.push(candidate_receipt); + test_state.candidate_receipt_templates.push(CandidateReceipt { + descriptor: candidate_receipt.descriptor.into(), + commitments_hash: candidate_receipt.commitments_hash, + }); } test_state.block_infos = (1..=config.num_blocks) diff --git a/polkadot/node/subsystem-bench/src/lib/mock/runtime_api.rs b/polkadot/node/subsystem-bench/src/lib/mock/runtime_api.rs index 61523de1f1b5..6c54d14448a1 100644 --- a/polkadot/node/subsystem-bench/src/lib/mock/runtime_api.rs +++ b/polkadot/node/subsystem-bench/src/lib/mock/runtime_api.rs @@ -26,9 +26,10 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_types::OverseerSignal; use polkadot_primitives::{ - node_features, ApprovalVotingParams, AsyncBackingParams, CandidateEvent, CandidateReceipt, - CoreState, GroupIndex, GroupRotationInfo, IndexedVec, NodeFeatures, OccupiedCore, - ScheduledCore, SessionIndex, SessionInfo, ValidationCode, ValidatorIndex, + node_features, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt, CoreState, OccupiedCore}, + ApprovalVotingParams, AsyncBackingParams, GroupIndex, GroupRotationInfo, IndexedVec, + NodeFeatures, ScheduledCore, SessionIndex, SessionInfo, ValidationCode, ValidatorIndex, }; use sp_consensus_babe::Epoch as BabeEpoch; use sp_core::H256; diff --git a/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs b/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs index 88b5e8b76b62..0d4037151488 100644 --- a/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs +++ b/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs @@ -41,9 +41,12 @@ use polkadot_node_subsystem_test_helpers::{ }; use polkadot_overseer::BlockInfo; use polkadot_primitives::{ - BlockNumber, CandidateHash, CandidateReceipt, CommittedCandidateReceipt, CompactStatement, - Hash, Header, Id, PersistedValidationData, SessionInfo, SignedStatement, SigningContext, - UncheckedSigned, ValidatorIndex, ValidatorPair, + vstaging::{ + CandidateReceiptV2 as CandidateReceipt, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, + }, + BlockNumber, CandidateHash, CompactStatement, Hash, Header, Id, PersistedValidationData, + SessionInfo, SignedStatement, SigningContext, UncheckedSigned, ValidatorIndex, ValidatorPair, }; use polkadot_primitives_test_helpers::{ dummy_committed_candidate_receipt, dummy_hash, dummy_head_data, dummy_pvd, @@ -125,8 +128,8 @@ impl TestState { let candidate_index = *pov_size_to_candidate.get(pov_size).expect("pov_size always exists; qed"); let mut receipt = receipt_templates[candidate_index].clone(); - receipt.descriptor.para_id = Id::new(core_idx as u32 + 1); - receipt.descriptor.relay_parent = block_info.hash; + receipt.descriptor.para_id() = Id::new(core_idx as u32 + 1); + receipt.descriptor.relay_parent() = block_info.hash; state.candidate_receipts.entry(block_info.hash).or_default().push( CandidateReceipt { diff --git a/polkadot/parachain/test-parachains/adder/collator/src/lib.rs b/polkadot/parachain/test-parachains/adder/collator/src/lib.rs index daeb8bc915dd..a2fb623331a0 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/lib.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/lib.rs @@ -236,7 +236,7 @@ impl Collator { if let Ok(res) = recv.await { if !matches!( res.statement.payload(), - Statement::Seconded(s) if s.descriptor.pov_hash == compressed_pov.hash(), + Statement::Seconded(s) if s.descriptor.pov_hash() == compressed_pov.hash(), ) { log::error!( "Seconded statement should match our collation: {:?}", diff --git a/polkadot/parachain/test-parachains/undying/collator/src/lib.rs b/polkadot/parachain/test-parachains/undying/collator/src/lib.rs index 920099f4499d..448c181ae062 100644 --- a/polkadot/parachain/test-parachains/undying/collator/src/lib.rs +++ b/polkadot/parachain/test-parachains/undying/collator/src/lib.rs @@ -282,7 +282,7 @@ impl Collator { if let Ok(res) = recv.await { if !matches!( res.statement.payload(), - Statement::Seconded(s) if s.descriptor.pov_hash == compressed_pov.hash(), + Statement::Seconded(s) if s.descriptor.pov_hash() == compressed_pov.hash(), ) { log::error!( "Seconded statement should match our collation: {:?}", diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index adde11486b4f..73c2e14a9fa5 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -142,7 +142,7 @@ impl From> for CandidateDescriptorV2 { } } -impl> CandidateDescriptorV2 { +impl> CandidateDescriptorV2 { /// Constructor pub fn new( para_id: Id, @@ -849,8 +849,6 @@ pub fn remap_claim_queue( #[cfg(test)] mod tests { - use std::hash::DefaultHasher; - use super::*; use crate::{ v8::{ diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index b62c6cc6a903..3c0747fbce20 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -88,6 +88,24 @@ pub fn dummy_candidate_receipt_bad_sig( } } + +/// Create a candidate receipt with a bogus signature and filler data. Optionally set the commitment +/// hash with the `commitments` arg. +pub fn dummy_candidate_receipt_v2_bad_sig( + relay_parent: Hash, + commitments: impl Into>, +) -> CandidateReceiptV2 { + let commitments_hash = if let Some(commitments) = commitments.into() { + commitments + } else { + dummy_candidate_commitments(dummy_head_data()).hash() + }; + CandidateReceiptV2:: { + commitments_hash, + descriptor: dummy_candidate_descriptor_bad_sig(relay_parent).into(), + } +} + /// Create candidate commitments with filler data. pub fn dummy_candidate_commitments(head_data: impl Into>) -> CandidateCommitments { CandidateCommitments { From add45925318aa54fc2d4844fb9dbc19c7fb9c091 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 11 Sep 2024 17:34:36 +0300 Subject: [PATCH 095/130] fmt Signed-off-by: Andrei Sandu --- cumulus/client/relay-chain-inprocess-interface/src/lib.rs | 7 ++++--- polkadot/primitives/test-helpers/src/lib.rs | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs index c7bba6884421..a005a638a525 100644 --- a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs +++ b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs @@ -19,9 +19,10 @@ use std::{collections::btree_map::BTreeMap, pin::Pin, sync::Arc, time::Duration} use async_trait::async_trait; use cumulus_primitives_core::{ relay_chain::{ - runtime_api::ParachainHost, Block as PBlock, BlockId, BlockNumber, - vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, vstaging::CoreState, Hash as PHash, Header as PHeader, InboundHrmpMessage, - OccupiedCoreAssumption, SessionIndex, ValidationCodeHash, ValidatorId, + runtime_api::ParachainHost, + vstaging::{CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState}, + Block as PBlock, BlockId, BlockNumber, Hash as PHash, Header as PHeader, + InboundHrmpMessage, OccupiedCoreAssumption, SessionIndex, ValidationCodeHash, ValidatorId, }, InboundDownwardMessage, ParaId, PersistedValidationData, }; diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index 3c0747fbce20..1c4f3c5a1420 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -88,7 +88,6 @@ pub fn dummy_candidate_receipt_bad_sig( } } - /// Create a candidate receipt with a bogus signature and filler data. Optionally set the commitment /// hash with the `commitments` arg. pub fn dummy_candidate_receipt_v2_bad_sig( From ef51144deb4a850fb3acd526d2952c81aea5796d Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 12 Sep 2024 15:10:57 +0300 Subject: [PATCH 096/130] extract test helpers in MutateDescriptorV2 Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 68 ++++++++++++++++++++----- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 73c2e14a9fa5..9029b47b8f34 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -171,18 +171,6 @@ impl> CandidateDescriptorV2 { } } - /// Set the PoV size in the descriptor. Only for tests. - #[cfg(feature = "test")] - pub fn set_pov_hash(&mut self, pov_hash: Hash) { - self.pov_hash = pov_hash; - } - - /// Set the version in the descriptor. Only for tests. - #[cfg(feature = "test")] - pub fn set_version(&mut self, version: InternalVersion) { - self.version = version; - } - /// Check the signature of the collator within this descriptor. pub fn check_collator_signature(&self) -> Result<(), ()> { // Return `Ok` if collator signature is not included (v2+ descriptor). @@ -202,6 +190,51 @@ impl> CandidateDescriptorV2 { } } +/// A trait to allow changing the descriptor field values in tests. +#[cfg(feature = "test")] + +pub trait MutateDescriptorV2 { + /// Set the relay parent of the descriptor. + fn set_relay_parent(&mut self, relay_parent: H); + /// Set the `ParaId` of the descriptor. + fn set_para_id(&mut self, para_id: Id); + /// Set the PoV hash of the descriptor. + fn set_pov_hash(&mut self, pov_hash: Hash); + /// Set the version field of the descriptor. + fn set_version(&mut self, version: InternalVersion); + /// Set the PVD of the descriptor. + fn set_persisted_validation_data_hash(&mut self, persisted_validation_data_hash: Hash); + /// Set the erasure root of the descriptor. + fn set_erasure_root(&mut self, erasure_root: Hash); +} + +#[cfg(feature = "test")] +impl MutateDescriptorV2 for CandidateDescriptorV2 { + fn set_para_id(&mut self, para_id: Id) { + self.para_id = para_id; + } + + fn set_relay_parent(&mut self, relay_parent: H) { + self.relay_parent = relay_parent; + } + + fn set_pov_hash(&mut self, pov_hash: Hash) { + self.pov_hash = pov_hash; + } + + fn set_version(&mut self, version: InternalVersion) { + self.version = version; + } + + fn set_persisted_validation_data_hash(&mut self, persisted_validation_data_hash: Hash) { + self.persisted_validation_data_hash = persisted_validation_data_hash; + } + + fn set_erasure_root(&mut self, erasure_root: Hash) { + self.erasure_root = erasure_root; + } +} + /// A candidate-receipt at version 2. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Hash))] @@ -279,6 +312,15 @@ impl CandidateReceiptV2 { } } +impl From> for CandidateReceiptV2 { + fn from(value: super::v8::CandidateReceipt) -> Self { + CandidateReceiptV2 { + descriptor: value.descriptor.into(), + commitments_hash: value.commitments_hash, + } + } +} + impl CommittedCandidateReceiptV2 { /// Transforms this into a plain `CandidateReceipt`. pub fn to_plain(&self) -> CandidateReceiptV2 { @@ -414,7 +456,7 @@ pub enum CandidateReceiptError { macro_rules! impl_getter { ($field:ident, $type:ident) => { - /// Returns the value of $field field. + /// Returns the value of `$field`` field. pub fn $field(&self) -> $type { self.$field } From 39814250a0674d0bed3e18ce59edfc4cd02ddfae Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 12 Sep 2024 15:11:14 +0300 Subject: [PATCH 097/130] fix tests Signed-off-by: Andrei Sandu --- polkadot/node/subsystem-bench/Cargo.toml | 2 +- .../subsystem-bench/src/lib/approval/helpers.rs | 8 +++----- .../src/lib/availability/test_state.rs | 10 ++++++---- .../src/lib/statement/test_state.rs | 17 +++++++++-------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index ae798cf2640a..a564160bc0c6 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -28,7 +28,7 @@ polkadot-node-subsystem = { workspace = true, default-features = true } polkadot-node-subsystem-util = { workspace = true, default-features = true } polkadot-node-subsystem-types = { workspace = true, default-features = true } polkadot-node-primitives = { workspace = true, default-features = true } -polkadot-primitives = { workspace = true, default-features = true } +polkadot-primitives = { workspace = true, features = ["test"] } polkadot-node-network-protocol = { workspace = true, default-features = true } polkadot-availability-recovery = { features = ["subsystem-benchmarks"], workspace = true, default-features = true } polkadot-availability-distribution = { workspace = true, default-features = true } diff --git a/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs b/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs index de811e510c23..bfd0feb6d1ce 100644 --- a/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs +++ b/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs @@ -29,9 +29,7 @@ use polkadot_primitives::{ vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt}, BlockNumber, CoreIndex, GroupIndex, Hash, Header, Id as ParaId, Slot, ValidatorIndex, }; -use polkadot_primitives_test_helpers::{ - dummy_candidate_receipt_bad_sig, dummy_candidate_receipt_v2_bad_sig, -}; +use polkadot_primitives_test_helpers::dummy_candidate_receipt_bad_sig; use rand::{seq::SliceRandom, SeedableRng}; use rand_chacha::ChaCha20Rng; use sc_network_types::PeerId; @@ -170,9 +168,9 @@ pub fn make_header(parent_hash: Hash, slot: Slot, number: u32) -> Header { /// Helper function to create a candidate receipt. fn make_candidate(para_id: ParaId, hash: &Hash) -> CandidateReceipt { - let mut r = dummy_candidate_receipt_v2_bad_sig(*hash, Some(Default::default())); + let mut r = dummy_candidate_receipt_bad_sig(*hash, Some(Default::default())); r.descriptor.para_id = para_id; - r.descriptor + r.into() } /// Helper function to create a list of candidates that are included in the block diff --git a/polkadot/node/subsystem-bench/src/lib/availability/test_state.rs b/polkadot/node/subsystem-bench/src/lib/availability/test_state.rs index d42f8fd80a9c..511795970e6c 100644 --- a/polkadot/node/subsystem-bench/src/lib/availability/test_state.rs +++ b/polkadot/node/subsystem-bench/src/lib/availability/test_state.rs @@ -34,9 +34,9 @@ use polkadot_node_subsystem_test_helpers::{ use polkadot_node_subsystem_util::availability_chunks::availability_chunk_indices; use polkadot_overseer::BlockInfo; use polkadot_primitives::{ - vstaging::CandidateReceiptV2 as CandidateReceipt, AvailabilityBitfield, BlockNumber, - CandidateHash, ChunkIndex, CoreIndex, Hash, HeadData, Header, PersistedValidationData, Signed, - SigningContext, ValidatorIndex, + vstaging::{CandidateReceiptV2 as CandidateReceipt, MutateDescriptorV2}, + AvailabilityBitfield, BlockNumber, CandidateHash, ChunkIndex, CoreIndex, Hash, HeadData, + Header, PersistedValidationData, Signed, SigningContext, ValidatorIndex, }; use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; use sp_core::H256; @@ -193,7 +193,9 @@ impl TestState { test_state.candidate_receipt_templates[candidate_index].clone(); // Make it unique. - candidate_receipt.descriptor.relay_parent = Hash::from_low_u64_be(index as u64); + candidate_receipt + .descriptor + .set_relay_parent(Hash::from_low_u64_be(index as u64)); // Store the new candidate in the state test_state.candidate_hashes.insert(candidate_receipt.hash(), candidate_index); diff --git a/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs b/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs index 0d4037151488..93adeeb53972 100644 --- a/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs +++ b/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs @@ -42,14 +42,15 @@ use polkadot_node_subsystem_test_helpers::{ use polkadot_overseer::BlockInfo; use polkadot_primitives::{ vstaging::{ - CandidateReceiptV2 as CandidateReceipt, - CommittedCandidateReceiptV2 as CommittedCandidateReceipt, + CandidateDescriptorV2, CandidateReceiptV2 as CandidateReceipt, + CommittedCandidateReceiptV2 as CommittedCandidateReceipt, MutateDescriptorV2, }, BlockNumber, CandidateHash, CompactStatement, Hash, Header, Id, PersistedValidationData, SessionInfo, SignedStatement, SigningContext, UncheckedSigned, ValidatorIndex, ValidatorPair, }; use polkadot_primitives_test_helpers::{ - dummy_committed_candidate_receipt, dummy_hash, dummy_head_data, dummy_pvd, + dummy_committed_candidate_receipt, dummy_committed_candidate_receipt_v2, dummy_hash, + dummy_head_data, dummy_pvd, }; use sc_network::{config::IncomingRequest, ProtocolName}; use sp_core::{Pair, H256}; @@ -128,8 +129,8 @@ impl TestState { let candidate_index = *pov_size_to_candidate.get(pov_size).expect("pov_size always exists; qed"); let mut receipt = receipt_templates[candidate_index].clone(); - receipt.descriptor.para_id() = Id::new(core_idx as u32 + 1); - receipt.descriptor.relay_parent() = block_info.hash; + receipt.descriptor.set_para_id(Id::new(core_idx as u32 + 1)); + receipt.descriptor.set_relay_parent(block_info.hash); state.candidate_receipts.entry(block_info.hash).or_default().push( CandidateReceipt { @@ -243,7 +244,7 @@ fn generate_receipt_templates( pov_size_to_candidate .iter() .map(|(&pov_size, &index)| { - let mut receipt = dummy_committed_candidate_receipt(dummy_hash()); + let mut receipt = dummy_committed_candidate_receipt_v2(dummy_hash()); let (_, erasure_root) = derive_erasure_chunks_with_proofs_and_root( n_validators, &AvailableData { @@ -252,8 +253,8 @@ fn generate_receipt_templates( }, |_, _| {}, ); - receipt.descriptor.persisted_validation_data_hash = pvd.hash(); - receipt.descriptor.erasure_root = erasure_root; + receipt.descriptor.set_persisted_validation_data_hash(pvd.hash()); + receipt.descriptor.set_erasure_root(erasure_root); receipt }) .collect() From 32af174797ed2add27d8fcb45b6d552004ef42e5 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 12 Sep 2024 18:50:01 +0300 Subject: [PATCH 098/130] more fixes Signed-off-by: Andrei Sandu --- cumulus/client/pov-recovery/src/tests.rs | 6 +- .../node/collation-generation/src/tests.rs | 3 +- polkadot/node/core/approval-voting/Cargo.toml | 1 + .../src/approval_db/v3/tests.rs | 5 +- .../node/core/approval-voting/src/import.rs | 32 +++++----- .../node/core/approval-voting/src/tests.rs | 62 ++++++++++--------- polkadot/node/core/backing/src/tests/mod.rs | 2 +- .../src/tests/prospective_parachains.rs | 8 +-- .../node/core/bitfield-signing/src/tests.rs | 2 +- .../core/candidate-validation/src/tests.rs | 39 ++++++++---- .../core/dispute-coordinator/src/db/v1.rs | 20 +++--- .../src/participation/queues/tests.rs | 4 +- .../src/participation/tests.rs | 3 +- .../dispute-coordinator/src/scraping/tests.rs | 7 ++- .../core/prospective-parachains/Cargo.toml | 1 + .../src/fragment_chain/tests.rs | 17 ++--- .../core/prospective-parachains/src/tests.rs | 19 +++--- polkadot/node/core/provisioner/Cargo.toml | 2 + .../disputes/prioritized_selection/tests.rs | 21 ++++--- polkadot/node/core/provisioner/src/tests.rs | 37 ++++++----- polkadot/node/malus/src/variants/common.rs | 6 +- .../variants/dispute_finalized_candidates.rs | 2 +- .../src/variants/suggest_garbage_candidate.rs | 6 +- .../src/tests/mod.rs | 2 +- .../src/tests/state.rs | 2 +- .../src/validator_side/tests/mod.rs | 5 +- .../tests/prospective_parachains.rs | 12 ++-- .../src/legacy_v1/tests.rs | 23 ++++--- .../src/v2/tests/mod.rs | 6 +- polkadot/node/overseer/src/tests.rs | 4 +- .../node/service/src/parachains_db/upgrade.rs | 4 +- .../src/lib/statement/test_state.rs | 5 +- polkadot/primitives/src/vstaging/mod.rs | 6 ++ polkadot/primitives/test-helpers/src/lib.rs | 9 +-- 34 files changed, 221 insertions(+), 162 deletions(-) diff --git a/cumulus/client/pov-recovery/src/tests.rs b/cumulus/client/pov-recovery/src/tests.rs index 6f274ed18b6b..3b7abab48d38 100644 --- a/cumulus/client/pov-recovery/src/tests.rs +++ b/cumulus/client/pov-recovery/src/tests.rs @@ -18,7 +18,8 @@ use super::*; use assert_matches::assert_matches; use codec::{Decode, Encode}; use cumulus_primitives_core::relay_chain::{ - BlockId, CandidateCommitments, CandidateDescriptor, CoreState, + vstaging::{CandidateDescriptorV2, CoreState}, + BlockId, CandidateCommitments, CandidateDescriptor, }; use cumulus_relay_chain_interface::{ InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption, PHash, PHeader, @@ -516,7 +517,8 @@ fn make_candidate_chain(candidate_number_range: Range) -> Vec CandidateReceipt { c.descriptor.para_id = para_id; c.descriptor.relay_parent = relay_parent; - c + c.into() } #[test] diff --git a/polkadot/node/core/approval-voting/src/import.rs b/polkadot/node/core/approval-voting/src/import.rs index e1ff46168e73..dd653d4d4d26 100644 --- a/polkadot/node/core/approval-voting/src/import.rs +++ b/polkadot/node/core/approval-voting/src/import.rs @@ -628,7 +628,7 @@ pub(crate) mod tests { node_features::FeatureIndex, ExecutorParams, Id as ParaId, IndexedVec, NodeFeatures, SessionInfo, ValidatorId, ValidatorIndex, }; - use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; + use polkadot_primitives_test_helpers::{dummy_candidate_receipt_v2, dummy_hash}; use schnellru::{ByLength, LruMap}; pub(crate) use sp_consensus_babe::{ digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest}, @@ -772,9 +772,9 @@ pub(crate) mod tests { let hash = header.hash(); let make_candidate = |para_id| { - let mut r = dummy_candidate_receipt(dummy_hash()); - r.descriptor.para_id = para_id; - r.descriptor.relay_parent = hash; + let mut r = dummy_candidate_receipt_v2(dummy_hash()); + r.descriptor.set_para_id(para_id); + r.descriptor.set_relay_parent(hash); r }; let candidates = vec![ @@ -924,9 +924,9 @@ pub(crate) mod tests { let hash = header.hash(); let make_candidate = |para_id| { - let mut r = dummy_candidate_receipt(dummy_hash()); - r.descriptor.para_id = para_id; - r.descriptor.relay_parent = hash; + let mut r = dummy_candidate_receipt_v2(dummy_hash()); + r.descriptor.set_para_id(para_id); + r.descriptor.set_relay_parent(hash); r }; let candidates = vec![ @@ -1063,9 +1063,9 @@ pub(crate) mod tests { let hash = header.hash(); let make_candidate = |para_id| { - let mut r = dummy_candidate_receipt(dummy_hash()); - r.descriptor.para_id = para_id; - r.descriptor.relay_parent = hash; + let mut r = dummy_candidate_receipt_v2(dummy_hash()); + r.descriptor.set_para_id(para_id); + r.descriptor.set_relay_parent(hash); r }; let candidates = vec![ @@ -1156,9 +1156,9 @@ pub(crate) mod tests { let hash = header.hash(); let make_candidate = |para_id| { - let mut r = dummy_candidate_receipt(dummy_hash()); - r.descriptor.para_id = para_id; - r.descriptor.relay_parent = hash; + let mut r = dummy_candidate_receipt_v2(dummy_hash()); + r.descriptor.set_para_id(para_id); + r.descriptor.set_relay_parent(hash); r }; let candidates = vec![ @@ -1346,9 +1346,9 @@ pub(crate) mod tests { let hash = header.hash(); let make_candidate = |para_id| { - let mut r = dummy_candidate_receipt(dummy_hash()); - r.descriptor.para_id = para_id; - r.descriptor.relay_parent = hash; + let mut r = dummy_candidate_receipt_v2(dummy_hash()); + r.descriptor.set_para_id(para_id); + r.descriptor.set_relay_parent(hash); r }; let candidates = vec![ diff --git a/polkadot/node/core/approval-voting/src/tests.rs b/polkadot/node/core/approval-voting/src/tests.rs index 7126f209a94f..666bd521f24c 100644 --- a/polkadot/node/core/approval-voting/src/tests.rs +++ b/polkadot/node/core/approval-voting/src/tests.rs @@ -69,7 +69,9 @@ use super::{ }, }; -use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_candidate_receipt_bad_sig}; +use polkadot_primitives_test_helpers::{ + dummy_candidate_receipt_v2, dummy_candidate_receipt_v2_bad_sig, +}; const SLOT_DURATION_MILLIS: u64 = 5000; @@ -643,8 +645,8 @@ where } fn make_candidate(para_id: ParaId, hash: &Hash) -> CandidateReceipt { - let mut r = dummy_candidate_receipt_bad_sig(*hash, Some(Default::default())); - r.descriptor.para_id = para_id; + let mut r = dummy_candidate_receipt_v2_bad_sig(*hash, Some(Default::default())); + r.descriptor.set_para_id(para_id); r } @@ -1287,7 +1289,7 @@ fn subsystem_rejects_approval_if_no_block_entry() { let block_hash = Hash::repeat_byte(0x01); let candidate_index = 0; let validator = ValidatorIndex(0); - let candidate_hash = dummy_candidate_receipt(block_hash).hash(); + let candidate_hash = dummy_candidate_receipt_v2(block_hash).hash(); let session_index = 1; let rx = import_approval( @@ -1329,7 +1331,7 @@ fn subsystem_rejects_approval_before_assignment() { let candidate_hash = { let mut candidate_receipt = - dummy_candidate_receipt_bad_sig(block_hash, Some(Default::default())); + dummy_candidate_receipt_v2_bad_sig(block_hash, Some(Default::default())); candidate_receipt.descriptor.para_id = ParaId::from(0_u32); candidate_receipt.descriptor.relay_parent = block_hash; candidate_receipt.hash() @@ -1395,15 +1397,17 @@ fn subsystem_accepts_duplicate_assignment() { let block_hash = Hash::repeat_byte(0x01); let candidate_receipt1 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(1_u32); receipt - }; + } + .into(); let candidate_receipt2 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(2_u32); receipt - }; + } + .into(); let candidate_index1 = 0; let candidate_index2 = 1; @@ -1577,7 +1581,7 @@ fn subsystem_accepts_and_imports_approval_after_assignment() { let candidate_hash = { let mut candidate_receipt = - dummy_candidate_receipt_bad_sig(block_hash, Some(Default::default())); + dummy_candidate_receipt_v2_bad_sig(block_hash, Some(Default::default())); candidate_receipt.descriptor.para_id = ParaId::from(0_u32); candidate_receipt.descriptor.relay_parent = block_hash; candidate_receipt.hash() @@ -1648,7 +1652,7 @@ fn subsystem_second_approval_import_only_schedules_wakeups() { let candidate_hash = { let mut candidate_receipt = - dummy_candidate_receipt_bad_sig(block_hash, Some(Default::default())); + dummy_candidate_receipt_v2_bad_sig(block_hash, Some(Default::default())); candidate_receipt.descriptor.para_id = ParaId::from(0_u32); candidate_receipt.descriptor.relay_parent = block_hash; candidate_receipt.hash() @@ -2407,12 +2411,12 @@ fn subsystem_import_checked_approval_sets_one_block_bit_at_a_time() { let block_hash = Hash::repeat_byte(0x01); let candidate_receipt1 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(1_u32); receipt }; let candidate_receipt2 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(2_u32); receipt }; @@ -2571,17 +2575,17 @@ fn inclusion_events_can_be_unordered_by_core_index() { let block_hash = Hash::repeat_byte(0x01); let candidate_receipt0 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(0_u32); receipt }; let candidate_receipt1 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(1_u32); receipt }; let candidate_receipt2 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(2_u32); receipt }; @@ -2715,7 +2719,7 @@ fn approved_ancestor_test( .iter() .enumerate() .map(|(i, hash)| { - let mut candidate_receipt = dummy_candidate_receipt(*hash); + let mut candidate_receipt = dummy_candidate_receipt_v2(*hash); candidate_receipt.descriptor.para_id = i.into(); candidate_receipt }) @@ -2887,7 +2891,7 @@ fn subsystem_validate_approvals_cache() { let block_hash = Hash::repeat_byte(0x01); let fork_block_hash = Hash::repeat_byte(0x02); let candidate_commitments = CandidateCommitments::default(); - let mut candidate_receipt = dummy_candidate_receipt(block_hash); + let mut candidate_receipt = dummy_candidate_receipt_v2(block_hash); candidate_receipt.commitments_hash = candidate_commitments.hash(); let candidate_hash = candidate_receipt.hash(); let slot = Slot::from(1); @@ -3017,12 +3021,12 @@ fn subsystem_doesnt_distribute_duplicate_compact_assignments() { let block_hash = Hash::repeat_byte(0x01); let candidate_receipt1 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(1_u32); receipt }; let candidate_receipt2 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(2_u32); receipt }; @@ -3268,7 +3272,7 @@ where ); let block_hash = Hash::repeat_byte(0x01); - let candidate_receipt = dummy_candidate_receipt(block_hash); + let candidate_receipt = dummy_candidate_receipt_v2(block_hash); let candidate_hash = candidate_receipt.hash(); let slot = Slot::from(1); let candidate_index = 0; @@ -3970,7 +3974,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_count() { let candidate_commitments = CandidateCommitments::default(); let candidate_receipt1 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(1_u32); receipt.commitments_hash = candidate_commitments.hash(); receipt @@ -3979,7 +3983,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_count() { let candidate_hash1 = candidate_receipt1.hash(); let candidate_receipt2 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(2_u32); receipt.commitments_hash = candidate_commitments.hash(); receipt @@ -4271,7 +4275,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { let candidate_commitments = CandidateCommitments::default(); let candidate_receipt1 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(1_u32); receipt.commitments_hash = candidate_commitments.hash(); receipt @@ -4280,7 +4284,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { let candidate_hash1 = candidate_receipt1.hash(); let candidate_receipt2 = { - let mut receipt = dummy_candidate_receipt(block_hash); + let mut receipt = dummy_candidate_receipt_v2(block_hash); receipt.descriptor.para_id = ParaId::from(2_u32); receipt.commitments_hash = candidate_commitments.hash(); receipt @@ -4425,7 +4429,7 @@ async fn setup_overseer_with_two_blocks_each_with_one_assignment_triggered( let block_hash = Hash::repeat_byte(0x01); let fork_block_hash = Hash::repeat_byte(0x02); let candidate_commitments = CandidateCommitments::default(); - let mut candidate_receipt = dummy_candidate_receipt(block_hash); + let mut candidate_receipt = dummy_candidate_receipt_v2(block_hash); candidate_receipt.commitments_hash = candidate_commitments.hash(); let candidate_hash = candidate_receipt.hash(); let slot = Slot::from(1); @@ -4554,7 +4558,7 @@ fn subsystem_relaunches_approval_work_on_restart() { let block_hash = Hash::repeat_byte(0x01); let fork_block_hash = Hash::repeat_byte(0x02); let candidate_commitments = CandidateCommitments::default(); - let mut candidate_receipt = dummy_candidate_receipt(block_hash); + let mut candidate_receipt = dummy_candidate_receipt_v2(block_hash); candidate_receipt.commitments_hash = candidate_commitments.hash(); let slot = Slot::from(1); clock.inner.lock().set_tick(slot_to_tick(slot + 2)); @@ -4810,7 +4814,7 @@ fn subsystem_sends_pending_approvals_on_approval_restart() { let block_hash = Hash::repeat_byte(0x01); let fork_block_hash = Hash::repeat_byte(0x02); let candidate_commitments = CandidateCommitments::default(); - let mut candidate_receipt = dummy_candidate_receipt(block_hash); + let mut candidate_receipt = dummy_candidate_receipt_v2(block_hash); candidate_receipt.commitments_hash = candidate_commitments.hash(); let slot = Slot::from(1); @@ -4820,7 +4824,7 @@ fn subsystem_sends_pending_approvals_on_approval_restart() { fork_block_hash, slot, sync_oracle_handle, - candidate_receipt, + candidate_receipt.into(), ) .await; chain_builder.build(&mut virtual_overseer).await; diff --git a/polkadot/node/core/backing/src/tests/mod.rs b/polkadot/node/core/backing/src/tests/mod.rs index 417c13b51a4f..78f9859ea1ca 100644 --- a/polkadot/node/core/backing/src/tests/mod.rs +++ b/polkadot/node/core/backing/src/tests/mod.rs @@ -433,7 +433,7 @@ async fn assert_validate_from_exhaustive( }, ) if validation_data == *assert_pvd && validation_code == *assert_validation_code && - *pov == *assert_pov && &candidate_receipt.descriptor == assert_candidate.descriptor && + *pov == *assert_pov && candidate_receipt.descriptor == assert_candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate_receipt.commitments_hash == assert_candidate.commitments.hash() => { diff --git a/polkadot/node/core/backing/src/tests/prospective_parachains.rs b/polkadot/node/core/backing/src/tests/prospective_parachains.rs index 6a36375b6525..55a96fee6e4d 100644 --- a/polkadot/node/core/backing/src/tests/prospective_parachains.rs +++ b/polkadot/node/core/backing/src/tests/prospective_parachains.rs @@ -275,7 +275,7 @@ async fn assert_validate_seconded_candidate( }) if &validation_data == assert_pvd && &validation_code == assert_validation_code && &*pov == assert_pov && - &candidate_receipt.descriptor == candidate.descriptor && + candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1011,7 +1011,7 @@ fn second_multiple_candidates_per_relay_parent() { assert_validate_seconded_candidate( &mut virtual_overseer, - candidate.descriptor().relay_parent, + candidate.descriptor.relay_parent(), &candidate, &pov, &pvd, @@ -1064,13 +1064,13 @@ fn second_multiple_candidates_per_relay_parent() { parent_hash, _signed_statement, ) - ) if parent_hash == candidate.descriptor().relay_parent => {} + ) if parent_hash == candidate.descriptor.relay_parent() => {} ); assert_matches!( virtual_overseer.recv().await, AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { - assert_eq!(candidate.descriptor().relay_parent, hash); + assert_eq!(candidate.descriptor.relay_parent(), hash); assert_matches!(statement.payload(), Statement::Seconded(_)); } ); diff --git a/polkadot/node/core/bitfield-signing/src/tests.rs b/polkadot/node/core/bitfield-signing/src/tests.rs index eeaa524d1c63..ce46b147a34c 100644 --- a/polkadot/node/core/bitfield-signing/src/tests.rs +++ b/polkadot/node/core/bitfield-signing/src/tests.rs @@ -17,7 +17,7 @@ use super::*; use futures::{executor::block_on, pin_mut, StreamExt}; use polkadot_node_subsystem::messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}; -use polkadot_primitives::{CandidateHash, OccupiedCore}; +use polkadot_primitives::{vstaging::OccupiedCore, CandidateHash}; use polkadot_primitives_test_helpers::dummy_candidate_descriptor; fn occupied_core(para_id: u32, candidate_hash: CandidateHash) -> CoreState { diff --git a/polkadot/node/core/candidate-validation/src/tests.rs b/polkadot/node/core/candidate-validation/src/tests.rs index 0dcd84bab6cf..b6eed45d36ad 100644 --- a/polkadot/node/core/candidate-validation/src/tests.rs +++ b/polkadot/node/core/candidate-validation/src/tests.rs @@ -52,7 +52,8 @@ fn correctly_checks_included_assumption() { dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< @@ -126,7 +127,8 @@ fn correctly_checks_timed_out_assumption() { dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< @@ -198,7 +200,8 @@ fn check_is_bad_request_if_no_validation_data() { dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< @@ -254,7 +257,8 @@ fn check_is_bad_request_if_no_validation_code() { dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< @@ -322,7 +326,8 @@ fn check_does_not_match() { dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< @@ -423,7 +428,8 @@ fn candidate_validation_ok_is_ok() { head_data.hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let check = perform_basic_checks( &descriptor, @@ -491,7 +497,8 @@ fn candidate_validation_bad_return_is_invalid() { dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let check = perform_basic_checks( &descriptor, @@ -535,7 +542,8 @@ fn perform_basic_checks_on_valid_candidate( head_data_hash, head_data_hash, Sr25519Keyring::Alice, - ); + ) + .into(); let check = perform_basic_checks( &descriptor, @@ -729,7 +737,8 @@ fn candidate_validation_retry_on_error_helper( dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let check = perform_basic_checks( &descriptor, @@ -769,7 +778,8 @@ fn candidate_validation_timeout_is_internal_error() { dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let check = perform_basic_checks( &descriptor, @@ -816,7 +826,8 @@ fn candidate_validation_commitment_hash_mismatch_is_invalid() { Sr25519Keyring::Alice, ), commitments_hash: Hash::zero(), - }; + } + .into(); // This will result in different commitments for this candidate. let validation_result = WasmValidationResult { @@ -860,7 +871,8 @@ fn candidate_validation_code_mismatch_is_invalid() { dummy_hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let check = perform_basic_checks( &descriptor, @@ -915,7 +927,8 @@ fn compressed_code_works() { head_data.hash(), dummy_hash(), Sr25519Keyring::Alice, - ); + ) + .into(); let validation_result = WasmValidationResult { head_data, diff --git a/polkadot/node/core/dispute-coordinator/src/db/v1.rs b/polkadot/node/core/dispute-coordinator/src/db/v1.rs index f3df6b6091b1..962dfcbbcfac 100644 --- a/polkadot/node/core/dispute-coordinator/src/db/v1.rs +++ b/polkadot/node/core/dispute-coordinator/src/db/v1.rs @@ -378,7 +378,9 @@ mod tests { use super::*; use polkadot_node_primitives::DISPUTE_WINDOW; use polkadot_primitives::{Hash, Id as ParaId}; - use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; + use polkadot_primitives_test_helpers::{ + dummy_candidate_receipt, dummy_candidate_receipt_v2, dummy_hash, + }; fn make_db() -> DbBackend { let db = kvdb_memorydb::create(1); @@ -404,7 +406,7 @@ mod tests { session, candidate_hash, CandidateVotes { - candidate_receipt: dummy_candidate_receipt(dummy_hash()), + candidate_receipt: dummy_candidate_receipt_v2(dummy_hash()), valid: Vec::new(), invalid: Vec::new(), }, @@ -496,7 +498,7 @@ mod tests { 1, CandidateHash(Hash::repeat_byte(1)), CandidateVotes { - candidate_receipt: dummy_candidate_receipt(dummy_hash()), + candidate_receipt: dummy_candidate_receipt_v2(dummy_hash()), valid: Vec::new(), invalid: Vec::new(), }, @@ -509,7 +511,7 @@ mod tests { let mut receipt = dummy_candidate_receipt(dummy_hash()); receipt.descriptor.para_id = ParaId::from(5_u32); - receipt + receipt.into() }, valid: Vec::new(), invalid: Vec::new(), @@ -533,7 +535,7 @@ mod tests { .unwrap() .candidate_receipt .descriptor - .para_id, + .para_id(), ParaId::from(5), ); @@ -557,7 +559,7 @@ mod tests { .unwrap() .candidate_receipt .descriptor - .para_id, + .para_id(), ParaId::from(5), ); } @@ -572,13 +574,13 @@ mod tests { 1, CandidateHash(Hash::repeat_byte(1)), CandidateVotes { - candidate_receipt: dummy_candidate_receipt(Hash::random()), + candidate_receipt: dummy_candidate_receipt_v2(Hash::random()), valid: Vec::new(), invalid: Vec::new(), }, ); - let receipt = dummy_candidate_receipt(dummy_hash()); + let receipt = dummy_candidate_receipt_v2(dummy_hash()); overlay_db.write_candidate_votes( 1, @@ -622,7 +624,7 @@ mod tests { let very_recent = current_session - 1; let blank_candidate_votes = || CandidateVotes { - candidate_receipt: dummy_candidate_receipt(dummy_hash()), + candidate_receipt: dummy_candidate_receipt_v2(dummy_hash()), valid: Vec::new(), invalid: Vec::new(), }; diff --git a/polkadot/node/core/dispute-coordinator/src/participation/queues/tests.rs b/polkadot/node/core/dispute-coordinator/src/participation/queues/tests.rs index 9176d00b2f5c..a25387a7eb5a 100644 --- a/polkadot/node/core/dispute-coordinator/src/participation/queues/tests.rs +++ b/polkadot/node/core/dispute-coordinator/src/participation/queues/tests.rs @@ -17,13 +17,13 @@ use crate::{metrics::Metrics, ParticipationPriority}; use assert_matches::assert_matches; use polkadot_primitives::{BlockNumber, Hash}; -use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; +use polkadot_primitives_test_helpers::{dummy_candidate_receipt_v2, dummy_hash}; use super::{CandidateComparator, ParticipationRequest, QueueError, Queues}; /// Make a `ParticipationRequest` based on the given commitments hash. fn make_participation_request(hash: Hash) -> ParticipationRequest { - let mut receipt = dummy_candidate_receipt(dummy_hash()); + let mut receipt = dummy_candidate_receipt_v2(dummy_hash()); // make it differ: receipt.commitments_hash = hash; let request_timer = Metrics::default().time_participation_pipeline(); diff --git a/polkadot/node/core/dispute-coordinator/src/participation/tests.rs b/polkadot/node/core/dispute-coordinator/src/participation/tests.rs index a80553828ac6..8746d6e3287a 100644 --- a/polkadot/node/core/dispute-coordinator/src/participation/tests.rs +++ b/polkadot/node/core/dispute-coordinator/src/participation/tests.rs @@ -68,7 +68,8 @@ async fn participate_with_commitments_hash( let mut receipt = dummy_candidate_receipt_bad_sig(dummy_hash(), dummy_hash()); receipt.commitments_hash = commitments_hash; receipt - }; + } + .into(); let session = 1; let request_timer = participation.metrics.time_participation_pipeline(); diff --git a/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs b/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs index ed2400387ef7..d7586a1ca2f8 100644 --- a/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs +++ b/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs @@ -36,8 +36,11 @@ use polkadot_node_subsystem_test_helpers::{ }; use polkadot_node_subsystem_util::{reexports::SubsystemContext, TimeoutExt}; use polkadot_primitives::{ - BlakeTwo256, BlockNumber, CandidateDescriptor, CandidateEvent, CandidateReceipt, CoreIndex, - GroupIndex, Hash, HashT, HeadData, Id as ParaId, + vstaging::{ + CandidateDescriptorV2 as CandidateDescriptor, CandidateEvent, + CandidateReceiptV2 as CandidateReceipt, + }, + BlakeTwo256, BlockNumber, CoreIndex, GroupIndex, Hash, HashT, HeadData, Id as ParaId, }; use polkadot_primitives_test_helpers::{dummy_collator, dummy_collator_signature, dummy_hash}; diff --git a/polkadot/node/core/prospective-parachains/Cargo.toml b/polkadot/node/core/prospective-parachains/Cargo.toml index 705014e67a05..5629e4ef7fbe 100644 --- a/polkadot/node/core/prospective-parachains/Cargo.toml +++ b/polkadot/node/core/prospective-parachains/Cargo.toml @@ -23,6 +23,7 @@ polkadot-node-subsystem-util = { workspace = true, default-features = true } assert_matches = { workspace = true } polkadot-node-subsystem-test-helpers = { workspace = true } polkadot-primitives-test-helpers = { workspace = true } +polkadot-primitives = { workspace = true, features = ["test"] } sp-tracing = { workspace = true } sp-core = { workspace = true, default-features = true } rand = { workspace = true } diff --git a/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs b/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs index 9886d19e5224..80cef6f3a247 100644 --- a/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs +++ b/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs @@ -73,7 +73,8 @@ fn make_committed_candidate( signature: test_helpers::dummy_collator_signature(), para_head: para_head.hash(), validation_code_hash: Hash::repeat_byte(42).into(), - }, + } + .into(), commitments: CandidateCommitments { upward_messages: Default::default(), horizontal_messages: Default::default(), @@ -283,7 +284,7 @@ fn candidate_storage_methods() { candidate.commitments.head_data = HeadData(vec![1; 10]); let mut pvd = pvd.clone(); pvd.parent_head = HeadData(vec![1; 10]); - candidate.descriptor.persisted_validation_data_hash = pvd.hash(); + candidate.descriptor.set_persisted_validation_data_hash(pvd.hash()); assert_matches!( CandidateEntry::new_seconded(candidate_hash, candidate, pvd), Err(CandidateEntryError::ZeroLengthCycle) @@ -291,7 +292,7 @@ fn candidate_storage_methods() { } assert!(!storage.contains(&candidate_hash)); assert_eq!(storage.possible_backed_para_children(&parent_head_hash).count(), 0); - assert_eq!(storage.head_data_by_hash(&candidate.descriptor.para_head), None); + assert_eq!(storage.head_data_by_hash(&candidate.descriptor.para_head()), None); assert_eq!(storage.head_data_by_hash(&parent_head_hash), None); // Add a valid candidate. @@ -305,9 +306,9 @@ fn candidate_storage_methods() { storage.add_candidate_entry(candidate_entry.clone()).unwrap(); assert!(storage.contains(&candidate_hash)); assert_eq!(storage.possible_backed_para_children(&parent_head_hash).count(), 0); - assert_eq!(storage.possible_backed_para_children(&candidate.descriptor.para_head).count(), 0); + assert_eq!(storage.possible_backed_para_children(&candidate.descriptor.para_head()).count(), 0); assert_eq!( - storage.head_data_by_hash(&candidate.descriptor.para_head).unwrap(), + storage.head_data_by_hash(&candidate.descriptor.para_head()).unwrap(), &candidate.commitments.head_data ); assert_eq!(storage.head_data_by_hash(&parent_head_hash).unwrap(), &pvd.parent_head); @@ -323,7 +324,7 @@ fn candidate_storage_methods() { .collect::>(), vec![candidate_hash] ); - assert_eq!(storage.possible_backed_para_children(&candidate.descriptor.para_head).count(), 0); + assert_eq!(storage.possible_backed_para_children(&candidate.descriptor.para_head()).count(), 0); // Re-adding a candidate fails. assert_matches!( @@ -339,7 +340,7 @@ fn candidate_storage_methods() { storage.remove_candidate(&candidate_hash); assert!(!storage.contains(&candidate_hash)); assert_eq!(storage.possible_backed_para_children(&parent_head_hash).count(), 0); - assert_eq!(storage.head_data_by_hash(&candidate.descriptor.para_head), None); + assert_eq!(storage.head_data_by_hash(&candidate.descriptor.para_head()), None); assert_eq!(storage.head_data_by_hash(&parent_head_hash), None); storage @@ -354,7 +355,7 @@ fn candidate_storage_methods() { .collect::>(), vec![candidate_hash] ); - assert_eq!(storage.possible_backed_para_children(&candidate.descriptor.para_head).count(), 0); + assert_eq!(storage.possible_backed_para_children(&candidate.descriptor.para_head()).count(), 0); // Now add a second candidate in Seconded state. This will be a fork. let (pvd_2, candidate_2) = make_committed_candidate( diff --git a/polkadot/node/core/prospective-parachains/src/tests.rs b/polkadot/node/core/prospective-parachains/src/tests.rs index 14a093239e8e..8584f09187d3 100644 --- a/polkadot/node/core/prospective-parachains/src/tests.rs +++ b/polkadot/node/core/prospective-parachains/src/tests.rs @@ -25,9 +25,12 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_primitives::{ - async_backing::{AsyncBackingParams, BackingState, Constraints, InboundHrmpLimitations}, - CommittedCandidateReceipt, CoreIndex, HeadData, Header, PersistedValidationData, ScheduledCore, - ValidationCodeHash, + async_backing::{AsyncBackingParams, Constraints, InboundHrmpLimitations}, + vstaging::{ + async_backing::BackingState, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, + MutateDescriptorV2, + }, + CoreIndex, HeadData, Header, PersistedValidationData, ScheduledCore, ValidationCodeHash, }; use polkadot_primitives_test_helpers::make_candidate; use rstest::rstest; @@ -393,15 +396,15 @@ async fn handle_leaf_activation( ); for pending in pending_availability { - if !used_relay_parents.contains(&pending.descriptor.relay_parent) { + if !used_relay_parents.contains(&pending.descriptor.relay_parent()) { send_block_header( virtual_overseer, - pending.descriptor.relay_parent, + pending.descriptor.relay_parent(), pending.relay_parent_number, ) .await; - used_relay_parents.insert(pending.descriptor.relay_parent); + used_relay_parents.insert(pending.descriptor.relay_parent()); } } } @@ -568,7 +571,7 @@ macro_rules! make_and_back_candidate { $test_state.validation_code_hash, ); // Set a field to make this candidate unique. - candidate.descriptor.para_head = Hash::from_low_u64_le($index); + candidate.descriptor.set_para_head(Hash::from_low_u64_le($index)); let candidate_hash = candidate.hash(); introduce_seconded_candidate(&mut $virtual_overseer, candidate.clone(), pvd).await; back_candidate(&mut $virtual_overseer, &candidate, candidate_hash).await; @@ -1378,7 +1381,7 @@ fn check_backable_query_single_candidate() { test_state.validation_code_hash, ); // Set a field to make this candidate unique. - candidate_b.descriptor.para_head = Hash::from_low_u64_le(1000); + candidate_b.descriptor.set_para_head(Hash::from_low_u64_le(1000)); let candidate_hash_b = candidate_b.hash(); // Introduce candidates. diff --git a/polkadot/node/core/provisioner/Cargo.toml b/polkadot/node/core/provisioner/Cargo.toml index 5869e494c70f..64a598b420f7 100644 --- a/polkadot/node/core/provisioner/Cargo.toml +++ b/polkadot/node/core/provisioner/Cargo.toml @@ -27,4 +27,6 @@ sp-application-crypto = { workspace = true, default-features = true } sp-keystore = { workspace = true, default-features = true } polkadot-node-subsystem-test-helpers = { workspace = true } polkadot-primitives-test-helpers = { workspace = true } +polkadot-primitives = { workspace = true, features = ["test"] } + rstest = { workspace = true } diff --git a/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs b/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs index ecb7aac78396..107b96947625 100644 --- a/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs +++ b/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs @@ -427,7 +427,8 @@ impl TestDisputes { let onchain_votes_count = self.validators_count * 80 / 100; let session_idx = 0; let lf = leaf(); - let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash); + let dummy_receipt = + polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -445,7 +446,8 @@ impl TestDisputes { let onchain_votes_count = self.validators_count * 40 / 100; let session_idx = 1; let lf = leaf(); - let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash); + let dummy_receipt = + polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -462,7 +464,8 @@ impl TestDisputes { let local_votes_count = self.validators_count * 90 / 100; let session_idx = 2; let lf = leaf(); - let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash); + let dummy_receipt = + polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Confirmed); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -478,7 +481,8 @@ impl TestDisputes { let onchain_votes_count = self.validators_count * 75 / 100; let session_idx = 3; let lf = leaf(); - let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash); + let dummy_receipt = + polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::ConcludedFor(0)); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -494,7 +498,8 @@ impl TestDisputes { let local_votes_count = self.validators_count * 90 / 100; let session_idx = 4; let lf = leaf(); - let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash); + let dummy_receipt = + polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::ConcludedFor(0)); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -510,7 +515,8 @@ impl TestDisputes { let onchain_votes_count = self.validators_count * 10 / 100; let session_idx = 5; let lf = leaf(); - let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash); + let dummy_receipt = + polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -527,7 +533,8 @@ impl TestDisputes { let local_votes_count = self.validators_count * 10 / 100; let session_idx = 6; let lf = leaf(); - let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash); + let dummy_receipt = + polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); diff --git a/polkadot/node/core/provisioner/src/tests.rs b/polkadot/node/core/provisioner/src/tests.rs index b38459302c8f..5ccc81985dea 100644 --- a/polkadot/node/core/provisioner/src/tests.rs +++ b/polkadot/node/core/provisioner/src/tests.rs @@ -16,14 +16,17 @@ use super::*; use bitvec::bitvec; -use polkadot_primitives::{OccupiedCore, ScheduledCore}; +use polkadot_primitives::{ + vstaging::{MutateDescriptorV2, OccupiedCore}, + ScheduledCore, +}; use polkadot_primitives_test_helpers::{dummy_candidate_descriptor, dummy_hash}; const MOCK_GROUP_SIZE: usize = 5; pub fn occupied_core(para_id: u32) -> CoreState { let mut candidate_descriptor = dummy_candidate_descriptor(dummy_hash()); - candidate_descriptor.para_id = para_id.into(); + candidate_descriptor.set_para_id(para_id.into()); CoreState::Occupied(OccupiedCore { group_responsible: para_id.into(), @@ -32,7 +35,7 @@ pub fn occupied_core(para_id: u32) -> CoreState { time_out_at: 200_u32, next_up_on_time_out: None, availability: bitvec![u8, bitvec::order::Lsb0; 0; 32], - candidate_descriptor, + candidate_descriptor: candidate_descriptor.into(), candidate_hash: Default::default(), }) } @@ -283,7 +286,7 @@ mod select_candidates { .take(core_count) .enumerate() .map(|(idx, mut candidate)| { - candidate.descriptor.para_id = idx.into(); + candidate.descriptor.set_para_id(idx.into()); candidate }) .collect(); @@ -559,14 +562,14 @@ mod select_candidates { use RuntimeApiMessage::Request; let mut backed = expected.clone().into_iter().fold(HashMap::new(), |mut acc, candidate| { - acc.entry(candidate.descriptor().para_id).or_insert(vec![]).push(candidate); + acc.entry(candidate.descriptor().para_id()).or_insert(vec![]).push(candidate); acc }); - expected.sort_by_key(|c| c.candidate().descriptor.para_id); + expected.sort_by_key(|c| c.candidate().descriptor.para_id()); let mut candidates_iter = expected .iter() - .map(|candidate| (candidate.hash(), candidate.descriptor().relay_parent)); + .map(|candidate| (candidate.hash(), candidate.descriptor().relay_parent())); while let Some(from_job) = receiver.next().await { match from_job { @@ -601,7 +604,7 @@ mod select_candidates { candidates .iter() .map(|candidate| { - (candidate.hash(), candidate.descriptor().relay_parent) + (candidate.hash(), candidate.descriptor().relay_parent()) }) .collect(), ) @@ -707,7 +710,7 @@ mod select_candidates { .take(mock_cores.len()) .enumerate() .map(|(idx, mut candidate)| { - candidate.descriptor.para_id = idx.into(); + candidate.descriptor.set_para_id(idx.into()); candidate }) .cycle() @@ -719,11 +722,11 @@ mod select_candidates { candidate } else if idx < mock_cores.len() * 2 { // for the second repetition of the candidates, give them the wrong hash - candidate.descriptor.persisted_validation_data_hash = Default::default(); + candidate.descriptor.set_persisted_validation_data_hash(Default::default()); candidate } else { // third go-around: right hash, wrong para_id - candidate.descriptor.para_id = idx.into(); + candidate.descriptor.set_para_id(idx.into()); candidate } }) @@ -808,8 +811,8 @@ mod select_candidates { let committed_receipts: Vec<_> = (0..=mock_cores.len()) .map(|i| { let mut descriptor = dummy_candidate_descriptor(dummy_hash()); - descriptor.para_id = i.into(); - descriptor.persisted_validation_data_hash = empty_hash; + descriptor.set_para_id(i.into()); + descriptor.set_persisted_validation_data_hash(empty_hash); CommittedCandidateReceipt { descriptor, commitments: CandidateCommitments { @@ -918,11 +921,11 @@ mod select_candidates { let committed_receipts: Vec<_> = (0..mock_cores.len()) .map(|i| { let mut descriptor = dummy_candidate_descriptor(dummy_hash()); - descriptor.para_id = if let Scheduled(scheduled_core) = &mock_cores[i] { + descriptor.set_para_id(if let Scheduled(scheduled_core) = &mock_cores[i] { scheduled_core.para_id } else { panic!("`mock_cores` is not initialized with `Scheduled`?") - }; + }); descriptor.persisted_validation_data_hash = empty_hash; descriptor.pov_hash = Hash::from_low_u64_be(i as u64); CommittedCandidateReceipt { @@ -1222,8 +1225,8 @@ mod select_candidates { .take(mock_cores.len() + 1) .enumerate() .map(|(idx, mut candidate)| { - candidate.descriptor.para_id = idx.into(); - candidate.descriptor.relay_parent = Hash::repeat_byte(idx as u8); + candidate.descriptor.set_para_id(idx.into()); + candidate.descriptor.set_relay_parent(Hash::repeat_byte(idx as u8)); candidate }) .collect(); diff --git a/polkadot/node/malus/src/variants/common.rs b/polkadot/node/malus/src/variants/common.rs index 1b6ac9a2d186..31d0c811a075 100644 --- a/polkadot/node/malus/src/variants/common.rs +++ b/polkadot/node/malus/src/variants/common.rs @@ -244,7 +244,7 @@ fn create_validation_response( gum::debug!( target: MALUS, - para_id = ?candidate_receipt.descriptor.para_id, + para_id = ?candidate_receipt.descriptor.para_id(), candidate_hash = ?candidate_receipt.hash(), "ValidationResult: {:?}", &result @@ -350,7 +350,7 @@ where gum::info!( target: MALUS, ?behave_maliciously, - para_id = ?candidate_receipt.descriptor.para_id, + para_id = ?candidate_receipt.descriptor.para_id(), "😈 Maliciously sending invalid validation result: {:?}.", &validation_result, ); @@ -459,7 +459,7 @@ where ValidationResult::Invalid(self.fake_validation_error.into()); gum::info!( target: MALUS, - para_id = ?candidate_receipt.descriptor.para_id, + para_id = ?candidate_receipt.descriptor.para_id(), "😈 Maliciously sending invalid validation result: {:?}.", &validation_result, ); diff --git a/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs b/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs index 7a95bdaead26..309be9e46d82 100644 --- a/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs +++ b/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs @@ -42,7 +42,7 @@ use polkadot_cli::{ use polkadot_node_subsystem::SpawnGlue; use polkadot_node_subsystem_types::{ChainApiBackend, OverseerSignal, RuntimeApiSubsystemClient}; use polkadot_node_subsystem_util::request_candidate_events; -use polkadot_primitives::CandidateEvent; +use polkadot_primitives::vstaging::CandidateEvent; use sp_core::traits::SpawnNamed; // Filter wrapping related types. diff --git a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs index f3900ee76a1a..292842963b75 100644 --- a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs +++ b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs @@ -32,7 +32,7 @@ use polkadot_cli::{ }; use polkadot_node_primitives::{AvailableData, BlockData, PoV}; use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; -use polkadot_primitives::{vstaging::CandidateReceiptV2, CandidateDescriptor, CandidateReceipt}; +use polkadot_primitives::{vstaging::CandidateReceiptV2, CandidateDescriptor}; use polkadot_node_subsystem_util::request_validators; use sp_core::traits::SpawnNamed; @@ -127,7 +127,7 @@ where let validation_code = { let validation_code_hash = - _candidate.descriptor().validation_code_hash; + _candidate.descriptor().validation_code_hash(); let (tx, rx) = oneshot::channel(); new_sender .send_message(RuntimeApiMessage::Request( @@ -214,7 +214,7 @@ where let collator_pair = CollatorPair::generate().0; let signature_payload = polkadot_primitives::collator_signature_payload( &relay_parent, - &candidate.descriptor().para_id, + &candidate.descriptor().para_id(), &validation_data_hash, &pov_hash, &validation_code_hash, diff --git a/polkadot/node/network/availability-distribution/src/tests/mod.rs b/polkadot/node/network/availability-distribution/src/tests/mod.rs index 3320871bceb5..f165add90ea0 100644 --- a/polkadot/node/network/availability-distribution/src/tests/mod.rs +++ b/polkadot/node/network/availability-distribution/src/tests/mod.rs @@ -22,7 +22,7 @@ use rstest::rstest; use polkadot_node_network_protocol::request_response::{ IncomingRequest, Protocol, ReqProtocolNames, }; -use polkadot_primitives::{node_features, Block, CoreState, Hash, NodeFeatures}; +use polkadot_primitives::{node_features, vstaging::CoreState, Block, Hash, NodeFeatures}; use sp_keystore::KeystorePtr; use super::*; diff --git a/polkadot/node/network/availability-distribution/src/tests/state.rs b/polkadot/node/network/availability-distribution/src/tests/state.rs index 97e616f79fb7..563f2fee329a 100644 --- a/polkadot/node/network/availability-distribution/src/tests/state.rs +++ b/polkadot/node/network/availability-distribution/src/tests/state.rs @@ -47,7 +47,7 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_primitives::{ - CandidateHash, ChunkIndex, CoreIndex, CoreState, ExecutorParams, GroupIndex, Hash, + vstaging::CoreState, CandidateHash, ChunkIndex, CoreIndex, ExecutorParams, GroupIndex, Hash, Id as ParaId, NodeFeatures, ScheduledCore, SessionInfo, ValidatorIndex, }; use test_helpers::mock::{make_ferdie_keystore, new_leaf}; diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs index 86c8bcb6bdcd..e6cdb6460d90 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs @@ -42,8 +42,9 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_node_subsystem_util::{reputation::add_reputation, TimeoutExt}; use polkadot_primitives::{ - CandidateReceipt, CollatorPair, CoreIndex, CoreState, GroupIndex, GroupRotationInfo, HeadData, - OccupiedCore, PersistedValidationData, ScheduledCore, ValidatorId, ValidatorIndex, + vstaging::{CandidateReceiptV2 as CandidateReceipt, CoreState, OccupiedCore}, + CollatorPair, CoreIndex, GroupIndex, GroupRotationInfo, HeadData, PersistedValidationData, + ScheduledCore, ValidatorId, ValidatorIndex, }; use polkadot_primitives_test_helpers::{ dummy_candidate_descriptor, dummy_candidate_receipt_bad_sig, dummy_hash, diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs index 472731b506ab..14a8c08cf83d 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs @@ -20,8 +20,8 @@ use super::*; use polkadot_node_subsystem::messages::ChainApiMessage; use polkadot_primitives::{ - AsyncBackingParams, BlockNumber, CandidateCommitments, CommittedCandidateReceipt, Header, - SigningContext, ValidatorId, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, AsyncBackingParams, BlockNumber, CandidateCommitments, + Header, SigningContext, ValidatorId, }; use rstest::rstest; @@ -1177,7 +1177,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { response_channel .send(Ok(( request_v2::CollationFetchingResponse::Collation( - candidate_a.clone(), + candidate_a.into().clone(), PoV { block_data: BlockData(vec![2]) }, ) .encode(), @@ -1209,7 +1209,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { incoming_pov, )) => { assert_eq!(head_c, relay_parent); - assert_eq!(test_state.chain_ids[0], candidate_receipt.descriptor.para_id); + assert_eq!(test_state.chain_ids[0], candidate_receipt.descriptor.para_id()); assert_eq!(PoV { block_data: BlockData(vec![2]) }, incoming_pov); assert_eq!(PersistedValidationData:: { parent_head: HeadData(vec![0]), @@ -1262,7 +1262,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { incoming_pov, )) => { assert_eq!(head_c, relay_parent); - assert_eq!(test_state.chain_ids[0], candidate_receipt.descriptor.para_id); + assert_eq!(test_state.chain_ids[0], candidate_receipt.descriptor.para_id()); assert_eq!(PoV { block_data: BlockData(vec![1]) }, incoming_pov); assert_eq!(PersistedValidationData:: { parent_head: HeadData(vec![1]), @@ -1290,7 +1290,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { // If candidate A is invalid, B won't be seconded. overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::Invalid(head_c, candidate_a), + CollatorProtocolMessage::Invalid(head_c, candidate_a.into()), ) .await; diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs index 8e6fcbaebbf1..a185b0021d21 100644 --- a/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs @@ -47,7 +47,8 @@ use polkadot_primitives::{ SessionInfo, ValidationCode, }; use polkadot_primitives_test_helpers::{ - dummy_committed_candidate_receipt, dummy_hash, AlwaysZeroRng, + dummy_committed_candidate_receipt, dummy_committed_candidate_receipt_v2, dummy_hash, + AlwaysZeroRng, }; use sc_keystore::LocalKeystore; use sc_network::ProtocolName; @@ -102,21 +103,24 @@ fn active_head_accepts_only_2_seconded_per_validator() { c.descriptor.relay_parent = parent_hash; c.descriptor.para_id = 1.into(); c - }; + } + .into(); let candidate_b = { let mut c = dummy_committed_candidate_receipt(dummy_hash()); c.descriptor.relay_parent = parent_hash; c.descriptor.para_id = 2.into(); c - }; + } + .into(); let candidate_c = { let mut c = dummy_committed_candidate_receipt(dummy_hash()); c.descriptor.relay_parent = parent_hash; c.descriptor.para_id = 3.into(); c - }; + } + .into(); let mut head_data = ActiveHeadData::new( IndexedVec::::from(validators), @@ -426,7 +430,8 @@ fn peer_view_update_sends_messages() { c.descriptor.relay_parent = hash_c; c.descriptor.para_id = ParaId::from(1_u32); c - }; + } + .into(); let candidate_hash = candidate.hash(); let old_view = view![hash_a, hash_b]; @@ -615,7 +620,8 @@ fn circulated_statement_goes_to_all_peers_with_view() { c.descriptor.relay_parent = hash_b; c.descriptor.para_id = ParaId::from(1_u32); c - }; + } + .into(); let peer_a = PeerId::random(); let peer_b = PeerId::random(); @@ -749,7 +755,8 @@ fn receiving_from_one_sends_to_another_and_to_candidate_backing() { c.descriptor.relay_parent = hash_a; c.descriptor.para_id = PARA_ID; c - }; + } + .into(); let peer_a = PeerId::random(); let peer_b = PeerId::random(); @@ -2597,7 +2604,7 @@ fn handle_multiple_seconded_statements() { let relay_parent_hash = Hash::repeat_byte(1); let pvd = dummy_pvd(); - let candidate = dummy_committed_candidate_receipt(relay_parent_hash); + let candidate = dummy_committed_candidate_receipt_v2(relay_parent_hash); let candidate_hash = candidate.hash(); // We want to ensure that our peers are not lucky diff --git a/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs b/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs index 119dc832d13a..9f2c36ad1018 100644 --- a/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs +++ b/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs @@ -33,9 +33,9 @@ use polkadot_node_subsystem::messages::{ use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_node_subsystem_util::TimeoutExt; use polkadot_primitives::{ - AssignmentPair, AsyncBackingParams, Block, BlockNumber, CommittedCandidateReceipt, CoreState, - GroupRotationInfo, HeadData, Header, IndexedVec, PersistedValidationData, ScheduledCore, - SessionIndex, SessionInfo, ValidatorPair, + vstaging::{CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState}, + AssignmentPair, AsyncBackingParams, Block, BlockNumber, GroupRotationInfo, HeadData, Header, + IndexedVec, PersistedValidationData, ScheduledCore, SessionIndex, SessionInfo, ValidatorPair, }; use sc_keystore::LocalKeystore; use sc_network::ProtocolName; diff --git a/polkadot/node/overseer/src/tests.rs b/polkadot/node/overseer/src/tests.rs index 3792165c7658..9aaee2e71f13 100644 --- a/polkadot/node/overseer/src/tests.rs +++ b/polkadot/node/overseer/src/tests.rs @@ -28,12 +28,12 @@ use polkadot_node_subsystem_types::messages::{ NetworkBridgeEvent, ReportPeerMessage, RuntimeApiRequest, }; use polkadot_primitives::{ - vstaging::CandidateReceiptV2, CandidateHash, CandidateReceipt, CollatorPair, Id as ParaId, + vstaging::CandidateReceiptV2, CandidateHash, CollatorPair, Id as ParaId, InvalidDisputeStatementKind, PvfExecKind, SessionIndex, ValidDisputeStatementKind, ValidatorIndex, }; use polkadot_primitives_test_helpers::{ - dummy_candidate_descriptor, dummy_candidate_receipt, dummy_candidate_receipt_v2, dummy_hash, + dummy_candidate_descriptor, dummy_candidate_receipt_v2, dummy_hash, }; use crate::{ diff --git a/polkadot/node/service/src/parachains_db/upgrade.rs b/polkadot/node/service/src/parachains_db/upgrade.rs index a82d751dff93..770b477d11ec 100644 --- a/polkadot/node/service/src/parachains_db/upgrade.rs +++ b/polkadot/node/service/src/parachains_db/upgrade.rs @@ -463,7 +463,7 @@ mod tests { v3::migration_helpers::{v1_to_latest_sanity_check, v2_fill_test_data}, }; use polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter; - use polkadot_primitives_test_helpers::dummy_candidate_receipt; + use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_candidate_receipt_v2}; #[test] fn test_paritydb_migrate_0_to_1() { @@ -648,7 +648,7 @@ mod tests { assert_eq!(db.num_columns(), super::columns::v3::NUM_COLUMNS as u32); let db = DbAdapter::new(db, columns::v3::ORDERED_COL); // Fill the approval voting column with test data. - v2_fill_test_data(std::sync::Arc::new(db), approval_cfg, dummy_candidate_receipt) + v2_fill_test_data(std::sync::Arc::new(db), approval_cfg, dummy_candidate_receipt_v2) .unwrap() }; diff --git a/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs b/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs index 93adeeb53972..2d2e9434b767 100644 --- a/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs +++ b/polkadot/node/subsystem-bench/src/lib/statement/test_state.rs @@ -42,15 +42,14 @@ use polkadot_node_subsystem_test_helpers::{ use polkadot_overseer::BlockInfo; use polkadot_primitives::{ vstaging::{ - CandidateDescriptorV2, CandidateReceiptV2 as CandidateReceipt, + CandidateReceiptV2 as CandidateReceipt, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, MutateDescriptorV2, }, BlockNumber, CandidateHash, CompactStatement, Hash, Header, Id, PersistedValidationData, SessionInfo, SignedStatement, SigningContext, UncheckedSigned, ValidatorIndex, ValidatorPair, }; use polkadot_primitives_test_helpers::{ - dummy_committed_candidate_receipt, dummy_committed_candidate_receipt_v2, dummy_hash, - dummy_head_data, dummy_pvd, + dummy_committed_candidate_receipt_v2, dummy_hash, dummy_head_data, dummy_pvd, }; use sc_network::{config::IncomingRequest, ProtocolName}; use sp_core::{Pair, H256}; diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 9029b47b8f34..eeada78c97d2 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -206,6 +206,8 @@ pub trait MutateDescriptorV2 { fn set_persisted_validation_data_hash(&mut self, persisted_validation_data_hash: Hash); /// Set the erasure root of the descriptor. fn set_erasure_root(&mut self, erasure_root: Hash); + /// Set the para head of the descriptor. + fn set_para_head(&mut self, para_head: Hash); } #[cfg(feature = "test")] @@ -233,6 +235,10 @@ impl MutateDescriptorV2 for CandidateDescriptorV2 { fn set_erasure_root(&mut self, erasure_root: Hash) { self.erasure_root = erasure_root; } + + fn set_para_head(&mut self, para_head: Hash) { + self.para_head = para_head; + } } /// A candidate-receipt at version 2. diff --git a/polkadot/primitives/test-helpers/src/lib.rs b/polkadot/primitives/test-helpers/src/lib.rs index 1c4f3c5a1420..c2eccafef788 100644 --- a/polkadot/primitives/test-helpers/src/lib.rs +++ b/polkadot/primitives/test-helpers/src/lib.rs @@ -227,7 +227,7 @@ pub fn make_candidate( parent_head: HeadData, head_data: HeadData, validation_code_hash: ValidationCodeHash, -) -> (CommittedCandidateReceipt, PersistedValidationData) { +) -> (CommittedCandidateReceiptV2, PersistedValidationData) { let pvd = dummy_pvd(parent_head, relay_parent_number); let commitments = CandidateCommitments { head_data, @@ -244,7 +244,8 @@ pub fn make_candidate( candidate.descriptor.para_id = para_id; candidate.descriptor.persisted_validation_data_hash = pvd.hash(); candidate.descriptor.validation_code_hash = validation_code_hash; - let candidate = CommittedCandidateReceipt { descriptor: candidate.descriptor, commitments }; + let candidate = + CommittedCandidateReceiptV2 { descriptor: candidate.descriptor.into(), commitments }; (candidate, pvd) } @@ -354,11 +355,11 @@ impl std::default::Default for TestCandidateBuilder { impl TestCandidateBuilder { /// Build a `CandidateReceipt`. - pub fn build(self) -> CandidateReceipt { + pub fn build(self) -> CandidateReceiptV2 { let mut descriptor = dummy_candidate_descriptor(self.relay_parent); descriptor.para_id = self.para_id; descriptor.pov_hash = self.pov_hash; - CandidateReceipt { descriptor, commitments_hash: self.commitments_hash } + CandidateReceipt { descriptor, commitments_hash: self.commitments_hash }.into() } } From 9eba1ef15adace4b8463745d9f3a0445b7f11b89 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 13 Sep 2024 13:27:30 +0300 Subject: [PATCH 099/130] more wip Signed-off-by: Andrei Sandu --- .../node/collation-generation/src/tests.rs | 76 ++++++++++--------- .../approval-voting/src/approval_checking.rs | 10 +-- .../src/approval_db/v2/tests.rs | 10 +-- .../src/approval_db/v3/tests.rs | 6 +- .../node/core/approval-voting/src/import.rs | 4 +- .../node/core/approval-voting/src/tests.rs | 45 +++++------ polkadot/node/core/backing/Cargo.toml | 2 + polkadot/node/core/backing/src/tests/mod.rs | 28 +++---- .../src/tests/prospective_parachains.rs | 12 +-- .../src/fragment_chain/tests.rs | 2 +- .../core/prospective-parachains/src/tests.rs | 6 +- .../disputes/prioritized_selection/tests.rs | 21 ++--- polkadot/node/core/provisioner/src/tests.rs | 21 ++--- .../src/tests/mock.rs | 4 +- .../src/validator_side/tests/mod.rs | 12 +-- .../tests/prospective_parachains.rs | 4 +- .../runtime/parachains/src/inclusion/tests.rs | 2 +- .../parachains/src/paras_inherent/tests.rs | 4 +- 18 files changed, 135 insertions(+), 134 deletions(-) diff --git a/polkadot/node/collation-generation/src/tests.rs b/polkadot/node/collation-generation/src/tests.rs index 95990538c066..c27403cc7b3a 100644 --- a/polkadot/node/collation-generation/src/tests.rs +++ b/polkadot/node/collation-generation/src/tests.rs @@ -30,13 +30,13 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_test_helpers::{subsystem_test_harness, TestSubsystemContextHandle}; use polkadot_node_subsystem_util::TimeoutExt; use polkadot_primitives::{ - async_backing::{CandidatePendingAvailability}, - vstaging::async_backing::BackingState, + vstaging::async_backing::CandidatePendingAvailability, vstaging::async_backing::BackingState, AsyncBackingParams, BlockNumber, CollatorPair, HeadData, PersistedValidationData, ScheduledCore, ValidationCode, }; use polkadot_primitives_test_helpers::{ - dummy_candidate_descriptor, dummy_hash, dummy_head_data, dummy_validator, make_candidate, + dummy_candidate_descriptor, dummy_candidate_descriptor_v2, dummy_hash, dummy_head_data, + dummy_validator, make_candidate, }; use rstest::rstest; use sp_keyring::sr25519::Keyring as Sr25519Keyring; @@ -491,7 +491,7 @@ fn sends_distribute_collation_message(#[case] runtime_version: u32) { erasure_root: dummy_hash(), // this isn't something we're checking right now para_head: test_collation().head_data.hash(), validation_code_hash: expect_validation_code_hash, - }; + }.into(); assert_eq!(to_collator_protocol.len(), 1); match AllMessages::from(to_collator_protocol.pop().unwrap()) { @@ -507,19 +507,19 @@ fn sends_distribute_collation_message(#[case] runtime_version: u32) { assert!(CollatorPair::verify( &descriptor.signature, &collator_signature_payload( - &descriptor.relay_parent, - &descriptor.para_id, - &descriptor.persisted_validation_data_hash, - &descriptor.pov_hash, - &descriptor.validation_code_hash, + &descriptor.relay_parent(), + &descriptor.para_id(), + &descriptor.persisted_validation_data_hash(), + &descriptor.pov_hash(), + &descriptor.validation_code_hash(), ) .as_ref(), - &descriptor.collator, + &descriptor.collator().unwrap(), )); let expect_descriptor = { let mut expect_descriptor = expect_descriptor; - expect_descriptor.signature = descriptor.signature.clone(); - expect_descriptor.erasure_root = descriptor.erasure_root; + expect_descriptor.signature = descriptor.signature.clone().unwrap(); + expect_descriptor.erasure_root = descriptor.erasure_root(); expect_descriptor }; assert_eq!(descriptor, expect_descriptor); @@ -753,9 +753,9 @@ fn submit_collation_leads_to_distribution() { }) => { let CandidateReceipt { descriptor, .. } = candidate_receipt; assert_eq!(parent_head_data_hash, parent_head.hash()); - assert_eq!(descriptor.persisted_validation_data_hash, expected_pvd.hash()); - assert_eq!(descriptor.para_head, dummy_head_data().hash()); - assert_eq!(descriptor.validation_code_hash, validation_code_hash); + assert_eq!(descriptor.persisted_validation_data_hash(), expected_pvd.hash()); + assert_eq!(descriptor.para_head(), dummy_head_data().hash()); + assert_eq!(descriptor.validation_code_hash(), validation_code_hash); } ); @@ -773,16 +773,17 @@ fn distribute_collation_for_occupied_core_with_async_backing_enabled(#[case] run let para_id = ParaId::from(5); // One core, in occupied state. The data in `CoreState` and `ClaimQueue` should match. - let cores: Vec = vec![CoreState::Occupied(polkadot_primitives::OccupiedCore { - next_up_on_available: Some(ScheduledCore { para_id, collator: None }), - occupied_since: 1, - time_out_at: 10, - next_up_on_time_out: Some(ScheduledCore { para_id, collator: None }), - availability: Default::default(), // doesn't matter - group_responsible: polkadot_primitives::GroupIndex(0), - candidate_hash: Default::default(), - candidate_descriptor: dummy_candidate_descriptor(dummy_hash()), - })]; + let cores: Vec = + vec![CoreState::Occupied(polkadot_primitives::vstaging::OccupiedCore { + next_up_on_available: Some(ScheduledCore { para_id, collator: None }), + occupied_since: 1, + time_out_at: 10, + next_up_on_time_out: Some(ScheduledCore { para_id, collator: None }), + availability: Default::default(), // doesn't matter + group_responsible: polkadot_primitives::GroupIndex(0), + candidate_hash: Default::default(), + candidate_descriptor: dummy_candidate_descriptor_v2(dummy_hash()), + })]; let claim_queue = BTreeMap::from([(CoreIndex::from(0), VecDeque::from([para_id]))]).into(); test_harness(|mut virtual_overseer| async move { @@ -883,7 +884,7 @@ fn distribute_collation_for_occupied_cores_with_async_backing_enabled_and_elasti let cores = (0..3) .into_iter() .map(|idx| { - CoreState::Occupied(polkadot_primitives::OccupiedCore { + CoreState::Occupied(polkadot_primitives::vstaging::OccupiedCore { next_up_on_available: Some(ScheduledCore { para_id, collator: None }), occupied_since: 0, time_out_at: 10, @@ -891,7 +892,7 @@ fn distribute_collation_for_occupied_cores_with_async_backing_enabled_and_elasti availability: Default::default(), // doesn't matter group_responsible: polkadot_primitives::GroupIndex(idx as u32), candidate_hash: Default::default(), - candidate_descriptor: dummy_candidate_descriptor(dummy_hash()), + candidate_descriptor: dummy_candidate_descriptor_v2(dummy_hash()), }) }) .collect::>(); @@ -1009,16 +1010,17 @@ fn no_collation_is_distributed_for_occupied_core_with_async_backing_disabled( let para_id = ParaId::from(5); // One core, in occupied state. The data in `CoreState` and `ClaimQueue` should match. - let cores: Vec = vec![CoreState::Occupied(polkadot_primitives::OccupiedCore { - next_up_on_available: Some(ScheduledCore { para_id, collator: None }), - occupied_since: 1, - time_out_at: 10, - next_up_on_time_out: Some(ScheduledCore { para_id, collator: None }), - availability: Default::default(), // doesn't matter - group_responsible: polkadot_primitives::GroupIndex(0), - candidate_hash: Default::default(), - candidate_descriptor: dummy_candidate_descriptor(dummy_hash()), - })]; + let cores: Vec = + vec![CoreState::Occupied(polkadot_primitives::vstaging::OccupiedCore { + next_up_on_available: Some(ScheduledCore { para_id, collator: None }), + occupied_since: 1, + time_out_at: 10, + next_up_on_time_out: Some(ScheduledCore { para_id, collator: None }), + availability: Default::default(), // doesn't matter + group_responsible: polkadot_primitives::GroupIndex(0), + candidate_hash: Default::default(), + candidate_descriptor: dummy_candidate_descriptor_v2(dummy_hash()), + })]; let claim_queue = BTreeMap::from([(CoreIndex::from(0), VecDeque::from([para_id]))]).into(); test_harness(|mut virtual_overseer| async move { diff --git a/polkadot/node/core/approval-voting/src/approval_checking.rs b/polkadot/node/core/approval-voting/src/approval_checking.rs index 3774edc69981..3b7262a46826 100644 --- a/polkadot/node/core/approval-voting/src/approval_checking.rs +++ b/polkadot/node/core/approval-voting/src/approval_checking.rs @@ -509,13 +509,13 @@ mod tests { use crate::{approval_db, BTreeMap}; use bitvec::{bitvec, order::Lsb0 as BitOrderLsb0, vec::BitVec}; use polkadot_primitives::GroupIndex; - use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; + use polkadot_primitives_test_helpers::{dummy_candidate_receipt_v2, dummy_hash}; #[test] fn pending_is_not_approved() { let candidate = CandidateEntry::from_v1( approval_db::v1::CandidateEntry { - candidate: dummy_candidate_receipt(dummy_hash()), + candidate: dummy_candidate_receipt_v2(dummy_hash()), session: 0, block_assignments: BTreeMap::default(), approvals: BitVec::default(), @@ -550,7 +550,7 @@ mod tests { fn exact_takes_only_assignments_up_to() { let mut candidate: CandidateEntry = CandidateEntry::from_v1( approval_db::v1::CandidateEntry { - candidate: dummy_candidate_receipt(dummy_hash()), + candidate: dummy_candidate_receipt_v2(dummy_hash()), session: 0, block_assignments: BTreeMap::default(), approvals: bitvec![u8, BitOrderLsb0; 0; 10], @@ -624,7 +624,7 @@ mod tests { fn one_honest_node_always_approves() { let mut candidate: CandidateEntry = CandidateEntry::from_v1( approval_db::v1::CandidateEntry { - candidate: dummy_candidate_receipt(dummy_hash()), + candidate: dummy_candidate_receipt_v2(dummy_hash()), session: 0, block_assignments: BTreeMap::default(), approvals: bitvec![u8, BitOrderLsb0; 0; 10], @@ -1097,7 +1097,7 @@ mod tests { let mut candidate: CandidateEntry = CandidateEntry::from_v1( approval_db::v1::CandidateEntry { - candidate: dummy_candidate_receipt(dummy_hash()), + candidate: dummy_candidate_receipt_v2(dummy_hash()), session: 0, block_assignments: BTreeMap::default(), approvals: bitvec![u8, BitOrderLsb0; 0; 3], diff --git a/polkadot/node/core/approval-voting/src/approval_db/v2/tests.rs b/polkadot/node/core/approval-voting/src/approval_db/v2/tests.rs index 06a3cc1e306b..82e6373e3668 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v2/tests.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v2/tests.rs @@ -26,7 +26,7 @@ use crate::{ ops::{add_block_entry, canonicalize, force_approve, NewCandidateInfo}, }; use polkadot_primitives::{ - BlockNumber, CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, Hash, + BlockNumber, CandidateHash, vstaging::CandidateReceiptV2 as CandidateReceipt, vstaging::MutateDescriptorV2, CoreIndex, GroupIndex, Hash, }; use polkadot_node_subsystem_util::database::Database; @@ -35,7 +35,7 @@ use sp_consensus_slots::Slot; use std::{collections::HashMap, sync::Arc}; use polkadot_primitives_test_helpers::{ - dummy_candidate_receipt, dummy_candidate_receipt_bad_sig, dummy_hash, + dummy_candidate_receipt, dummy_candidate_receipt_bad_sig, dummy_candidate_receipt_v2, dummy_hash }; const DATA_COL: u32 = 0; @@ -72,10 +72,10 @@ fn make_block_entry( } fn make_candidate(para_id: ParaId, relay_parent: Hash) -> CandidateReceipt { - let mut c = dummy_candidate_receipt(dummy_hash()); + let mut c = dummy_candidate_receipt_v2(dummy_hash()); - c.descriptor.para_id = para_id; - c.descriptor.relay_parent = relay_parent; + c.descriptor.set_para_id(para_id); + c.descriptor.set_relay_parent(relay_parent); c } diff --git a/polkadot/node/core/approval-voting/src/approval_db/v3/tests.rs b/polkadot/node/core/approval-voting/src/approval_db/v3/tests.rs index 9233d7518483..4b548ae762ad 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v3/tests.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v3/tests.rs @@ -35,7 +35,7 @@ use sp_consensus_slots::Slot; use std::{collections::HashMap, sync::Arc}; use polkadot_primitives_test_helpers::{ - dummy_candidate_receipt, dummy_candidate_receipt_bad_sig, dummy_hash, + dummy_candidate_receipt, dummy_candidate_receipt_bad_sig, dummy_candidate_receipt_v2_bad_sig, dummy_hash }; const DATA_COL: u32 = 0; @@ -87,7 +87,7 @@ fn read_write() { let hash_a = Hash::repeat_byte(1); let hash_b = Hash::repeat_byte(2); - let candidate_hash = dummy_candidate_receipt_bad_sig(dummy_hash(), None).hash(); + let candidate_hash = dummy_candidate_receipt_v2_bad_sig(dummy_hash(), None).hash(); let range = StoredBlockRange(10, 20); let at_height = vec![hash_a, hash_b]; @@ -96,7 +96,7 @@ fn read_write() { make_block_entry(hash_a, Default::default(), 1, vec![(CoreIndex(0), candidate_hash)]); let candidate_entry = CandidateEntry { - candidate: dummy_candidate_receipt_bad_sig(dummy_hash(), None), + candidate: dummy_candidate_receipt_v2_bad_sig(dummy_hash(), None), session: 5, block_assignments: vec![( hash_a, diff --git a/polkadot/node/core/approval-voting/src/import.rs b/polkadot/node/core/approval-voting/src/import.rs index dd653d4d4d26..3658a59868d7 100644 --- a/polkadot/node/core/approval-voting/src/import.rs +++ b/polkadot/node/core/approval-voting/src/import.rs @@ -46,7 +46,7 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_util::{determine_new_blocks, runtime::RuntimeInfo}; use polkadot_primitives::{ node_features, - vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt}, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt,}, BlockNumber, CandidateHash, ConsensusLog, CoreIndex, GroupIndex, Hash, Header, SessionIndex, }; use sc_keystore::LocalKeystore; @@ -626,7 +626,7 @@ pub(crate) mod tests { use polkadot_node_subsystem_util::database::Database; use polkadot_primitives::{ node_features::FeatureIndex, ExecutorParams, Id as ParaId, IndexedVec, NodeFeatures, - SessionInfo, ValidatorId, ValidatorIndex, + SessionInfo, ValidatorId, ValidatorIndex, vstaging::MutateDescriptorV2, }; use polkadot_primitives_test_helpers::{dummy_candidate_receipt_v2, dummy_hash}; use schnellru::{ByLength, LruMap}; diff --git a/polkadot/node/core/approval-voting/src/tests.rs b/polkadot/node/core/approval-voting/src/tests.rs index 666bd521f24c..ab5582e88a7c 100644 --- a/polkadot/node/core/approval-voting/src/tests.rs +++ b/polkadot/node/core/approval-voting/src/tests.rs @@ -41,8 +41,9 @@ use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_node_subsystem_util::TimeoutExt; use polkadot_overseer::HeadSupportsParachains; use polkadot_primitives::{ - ApprovalVote, CandidateCommitments, CandidateEvent, CoreIndex, DisputeStatement, GroupIndex, - Header, Id as ParaId, IndexedVec, NodeFeatures, ValidDisputeStatementKind, ValidationCode, + vstaging::{CandidateEvent, MutateDescriptorV2}, + ApprovalVote, CandidateCommitments, CoreIndex, DisputeStatement, GroupIndex, Header, + Id as ParaId, IndexedVec, NodeFeatures, ValidDisputeStatementKind, ValidationCode, ValidatorSignature, }; use std::{cmp::max, time::Duration}; @@ -1332,8 +1333,8 @@ fn subsystem_rejects_approval_before_assignment() { let candidate_hash = { let mut candidate_receipt = dummy_candidate_receipt_v2_bad_sig(block_hash, Some(Default::default())); - candidate_receipt.descriptor.para_id = ParaId::from(0_u32); - candidate_receipt.descriptor.relay_parent = block_hash; + candidate_receipt.descriptor.set_para_id(ParaId::from(0_u32)); + candidate_receipt.descriptor.set_relay_parent(block_hash); candidate_receipt.hash() }; @@ -1398,13 +1399,13 @@ fn subsystem_accepts_duplicate_assignment() { let candidate_receipt1 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(1_u32); + receipt.descriptor.set_para_id(ParaId::from(1_u32)); receipt } .into(); let candidate_receipt2 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(2_u32); + receipt.descriptor.set_para_id(ParaId::from(2_u32)); receipt } .into(); @@ -1582,8 +1583,8 @@ fn subsystem_accepts_and_imports_approval_after_assignment() { let candidate_hash = { let mut candidate_receipt = dummy_candidate_receipt_v2_bad_sig(block_hash, Some(Default::default())); - candidate_receipt.descriptor.para_id = ParaId::from(0_u32); - candidate_receipt.descriptor.relay_parent = block_hash; + candidate_receipt.descriptor.set_para_id(ParaId::from(0_u32)); + candidate_receipt.descriptor.set_relay_parent(block_hash); candidate_receipt.hash() }; @@ -1653,8 +1654,8 @@ fn subsystem_second_approval_import_only_schedules_wakeups() { let candidate_hash = { let mut candidate_receipt = dummy_candidate_receipt_v2_bad_sig(block_hash, Some(Default::default())); - candidate_receipt.descriptor.para_id = ParaId::from(0_u32); - candidate_receipt.descriptor.relay_parent = block_hash; + candidate_receipt.descriptor.set_para_id(ParaId::from(0_u32)); + candidate_receipt.descriptor.set_relay_parent(block_hash); candidate_receipt.hash() }; @@ -2412,12 +2413,12 @@ fn subsystem_import_checked_approval_sets_one_block_bit_at_a_time() { let candidate_receipt1 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(1_u32); + receipt.descriptor.set_para_id(ParaId::from(1_u32)); receipt }; let candidate_receipt2 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(2_u32); + receipt.descriptor.set_para_id(ParaId::from(2_u32)); receipt }; let candidate_hash1 = candidate_receipt1.hash(); @@ -2576,17 +2577,17 @@ fn inclusion_events_can_be_unordered_by_core_index() { let candidate_receipt0 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(0_u32); + receipt.descriptor.set_para_id(ParaId::from(0_u32)); receipt }; let candidate_receipt1 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(1_u32); + receipt.descriptor.set_para_id(ParaId::from(1_u32)); receipt }; let candidate_receipt2 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(2_u32); + receipt.descriptor.set_para_id(ParaId::from(2_u32)); receipt }; let candidate_index0 = 0; @@ -2720,7 +2721,7 @@ fn approved_ancestor_test( .enumerate() .map(|(i, hash)| { let mut candidate_receipt = dummy_candidate_receipt_v2(*hash); - candidate_receipt.descriptor.para_id = i.into(); + candidate_receipt.descriptor.set_para_id(i.into()); candidate_receipt }) .collect(); @@ -3022,12 +3023,12 @@ fn subsystem_doesnt_distribute_duplicate_compact_assignments() { let candidate_receipt1 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(1_u32); + receipt.descriptor.set_para_id(ParaId::from(1_u32)); receipt }; let candidate_receipt2 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(2_u32); + receipt.descriptor.set_para_id(ParaId::from(2_u32)); receipt }; let candidate_index1 = 0; @@ -3975,7 +3976,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_count() { let candidate_receipt1 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(1_u32); + receipt.descriptor.set_para_id(ParaId::from(1_u32)); receipt.commitments_hash = candidate_commitments.hash(); receipt }; @@ -3984,7 +3985,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_count() { let candidate_receipt2 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(2_u32); + receipt.descriptor.set_para_id(ParaId::from(2_u32)); receipt.commitments_hash = candidate_commitments.hash(); receipt }; @@ -4276,7 +4277,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { let candidate_receipt1 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(1_u32); + receipt.descriptor.set_para_id(ParaId::from(1_u32)); receipt.commitments_hash = candidate_commitments.hash(); receipt }; @@ -4285,7 +4286,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { let candidate_receipt2 = { let mut receipt = dummy_candidate_receipt_v2(block_hash); - receipt.descriptor.para_id = ParaId::from(2_u32); + receipt.descriptor.set_para_id(ParaId::from(2_u32)); receipt.commitments_hash = candidate_commitments.hash(); receipt }; diff --git a/polkadot/node/core/backing/Cargo.toml b/polkadot/node/core/backing/Cargo.toml index 1b52afc309bc..09094bfd9c68 100644 --- a/polkadot/node/core/backing/Cargo.toml +++ b/polkadot/node/core/backing/Cargo.toml @@ -35,3 +35,5 @@ assert_matches = { workspace = true } rstest = { workspace = true } polkadot-node-subsystem-test-helpers = { workspace = true } polkadot-primitives-test-helpers = { workspace = true } +polkadot-primitives = { workspace = true, features = ["test"] } + diff --git a/polkadot/node/core/backing/src/tests/mod.rs b/polkadot/node/core/backing/src/tests/mod.rs index 78f9859ea1ca..4fe1f02708cd 100644 --- a/polkadot/node/core/backing/src/tests/mod.rs +++ b/polkadot/node/core/backing/src/tests/mod.rs @@ -33,8 +33,7 @@ use polkadot_primitives::{ PvfExecKind, ScheduledCore, SessionIndex, LEGACY_MIN_BACKING_VOTES, }; use polkadot_primitives_test_helpers::{ - dummy_candidate_receipt_bad_sig, dummy_collator, dummy_collator_signature, - dummy_committed_candidate_receipt, dummy_hash, validator_pubkeys, + dummy_candidate_receipt_bad_sig, dummy_collator, dummy_collator_signature, dummy_committed_candidate_receipt, dummy_committed_candidate_receipt_v2, dummy_hash, validator_pubkeys }; use polkadot_statement_table::v2::Misbehavior; use rstest::rstest; @@ -236,7 +235,8 @@ impl TestCandidateBuilder { para_head: self.head_data.hash(), validation_code_hash: ValidationCode(self.validation_code).hash(), persisted_validation_data_hash: self.persisted_validation_data_hash, - }, + } + .into(), commitments: CandidateCommitments { head_data: self.head_data, upward_messages: Default::default(), @@ -650,7 +650,7 @@ fn backing_works(#[case] elastic_scaling_mvp: bool) { }, ) if validation_data == pvd_ab && validation_code == validation_code_ab && - *pov == pov_ab && &candidate_receipt.descriptor == candidate_a.descriptor() && + *pov == pov_ab && &candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::Backing && candidate_receipt.commitments_hash == candidate_a_commitments_hash => { @@ -1121,7 +1121,7 @@ fn extract_core_index_from_statement_works() { .flatten() .expect("should be signed"); - candidate.descriptor.para_id = test_state.chain_ids[1]; + candidate.descriptor.set_para_id(test_state.chain_ids[1]); let signed_statement_3 = SignedFullStatementWithPVD::sign( &test_state.keystore, @@ -1286,7 +1286,7 @@ fn backing_works_while_validation_ongoing() { }, ) if validation_data == pvd_abc && validation_code == validation_code_abc && - *pov == pov_abc && &candidate_receipt.descriptor == candidate_a.descriptor() && + *pov == pov_abc && &candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::Backing && candidate_a_commitments_hash == candidate_receipt.commitments_hash => { @@ -1453,7 +1453,7 @@ fn backing_misbehavior_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate_a.descriptor() && + *pov == pov_a && &candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::Backing && candidate_a_commitments_hash == candidate_receipt.commitments_hash => { @@ -1620,7 +1620,7 @@ fn backing_dont_second_invalid() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_block_a && &candidate_receipt.descriptor == candidate_a.descriptor() && + *pov == pov_block_a && &candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::Backing && candidate_a.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1660,7 +1660,7 @@ fn backing_dont_second_invalid() { }, ) if validation_data == pvd_b && validation_code == validation_code_b && - *pov == pov_block_b && &candidate_receipt.descriptor == candidate_b.descriptor() && + *pov == pov_block_b && &candidate_receipt.descriptor == candidate_b.descriptor && exec_kind == PvfExecKind::Backing && candidate_b.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1787,7 +1787,7 @@ fn backing_second_after_first_fails_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor() && + *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1931,7 +1931,7 @@ fn backing_works_after_failed_validation() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor() && + *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1999,7 +1999,7 @@ fn candidate_backing_reorders_votes() { }; let attested = TableAttestedCandidate { - candidate: dummy_committed_candidate_receipt(dummy_hash()), + candidate: dummy_committed_candidate_receipt_v2(dummy_hash()), validity_votes: vec![ (ValidatorIndex(5), fake_attestation(5)), (ValidatorIndex(3), fake_attestation(3)), @@ -2210,7 +2210,7 @@ fn retry_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && + *pov == pov_a && candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate.commitments.hash() == candidate_receipt.commitments_hash ); @@ -2752,7 +2752,7 @@ fn validator_ignores_statements_from_disabled_validators() { } ) if validation_data == pvd && validation_code == expected_validation_code && - *pov == expected_pov && &candidate_receipt.descriptor == candidate.descriptor && + *pov == expected_pov && candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate_commitments_hash == candidate_receipt.commitments_hash => { diff --git a/polkadot/node/core/backing/src/tests/prospective_parachains.rs b/polkadot/node/core/backing/src/tests/prospective_parachains.rs index 55a96fee6e4d..aaefdf6e52e0 100644 --- a/polkadot/node/core/backing/src/tests/prospective_parachains.rs +++ b/polkadot/node/core/backing/src/tests/prospective_parachains.rs @@ -20,7 +20,7 @@ use polkadot_node_subsystem::{ messages::{ChainApiMessage, HypotheticalMembership}, ActivatedLeaf, TimeoutExt, }; -use polkadot_primitives::{AsyncBackingParams, BlockNumber, Header, OccupiedCore}; +use polkadot_primitives::{vstaging::OccupiedCore, AsyncBackingParams, BlockNumber, Header}; use super::*; @@ -890,7 +890,7 @@ fn prospective_parachains_reject_candidate() { AllMessages::CollatorProtocol(CollatorProtocolMessage::Invalid( relay_parent, candidate_receipt, - )) if candidate_receipt.descriptor() == candidate.descriptor() && + )) if candidate_receipt.descriptor == candidate.descriptor && candidate_receipt.commitments_hash == candidate.commitments.hash() && relay_parent == leaf_a_parent ); @@ -1179,7 +1179,7 @@ fn backing_works() { assert_validate_seconded_candidate( &mut virtual_overseer, - candidate_a.descriptor().relay_parent, + candidate_a.descriptor.relay_parent(), &candidate_a, &pov, &pvd, @@ -1544,7 +1544,7 @@ fn seconding_sanity_check_occupy_same_depth() { assert_validate_seconded_candidate( &mut virtual_overseer, - candidate.descriptor().relay_parent, + candidate.descriptor.relay_parent(), &candidate, &pov, &pvd, @@ -1599,13 +1599,13 @@ fn seconding_sanity_check_occupy_same_depth() { parent_hash, _signed_statement, ) - ) if parent_hash == candidate.descriptor().relay_parent => {} + ) if parent_hash == candidate.descriptor.relay_parent() => {} ); assert_matches!( virtual_overseer.recv().await, AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => { - assert_eq!(candidate.descriptor().relay_parent, hash); + assert_eq!(candidate.descriptor.relay_parent(), hash); assert_matches!(statement.payload(), Statement::Seconded(_)); } ); diff --git a/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs b/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs index 80cef6f3a247..c311511abdf0 100644 --- a/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs +++ b/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs @@ -18,7 +18,7 @@ use super::*; use assert_matches::assert_matches; use polkadot_node_subsystem_util::inclusion_emulator::InboundHrmpLimitations; use polkadot_primitives::{ - BlockNumber, CandidateCommitments, CandidateDescriptor, HeadData, Id as ParaId, + BlockNumber, CandidateCommitments,vstaging::MutateDescriptorV2, vstaging::CandidateDescriptorV2 as CandidateDescriptor, HeadData, Id as ParaId, }; use polkadot_primitives_test_helpers as test_helpers; use rand::{seq::SliceRandom, thread_rng}; diff --git a/polkadot/node/core/prospective-parachains/src/tests.rs b/polkadot/node/core/prospective-parachains/src/tests.rs index 8584f09187d3..3f1eaa4e41ed 100644 --- a/polkadot/node/core/prospective-parachains/src/tests.rs +++ b/polkadot/node/core/prospective-parachains/src/tests.rs @@ -439,7 +439,7 @@ async fn introduce_seconded_candidate( pvd: PersistedValidationData, ) { let req = IntroduceSecondedCandidateRequest { - candidate_para: candidate.descriptor().para_id, + candidate_para: candidate.descriptor.para_id(), candidate_receipt: candidate, persisted_validation_data: pvd, }; @@ -458,7 +458,7 @@ async fn introduce_seconded_candidate_failed( pvd: PersistedValidationData, ) { let req = IntroduceSecondedCandidateRequest { - candidate_para: candidate.descriptor().para_id, + candidate_para: candidate.descriptor.para_id(), candidate_receipt: candidate, persisted_validation_data: pvd, }; @@ -479,7 +479,7 @@ async fn back_candidate( virtual_overseer .send(overseer::FromOrchestra::Communication { msg: ProspectiveParachainsMessage::CandidateBacked( - candidate.descriptor.para_id, + candidate.descriptor.para_id(), candidate_hash, ), }) diff --git a/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs b/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs index 107b96947625..8c0d478b67df 100644 --- a/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs +++ b/polkadot/node/core/provisioner/src/disputes/prioritized_selection/tests.rs @@ -427,8 +427,7 @@ impl TestDisputes { let onchain_votes_count = self.validators_count * 80 / 100; let session_idx = 0; let lf = leaf(); - let dummy_receipt = - polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); + let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt_v2(lf.hash); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -446,8 +445,7 @@ impl TestDisputes { let onchain_votes_count = self.validators_count * 40 / 100; let session_idx = 1; let lf = leaf(); - let dummy_receipt = - polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); + let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt_v2(lf.hash); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -464,8 +462,7 @@ impl TestDisputes { let local_votes_count = self.validators_count * 90 / 100; let session_idx = 2; let lf = leaf(); - let dummy_receipt = - polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); + let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt_v2(lf.hash); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Confirmed); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -481,8 +478,7 @@ impl TestDisputes { let onchain_votes_count = self.validators_count * 75 / 100; let session_idx = 3; let lf = leaf(); - let dummy_receipt = - polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); + let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt_v2(lf.hash); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::ConcludedFor(0)); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -498,8 +494,7 @@ impl TestDisputes { let local_votes_count = self.validators_count * 90 / 100; let session_idx = 4; let lf = leaf(); - let dummy_receipt = - polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); + let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt_v2(lf.hash); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::ConcludedFor(0)); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -515,8 +510,7 @@ impl TestDisputes { let onchain_votes_count = self.validators_count * 10 / 100; let session_idx = 5; let lf = leaf(); - let dummy_receipt = - polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); + let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt_v2(lf.hash); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); @@ -533,8 +527,7 @@ impl TestDisputes { let local_votes_count = self.validators_count * 10 / 100; let session_idx = 6; let lf = leaf(); - let dummy_receipt = - polkadot_primitives_test_helpers::dummy_candidate_receipt(lf.hash).into(); + let dummy_receipt = polkadot_primitives_test_helpers::dummy_candidate_receipt_v2(lf.hash); for _ in 0..dispute_count { let d = (session_idx, CandidateHash(Hash::random()), DisputeStatus::Active); self.add_offchain_dispute(d, local_votes_count, dummy_receipt.clone()); diff --git a/polkadot/node/core/provisioner/src/tests.rs b/polkadot/node/core/provisioner/src/tests.rs index 5ccc81985dea..a09b243f3ab1 100644 --- a/polkadot/node/core/provisioner/src/tests.rs +++ b/polkadot/node/core/provisioner/src/tests.rs @@ -20,12 +20,12 @@ use polkadot_primitives::{ vstaging::{MutateDescriptorV2, OccupiedCore}, ScheduledCore, }; -use polkadot_primitives_test_helpers::{dummy_candidate_descriptor, dummy_hash}; +use polkadot_primitives_test_helpers::{dummy_candidate_descriptor_v2, dummy_hash}; const MOCK_GROUP_SIZE: usize = 5; pub fn occupied_core(para_id: u32) -> CoreState { - let mut candidate_descriptor = dummy_candidate_descriptor(dummy_hash()); + let mut candidate_descriptor = dummy_candidate_descriptor_v2(dummy_hash()); candidate_descriptor.set_para_id(para_id.into()); CoreState::Occupied(OccupiedCore { @@ -257,9 +257,10 @@ mod select_candidates { use polkadot_node_subsystem_test_helpers::TestSubsystemSender; use polkadot_node_subsystem_util::runtime::ProspectiveParachainsMode; use polkadot_primitives::{ - BlockNumber, CandidateCommitments, CommittedCandidateReceipt, PersistedValidationData, + vstaging::{CommittedCandidateReceiptV2 as CommittedCandidateReceipt, MutateDescriptorV2}, + BlockNumber, CandidateCommitments, PersistedValidationData, }; - use polkadot_primitives_test_helpers::{dummy_candidate_descriptor, dummy_hash}; + use polkadot_primitives_test_helpers::{dummy_candidate_descriptor_v2, dummy_hash}; use rstest::rstest; use std::ops::Not; use CoreState::{Free, Scheduled}; @@ -269,8 +270,8 @@ mod select_candidates { fn dummy_candidate_template() -> CandidateReceipt { let empty_hash = PersistedValidationData::::default().hash(); - let mut descriptor_template = dummy_candidate_descriptor(dummy_hash()); - descriptor_template.persisted_validation_data_hash = empty_hash; + let mut descriptor_template = dummy_candidate_descriptor_v2(dummy_hash()); + descriptor_template.set_persisted_validation_data_hash(empty_hash); CandidateReceipt { descriptor: descriptor_template, commitments_hash: CandidateCommitments::default().hash(), @@ -810,7 +811,7 @@ mod select_candidates { let committed_receipts: Vec<_> = (0..=mock_cores.len()) .map(|i| { - let mut descriptor = dummy_candidate_descriptor(dummy_hash()); + let mut descriptor = dummy_candidate_descriptor_v2(dummy_hash()); descriptor.set_para_id(i.into()); descriptor.set_persisted_validation_data_hash(empty_hash); CommittedCandidateReceipt { @@ -920,14 +921,14 @@ mod select_candidates { let committed_receipts: Vec<_> = (0..mock_cores.len()) .map(|i| { - let mut descriptor = dummy_candidate_descriptor(dummy_hash()); + let mut descriptor = dummy_candidate_descriptor_v2(dummy_hash()); descriptor.set_para_id(if let Scheduled(scheduled_core) = &mock_cores[i] { scheduled_core.para_id } else { panic!("`mock_cores` is not initialized with `Scheduled`?") }); - descriptor.persisted_validation_data_hash = empty_hash; - descriptor.pov_hash = Hash::from_low_u64_be(i as u64); + descriptor.set_persisted_validation_data_hash(empty_hash); + descriptor.set_pov_hash(Hash::from_low_u64_be(i as u64)); CommittedCandidateReceipt { descriptor, commitments: CandidateCommitments { diff --git a/polkadot/node/network/availability-distribution/src/tests/mock.rs b/polkadot/node/network/availability-distribution/src/tests/mock.rs index b41c493a1072..b2c240ca53ad 100644 --- a/polkadot/node/network/availability-distribution/src/tests/mock.rs +++ b/polkadot/node/network/availability-distribution/src/tests/mock.rs @@ -23,8 +23,8 @@ use sp_keyring::Sr25519Keyring; use polkadot_erasure_coding::{branches, obtain_chunks_v1 as obtain_chunks}; use polkadot_node_primitives::{AvailableData, BlockData, ErasureChunk, PoV, Proof}; use polkadot_primitives::{ - CandidateCommitments, CandidateDescriptor, CandidateHash, ChunkIndex, - CommittedCandidateReceipt, GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec, OccupiedCore, + CandidateCommitments, vstaging::CandidateDescriptorV2 as CandidateDescriptor, CandidateHash, ChunkIndex, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec, vstaging::OccupiedCore, PersistedValidationData, SessionInfo, ValidatorIndex, }; use polkadot_primitives_test_helpers::{ diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs index e6cdb6460d90..75dd1bb45098 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs @@ -342,7 +342,7 @@ async fn assert_candidate_backing_second( incoming_pov, )) => { assert_eq!(expected_relay_parent, relay_parent); - assert_eq!(expected_para_id, candidate_receipt.descriptor.para_id); + assert_eq!(expected_para_id, candidate_receipt.descriptor.para_id()); assert_eq!(*expected_pov, incoming_pov); assert_eq!(pvd, received_pvd); candidate_receipt @@ -592,7 +592,7 @@ fn act_on_advertisement_v2() { response_channel .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) .encode(), ProtocolName::from(""), ))) @@ -794,7 +794,7 @@ fn fetch_one_collation_at_a_time() { candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); response_channel .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) .encode(), ProtocolName::from(""), ))) @@ -918,7 +918,7 @@ fn fetches_next_collation() { // First request finishes now: response_channel_non_exclusive .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) .encode(), ProtocolName::from(""), ))) @@ -926,7 +926,7 @@ fn fetches_next_collation() { response_channel .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) .encode(), ProtocolName::from(""), ))) @@ -1056,7 +1056,7 @@ fn fetch_next_collation_on_invalid_collation() { candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); response_channel .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) .encode(), ProtocolName::from(""), ))) diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs index 14a8c08cf83d..1cc4c3e1cb73 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs @@ -20,8 +20,8 @@ use super::*; use polkadot_node_subsystem::messages::ChainApiMessage; use polkadot_primitives::{ - vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, AsyncBackingParams, BlockNumber, CandidateCommitments, - Header, SigningContext, ValidatorId, + vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, AsyncBackingParams, + BlockNumber, CandidateCommitments, Header, SigningContext, ValidatorId, }; use rstest::rstest; diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index f12f007e1677..ed38683663d7 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -36,7 +36,7 @@ use frame_support::assert_noop; use polkadot_primitives::{ BlockNumber, CandidateCommitments, CollatorId, CollatorSignature, CompactStatement as Statement, Hash, SignedAvailabilityBitfield, SignedStatement, - ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, + ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, vstaging::MutateDescriptorV2, }; use polkadot_primitives_test_helpers::dummy_validation_code; use sc_keystore::LocalKeystore; diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index b411e71d532c..796574c0cd1d 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -62,7 +62,9 @@ mod enter { use frame_support::assert_ok; use frame_system::limits; use polkadot_primitives::{ - vstaging::{CandidateDescriptorV2, CommittedCandidateReceiptV2, InternalVersion}, + vstaging::{ + CandidateDescriptorV2, CommittedCandidateReceiptV2, InternalVersion, MutateDescriptorV2, + }, AvailabilityBitfield, CandidateDescriptor, UncheckedSigned, }; use sp_runtime::Perbill; From caff5435eb294b5c017ea17e06b4351a6b9c4fee Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 13 Sep 2024 15:42:34 +0300 Subject: [PATCH 100/130] feedback Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 32 +++++++-------- polkadot/runtime/parachains/src/builder.rs | 2 +- .../parachains/src/paras_inherent/mod.rs | 13 ++----- .../parachains/src/paras_inherent/tests.rs | 12 +++--- polkadot/runtime/parachains/src/shared.rs | 6 +-- .../parachains/src/shared/migration.rs | 39 +++++++++++-------- .../runtime/parachains/src/shared/tests.rs | 24 ++++++------ 7 files changed, 63 insertions(+), 65 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 6bdbfc632705..ebd93ce77091 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -460,7 +460,7 @@ impl CommittedCandidateReceiptV2 { /// between `ParaId` and the cores assigned per depth. pub fn check_core_index( &self, - cores_per_para: &BTreeMap>>, + cores_per_para: &BTreeMap>>, ) -> Result<(), CandidateReceiptError> { match self.descriptor.version() { // Don't check v1 descriptors. @@ -476,7 +476,7 @@ impl CommittedCandidateReceiptV2 { let (offset, core_selected) = if let Some((_core_selector, cq_offset)) = self.commitments.selected_core() { - (cq_offset.0 as usize, true) + (cq_offset.0, true) } else { // If no core has been selected then we use offset 0 (top of claim queue) (0, false) @@ -486,7 +486,7 @@ impl CommittedCandidateReceiptV2 { let assigned_cores = cores_per_para .get(&self.descriptor.para_id()) .ok_or(CandidateReceiptError::NoAssignment)? - .get(offset) + .get(&offset) .ok_or(CandidateReceiptError::NoAssignment)? .into_iter() .collect::>(); @@ -752,20 +752,18 @@ impl From> for super::v8::CoreState { /// Returns a mapping between the para id and the core indices assigned at different /// depths in the claim queue. -pub fn remap_claim_queue( +pub fn transpose_claim_queue( claim_queue: BTreeMap>, -) -> BTreeMap>> { +) -> BTreeMap>> { let mut per_para_claim_queue = BTreeMap::new(); for (core, paras) in claim_queue { // Iterate paras assigned to this core at each depth. for (depth, para) in paras.into_iter().enumerate() { - let depths: &mut VecDeque> = + let depths: &mut BTreeMap> = per_para_claim_queue.entry(para).or_insert_with(|| Default::default()); - let initialize_count = (depth + 1).saturating_sub(depths.len()); - depths.extend((0..initialize_count).into_iter().map(|_| BTreeSet::new())); - depths[depth].insert(core); + depths.entry(depth as u8).or_default().insert(core); } } @@ -883,7 +881,7 @@ mod tests { vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); - assert_eq!(new_ccr.check_core_index(&remap_claim_queue(cq)), Ok(())); + assert_eq!(new_ccr.check_core_index(&transpose_claim_queue(cq)), Ok(())); } #[test] @@ -900,7 +898,7 @@ mod tests { // The check should not fail because no `SelectCore` signal was sent. // The message is optional. - assert!(new_ccr.check_core_index(&remap_claim_queue(cq)).is_ok()); + assert!(new_ccr.check_core_index(&transpose_claim_queue(cq)).is_ok()); // Garbage message. new_ccr.commitments.upward_messages.force_push(vec![0, 13, 200].encode()); @@ -919,7 +917,7 @@ mod tests { ); assert_eq!( - new_ccr.check_core_index(&remap_claim_queue(cq.clone())), + new_ccr.check_core_index(&transpose_claim_queue(cq.clone())), Err(CandidateReceiptError::NoCoreSelected) ); @@ -938,7 +936,7 @@ mod tests { .force_push(UMPSignal::SelectCore(CoreSelector(1), ClaimQueueOffset(1)).encode()); // Duplicate doesn't override first signal. - assert_eq!(new_ccr.check_core_index(&remap_claim_queue(cq)), Ok(())); + assert_eq!(new_ccr.check_core_index(&transpose_claim_queue(cq)), Ok(())); } #[test] @@ -982,7 +980,7 @@ mod tests { vec![new_ccr.descriptor.para_id(), new_ccr.descriptor.para_id()].into(), ); - assert_eq!(new_ccr.check_core_index(&remap_claim_queue(cq)), Ok(())); + assert_eq!(new_ccr.check_core_index(&transpose_claim_queue(cq)), Ok(())); assert_eq!(new_ccr.hash(), v2_ccr.hash()); } @@ -1014,7 +1012,7 @@ mod tests { cq.insert(CoreIndex(0), vec![v1_ccr.descriptor.para_id()].into()); cq.insert(CoreIndex(1), vec![v1_ccr.descriptor.para_id()].into()); - assert!(v1_ccr.check_core_index(&remap_claim_queue(cq)).is_ok()); + assert!(v1_ccr.check_core_index(&transpose_claim_queue(cq)).is_ok()); assert_eq!( v1_ccr.commitments.committed_core_index(&vec![&CoreIndex(10), &CoreIndex(5)]), @@ -1039,7 +1037,7 @@ mod tests { // Since collator sig and id are zeroed, it means that the descriptor uses format // version 2. Should still pass checks without core selector. - assert!(new_ccr.check_core_index(&remap_claim_queue(cq)).is_ok()); + assert!(new_ccr.check_core_index(&transpose_claim_queue(cq)).is_ok()); let mut cq = BTreeMap::new(); cq.insert(CoreIndex(0), vec![new_ccr.descriptor.para_id()].into()); @@ -1047,7 +1045,7 @@ mod tests { // Should fail because 2 cores are assigned, assert_eq!( - new_ccr.check_core_index(&remap_claim_queue(cq)), + new_ccr.check_core_index(&transpose_claim_queue(cq)), Err(CandidateReceiptError::NoCoreSelected) ); diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index b12637da2e42..1654590d109e 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -689,7 +689,7 @@ impl BenchBuilder { para_id, relay_parent, core_idx, - 2, + self.target_session, persisted_validation_data_hash, pov_hash, Default::default(), diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index f571dba314a5..a581d31d8a85 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -1525,15 +1525,8 @@ fn map_candidates_to_cores::set_node_feature( RuntimeOrigin::root(), FeatureIndex::ElasticScalingMVP as u8, - true, + injected_core, ) .unwrap(); @@ -1707,7 +1709,7 @@ mod enter { fill_claimqueue: true, elastic_paras: [(2, 3)].into_iter().collect(), unavailable_cores: unavailable_cores.clone(), - v2_descriptor: false, + v2_descriptor: true, candidate_modifier: None, }); diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index 4e982313791c..f582bf0d90b5 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -26,7 +26,7 @@ use alloc::{ use frame_support::{pallet_prelude::*, traits::DisabledValidators}; use frame_system::pallet_prelude::BlockNumberFor; use polkadot_primitives::{ - vstaging::remap_claim_queue, CoreIndex, Id, SessionIndex, ValidatorId, ValidatorIndex, + vstaging::transpose_claim_queue, CoreIndex, Id, SessionIndex, ValidatorId, ValidatorIndex, }; use sp_runtime::traits::AtLeast32BitUnsigned; @@ -56,7 +56,7 @@ pub struct RelayParentInfo { pub state_root: Hash, // Claim queue snapshot, optimized for accessing the assignments by `ParaId`. // For each para we store the cores assigned per depth. - pub claim_queue: BTreeMap>>, + pub claim_queue: BTreeMap>>, } /// Keeps tracks of information about all viable relay parents. @@ -88,7 +88,7 @@ impl number: BlockNumber, max_ancestry_len: u32, ) { - let claim_queue = remap_claim_queue(claim_queue); + let claim_queue = transpose_claim_queue(claim_queue); // + 1 for the most recent block, which is always allowed. let buffer_size_limit = max_ancestry_len as usize + 1; diff --git a/polkadot/runtime/parachains/src/shared/migration.rs b/polkadot/runtime/parachains/src/shared/migration.rs index 0126f817e0da..f2af28c189cc 100644 --- a/polkadot/runtime/parachains/src/shared/migration.rs +++ b/polkadot/runtime/parachains/src/shared/migration.rs @@ -24,6 +24,16 @@ pub mod v0 { use super::*; use alloc::collections::vec_deque::VecDeque; + use frame_support::storage_alias; + + /// All allowed relay-parents storage at version 0. + #[storage_alias] + pub(crate) type AllowedRelayParents = StorageValue< + Pallet, + super::v0::AllowedRelayParentsTracker<::Hash, BlockNumberFor>, + ValueQuery, + >; + #[derive(Encode, Decode, Default, TypeInfo)] pub struct AllowedRelayParentsTracker { // The past relay parents, paired with state roots, that are viable to build upon. @@ -71,23 +81,13 @@ mod v1 { traits::{GetStorageVersion, StorageVersion}, }; - use frame_support::storage_alias; - - /// All allowed relay-parents storage at version 0. - #[storage_alias] - pub(crate) type AllowedRelayParents = StorageValue< - Pallet, - super::v0::AllowedRelayParentsTracker<::Hash, BlockNumberFor>, - ValueQuery, - >; - pub struct VersionUncheckedMigrateToV1(core::marker::PhantomData); impl UncheckedOnRuntimeUpgrade for VersionUncheckedMigrateToV1 { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { - log::trace!(target: LOG_TARGET, "Running pre_upgrade() for inclusion MigrateToV1"); - let bytes = u32::to_ne_bytes(AllowedRelayParents::::get().buffer.len() as u32); + log::trace!(target: LOG_TARGET, "Running pre_upgrade() for shared MigrateToV1"); + let bytes = u32::to_ne_bytes(v0::AllowedRelayParents::::get().buffer.len() as u32); Ok(bytes.to_vec()) } @@ -96,7 +96,7 @@ mod v1 { let mut weight: Weight = Weight::zero(); // Read old storage. - let old_rp_tracker = AllowedRelayParents::::take(); + let old_rp_tracker = v0::AllowedRelayParents::::take(); super::AllowedRelayParents::::set(old_rp_tracker.into()); @@ -107,14 +107,17 @@ mod v1 { #[cfg(feature = "try-runtime")] fn post_upgrade(state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { - log::trace!(target: LOG_TARGET, "Running post_upgrade() for inclusion MigrateToV1"); + log::trace!(target: LOG_TARGET, "Running post_upgrade() for shared MigrateToV1"); ensure!( Pallet::::on_chain_storage_version() >= StorageVersion::new(1), "Storage version should be >= 1 after the migration" ); - let relay_parent_count = - u32::decode(&mut &state[..]).expect("Was properly encoded") as usize; + let relay_parent_count = u32::from_ne_bytes( + state + .try_into() + .expect("u32::from_ne_bytes(to_ne_bytes(u32)) always works; qed"), + ); let rp_tracker = AllowedRelayParents::::get(); @@ -155,12 +158,14 @@ mod tests { .collect::>(), }; - v1::AllowedRelayParents::::put(rp_tracker); + v0::AllowedRelayParents::::put(rp_tracker); as UncheckedOnRuntimeUpgrade>::on_runtime_upgrade(); let rp_tracker = AllowedRelayParents::::get(); + assert_eq!(rp_tracker.buffer.len(), 10); + for idx in 0..10u64 { let relay_parent = Hash::from_low_u64_ne(idx); let state_root = Hash::from_low_u64_ne(2 * idx); diff --git a/polkadot/runtime/parachains/src/shared/tests.rs b/polkadot/runtime/parachains/src/shared/tests.rs index fb04db5d79bb..6da84e254f05 100644 --- a/polkadot/runtime/parachains/src/shared/tests.rs +++ b/polkadot/runtime/parachains/src/shared/tests.rs @@ -65,38 +65,38 @@ fn tracker_claim_queue_remap() { let (info, _block_num) = tracker.acquire_info(Hash::zero(), None).unwrap(); assert_eq!( - info.claim_queue.get(&Id::from(0)).unwrap()[0], + info.claim_queue.get(&Id::from(0)).unwrap()[&0], vec![CoreIndex(0), CoreIndex(1)].into_iter().collect::>() ); assert_eq!( - info.claim_queue.get(&Id::from(1)).unwrap()[0], + info.claim_queue.get(&Id::from(1)).unwrap()[&0], vec![CoreIndex(2)].into_iter().collect::>() ); - assert_eq!(info.claim_queue.get(&Id::from(2)).unwrap()[0], BTreeSet::new()); - assert_eq!(info.claim_queue.get(&Id::from(100)).unwrap()[0], BTreeSet::new()); + assert_eq!(info.claim_queue.get(&Id::from(2)).unwrap().get(&0), None); + assert_eq!(info.claim_queue.get(&Id::from(100)).unwrap().get(&0), None); assert_eq!( - info.claim_queue.get(&Id::from(0)).unwrap()[1], + info.claim_queue.get(&Id::from(0)).unwrap()[&1], vec![CoreIndex(1)].into_iter().collect::>() ); assert_eq!( - info.claim_queue.get(&Id::from(1)).unwrap()[1], + info.claim_queue.get(&Id::from(1)).unwrap()[&1], vec![CoreIndex(0)].into_iter().collect::>() ); assert_eq!( - info.claim_queue.get(&Id::from(2)).unwrap()[1], + info.claim_queue.get(&Id::from(2)).unwrap()[&1], vec![CoreIndex(2)].into_iter().collect::>() ); - assert_eq!(info.claim_queue.get(&Id::from(100)).unwrap()[1], BTreeSet::new()); + assert_eq!(info.claim_queue.get(&Id::from(100)).unwrap().get(&1), None); - assert_eq!(info.claim_queue.get(&Id::from(0)).unwrap().get(2), None); - assert_eq!(info.claim_queue.get(&Id::from(1)).unwrap().get(2), None); + assert_eq!(info.claim_queue.get(&Id::from(0)).unwrap().get(&2), None); + assert_eq!(info.claim_queue.get(&Id::from(1)).unwrap().get(&2), None); assert_eq!( - info.claim_queue.get(&Id::from(2)).unwrap()[2], + info.claim_queue.get(&Id::from(2)).unwrap()[&2], vec![CoreIndex(0)].into_iter().collect::>() ); assert_eq!( - info.claim_queue.get(&Id::from(100)).unwrap()[2], + info.claim_queue.get(&Id::from(100)).unwrap()[&2], vec![CoreIndex(1), CoreIndex(2)].into_iter().collect::>() ); } From 218f53036819b53a9032ca3d79c55945dcdea617 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 13 Sep 2024 15:52:24 +0300 Subject: [PATCH 101/130] refactor Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/paras_inherent/tests.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index d2cfea19ab6e..1078d6848c0c 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -231,8 +231,7 @@ mod enter { #[case((true, false))] #[case((true, true))] #[case((false, true))] - fn include_backed_candidates_elastic_scaling(#[case] params: (bool, bool)) { - let (v2_descriptor, injected_core) = params; + fn include_backed_candidates_elastic_scaling(#[case] v2_descriptor: bool, injected_core: bool) { // ParaId 0 has one pending candidate on core 0. // ParaId 1 has one pending candidate on core 1. // ParaId 2 has three pending candidates on cores 2, 3 and 4. From 216937ae90c15ffdcaaabbf0619f45bcb5985719 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Sat, 14 Sep 2024 00:03:05 +0300 Subject: [PATCH 102/130] fix try-runtime Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/shared/migration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/shared/migration.rs b/polkadot/runtime/parachains/src/shared/migration.rs index f2af28c189cc..a8b9612bb1c9 100644 --- a/polkadot/runtime/parachains/src/shared/migration.rs +++ b/polkadot/runtime/parachains/src/shared/migration.rs @@ -122,7 +122,7 @@ mod v1 { let rp_tracker = AllowedRelayParents::::get(); ensure!( - relay_parent_count == rp_tracker.buffer.len(), + relay_parent_count as usize == rp_tracker.buffer.len(), "Number of allowed relay parents should be the same as the one before the upgrade." ); From e169d0dfe108dfd8d6f225fcbbf42d9b04963b8b Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 16 Sep 2024 14:42:18 +0300 Subject: [PATCH 103/130] Finally all tests compile Signed-off-by: Andrei Sandu --- cumulus/client/consensus/common/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cumulus/client/consensus/common/src/tests.rs b/cumulus/client/consensus/common/src/tests.rs index 06f90330d474..ffd3367d14cd 100644 --- a/cumulus/client/consensus/common/src/tests.rs +++ b/cumulus/client/consensus/common/src/tests.rs @@ -20,7 +20,7 @@ use async_trait::async_trait; use codec::Encode; use cumulus_client_pov_recovery::RecoveryKind; use cumulus_primitives_core::{ - relay_chain::{BlockId, BlockNumber, CoreState}, + relay_chain::{vstaging::CoreState, BlockId, BlockNumber}, CumulusDigestItem, InboundDownwardMessage, InboundHrmpMessage, }; use cumulus_relay_chain_interface::{ From ceac8b29c86741e73f6d5fb2665d675127c3847f Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 16 Sep 2024 14:43:08 +0300 Subject: [PATCH 104/130] :facepalm: Signed-off-by: Andrei Sandu --- cumulus/client/network/src/tests.rs | 22 ++++---- polkadot/node/collation-generation/Cargo.toml | 2 + .../node/collation-generation/src/tests.rs | 21 ++++---- .../src/approval_db/v2/tests.rs | 8 +-- .../src/approval_db/v3/tests.rs | 12 ++--- .../node/core/approval-voting/src/import.rs | 6 +-- polkadot/node/core/av-store/src/tests.rs | 4 +- polkadot/node/core/backing/src/tests/mod.rs | 21 ++++---- .../src/tests/prospective_parachains.rs | 2 +- .../node/core/bitfield-signing/src/tests.rs | 4 +- .../core/candidate-validation/src/tests.rs | 11 ++-- .../node/core/dispute-coordinator/Cargo.toml | 1 + .../dispute-coordinator/src/scraping/tests.rs | 11 ++-- .../core/dispute-coordinator/src/tests.rs | 30 ++++++----- .../src/fragment_chain/tests.rs | 3 +- polkadot/node/core/runtime-api/src/tests.rs | 22 +++++--- .../src/requester/tests.rs | 2 +- .../src/tests/mock.rs | 10 ++-- .../availability-recovery/src/tests.rs | 34 +++++++----- .../src/validator_side/tests/mod.rs | 37 +++++++++---- .../tests/prospective_parachains.rs | 16 +++--- .../dispute-distribution/src/tests/mock.rs | 8 +-- .../dispute-distribution/src/tests/mod.rs | 4 +- .../network/statement-distribution/Cargo.toml | 1 + .../src/legacy_v1/tests.rs | 54 +++++++++---------- .../statement-distribution/src/v2/requests.rs | 10 ++-- .../node/service/src/parachains_db/upgrade.rs | 2 +- polkadot/primitives/src/vstaging/mod.rs | 9 ++++ .../runtime/parachains/src/inclusion/tests.rs | 4 +- 29 files changed, 213 insertions(+), 158 deletions(-) diff --git a/cumulus/client/network/src/tests.rs b/cumulus/client/network/src/tests.rs index cde73c4c5180..a86f3930c2ea 100644 --- a/cumulus/client/network/src/tests.rs +++ b/cumulus/client/network/src/tests.rs @@ -26,10 +26,11 @@ use futures::{executor::block_on, poll, task::Poll, FutureExt, Stream, StreamExt use parking_lot::Mutex; use polkadot_node_primitives::{SignedFullStatement, Statement}; use polkadot_primitives::{ + vstaging::{CommittedCandidateReceiptV2, CoreState}, BlockNumber, CandidateCommitments, CandidateDescriptor, CollatorPair, - CommittedCandidateReceipt, CoreState, Hash as PHash, HeadData, InboundDownwardMessage, - InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, SessionIndex, - SigningContext, ValidationCodeHash, ValidatorId, + CommittedCandidateReceipt, Hash as PHash, HeadData, InboundDownwardMessage, InboundHrmpMessage, + OccupiedCoreAssumption, PersistedValidationData, SessionIndex, SigningContext, + ValidationCodeHash, ValidatorId, }; use polkadot_test_client::{ Client as PClient, ClientBlockImportExt, DefaultTestClientBuilderExt, FullBackend as PBackend, @@ -162,7 +163,7 @@ impl RelayChainInterface for DummyRelayChainInterface { &self, _: PHash, _: ParaId, - ) -> RelayChainResult> { + ) -> RelayChainResult> { if self.data.lock().runtime_version >= RuntimeApiRequest::CANDIDATES_PENDING_AVAILABILITY_RUNTIME_REQUIREMENT { @@ -170,7 +171,7 @@ impl RelayChainInterface for DummyRelayChainInterface { } if self.data.lock().has_pending_availability { - Ok(Some(dummy_candidate())) + Ok(Some(dummy_candidate().into())) } else { Ok(None) } @@ -180,7 +181,7 @@ impl RelayChainInterface for DummyRelayChainInterface { &self, _: PHash, _: ParaId, - ) -> RelayChainResult> { + ) -> RelayChainResult> { if self.data.lock().runtime_version < RuntimeApiRequest::CANDIDATES_PENDING_AVAILABILITY_RUNTIME_REQUIREMENT { @@ -188,7 +189,7 @@ impl RelayChainInterface for DummyRelayChainInterface { } if self.data.lock().has_pending_availability { - Ok(vec![dummy_candidate()]) + Ok(vec![dummy_candidate().into()]) } else { Ok(vec![]) } @@ -392,7 +393,7 @@ async fn make_gossip_message_and_header( validation_code_hash: ValidationCodeHash::from(PHash::random()), }, }; - let statement = Statement::Seconded(candidate_receipt); + let statement = Statement::Seconded(candidate_receipt.into()); let signed = SignedFullStatement::sign( &keystore, statement, @@ -505,7 +506,7 @@ fn legacy_block_announce_data_handling() { let block_data = BlockAnnounceData::decode(&mut &data[..]).expect("Decoding works from legacy works"); - assert_eq!(receipt.descriptor.relay_parent, block_data.relay_parent); + assert_eq!(receipt.descriptor.relay_parent(), block_data.relay_parent); let data = block_data.encode(); LegacyBlockAnnounceData::decode(&mut &data[..]).expect("Decoding works"); @@ -580,7 +581,8 @@ async fn check_statement_seconded() { erasure_root: PHash::random(), signature: sp_core::sr25519::Signature::default().into(), validation_code_hash: ValidationCodeHash::from(PHash::random()), - }, + } + .into(), }, statement: signed_statement.convert_payload().into(), relay_parent, diff --git a/polkadot/node/collation-generation/Cargo.toml b/polkadot/node/collation-generation/Cargo.toml index 4b0a5f7248ab..df9768658443 100644 --- a/polkadot/node/collation-generation/Cargo.toml +++ b/polkadot/node/collation-generation/Cargo.toml @@ -28,3 +28,5 @@ polkadot-primitives-test-helpers = { workspace = true } assert_matches = { workspace = true } rstest = { workspace = true } sp-keyring = { workspace = true, default-features = true } +polkadot-primitives = { workspace = true, features = ["test"] } + diff --git a/polkadot/node/collation-generation/src/tests.rs b/polkadot/node/collation-generation/src/tests.rs index c27403cc7b3a..affe639108ee 100644 --- a/polkadot/node/collation-generation/src/tests.rs +++ b/polkadot/node/collation-generation/src/tests.rs @@ -30,13 +30,12 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_test_helpers::{subsystem_test_harness, TestSubsystemContextHandle}; use polkadot_node_subsystem_util::TimeoutExt; use polkadot_primitives::{ - vstaging::async_backing::CandidatePendingAvailability, vstaging::async_backing::BackingState, + vstaging::async_backing::{BackingState, CandidatePendingAvailability}, AsyncBackingParams, BlockNumber, CollatorPair, HeadData, PersistedValidationData, ScheduledCore, ValidationCode, }; use polkadot_primitives_test_helpers::{ - dummy_candidate_descriptor, dummy_candidate_descriptor_v2, dummy_hash, dummy_head_data, - dummy_validator, make_candidate, + dummy_candidate_descriptor_v2, dummy_hash, dummy_head_data, dummy_validator, make_candidate, }; use rstest::rstest; use sp_keyring::sr25519::Keyring as Sr25519Keyring; @@ -491,7 +490,7 @@ fn sends_distribute_collation_message(#[case] runtime_version: u32) { erasure_root: dummy_hash(), // this isn't something we're checking right now para_head: test_collation().head_data.hash(), validation_code_hash: expect_validation_code_hash, - }.into(); + }; assert_eq!(to_collator_protocol.len(), 1); match AllMessages::from(to_collator_protocol.pop().unwrap()) { @@ -505,7 +504,7 @@ fn sends_distribute_collation_message(#[case] runtime_version: u32) { // descriptor has a valid signature, then just copy in the generated signature // and check the rest of the fields for equality. assert!(CollatorPair::verify( - &descriptor.signature, + &descriptor.signature().unwrap(), &collator_signature_payload( &descriptor.relay_parent(), &descriptor.para_id(), @@ -518,9 +517,9 @@ fn sends_distribute_collation_message(#[case] runtime_version: u32) { )); let expect_descriptor = { let mut expect_descriptor = expect_descriptor; - expect_descriptor.signature = descriptor.signature.clone().unwrap(); + expect_descriptor.signature = descriptor.signature().clone().unwrap(); expect_descriptor.erasure_root = descriptor.erasure_root(); - expect_descriptor + expect_descriptor.into() }; assert_eq!(descriptor, expect_descriptor); }, @@ -659,7 +658,7 @@ fn fallback_when_no_validation_code_hash_api(#[case] runtime_version: u32) { .. }) => { let CandidateReceipt { descriptor, .. } = candidate_receipt; - assert_eq!(expect_validation_code_hash, descriptor.validation_code_hash); + assert_eq!(expect_validation_code_hash, descriptor.validation_code_hash()); }, _ => panic!("received wrong message type"), } @@ -1252,9 +1251,9 @@ mod helpers { .. }) => { assert_eq!(parent_head_data_hash, parent_head.hash()); - assert_eq!(candidate_receipt.descriptor().persisted_validation_data_hash, pvd.hash()); - assert_eq!(candidate_receipt.descriptor().para_head, dummy_head_data().hash()); - assert_eq!(candidate_receipt.descriptor().validation_code_hash, validation_code_hash); + assert_eq!(candidate_receipt.descriptor().persisted_validation_data_hash(), pvd.hash()); + assert_eq!(candidate_receipt.descriptor().para_head(), dummy_head_data().hash()); + assert_eq!(candidate_receipt.descriptor().validation_code_hash(), validation_code_hash); } ); } diff --git a/polkadot/node/core/approval-voting/src/approval_db/v2/tests.rs b/polkadot/node/core/approval-voting/src/approval_db/v2/tests.rs index 82e6373e3668..866702f861c1 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v2/tests.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v2/tests.rs @@ -26,7 +26,8 @@ use crate::{ ops::{add_block_entry, canonicalize, force_approve, NewCandidateInfo}, }; use polkadot_primitives::{ - BlockNumber, CandidateHash, vstaging::CandidateReceiptV2 as CandidateReceipt, vstaging::MutateDescriptorV2, CoreIndex, GroupIndex, Hash, + vstaging::{CandidateReceiptV2 as CandidateReceipt, MutateDescriptorV2}, + BlockNumber, CandidateHash, CoreIndex, GroupIndex, Hash, }; use polkadot_node_subsystem_util::database::Database; @@ -35,7 +36,8 @@ use sp_consensus_slots::Slot; use std::{collections::HashMap, sync::Arc}; use polkadot_primitives_test_helpers::{ - dummy_candidate_receipt, dummy_candidate_receipt_bad_sig, dummy_candidate_receipt_v2, dummy_hash + dummy_candidate_receipt_bad_sig, dummy_candidate_receipt_v2, + dummy_candidate_receipt_v2_bad_sig, dummy_hash, }; const DATA_COL: u32 = 0; @@ -95,7 +97,7 @@ fn read_write() { make_block_entry(hash_a, Default::default(), 1, vec![(CoreIndex(0), candidate_hash)]); let candidate_entry = CandidateEntry { - candidate: dummy_candidate_receipt_bad_sig(dummy_hash(), None), + candidate: dummy_candidate_receipt_v2_bad_sig(dummy_hash(), None), session: 5, block_assignments: vec![( hash_a, diff --git a/polkadot/node/core/approval-voting/src/approval_db/v3/tests.rs b/polkadot/node/core/approval-voting/src/approval_db/v3/tests.rs index 4b548ae762ad..372dd49803cb 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v3/tests.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v3/tests.rs @@ -25,8 +25,8 @@ use crate::{ ops::{add_block_entry, canonicalize, force_approve, NewCandidateInfo}, }; use polkadot_primitives::{ - vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, CoreIndex, - GroupIndex, Hash, + vstaging::{CandidateReceiptV2 as CandidateReceipt, MutateDescriptorV2}, + BlockNumber, CandidateHash, CoreIndex, GroupIndex, Hash, }; use polkadot_node_subsystem_util::database::Database; @@ -35,7 +35,7 @@ use sp_consensus_slots::Slot; use std::{collections::HashMap, sync::Arc}; use polkadot_primitives_test_helpers::{ - dummy_candidate_receipt, dummy_candidate_receipt_bad_sig, dummy_candidate_receipt_v2_bad_sig, dummy_hash + dummy_candidate_receipt_v2, dummy_candidate_receipt_v2_bad_sig, dummy_hash, }; const DATA_COL: u32 = 0; @@ -73,10 +73,10 @@ fn make_block_entry( } fn make_candidate(para_id: ParaId, relay_parent: Hash) -> CandidateReceipt { - let mut c = dummy_candidate_receipt(dummy_hash()); + let mut c = dummy_candidate_receipt_v2(dummy_hash()); - c.descriptor.para_id = para_id; - c.descriptor.relay_parent = relay_parent; + c.descriptor.set_para_id(para_id); + c.descriptor.set_relay_parent(relay_parent); c.into() } diff --git a/polkadot/node/core/approval-voting/src/import.rs b/polkadot/node/core/approval-voting/src/import.rs index 3658a59868d7..93689f4dd599 100644 --- a/polkadot/node/core/approval-voting/src/import.rs +++ b/polkadot/node/core/approval-voting/src/import.rs @@ -46,7 +46,7 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_util::{determine_new_blocks, runtime::RuntimeInfo}; use polkadot_primitives::{ node_features, - vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt,}, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt}, BlockNumber, CandidateHash, ConsensusLog, CoreIndex, GroupIndex, Hash, Header, SessionIndex, }; use sc_keystore::LocalKeystore; @@ -625,8 +625,8 @@ pub(crate) mod tests { use polkadot_node_subsystem_test_helpers::make_subsystem_context; use polkadot_node_subsystem_util::database::Database; use polkadot_primitives::{ - node_features::FeatureIndex, ExecutorParams, Id as ParaId, IndexedVec, NodeFeatures, - SessionInfo, ValidatorId, ValidatorIndex, vstaging::MutateDescriptorV2, + node_features::FeatureIndex, vstaging::MutateDescriptorV2, ExecutorParams, Id as ParaId, + IndexedVec, NodeFeatures, SessionInfo, ValidatorId, ValidatorIndex, }; use polkadot_primitives_test_helpers::{dummy_candidate_receipt_v2, dummy_hash}; use schnellru::{ByLength, LruMap}; diff --git a/polkadot/node/core/av-store/src/tests.rs b/polkadot/node/core/av-store/src/tests.rs index 958917a3104f..80043e56976b 100644 --- a/polkadot/node/core/av-store/src/tests.rs +++ b/polkadot/node/core/av-store/src/tests.rs @@ -31,8 +31,8 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_node_subsystem_util::{database::Database, TimeoutExt}; use polkadot_primitives::{ - node_features, CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, HeadData, Header, - PersistedValidationData, ValidatorId, + node_features, vstaging::CandidateReceiptV2 as CandidateReceipt, CandidateHash, CoreIndex, + GroupIndex, HeadData, Header, PersistedValidationData, ValidatorId, }; use polkadot_primitives_test_helpers::TestCandidateBuilder; use sp_keyring::Sr25519Keyring; diff --git a/polkadot/node/core/backing/src/tests/mod.rs b/polkadot/node/core/backing/src/tests/mod.rs index 4fe1f02708cd..384e733080de 100644 --- a/polkadot/node/core/backing/src/tests/mod.rs +++ b/polkadot/node/core/backing/src/tests/mod.rs @@ -29,11 +29,12 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_primitives::{ - node_features, CandidateDescriptor, GroupRotationInfo, HeadData, PersistedValidationData, - PvfExecKind, ScheduledCore, SessionIndex, LEGACY_MIN_BACKING_VOTES, + node_features, vstaging::MutateDescriptorV2, CandidateDescriptor, GroupRotationInfo, HeadData, + PersistedValidationData, PvfExecKind, ScheduledCore, SessionIndex, LEGACY_MIN_BACKING_VOTES, }; use polkadot_primitives_test_helpers::{ - dummy_candidate_receipt_bad_sig, dummy_collator, dummy_collator_signature, dummy_committed_candidate_receipt, dummy_committed_candidate_receipt_v2, dummy_hash, validator_pubkeys + dummy_candidate_receipt_bad_sig, dummy_collator, dummy_collator_signature, + dummy_committed_candidate_receipt_v2, dummy_hash, validator_pubkeys, }; use polkadot_statement_table::v2::Misbehavior; use rstest::rstest; @@ -650,7 +651,7 @@ fn backing_works(#[case] elastic_scaling_mvp: bool) { }, ) if validation_data == pvd_ab && validation_code == validation_code_ab && - *pov == pov_ab && &candidate_receipt.descriptor == candidate_a.descriptor && + *pov == pov_ab && candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::Backing && candidate_receipt.commitments_hash == candidate_a_commitments_hash => { @@ -1286,7 +1287,7 @@ fn backing_works_while_validation_ongoing() { }, ) if validation_data == pvd_abc && validation_code == validation_code_abc && - *pov == pov_abc && &candidate_receipt.descriptor == candidate_a.descriptor && + *pov == pov_abc && candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::Backing && candidate_a_commitments_hash == candidate_receipt.commitments_hash => { @@ -1453,7 +1454,7 @@ fn backing_misbehavior_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate_a.descriptor && + *pov == pov_a && candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::Backing && candidate_a_commitments_hash == candidate_receipt.commitments_hash => { @@ -1620,7 +1621,7 @@ fn backing_dont_second_invalid() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_block_a && &candidate_receipt.descriptor == candidate_a.descriptor && + *pov == pov_block_a && candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::Backing && candidate_a.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1660,7 +1661,7 @@ fn backing_dont_second_invalid() { }, ) if validation_data == pvd_b && validation_code == validation_code_b && - *pov == pov_block_b && &candidate_receipt.descriptor == candidate_b.descriptor && + *pov == pov_block_b && candidate_receipt.descriptor == candidate_b.descriptor && exec_kind == PvfExecKind::Backing && candidate_b.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1787,7 +1788,7 @@ fn backing_second_after_first_fails_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && + *pov == pov_a && candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1931,7 +1932,7 @@ fn backing_works_after_failed_validation() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && + *pov == pov_a && candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::Backing && candidate.commitments.hash() == candidate_receipt.commitments_hash => { diff --git a/polkadot/node/core/backing/src/tests/prospective_parachains.rs b/polkadot/node/core/backing/src/tests/prospective_parachains.rs index aaefdf6e52e0..673546ae0afe 100644 --- a/polkadot/node/core/backing/src/tests/prospective_parachains.rs +++ b/polkadot/node/core/backing/src/tests/prospective_parachains.rs @@ -1637,7 +1637,7 @@ fn occupied_core_assignment() { time_out_at: 200_u32, next_up_on_time_out: None, availability: Default::default(), - candidate_descriptor, + candidate_descriptor: candidate_descriptor.into(), candidate_hash: Default::default(), }); diff --git a/polkadot/node/core/bitfield-signing/src/tests.rs b/polkadot/node/core/bitfield-signing/src/tests.rs index ce46b147a34c..efbe2b5147f0 100644 --- a/polkadot/node/core/bitfield-signing/src/tests.rs +++ b/polkadot/node/core/bitfield-signing/src/tests.rs @@ -18,7 +18,7 @@ use super::*; use futures::{executor::block_on, pin_mut, StreamExt}; use polkadot_node_subsystem::messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}; use polkadot_primitives::{vstaging::OccupiedCore, CandidateHash}; -use polkadot_primitives_test_helpers::dummy_candidate_descriptor; +use polkadot_primitives_test_helpers::dummy_candidate_descriptor_v2; fn occupied_core(para_id: u32, candidate_hash: CandidateHash) -> CoreState { CoreState::Occupied(OccupiedCore { @@ -29,7 +29,7 @@ fn occupied_core(para_id: u32, candidate_hash: CandidateHash) -> CoreState { next_up_on_time_out: None, availability: Default::default(), candidate_hash, - candidate_descriptor: dummy_candidate_descriptor(Hash::zero()), + candidate_descriptor: dummy_candidate_descriptor_v2(Hash::zero()), }) } diff --git a/polkadot/node/core/candidate-validation/src/tests.rs b/polkadot/node/core/candidate-validation/src/tests.rs index b6eed45d36ad..c80f1f64fb3c 100644 --- a/polkadot/node/core/candidate-validation/src/tests.rs +++ b/polkadot/node/core/candidate-validation/src/tests.rs @@ -25,7 +25,8 @@ use polkadot_node_subsystem::messages::AllMessages; use polkadot_node_subsystem_util::reexports::SubsystemContext; use polkadot_overseer::ActivatedLeaf; use polkadot_primitives::{ - CoreIndex, GroupIndex, HeadData, Id as ParaId, SessionInfo, UpwardMessage, ValidatorId, + vstaging::CandidateDescriptorV2, CandidateDescriptor, CoreIndex, GroupIndex, HeadData, + Id as ParaId, SessionInfo, UpwardMessage, ValidatorId, }; use polkadot_primitives_test_helpers::{ dummy_collator, dummy_collator_signature, dummy_hash, make_valid_candidate_descriptor, @@ -532,7 +533,7 @@ fn perform_basic_checks_on_valid_candidate( validation_code: &ValidationCode, validation_data: &PersistedValidationData, head_data_hash: Hash, -) -> CandidateDescriptor { +) -> CandidateDescriptorV2 { let descriptor = make_valid_candidate_descriptor( ParaId::from(1_u32), dummy_hash(), @@ -824,7 +825,8 @@ fn candidate_validation_commitment_hash_mismatch_is_invalid() { head_data.hash(), dummy_hash(), Sr25519Keyring::Alice, - ), + ) + .into(), commitments_hash: Hash::zero(), } .into(); @@ -1196,7 +1198,8 @@ fn dummy_candidate_backed( signature: dummy_collator_signature(), para_head: zeros, validation_code_hash, - }; + } + .into(); CandidateEvent::CandidateBacked( CandidateReceipt { descriptor, commitments_hash: zeros }, diff --git a/polkadot/node/core/dispute-coordinator/Cargo.toml b/polkadot/node/core/dispute-coordinator/Cargo.toml index eb4600b235b9..344b66af1933 100644 --- a/polkadot/node/core/dispute-coordinator/Cargo.toml +++ b/polkadot/node/core/dispute-coordinator/Cargo.toml @@ -37,6 +37,7 @@ polkadot-primitives-test-helpers = { workspace = true } futures-timer = { workspace = true } sp-application-crypto = { workspace = true, default-features = true } sp-tracing = { workspace = true, default-features = true } +polkadot-primitives = { workspace = true, features = ["test"] } [features] # If not enabled, the dispute coordinator will do nothing. diff --git a/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs b/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs index d7586a1ca2f8..fe04193014c6 100644 --- a/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs +++ b/polkadot/node/core/dispute-coordinator/src/scraping/tests.rs @@ -36,11 +36,9 @@ use polkadot_node_subsystem_test_helpers::{ }; use polkadot_node_subsystem_util::{reexports::SubsystemContext, TimeoutExt}; use polkadot_primitives::{ - vstaging::{ - CandidateDescriptorV2 as CandidateDescriptor, CandidateEvent, - CandidateReceiptV2 as CandidateReceipt, - }, - BlakeTwo256, BlockNumber, CoreIndex, GroupIndex, Hash, HashT, HeadData, Id as ParaId, + vstaging::{CandidateEvent, CandidateReceiptV2 as CandidateReceipt}, + BlakeTwo256, BlockNumber, CandidateDescriptor, CoreIndex, GroupIndex, Hash, HashT, HeadData, + Id as ParaId, }; use polkadot_primitives_test_helpers::{dummy_collator, dummy_collator_signature, dummy_hash}; @@ -138,7 +136,8 @@ fn make_candidate_receipt(relay_parent: Hash) -> CandidateReceipt { signature: dummy_collator_signature(), para_head: zeros, validation_code_hash: zeros.into(), - }; + } + .into(); CandidateReceipt { descriptor, commitments_hash: zeros } } diff --git a/polkadot/node/core/dispute-coordinator/src/tests.rs b/polkadot/node/core/dispute-coordinator/src/tests.rs index f97a625a9528..36c6e75b420b 100644 --- a/polkadot/node/core/dispute-coordinator/src/tests.rs +++ b/polkadot/node/core/dispute-coordinator/src/tests.rs @@ -60,13 +60,18 @@ use polkadot_node_subsystem_test_helpers::{ make_buffered_subsystem_context, mock::new_leaf, TestSubsystemContextHandle, }; use polkadot_primitives::{ - ApprovalVote, BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash, - CandidateReceipt, CoreIndex, DisputeStatement, ExecutorParams, GroupIndex, Hash, HeadData, - Header, IndexedVec, MultiDisputeStatementSet, NodeFeatures, ScrapedOnChainVotes, SessionIndex, - SessionInfo, SigningContext, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, - ValidatorSignature, + vstaging::{ + CandidateEvent, CandidateReceiptV2 as CandidateReceipt, MutateDescriptorV2, + ScrapedOnChainVotes, + }, + ApprovalVote, BlockNumber, CandidateCommitments, CandidateHash, CoreIndex, DisputeStatement, + ExecutorParams, GroupIndex, Hash, HeadData, Header, IndexedVec, MultiDisputeStatementSet, + NodeFeatures, SessionIndex, SessionInfo, SigningContext, ValidDisputeStatementKind, + ValidatorId, ValidatorIndex, ValidatorSignature, +}; +use polkadot_primitives_test_helpers::{ + dummy_candidate_receipt_v2_bad_sig, dummy_digest, dummy_hash, }; -use polkadot_primitives_test_helpers::{dummy_candidate_receipt_bad_sig, dummy_digest, dummy_hash}; use crate::{ backend::Backend, @@ -647,11 +652,11 @@ fn make_valid_candidate_receipt() -> CandidateReceipt { } fn make_invalid_candidate_receipt() -> CandidateReceipt { - dummy_candidate_receipt_bad_sig(Default::default(), Some(Default::default())) + dummy_candidate_receipt_v2_bad_sig(Default::default(), Some(Default::default())) } fn make_another_valid_candidate_receipt(relay_parent: Hash) -> CandidateReceipt { - let mut candidate_receipt = dummy_candidate_receipt_bad_sig(relay_parent, dummy_hash()); + let mut candidate_receipt = dummy_candidate_receipt_v2_bad_sig(relay_parent, dummy_hash()); candidate_receipt.commitments_hash = CandidateCommitments::default().hash(); candidate_receipt } @@ -3857,14 +3862,15 @@ fn participation_requests_reprioritized_for_newly_included() { for repetition in 1..=3u8 { // Building candidate receipts let mut candidate_receipt = make_valid_candidate_receipt(); - candidate_receipt.descriptor.pov_hash = Hash::from( + candidate_receipt.descriptor.set_pov_hash(Hash::from( [repetition; 32], // Altering this receipt so its hash will be changed - ); + )); // Set consecutive parents (starting from zero). They will order the candidates for // participation. let parent_block_num: BlockNumber = repetition as BlockNumber - 1; - candidate_receipt.descriptor.relay_parent = - *test_state.block_num_to_header.get(&parent_block_num).unwrap(); + candidate_receipt.descriptor.set_relay_parent( + *test_state.block_num_to_header.get(&parent_block_num).unwrap(), + ); receipts.push(candidate_receipt.clone()); } diff --git a/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs b/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs index c311511abdf0..ebdfd76c37a4 100644 --- a/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs +++ b/polkadot/node/core/prospective-parachains/src/fragment_chain/tests.rs @@ -18,7 +18,8 @@ use super::*; use assert_matches::assert_matches; use polkadot_node_subsystem_util::inclusion_emulator::InboundHrmpLimitations; use polkadot_primitives::{ - BlockNumber, CandidateCommitments,vstaging::MutateDescriptorV2, vstaging::CandidateDescriptorV2 as CandidateDescriptor, HeadData, Id as ParaId, + vstaging::MutateDescriptorV2, BlockNumber, CandidateCommitments, CandidateDescriptor, HeadData, + Id as ParaId, }; use polkadot_primitives_test_helpers as test_helpers; use rand::{seq::SliceRandom, thread_rng}; diff --git a/polkadot/node/core/runtime-api/src/tests.rs b/polkadot/node/core/runtime-api/src/tests.rs index 7c382707264f..d4fa07323886 100644 --- a/polkadot/node/core/runtime-api/src/tests.rs +++ b/polkadot/node/core/runtime-api/src/tests.rs @@ -20,14 +20,20 @@ use polkadot_node_primitives::{BabeAllowedSlots, BabeEpoch, BabeEpochConfigurati use polkadot_node_subsystem::SpawnGlue; use polkadot_node_subsystem_test_helpers::make_subsystem_context; use polkadot_primitives::{ - async_backing, slashing, ApprovalVotingParams, AuthorityDiscoveryId, BlockNumber, - CandidateCommitments, CandidateEvent, CandidateHash, CommittedCandidateReceipt, CoreIndex, - CoreState, DisputeState, ExecutorParams, GroupRotationInfo, Id as ParaId, + async_backing, slashing, vstaging, + vstaging::{ + CandidateEvent, CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, + ScrapedOnChainVotes, + }, + ApprovalVotingParams, AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateHash, + CoreIndex, DisputeState, ExecutorParams, GroupRotationInfo, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, NodeFeatures, OccupiedCoreAssumption, - PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, - Slot, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, + PersistedValidationData, PvfCheckStatement, SessionIndex, SessionInfo, Slot, ValidationCode, + ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, +}; +use polkadot_primitives_test_helpers::{ + dummy_committed_candidate_receipt_v2, dummy_validation_code, }; -use polkadot_primitives_test_helpers::{dummy_committed_candidate_receipt, dummy_validation_code}; use sp_api::ApiError; use sp_core::testing::TaskExecutor; use std::{ @@ -279,7 +285,7 @@ impl RuntimeApiSubsystemClient for MockSubsystemClient { &self, _: Hash, _: ParaId, - ) -> Result, ApiError> { + ) -> Result, ApiError> { todo!("Not required for tests") } @@ -699,7 +705,7 @@ fn requests_candidate_pending_availability() { let para_a = ParaId::from(5_u32); let para_b = ParaId::from(6_u32); let spawner = sp_core::testing::TaskExecutor::new(); - let candidate_receipt = dummy_committed_candidate_receipt(relay_parent); + let candidate_receipt = dummy_committed_candidate_receipt_v2(relay_parent); let mut subsystem_client = MockSubsystemClient::default(); subsystem_client diff --git a/polkadot/node/network/availability-distribution/src/requester/tests.rs b/polkadot/node/network/availability-distribution/src/requester/tests.rs index decb3156004e..95c12d95dc99 100644 --- a/polkadot/node/network/availability-distribution/src/requester/tests.rs +++ b/polkadot/node/network/availability-distribution/src/requester/tests.rs @@ -21,7 +21,7 @@ use polkadot_node_network_protocol::{jaeger, request_response::ReqProtocolNames} use polkadot_node_primitives::{BlockData, ErasureChunk, PoV}; use polkadot_node_subsystem_util::runtime::RuntimeInfo; use polkadot_primitives::{ - BlockNumber, ChunkIndex, CoreState, ExecutorParams, GroupIndex, Hash, Id as ParaId, + vstaging::CoreState, BlockNumber, ChunkIndex, ExecutorParams, GroupIndex, Hash, Id as ParaId, ScheduledCore, SessionIndex, SessionInfo, }; use sp_core::{testing::TaskExecutor, traits::SpawnNamed}; diff --git a/polkadot/node/network/availability-distribution/src/tests/mock.rs b/polkadot/node/network/availability-distribution/src/tests/mock.rs index b2c240ca53ad..f900cb6e6156 100644 --- a/polkadot/node/network/availability-distribution/src/tests/mock.rs +++ b/polkadot/node/network/availability-distribution/src/tests/mock.rs @@ -23,8 +23,9 @@ use sp_keyring::Sr25519Keyring; use polkadot_erasure_coding::{branches, obtain_chunks_v1 as obtain_chunks}; use polkadot_node_primitives::{AvailableData, BlockData, ErasureChunk, PoV, Proof}; use polkadot_primitives::{ - CandidateCommitments, vstaging::CandidateDescriptorV2 as CandidateDescriptor, CandidateHash, ChunkIndex, - vstaging::CommittedCandidateReceiptV2 as CommittedCandidateReceipt, GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec, vstaging::OccupiedCore, + vstaging::{CommittedCandidateReceiptV2, OccupiedCore}, + CandidateCommitments, CandidateDescriptor, CandidateHash, ChunkIndex, + CommittedCandidateReceipt, GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec, PersistedValidationData, SessionInfo, ValidatorIndex, }; use polkadot_primitives_test_helpers::{ @@ -101,7 +102,7 @@ impl OccupiedCoreBuilder { availability: Default::default(), group_responsible: self.group_responsible, candidate_hash: candidate_receipt.hash(), - candidate_descriptor: candidate_receipt.descriptor().clone(), + candidate_descriptor: candidate_receipt.descriptor.clone(), }; (core, (candidate_receipt.hash(), chunk)) } @@ -117,7 +118,7 @@ pub struct TestCandidateBuilder { } impl TestCandidateBuilder { - pub fn build(self) -> CommittedCandidateReceipt { + pub fn build(self) -> CommittedCandidateReceiptV2 { CommittedCandidateReceipt { descriptor: CandidateDescriptor { para_id: self.para_id, @@ -132,6 +133,7 @@ impl TestCandidateBuilder { }, commitments: CandidateCommitments { head_data: self.head_data, ..Default::default() }, } + .into() } } diff --git a/polkadot/node/network/availability-recovery/src/tests.rs b/polkadot/node/network/availability-recovery/src/tests.rs index 4fd9ede40ff6..9a46d5420782 100644 --- a/polkadot/node/network/availability-recovery/src/tests.rs +++ b/polkadot/node/network/availability-recovery/src/tests.rs @@ -41,8 +41,8 @@ use polkadot_node_subsystem_test_helpers::{ }; use polkadot_node_subsystem_util::TimeoutExt; use polkadot_primitives::{ - node_features, AuthorityDiscoveryId, Block, ExecutorParams, Hash, HeadData, IndexedVec, - NodeFeatures, PersistedValidationData, SessionInfo, ValidatorId, + node_features, vstaging::MutateDescriptorV2, AuthorityDiscoveryId, Block, ExecutorParams, Hash, + HeadData, IndexedVec, NodeFeatures, PersistedValidationData, SessionInfo, ValidatorId, }; use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; use sc_network::{IfDisconnected, OutboundFailure, ProtocolName, RequestFailure}; @@ -346,7 +346,7 @@ impl TestState { ) .unwrap(), current, - candidate, + candidate: candidate.into(), session_index, core_index, node_features, @@ -800,12 +800,12 @@ fn availability_is_recovered_from_chunks_if_no_group_provided(#[case] systematic // Test another candidate, send no chunks. let mut new_candidate = dummy_candidate_receipt(dummy_hash()); - new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent; + new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent(); overseer_send( &mut virtual_overseer, AvailabilityRecoveryMessage::RecoverAvailableData( - new_candidate.clone(), + new_candidate.clone().into(), test_state.session_index, None, Some(test_state.core_index), @@ -929,12 +929,12 @@ fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunk // Test another candidate, send no chunks. let mut new_candidate = dummy_candidate_receipt(dummy_hash()); - new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent; + new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent(); overseer_send( &mut virtual_overseer, AvailabilityRecoveryMessage::RecoverAvailableData( - new_candidate.clone(), + new_candidate.clone().into(), test_state.session_index, Some(GroupIndex(1)), Some(test_state.core_index), @@ -1218,7 +1218,7 @@ fn invalid_erasure_coding_leads_to_invalid_error(#[case] systematic_recovery: bo test_state.validators.len(), test_state.core_index, ); - test_state.candidate.descriptor.erasure_root = bad_erasure_root; + test_state.candidate.descriptor.set_erasure_root(bad_erasure_root); let candidate_hash = test_state.candidate.hash(); @@ -1283,7 +1283,7 @@ fn invalid_pov_hash_leads_to_invalid_error() { test_harness(subsystem, |mut virtual_overseer| async move { let pov = PoV { block_data: BlockData(vec![69; 64]) }; - test_state.candidate.descriptor.pov_hash = pov.hash(); + test_state.candidate.descriptor.set_pov_hash(pov.hash()); let candidate_hash = test_state.candidate.hash(); @@ -1420,7 +1420,10 @@ fn recovers_from_only_chunks_if_pov_large( test_state.threshold(), ), (false, true) => { - test_state.candidate.descriptor.pov_hash = test_state.available_data.pov.hash(); + test_state + .candidate + .descriptor + .set_pov_hash(test_state.available_data.pov.hash()); ( AvailabilityRecoverySubsystem::for_collator( None, @@ -1497,12 +1500,12 @@ fn recovers_from_only_chunks_if_pov_large( // Test another candidate, send no chunks. let mut new_candidate = dummy_candidate_receipt(dummy_hash()); - new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent; + new_candidate.descriptor.relay_parent = test_state.candidate.descriptor.relay_parent(); overseer_send( &mut virtual_overseer, AvailabilityRecoveryMessage::RecoverAvailableData( - new_candidate.clone(), + new_candidate.clone().into(), test_state.session_index, Some(GroupIndex(1)), Some(test_state.core_index), @@ -1593,7 +1596,10 @@ fn fast_path_backing_group_recovers_if_pov_small( Metrics::new_dummy(), ), (false, true) => { - test_state.candidate.descriptor.pov_hash = test_state.available_data.pov.hash(); + test_state + .candidate + .descriptor + .set_pov_hash(test_state.available_data.pov.hash()); AvailabilityRecoverySubsystem::for_collator( None, request_receiver(&req_protocol_names), @@ -2635,7 +2641,7 @@ fn number_of_request_retries_is_bounded( ); test_state.chunks = map_chunks(chunks, &test_state.node_features, n_validators, test_state.core_index); - test_state.candidate.descriptor.erasure_root = erasure_root; + test_state.candidate.descriptor.set_erasure_root(erasure_root); let (subsystem, retry_limit) = match systematic_recovery { false => ( diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs index 75dd1bb45098..290c4db901d5 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs @@ -122,7 +122,7 @@ impl Default for TestState { let mut d = dummy_candidate_descriptor(dummy_hash()); d.para_id = chain_ids[1]; - d + d.into() }, }), ]; @@ -592,8 +592,11 @@ fn act_on_advertisement_v2() { response_channel .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) - .encode(), + request_v1::CollationFetchingResponse::Collation( + candidate_a.clone().into(), + pov.clone(), + ) + .encode(), ProtocolName::from(""), ))) .expect("Sending response should succeed"); @@ -794,8 +797,11 @@ fn fetch_one_collation_at_a_time() { candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); response_channel .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) - .encode(), + request_v1::CollationFetchingResponse::Collation( + candidate_a.clone().into(), + pov.clone(), + ) + .encode(), ProtocolName::from(""), ))) .expect("Sending response should succeed"); @@ -918,16 +924,22 @@ fn fetches_next_collation() { // First request finishes now: response_channel_non_exclusive .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) - .encode(), + request_v1::CollationFetchingResponse::Collation( + candidate_a.clone().into(), + pov.clone(), + ) + .encode(), ProtocolName::from(""), ))) .expect("Sending response should succeed"); response_channel .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) - .encode(), + request_v1::CollationFetchingResponse::Collation( + candidate_a.clone().into(), + pov.clone(), + ) + .encode(), ProtocolName::from(""), ))) .expect("Sending response should succeed"); @@ -1056,8 +1068,11 @@ fn fetch_next_collation_on_invalid_collation() { candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); response_channel .send(Ok(( - request_v1::CollationFetchingResponse::Collation(candidate_a.clone().into(), pov.clone()) - .encode(), + request_v1::CollationFetchingResponse::Collation( + candidate_a.clone().into(), + pov.clone(), + ) + .encode(), ProtocolName::from(""), ))) .expect("Sending response should succeed"); diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs index 1cc4c3e1cb73..a75b924e65d4 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs @@ -226,7 +226,7 @@ async fn send_seconded_statement( overseer_send( virtual_overseer, - CollatorProtocolMessage::Seconded(candidate.descriptor.relay_parent, stmt), + CollatorProtocolMessage::Seconded(candidate.descriptor.relay_parent(), stmt), ) .await; } @@ -375,7 +375,7 @@ fn v1_advertisement_accepted_and_seconded() { hrmp_watermark: 0, }; candidate.commitments_hash = commitments.hash(); - + let candidate: CandidateReceipt = candidate.into(); let pov = PoV { block_data: BlockData(vec![1]) }; response_channel @@ -596,6 +596,7 @@ fn second_multiple_candidates_per_relay_parent() { hrmp_watermark: 0, }; candidate.commitments_hash = commitments.hash(); + let candidate: CandidateReceipt = candidate.into(); let candidate_hash = candidate.hash(); let parent_head_data_hash = Hash::zero(); @@ -751,7 +752,7 @@ fn fetched_collation_sanity_check() { hrmp_watermark: 0, }; candidate.commitments_hash = commitments.hash(); - + let candidate: CandidateReceipt = candidate.into(); let candidate_hash = CandidateHash(Hash::zero()); let parent_head_data_hash = Hash::zero(); @@ -846,7 +847,6 @@ fn sanity_check_invalid_parent_head_data() { let mut candidate = dummy_candidate_receipt_bad_sig(head_c, Some(Default::default())); candidate.descriptor.para_id = test_state.chain_ids[0]; - let commitments = CandidateCommitments { head_data: HeadData(vec![1, 2, 3]), horizontal_messages: Default::default(), @@ -865,6 +865,7 @@ fn sanity_check_invalid_parent_head_data() { pvd.parent_head = parent_head_data; candidate.descriptor.persisted_validation_data_hash = pvd.hash(); + let candidate: CandidateReceipt = candidate.into(); let candidate_hash = candidate.hash(); @@ -1069,6 +1070,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { processed_downward_messages: 0, hrmp_watermark: 0, }; + let mut candidate_b: CandidateReceipt = candidate_b.into(); candidate_b.commitments_hash = candidate_b_commitments.hash(); let candidate_b_hash = candidate_b.hash(); @@ -1135,6 +1137,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { relay_parent_storage_root: Default::default(), } .hash(); + let mut candidate_a: CandidateReceipt = candidate_a.into(); let candidate_a_commitments = CandidateCommitments { head_data: HeadData(vec![1]), horizontal_messages: Default::default(), @@ -1145,6 +1148,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { }; candidate_a.commitments_hash = candidate_a_commitments.hash(); + let candidate_a: CandidateReceipt = candidate_a.into(); let candidate_a_hash = candidate_a.hash(); advertise_collation( @@ -1177,7 +1181,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { response_channel .send(Ok(( request_v2::CollationFetchingResponse::Collation( - candidate_a.into().clone(), + candidate_a.clone(), PoV { block_data: BlockData(vec![2]) }, ) .encode(), @@ -1290,7 +1294,7 @@ fn child_blocked_from_seconding_by_parent(#[case] valid_parent: bool) { // If candidate A is invalid, B won't be seconded. overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::Invalid(head_c, candidate_a.into()), + CollatorProtocolMessage::Invalid(head_c, candidate_a), ) .await; diff --git a/polkadot/node/network/dispute-distribution/src/tests/mock.rs b/polkadot/node/network/dispute-distribution/src/tests/mock.rs index ccc050233e84..69054a1049d2 100644 --- a/polkadot/node/network/dispute-distribution/src/tests/mock.rs +++ b/polkadot/node/network/dispute-distribution/src/tests/mock.rs @@ -34,10 +34,10 @@ use sp_keystore::{Keystore, KeystorePtr}; use polkadot_node_primitives::{DisputeMessage, SignedDisputeStatement}; use polkadot_primitives::{ - AuthorityDiscoveryId, CandidateHash, CandidateReceipt, Hash, SessionIndex, SessionInfo, - ValidatorId, ValidatorIndex, + vstaging::CandidateReceiptV2 as CandidateReceipt, AuthorityDiscoveryId, CandidateHash, Hash, + SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, }; -use polkadot_primitives_test_helpers::dummy_candidate_descriptor; +use polkadot_primitives_test_helpers::dummy_candidate_descriptor_v2; use crate::LOG_TARGET; @@ -121,7 +121,7 @@ pub static ref MOCK_NEXT_SESSION_INFO: SessionInfo = pub fn make_candidate_receipt(relay_parent: Hash) -> CandidateReceipt { CandidateReceipt { - descriptor: dummy_candidate_descriptor(relay_parent), + descriptor: dummy_candidate_descriptor_v2(relay_parent), commitments_hash: Hash::random(), } } diff --git a/polkadot/node/network/dispute-distribution/src/tests/mod.rs b/polkadot/node/network/dispute-distribution/src/tests/mod.rs index 60820e62ca2d..5306b22828cc 100644 --- a/polkadot/node/network/dispute-distribution/src/tests/mod.rs +++ b/polkadot/node/network/dispute-distribution/src/tests/mod.rs @@ -57,8 +57,8 @@ use polkadot_node_subsystem_test_helpers::{ subsystem_test_harness, TestSubsystemContextHandle, }; use polkadot_primitives::{ - AuthorityDiscoveryId, Block, CandidateHash, CandidateReceipt, ExecutorParams, Hash, - NodeFeatures, SessionIndex, SessionInfo, + vstaging::CandidateReceiptV2 as CandidateReceipt, AuthorityDiscoveryId, Block, CandidateHash, + ExecutorParams, Hash, NodeFeatures, SessionIndex, SessionInfo, }; use self::mock::{ diff --git a/polkadot/node/network/statement-distribution/Cargo.toml b/polkadot/node/network/statement-distribution/Cargo.toml index 2a9773ddde4b..08059353033d 100644 --- a/polkadot/node/network/statement-distribution/Cargo.toml +++ b/polkadot/node/network/statement-distribution/Cargo.toml @@ -40,6 +40,7 @@ sp-tracing = { workspace = true, default-features = true } sc-keystore = { workspace = true, default-features = true } sc-network = { workspace = true, default-features = true } futures-timer = { workspace = true } +polkadot-primitives = { workspace = true, features = ["test"] } polkadot-primitives-test-helpers = { workspace = true } rand_chacha = { workspace = true, default-features = true } polkadot-subsystem-bench = { workspace = true } diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs index a185b0021d21..1e7c7d0e8c07 100644 --- a/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs @@ -103,24 +103,21 @@ fn active_head_accepts_only_2_seconded_per_validator() { c.descriptor.relay_parent = parent_hash; c.descriptor.para_id = 1.into(); c - } - .into(); + }; let candidate_b = { let mut c = dummy_committed_candidate_receipt(dummy_hash()); c.descriptor.relay_parent = parent_hash; c.descriptor.para_id = 2.into(); c - } - .into(); + }; let candidate_c = { let mut c = dummy_committed_candidate_receipt(dummy_hash()); c.descriptor.relay_parent = parent_hash; c.descriptor.para_id = 3.into(); c - } - .into(); + }; let mut head_data = ActiveHeadData::new( IndexedVec::::from(validators), @@ -145,7 +142,7 @@ fn active_head_accepts_only_2_seconded_per_validator() { // note A let a_seconded_val_0 = SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate_a.clone()), + Statement::Seconded(candidate_a.into()), &signing_context, ValidatorIndex(0), &alice_public.into(), @@ -172,7 +169,7 @@ fn active_head_accepts_only_2_seconded_per_validator() { // note B let statement = SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate_b.clone()), + Statement::Seconded(candidate_b.clone().into()), &signing_context, ValidatorIndex(0), &alice_public.into(), @@ -189,7 +186,7 @@ fn active_head_accepts_only_2_seconded_per_validator() { // note C (beyond 2 - ignored) let statement = SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate_c.clone()), + Statement::Seconded(candidate_c.clone().into()), &signing_context, ValidatorIndex(0), &alice_public.into(), @@ -207,7 +204,7 @@ fn active_head_accepts_only_2_seconded_per_validator() { // note B (new validator) let statement = SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate_b.clone()), + Statement::Seconded(candidate_b.into()), &signing_context, ValidatorIndex(1), &bob_public.into(), @@ -224,7 +221,7 @@ fn active_head_accepts_only_2_seconded_per_validator() { // note C (new validator) let statement = SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate_c.clone()), + Statement::Seconded(candidate_c.into()), &signing_context, ValidatorIndex(1), &bob_public.into(), @@ -430,8 +427,7 @@ fn peer_view_update_sends_messages() { c.descriptor.relay_parent = hash_c; c.descriptor.para_id = ParaId::from(1_u32); c - } - .into(); + }; let candidate_hash = candidate.hash(); let old_view = view![hash_a, hash_b]; @@ -477,7 +473,7 @@ fn peer_view_update_sends_messages() { let statement = SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate.clone()), + Statement::Seconded(candidate.clone().into()), &signing_context, ValidatorIndex(0), &alice_public.into(), @@ -619,9 +615,8 @@ fn circulated_statement_goes_to_all_peers_with_view() { let mut c = dummy_committed_candidate_receipt(dummy_hash()); c.descriptor.relay_parent = hash_b; c.descriptor.para_id = ParaId::from(1_u32); - c - } - .into(); + c.into() + }; let peer_a = PeerId::random(); let peer_b = PeerId::random(); @@ -754,9 +749,8 @@ fn receiving_from_one_sends_to_another_and_to_candidate_backing() { let mut c = dummy_committed_candidate_receipt(dummy_hash()); c.descriptor.relay_parent = hash_a; c.descriptor.para_id = PARA_ID; - c - } - .into(); + c.into() + }; let peer_a = PeerId::random(); let peer_b = PeerId::random(); @@ -1208,7 +1202,7 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate.clone()), + Statement::Seconded(candidate.clone().into()), &signing_context, ValidatorIndex(0), &alice_public.into(), @@ -1346,7 +1340,7 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( let bad_candidate = { let mut bad = candidate.clone(); bad.descriptor.para_id = 0xeadbeaf.into(); - bad + bad.into() }; let response = StatementFetchingResponse::Statement(bad_candidate); outgoing.pending_response.send(Ok((response.encode(), ProtocolName::from("")))).unwrap(); @@ -1400,7 +1394,7 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( assert_eq!(req.candidate_hash, metadata.candidate_hash); // On retry, we should have reverse order: assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); - let response = StatementFetchingResponse::Statement(candidate.clone()); + let response = StatementFetchingResponse::Statement(candidate.clone().into()); outgoing.pending_response.send(Ok((response.encode(), ProtocolName::from("")))).unwrap(); } ); @@ -1526,7 +1520,7 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( req_cfg.inbound_queue.as_mut().unwrap().send(req).await.unwrap(); let StatementFetchingResponse::Statement(committed) = Decode::decode(&mut response_rx.await.unwrap().result.unwrap().as_ref()).unwrap(); - assert_eq!(committed, candidate); + assert_eq!(committed, candidate.into()); handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; }; @@ -1753,7 +1747,7 @@ fn delay_reputation_changes() { SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate.clone()), + Statement::Seconded(candidate.clone().into()), &signing_context, ValidatorIndex(0), &alice_public.into(), @@ -1893,7 +1887,7 @@ fn delay_reputation_changes() { bad.descriptor.para_id = 0xeadbeaf.into(); bad }; - let response = StatementFetchingResponse::Statement(bad_candidate); + let response = StatementFetchingResponse::Statement(bad_candidate.into()); outgoing.pending_response.send(Ok((response.encode(), ProtocolName::from("")))).unwrap(); } ); @@ -1937,7 +1931,7 @@ fn delay_reputation_changes() { assert_eq!(req.candidate_hash, metadata.candidate_hash); // On retry, we should have reverse order: assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); - let response = StatementFetchingResponse::Statement(candidate.clone()); + let response = StatementFetchingResponse::Statement(candidate.clone().into()); outgoing.pending_response.send(Ok((response.encode(), ProtocolName::from("")))).unwrap(); } ); @@ -2297,7 +2291,7 @@ fn share_prioritizes_backing_group() { SignedFullStatementWithPVD::sign( &keystore, - Statement::Seconded(candidate.clone()).supply_pvd(pvd), + Statement::Seconded(candidate.clone().into()).supply_pvd(pvd), &signing_context, ValidatorIndex(4), &ferdie_public.into(), @@ -2361,7 +2355,7 @@ fn share_prioritizes_backing_group() { req_cfg.inbound_queue.as_mut().unwrap().send(req).await.unwrap(); let StatementFetchingResponse::Statement(committed) = Decode::decode(&mut response_rx.await.unwrap().result.unwrap().as_ref()).unwrap(); - assert_eq!(committed, candidate); + assert_eq!(committed, candidate.into()); handle.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; }; @@ -2523,7 +2517,7 @@ fn peer_cant_flood_with_large_statements() { SignedFullStatement::sign( &keystore, - Statement::Seconded(candidate.clone()), + Statement::Seconded(candidate.clone().into()), &signing_context, ValidatorIndex(0), &alice_public.into(), diff --git a/polkadot/node/network/statement-distribution/src/v2/requests.rs b/polkadot/node/network/statement-distribution/src/v2/requests.rs index 4e48f5c4dd50..74f29710956f 100644 --- a/polkadot/node/network/statement-distribution/src/v2/requests.rs +++ b/polkadot/node/network/statement-distribution/src/v2/requests.rs @@ -1019,6 +1019,7 @@ mod tests { candidate_receipt.descriptor.persisted_validation_data_hash = persisted_validation_data.hash(); let candidate = candidate_receipt.hash(); + let candidate_receipt: CommittedCandidateReceipt = candidate_receipt.into(); let requested_peer_1 = PeerId::random(); let requested_peer_2 = PeerId::random(); @@ -1074,7 +1075,7 @@ mod tests { requested_peer: requested_peer_1, props: request_properties.clone(), response: Ok(AttestedCandidateResponse { - candidate_receipt: candidate_receipt.clone(), + candidate_receipt: candidate_receipt.clone().into(), persisted_validation_data: persisted_validation_data.clone(), statements, }), @@ -1114,7 +1115,7 @@ mod tests { requested_peer: requested_peer_2, props: request_properties, response: Ok(AttestedCandidateResponse { - candidate_receipt: candidate_receipt.clone(), + candidate_receipt: candidate_receipt.clone().into(), persisted_validation_data: persisted_validation_data.clone(), statements, }), @@ -1197,7 +1198,7 @@ mod tests { requested_peer, props: request_properties, response: Ok(AttestedCandidateResponse { - candidate_receipt: candidate_receipt.clone(), + candidate_receipt: candidate_receipt.clone().into(), persisted_validation_data: persisted_validation_data.clone(), statements, }), @@ -1236,6 +1237,7 @@ mod tests { candidate_receipt.descriptor.persisted_validation_data_hash = persisted_validation_data.hash(); let candidate = candidate_receipt.hash(); + let candidate_receipt: CommittedCandidateReceipt = candidate_receipt.into(); let requested_peer = PeerId::random(); let identifier = request_manager @@ -1417,7 +1419,7 @@ mod tests { requested_peer: requested_peer_1, props: request_properties.clone(), response: Ok(AttestedCandidateResponse { - candidate_receipt: candidate_receipt_1.clone(), + candidate_receipt: candidate_receipt_1.clone().into(), persisted_validation_data: persisted_validation_data_1.clone(), statements, }), diff --git a/polkadot/node/service/src/parachains_db/upgrade.rs b/polkadot/node/service/src/parachains_db/upgrade.rs index 770b477d11ec..52b010f0b5d0 100644 --- a/polkadot/node/service/src/parachains_db/upgrade.rs +++ b/polkadot/node/service/src/parachains_db/upgrade.rs @@ -463,7 +463,7 @@ mod tests { v3::migration_helpers::{v1_to_latest_sanity_check, v2_fill_test_data}, }; use polkadot_node_subsystem_util::database::kvdb_impl::DbAdapter; - use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_candidate_receipt_v2}; + use polkadot_primitives_test_helpers::dummy_candidate_receipt_v2; #[test] fn test_paritydb_migrate_0_to_1() { diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index eeada78c97d2..a26df4d1119a 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -327,6 +327,15 @@ impl From> for CandidateReceiptV2 { } } +impl From> for CommittedCandidateReceiptV2 { + fn from(value: super::v8::CommittedCandidateReceipt) -> Self { + CommittedCandidateReceiptV2 { + descriptor: value.descriptor.into(), + commitments: value.commitments, + } + } +} + impl CommittedCandidateReceiptV2 { /// Transforms this into a plain `CandidateReceipt`. pub fn to_plain(&self) -> CandidateReceiptV2 { diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index ed38683663d7..44bef71e1e9d 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -34,9 +34,9 @@ use assert_matches::assert_matches; use codec::DecodeAll; use frame_support::assert_noop; use polkadot_primitives::{ - BlockNumber, CandidateCommitments, CollatorId, CollatorSignature, + vstaging::MutateDescriptorV2, BlockNumber, CandidateCommitments, CollatorId, CollatorSignature, CompactStatement as Statement, Hash, SignedAvailabilityBitfield, SignedStatement, - ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, vstaging::MutateDescriptorV2, + ValidationCode, ValidatorId, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, }; use polkadot_primitives_test_helpers::dummy_validation_code; use sc_keystore::LocalKeystore; From c0aee8c93581a31b24e2ec9c63b1a76e7a791374 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 16 Sep 2024 15:30:50 +0300 Subject: [PATCH 105/130] check ump signal count and test Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/inclusion/mod.rs | 16 +++- .../parachains/src/paras_inherent/tests.rs | 79 ++++++++++++++++++- 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index 248fda8a3c56..683ebb61e404 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -440,6 +440,9 @@ pub(crate) enum UmpAcceptanceCheckErr { TotalSizeExceeded { total_size: u64, limit: u64 }, /// A para-chain cannot send UMP messages while it is offboarding. IsOffboarding, + /// The allowed number of `UMPSignal` messages in the queue was exceeded. + /// Currenly only one such message is allowed. + TooManyUMPSignals { count: u32 }, } impl fmt::Debug for UmpAcceptanceCheckErr { @@ -468,6 +471,9 @@ impl fmt::Debug for UmpAcceptanceCheckErr { UmpAcceptanceCheckErr::IsOffboarding => { write!(fmt, "upward message rejected because the para is off-boarding") }, + UmpAcceptanceCheckErr::TooManyUMPSignals { count } => { + write!(fmt, "the umpq queue has too many `UMPSignal` mesages ({} > 1 )", count) + }, } } } @@ -939,7 +945,15 @@ impl Pallet { let upward_messages = if let Some(separator_index) = upward_messages.iter().rposition(|message| message.is_empty()) { - upward_messages.split_at(separator_index).0 + let (upward_messages, ump_signals) = upward_messages.split_at(separator_index); + + if ump_signals.len() > 2 { + return Err(UmpAcceptanceCheckErr::TooManyUMPSignals { + count: ump_signals.len() as u32, + }) + } + + upward_messages } else { upward_messages }; diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 1078d6848c0c..6010350dc332 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -228,10 +228,13 @@ mod enter { } #[rstest] - #[case((true, false))] - #[case((true, true))] - #[case((false, true))] - fn include_backed_candidates_elastic_scaling(#[case] v2_descriptor: bool, injected_core: bool) { + #[case(true, false)] + #[case(true, true)] + #[case(false, true)] + fn include_backed_candidates_elastic_scaling( + #[case] v2_descriptor: bool, + #[case] injected_core: bool, + ) { // ParaId 0 has one pending candidate on core 0. // ParaId 1 has one pending candidate on core 1. // ParaId 2 has three pending candidates on cores 2, 3 and 4. @@ -1671,6 +1674,74 @@ mod enter { }); } + #[test] + fn too_many_ump_signals() { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + true, + ) + .unwrap(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); + + let unavailable_cores = vec![]; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + fill_claimqueue: true, + elastic_paras: [(2, 8)].into_iter().collect(), + unavailable_cores: unavailable_cores.clone(), + v2_descriptor: true, + candidate_modifier: Some(|mut candidate: CommittedCandidateReceiptV2| { + if candidate.descriptor.para_id() == 2.into() { + // Add an extra message so `verify_backed_candidates` fails. + candidate.commitments.upward_messages.force_push( + UMPSignal::SelectCore(CoreSelector(123 as u8), ClaimQueueOffset(2)) + .encode(), + ); + } + candidate + }), + }); + + let unfiltered_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 10 backed candidates) + assert_eq!(unfiltered_para_inherent_data.bitfields.len(), 50); + // * 10 v2 candidate descriptors. + assert_eq!(unfiltered_para_inherent_data.backed_candidates.len(), 10); + + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) + .unwrap(); + + let dispatch_error = Pallet::::enter( + frame_system::RawOrigin::None.into(), + unfiltered_para_inherent_data, + ) + .unwrap_err() + .error; + + // We expect `enter` to fail because the inherent data contains backed candidates with + // v2 descriptors. + assert_eq!(dispatch_error, Error::::CandidatesFilteredDuringExecution.into()); + }); + } + #[test] fn v2_descriptors_are_accepted() { let config = default_config(); From 1ef79523e24f1772b9ba644cf6fbe307b4e61b98 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 18 Sep 2024 22:14:38 +0300 Subject: [PATCH 106/130] remove unused Signed-off-by: Andrei Sandu --- polkadot/runtime/parachains/src/shared/migration.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/polkadot/runtime/parachains/src/shared/migration.rs b/polkadot/runtime/parachains/src/shared/migration.rs index a8b9612bb1c9..43d6249b6846 100644 --- a/polkadot/runtime/parachains/src/shared/migration.rs +++ b/polkadot/runtime/parachains/src/shared/migration.rs @@ -73,8 +73,6 @@ pub mod v0 { mod v1 { use super::*; - #[cfg(feature = "try-runtime")] - use codec::Decode; #[cfg(feature = "try-runtime")] use frame_support::{ ensure, From 5790b8e784aad2b075a7ec3a8067e8447c47a4a9 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 19 Sep 2024 12:42:16 +0300 Subject: [PATCH 107/130] fix prdoc Signed-off-by: Andrei Sandu --- prdoc/pr_5423.prdoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/prdoc/pr_5423.prdoc b/prdoc/pr_5423.prdoc index ee75b3d7849a..dbd685d73dc3 100644 --- a/prdoc/pr_5423.prdoc +++ b/prdoc/pr_5423.prdoc @@ -15,4 +15,6 @@ crates: - name: rococo-runtime bump: patch - name: westend-runtime - bump: patch \ No newline at end of file + bump: patch + - name: polkadot + bump: patch From ba9d3ffbfa7a032c3e9ecd734f5a8a78be6bc404 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 19 Sep 2024 15:45:21 +0300 Subject: [PATCH 108/130] more tests cases Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/inclusion/tests.rs | 50 ++++++- .../parachains/src/paras_inherent/tests.rs | 133 ++++++++++++------ 2 files changed, 135 insertions(+), 48 deletions(-) diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index f12f007e1677..87d21e209a49 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -26,8 +26,13 @@ use crate::{ shared::AllowedRelayParentsTracker, }; use polkadot_primitives::{ - effective_minimum_backing_votes, AvailabilityBitfield, CandidateDescriptor, - SignedAvailabilityBitfields, UncheckedSignedAvailabilityBitfields, + effective_minimum_backing_votes, + vstaging::{ + CandidateDescriptorV2, CandidateDescriptorVersion, ClaimQueueOffset, CoreSelector, + UMPSignal, UMP_SEPARATOR, + }, + AvailabilityBitfield, CandidateDescriptor, SignedAvailabilityBitfields, + UncheckedSignedAvailabilityBitfields, }; use assert_matches::assert_matches; @@ -262,6 +267,10 @@ pub(crate) struct TestCandidateBuilder { pub(crate) new_validation_code: Option, pub(crate) validation_code: ValidationCode, pub(crate) hrmp_watermark: BlockNumber, + /// Creates a v2 descriptor if set. + pub(crate) core_index: Option, + /// The core selector to use. + pub(crate) core_selector: Option, } impl std::default::Default for TestCandidateBuilder { @@ -277,14 +286,28 @@ impl std::default::Default for TestCandidateBuilder { new_validation_code: None, validation_code: dummy_validation_code(), hrmp_watermark: 0u32.into(), + core_index: None, + core_selector: None, } } } impl TestCandidateBuilder { pub(crate) fn build(self) -> CommittedCandidateReceipt { - CommittedCandidateReceipt { - descriptor: CandidateDescriptor { + let descriptor = if let Some(core_index) = self.core_index { + CandidateDescriptorV2::new( + self.para_id, + self.relay_parent, + core_index, + 0, + self.persisted_validation_data_hash, + self.pov_hash, + Default::default(), + self.para_head_hash.unwrap_or_else(|| self.head_data.hash()), + self.validation_code.hash(), + ) + } else { + CandidateDescriptor { para_id: self.para_id, pov_hash: self.pov_hash, relay_parent: self.relay_parent, @@ -301,14 +324,31 @@ impl TestCandidateBuilder { ) .expect("32 bytes; qed"), } - .into(), + .into() + }; + let mut ccr = CommittedCandidateReceipt { + descriptor, commitments: CandidateCommitments { head_data: self.head_data, new_validation_code: self.new_validation_code, hrmp_watermark: self.hrmp_watermark, ..Default::default() }, + }; + + if ccr.descriptor.version() == CandidateDescriptorVersion::V2 { + ccr.commitments.upward_messages.force_push(UMP_SEPARATOR); + + ccr.commitments.upward_messages.force_push( + UMPSignal::SelectCore( + CoreSelector(self.core_selector.unwrap_or_default()), + ClaimQueueOffset(0), + ) + .encode(), + ); } + + ccr } } diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index 6010350dc332..e991890df954 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -2520,19 +2520,12 @@ mod sanitizers { // Para 6 is not scheduled. One candidate supplied. // Para 7 is scheduled on core 7 and 8, but the candidate contains the wrong core index. // Para 8 is scheduled on core 9, but the candidate contains the wrong core index. - fn get_test_data_multiple_cores_per_para(core_index_enabled: bool) -> TestData { + fn get_test_data_multiple_cores_per_para( + core_index_enabled: bool, + v2_descriptor: bool, + ) -> TestData { const RELAY_PARENT_NUM: u32 = 3; - // Add the relay parent to `shared` pallet. Otherwise some code (e.g. filtering backing - // votes) won't behave correctly - shared::Pallet::::add_allowed_relay_parent( - default_header().hash(), - Default::default(), - Default::default(), - RELAY_PARENT_NUM, - 1, - ); - let header = default_header(); let relay_parent = header.hash(); let session_index = SessionIndex::from(0_u32); @@ -2651,6 +2644,21 @@ mod sanitizers { ), ])); + // Add the relay parent to `shared` pallet. Otherwise some code (e.g. filtering backing + // votes) won't behave correctly + shared::Pallet::::add_allowed_relay_parent( + relay_parent, + Default::default(), + scheduler::ClaimQueue::::get() + .into_iter() + .map(|(core_index, paras)| { + (core_index, paras.into_iter().map(|e| e.para_id()).collect()) + }) + .collect(), + RELAY_PARENT_NUM, + 1, + ); + // Set the on-chain included head data and current code hash. for id in 1..=8u32 { paras::Pallet::::set_current_head(ParaId::from(id), HeadData(vec![id as u8])); @@ -2680,6 +2688,14 @@ mod sanitizers { let mut backed_candidates = vec![]; let mut expected_backed_candidates_with_core = BTreeMap::new(); + let maybe_core_index = |core_index: CoreIndex| -> Option { + if !v2_descriptor { + None + } else { + Some(core_index) + } + }; + // Para 1 { let candidate = TestCandidateBuilder { @@ -2696,6 +2712,7 @@ mod sanitizers { hrmp_watermark: RELAY_PARENT_NUM, head_data: HeadData(vec![1, 1]), validation_code: ValidationCode(vec![1]), + core_index: maybe_core_index(CoreIndex(0)), ..Default::default() } .build(); @@ -2711,7 +2728,7 @@ mod sanitizers { core_index_enabled.then_some(CoreIndex(0 as u32)), ); backed_candidates.push(backed.clone()); - if core_index_enabled { + if core_index_enabled || v2_descriptor { expected_backed_candidates_with_core .entry(ParaId::from(1)) .or_insert(vec![]) @@ -2732,6 +2749,8 @@ mod sanitizers { .hash(), hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![1]), + core_index: maybe_core_index(CoreIndex(1)), + core_selector: Some(1), ..Default::default() } .build(); @@ -2746,7 +2765,7 @@ mod sanitizers { core_index_enabled.then_some(CoreIndex(1 as u32)), ); backed_candidates.push(backed.clone()); - if core_index_enabled { + if core_index_enabled || v2_descriptor { expected_backed_candidates_with_core .entry(ParaId::from(1)) .or_insert(vec![]) @@ -2769,6 +2788,7 @@ mod sanitizers { .hash(), hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![2]), + core_index: maybe_core_index(CoreIndex(2)), ..Default::default() } .build(); @@ -2783,7 +2803,7 @@ mod sanitizers { core_index_enabled.then_some(CoreIndex(2 as u32)), ); backed_candidates.push(backed.clone()); - if core_index_enabled { + if core_index_enabled || v2_descriptor { expected_backed_candidates_with_core .entry(ParaId::from(2)) .or_insert(vec![]) @@ -2806,6 +2826,7 @@ mod sanitizers { .hash(), hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![3]), + core_index: maybe_core_index(CoreIndex(4)), ..Default::default() } .build(); @@ -2841,6 +2862,7 @@ mod sanitizers { .hash(), hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![4]), + core_index: maybe_core_index(CoreIndex(5)), ..Default::default() } .build(); @@ -2875,6 +2897,7 @@ mod sanitizers { .hash(), hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![4]), + core_index: maybe_core_index(CoreIndex(5)), ..Default::default() } .build(); @@ -2908,6 +2931,7 @@ mod sanitizers { .hash(), hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![6]), + core_index: maybe_core_index(CoreIndex(6)), ..Default::default() } .build(); @@ -2939,6 +2963,7 @@ mod sanitizers { .hash(), hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![7]), + core_index: maybe_core_index(CoreIndex(6)), ..Default::default() } .build(); @@ -2970,6 +2995,7 @@ mod sanitizers { .hash(), hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![8]), + core_index: maybe_core_index(CoreIndex(7)), ..Default::default() } .build(); @@ -2984,7 +3010,7 @@ mod sanitizers { core_index_enabled.then_some(CoreIndex(7 as u32)), ); backed_candidates.push(backed.clone()); - if !core_index_enabled { + if !core_index_enabled && !v2_descriptor { expected_backed_candidates_with_core .entry(ParaId::from(8)) .or_insert(vec![]) @@ -3045,14 +3071,6 @@ mod sanitizers { let header = default_header(); let relay_parent = header.hash(); - shared::Pallet::::add_allowed_relay_parent( - relay_parent, - Default::default(), - Default::default(), - RELAY_PARENT_NUM, - 1, - ); - let session_index = SessionIndex::from(0_u32); let keystore = LocalKeystore::in_memory(); @@ -3164,6 +3182,19 @@ mod sanitizers { ), ])); + shared::Pallet::::add_allowed_relay_parent( + relay_parent, + Default::default(), + scheduler::ClaimQueue::::get() + .into_iter() + .map(|(core_index, paras)| { + (core_index, paras.into_iter().map(|e| e.para_id()).collect()) + }) + .collect(), + RELAY_PARENT_NUM, + 1, + ); + // Set the on-chain included head data and current code hash. for id in 1..=4u32 { paras::Pallet::::set_current_head(ParaId::from(id), HeadData(vec![id as u8])); @@ -3958,15 +3989,20 @@ mod sanitizers { } #[rstest] - #[case(false)] - #[case(true)] - fn test_with_multiple_cores_per_para(#[case] core_index_enabled: bool) { + #[case(false, false)] + #[case(true, false)] + #[case(false, true)] + #[case(true, true)] + fn test_with_multiple_cores_per_para( + #[case] core_index_enabled: bool, + #[case] v2_descriptor: bool, + ) { new_test_ext(default_config()).execute_with(|| { let TestData { backed_candidates, expected_backed_candidates_with_core, scheduled_paras: scheduled, - } = get_test_data_multiple_cores_per_para(core_index_enabled); + } = get_test_data_multiple_cores_per_para(core_index_enabled, v2_descriptor); assert_eq!( sanitize_backed_candidates::( @@ -3975,7 +4011,7 @@ mod sanitizers { BTreeSet::new(), scheduled, core_index_enabled, - false, + v2_descriptor, ), expected_backed_candidates_with_core, ); @@ -4162,17 +4198,22 @@ mod sanitizers { // nothing is scheduled, so no paraids match, thus all backed candidates are skipped #[rstest] - #[case(false, false)] - #[case(true, true)] - #[case(false, true)] - #[case(true, false)] + #[case(false, false, true)] + #[case(true, true, true)] + #[case(false, true, true)] + #[case(true, false, true)] + #[case(false, false, false)] + #[case(true, true, false)] + #[case(false, true, false)] + #[case(true, false, false)] fn nothing_scheduled( #[case] core_index_enabled: bool, #[case] multiple_cores_per_para: bool, + #[case] v2_descriptor: bool, ) { new_test_ext(default_config()).execute_with(|| { let TestData { backed_candidates, .. } = if multiple_cores_per_para { - get_test_data_multiple_cores_per_para(core_index_enabled) + get_test_data_multiple_cores_per_para(core_index_enabled, v2_descriptor) } else { get_test_data_one_core_per_para(core_index_enabled) }; @@ -4229,8 +4270,14 @@ mod sanitizers { } // candidates that have concluded as invalid are filtered out, as well as their descendants. - #[test] - fn concluded_invalid_are_filtered_out_multiple_cores_per_para() { + #[rstest] + #[case(false, true)] + #[case(true, false)] + #[case(true, true)] + fn concluded_invalid_are_filtered_out_multiple_cores_per_para( + #[case] core_index_enabled: bool, + #[case] v2_descriptor: bool, + ) { // Mark the first candidate of paraid 1 as invalid. Its descendant should also // be dropped. Also mark the candidate of paraid 3 as invalid. new_test_ext(default_config()).execute_with(|| { @@ -4239,7 +4286,7 @@ mod sanitizers { scheduled_paras: scheduled, mut expected_backed_candidates_with_core, .. - } = get_test_data_multiple_cores_per_para(true); + } = get_test_data_multiple_cores_per_para(core_index_enabled, v2_descriptor); let mut invalid_set = std::collections::BTreeSet::new(); @@ -4258,8 +4305,8 @@ mod sanitizers { &shared::AllowedRelayParents::::get(), invalid_set, scheduled, - true, - false, + core_index_enabled, + v2_descriptor, ); // We'll be left with candidates from paraid 2 and 4. @@ -4278,7 +4325,7 @@ mod sanitizers { scheduled_paras: scheduled, mut expected_backed_candidates_with_core, .. - } = get_test_data_multiple_cores_per_para(true); + } = get_test_data_multiple_cores_per_para(core_index_enabled, v2_descriptor); let mut invalid_set = std::collections::BTreeSet::new(); @@ -4295,8 +4342,8 @@ mod sanitizers { &shared::AllowedRelayParents::::get(), invalid_set, scheduled, - true, - false, + core_index_enabled, + v2_descriptor, ); // Only the second candidate of paraid 1 should be removed. @@ -4507,7 +4554,7 @@ mod sanitizers { // Disable Bob, only the second candidate of paraid 1 should be removed. new_test_ext(default_config()).execute_with(|| { let TestData { mut expected_backed_candidates_with_core, .. } = - get_test_data_multiple_cores_per_para(true); + get_test_data_multiple_cores_per_para(true, false); set_disabled_validators(vec![1]); @@ -4529,7 +4576,7 @@ mod sanitizers { for disabled in [vec![0], vec![0, 1]] { new_test_ext(default_config()).execute_with(|| { let TestData { mut expected_backed_candidates_with_core, .. } = - get_test_data_multiple_cores_per_para(true); + get_test_data_multiple_cores_per_para(true, false); set_disabled_validators(disabled); From 0dcf739551f3cff82a35111262216b7278c91089 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 20 Sep 2024 14:09:48 +0300 Subject: [PATCH 109/130] workaround #64 Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/runtime_api_impl/v10.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs index ead825b38f07..6004867f9cae 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs @@ -451,7 +451,16 @@ pub fn backing_state( // // Thus, minimum relay parent is ensured to have asynchronous backing enabled. let now = frame_system::Pallet::::block_number(); - let min_relay_parent_number = shared::AllowedRelayParents::::get() + + // Workaround for issue #64. + let allowed_relay_parents = + if shared::Pallet::::on_chain_storage_version() == StorageVersion::new(0) { + shared::migration::v0::AllowedRelayParents::::get().into() + } else { + shared::AllowedRelayParents::::get() + }; + + let min_relay_parent_number = allowed_relay_parents .hypothetical_earliest_block_number(now, config.async_backing_params.allowed_ancestry_len); let required_parent = paras::Heads::::get(para_id)?; From 604273b6d3ccec41a2e1bb1fe45db9ccdd9ee4fd Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 23 Sep 2024 13:01:29 +0300 Subject: [PATCH 110/130] stricter UMP signal checks and tests Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/inclusion/mod.rs | 11 ++- .../parachains/src/paras_inherent/tests.rs | 69 ++++++++++++++++++- polkadot/runtime/parachains/src/ump_tests.rs | 2 +- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index 683ebb61e404..79029952e7c1 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -443,6 +443,8 @@ pub(crate) enum UmpAcceptanceCheckErr { /// The allowed number of `UMPSignal` messages in the queue was exceeded. /// Currenly only one such message is allowed. TooManyUMPSignals { count: u32 }, + /// The UMP queue contains an invalid `UMPSignal` + InvalidUMPSignal, } impl fmt::Debug for UmpAcceptanceCheckErr { @@ -472,7 +474,10 @@ impl fmt::Debug for UmpAcceptanceCheckErr { write!(fmt, "upward message rejected because the para is off-boarding") }, UmpAcceptanceCheckErr::TooManyUMPSignals { count } => { - write!(fmt, "the umpq queue has too many `UMPSignal` mesages ({} > 1 )", count) + write!(fmt, "the ump queue has too many `UMPSignal` mesages ({} > 1 )", count) + }, + UmpAcceptanceCheckErr::InvalidUMPSignal => { + write!(fmt, "the ump queue contains an invalid UMP signal") }, } } @@ -953,6 +958,10 @@ impl Pallet { }) } + if ump_signals.len() == 1 { + return Err(UmpAcceptanceCheckErr::InvalidUMPSignal) + } + upward_messages } else { upward_messages diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index e55ab0ea5248..88af8332dccd 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1744,6 +1744,73 @@ mod enter { }); } + #[test] + fn invalid_ump_signals() { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + true, + ) + .unwrap(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); + + let unavailable_cores = vec![]; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + fill_claimqueue: true, + elastic_paras: [(2, 8)].into_iter().collect(), + unavailable_cores: unavailable_cores.clone(), + v2_descriptor: true, + candidate_modifier: Some(|mut candidate: CommittedCandidateReceiptV2| { + if candidate.descriptor.para_id() == 1.into() { + // Drop the core selector to make it invalid + candidate + .commitments + .upward_messages + .truncate(candidate.commitments.upward_messages.len() - 1); + } + candidate + }), + }); + + let unfiltered_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 10 backed candidates) + assert_eq!(unfiltered_para_inherent_data.bitfields.len(), 50); + // * 10 v2 candidate descriptors. + assert_eq!(unfiltered_para_inherent_data.backed_candidates.len(), 10); + + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) + .unwrap(); + + let dispatch_error = Pallet::::enter( + frame_system::RawOrigin::None.into(), + unfiltered_para_inherent_data, + ) + .unwrap_err() + .error; + + // We expect `enter` to fail because the inherent data contains backed candidates with + // v2 descriptors. + assert_eq!(dispatch_error, Error::::CandidatesFilteredDuringExecution.into()); + }); + } #[test] fn v2_descriptors_are_accepted() { let config = default_config(); @@ -1939,7 +2006,7 @@ mod enter { }); } - // A test to ensure that the `paras_inherent`` filters out candidates with invalid + // A test to ensure that the `paras_inherent` filters out candidates with invalid // session index in the descriptor. #[test] fn invalid_session_index() { diff --git a/polkadot/runtime/parachains/src/ump_tests.rs b/polkadot/runtime/parachains/src/ump_tests.rs index 571fc5ab2271..d6cef850fb6a 100644 --- a/polkadot/runtime/parachains/src/ump_tests.rs +++ b/polkadot/runtime/parachains/src/ump_tests.rs @@ -164,7 +164,7 @@ mod check_upward_messages { let max_per_candidate = configuration::ActiveConfig::::get().max_upward_message_num_per_candidate; - for msg_size in 0..=max_size { + for msg_size in 1..=max_size { check(P_0, vec![vec![0; msg_size as usize]], None); } for msg_size in max_size + 1..max_size + 10 { From 9c4e2aee40eaf8b2d4afb9b780ea166bcb7c7dc7 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 23 Sep 2024 13:01:29 +0300 Subject: [PATCH 111/130] stricter UMP signal checks and tests Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/inclusion/mod.rs | 11 ++- .../parachains/src/paras_inherent/tests.rs | 69 ++++++++++++++++++- polkadot/runtime/parachains/src/ump_tests.rs | 2 +- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/parachains/src/inclusion/mod.rs b/polkadot/runtime/parachains/src/inclusion/mod.rs index 683ebb61e404..79029952e7c1 100644 --- a/polkadot/runtime/parachains/src/inclusion/mod.rs +++ b/polkadot/runtime/parachains/src/inclusion/mod.rs @@ -443,6 +443,8 @@ pub(crate) enum UmpAcceptanceCheckErr { /// The allowed number of `UMPSignal` messages in the queue was exceeded. /// Currenly only one such message is allowed. TooManyUMPSignals { count: u32 }, + /// The UMP queue contains an invalid `UMPSignal` + InvalidUMPSignal, } impl fmt::Debug for UmpAcceptanceCheckErr { @@ -472,7 +474,10 @@ impl fmt::Debug for UmpAcceptanceCheckErr { write!(fmt, "upward message rejected because the para is off-boarding") }, UmpAcceptanceCheckErr::TooManyUMPSignals { count } => { - write!(fmt, "the umpq queue has too many `UMPSignal` mesages ({} > 1 )", count) + write!(fmt, "the ump queue has too many `UMPSignal` mesages ({} > 1 )", count) + }, + UmpAcceptanceCheckErr::InvalidUMPSignal => { + write!(fmt, "the ump queue contains an invalid UMP signal") }, } } @@ -953,6 +958,10 @@ impl Pallet { }) } + if ump_signals.len() == 1 { + return Err(UmpAcceptanceCheckErr::InvalidUMPSignal) + } + upward_messages } else { upward_messages diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index e991890df954..f5c3d5077764 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1742,6 +1742,73 @@ mod enter { }); } + #[test] + fn invalid_ump_signals() { + let config = default_config(); + assert!(config.configuration.config.scheduler_params.lookahead > 0); + new_test_ext(config).execute_with(|| { + // Set the elastic scaling MVP feature. + configuration::Pallet::::set_node_feature( + RuntimeOrigin::root(), + FeatureIndex::CandidateReceiptV2 as u8, + true, + ) + .unwrap(); + + let mut backed_and_concluding = BTreeMap::new(); + backed_and_concluding.insert(0, 1); + backed_and_concluding.insert(1, 1); + backed_and_concluding.insert(2, 1); + + let unavailable_cores = vec![]; + + let scenario = make_inherent_data(TestConfig { + dispute_statements: BTreeMap::new(), + dispute_sessions: vec![], // No disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + fill_claimqueue: true, + elastic_paras: [(2, 8)].into_iter().collect(), + unavailable_cores: unavailable_cores.clone(), + v2_descriptor: true, + candidate_modifier: Some(|mut candidate: CommittedCandidateReceiptV2| { + if candidate.descriptor.para_id() == 1.into() { + // Drop the core selector to make it invalid + candidate + .commitments + .upward_messages + .truncate(candidate.commitments.upward_messages.len() - 1); + } + candidate + }), + }); + + let unfiltered_para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 10 backed candidates) + assert_eq!(unfiltered_para_inherent_data.bitfields.len(), 50); + // * 10 v2 candidate descriptors. + assert_eq!(unfiltered_para_inherent_data.backed_candidates.len(), 10); + + let mut inherent_data = InherentData::new(); + inherent_data + .put_data(PARACHAINS_INHERENT_IDENTIFIER, &unfiltered_para_inherent_data) + .unwrap(); + + let dispatch_error = Pallet::::enter( + frame_system::RawOrigin::None.into(), + unfiltered_para_inherent_data, + ) + .unwrap_err() + .error; + + // We expect `enter` to fail because the inherent data contains backed candidates with + // v2 descriptors. + assert_eq!(dispatch_error, Error::::CandidatesFilteredDuringExecution.into()); + }); + } #[test] fn v2_descriptors_are_accepted() { let config = default_config(); @@ -1937,7 +2004,7 @@ mod enter { }); } - // A test to ensure that the `paras_inherent`` filters out candidates with invalid + // A test to ensure that the `paras_inherent` filters out candidates with invalid // session index in the descriptor. #[test] fn invalid_session_index() { diff --git a/polkadot/runtime/parachains/src/ump_tests.rs b/polkadot/runtime/parachains/src/ump_tests.rs index 571fc5ab2271..d6cef850fb6a 100644 --- a/polkadot/runtime/parachains/src/ump_tests.rs +++ b/polkadot/runtime/parachains/src/ump_tests.rs @@ -164,7 +164,7 @@ mod check_upward_messages { let max_per_candidate = configuration::ActiveConfig::::get().max_upward_message_num_per_candidate; - for msg_size in 0..=max_size { + for msg_size in 1..=max_size { check(P_0, vec![vec![0; msg_size as usize]], None); } for msg_size in max_size + 1..max_size + 10 { From 43bbb9dd0d0f966ab07adf51d126433f1f74a52b Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 24 Sep 2024 11:35:57 +0300 Subject: [PATCH 112/130] type alias Signed-off-by: Andrei Sandu --- polkadot/primitives/src/vstaging/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index ebd93ce77091..bc687f7e2fbe 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -460,7 +460,7 @@ impl CommittedCandidateReceiptV2 { /// between `ParaId` and the cores assigned per depth. pub fn check_core_index( &self, - cores_per_para: &BTreeMap>>, + cores_per_para: &TransposedClaimQueue, ) -> Result<(), CandidateReceiptError> { match self.descriptor.version() { // Don't check v1 descriptors. @@ -750,11 +750,14 @@ impl From> for super::v8::CoreState { } } +/// The claim queue mapped by parachain id. +pub type TransposedClaimQueue = BTreeMap>>; + /// Returns a mapping between the para id and the core indices assigned at different /// depths in the claim queue. pub fn transpose_claim_queue( claim_queue: BTreeMap>, -) -> BTreeMap>> { +) -> TransposedClaimQueue { let mut per_para_claim_queue = BTreeMap::new(); for (core, paras) in claim_queue { From a493225c66420c08b68893e3a62d0fe377c891ec Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 24 Sep 2024 11:40:11 +0300 Subject: [PATCH 113/130] remove unused Signed-off-by: Andrei Sandu --- cumulus/client/pov-recovery/src/tests.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cumulus/client/pov-recovery/src/tests.rs b/cumulus/client/pov-recovery/src/tests.rs index 3b7abab48d38..1355d559a2c9 100644 --- a/cumulus/client/pov-recovery/src/tests.rs +++ b/cumulus/client/pov-recovery/src/tests.rs @@ -18,8 +18,7 @@ use super::*; use assert_matches::assert_matches; use codec::{Decode, Encode}; use cumulus_primitives_core::relay_chain::{ - vstaging::{CandidateDescriptorV2, CoreState}, - BlockId, CandidateCommitments, CandidateDescriptor, + vstaging::CoreState, BlockId, CandidateCommitments, CandidateDescriptor, }; use cumulus_relay_chain_interface::{ InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption, PHash, PHeader, From 73525776ffb9e724fd703e01e592d5737c7f93ae Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 24 Sep 2024 13:01:45 +0300 Subject: [PATCH 114/130] add prdoc Signed-off-by: Andrei Sandu --- prdoc/pr_5679.prdoc | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 prdoc/pr_5679.prdoc diff --git a/prdoc/pr_5679.prdoc b/prdoc/pr_5679.prdoc new file mode 100644 index 000000000000..988d6408cec0 --- /dev/null +++ b/prdoc/pr_5679.prdoc @@ -0,0 +1,42 @@ +title: "Switch to new `CandidateReceipt` primitives" + +doc: + - audience: Node Dev + description: | + This change is just plumbing work and updates all crate interfaces to use the new primitives. + Id doesn't alter any functionality and is required before implementing RFC103 on the + node side. + +crates: + - name: polkadot-primitives + bump: minor + - name: polkadot-runtime-parachains + bump: minor + - name: cumulus-client-consensus-common + bump: major + - name: cumulus-client-pov-recovery + bump: major + - name: cumulus-relay-chain-interface + bump: major + - name: polkadot-node-core-candidate-validation + bump: major + - name: polkadot-node-core-dispute-coordinator + bump: major + - name: polkadot-node-core-parachains-inherent + bump: major + - name: polkadot-node-core-prospective-parachains + bump: major + - name: polkadot-node-core-provisioner + bump: major + - name: polkadot-node-core-runtime-api + bump: major + - name: cumulus-client-network + bump: major + - name: cumulus-relay-chain-inprocess-interface + bump: major + - name: cumulus-client-consensus-aura + bump: major + - name: cumulus-relay-chain-minimal-node + bump: major + - name: cumulus-relay-chain-rpc-interface + bump: major From c9e44d1865faa1b8dcd9939a9974f3b7a183a435 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 24 Sep 2024 13:07:17 +0300 Subject: [PATCH 115/130] fix merge damage Signed-off-by: Andrei Sandu --- .../client/consensus/aura/src/collators/mod.rs | 2 +- cumulus/client/relay-chain-interface/src/lib.rs | 2 +- polkadot/node/core/approval-voting/src/lib.rs | 17 +++++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/cumulus/client/consensus/aura/src/collators/mod.rs b/cumulus/client/consensus/aura/src/collators/mod.rs index 44a57993ea2b..2346af16caac 100644 --- a/cumulus/client/consensus/aura/src/collators/mod.rs +++ b/cumulus/client/consensus/aura/src/collators/mod.rs @@ -30,7 +30,7 @@ use cumulus_primitives_core::{relay_chain::Hash as ParaHash, BlockT, ClaimQueueO use cumulus_relay_chain_interface::RelayChainInterface; use polkadot_node_subsystem_util::runtime::ClaimQueueSnapshot; use polkadot_primitives::{ - vstaging::CoreState, AsyncBackingParams, CoreIndex, Hash as RelayHash, Id as ParaId, + AsyncBackingParams, CoreIndex, Hash as RelayHash, Id as ParaId, OccupiedCoreAssumption, ValidationCodeHash, }; use sc_consensus_aura::{standalone as aura_internal, AuraApi}; diff --git a/cumulus/client/relay-chain-interface/src/lib.rs b/cumulus/client/relay-chain-interface/src/lib.rs index 7202055a4883..c3742167898d 100644 --- a/cumulus/client/relay-chain-interface/src/lib.rs +++ b/cumulus/client/relay-chain-interface/src/lib.rs @@ -35,7 +35,7 @@ pub use cumulus_primitives_core::{ relay_chain::{ vstaging::{CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState}, BlockNumber, Hash as PHash, Header as PHeader, InboundHrmpMessage, OccupiedCoreAssumption, - SessionIndex, ValidationCodeHash, ValidatorId, + SessionIndex, ValidationCodeHash, ValidatorId, CoreIndex, }, InboundDownwardMessage, ParaId, PersistedValidationData, }; diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index 27f0342fbdfe..314cbcda26c0 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -3511,14 +3511,15 @@ async fn launch_approval< .with_string_tag("block-hash", format!("{:?}", block_hash)) .with_stage(jaeger::Stage::ApprovalChecking); - ctx.send_message(RuntimeApiMessage::Request( - block_hash, - RuntimeApiRequest::ValidationCodeByHash( - candidate.descriptor.validation_code_hash(), - code_tx, - ), - )) - .await; + sender + .send_message(RuntimeApiMessage::Request( + block_hash, + RuntimeApiRequest::ValidationCodeByHash( + candidate.descriptor.validation_code_hash(), + code_tx, + ), + )) + .await; let candidate = candidate.clone(); let metrics_guard = StaleGuard(Some(metrics)); From bf948a7989e6b6edc8d35b0b237351a5cf4c402c Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 24 Sep 2024 14:20:57 +0300 Subject: [PATCH 116/130] fix Signed-off-by: Andrei Sandu --- cumulus/client/relay-chain-inprocess-interface/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs index 076db8866f38..24be5998e3a6 100644 --- a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs +++ b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs @@ -28,6 +28,7 @@ use cumulus_primitives_core::{ vstaging::{CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState}, Block as PBlock, BlockId, BlockNumber, Hash as PHash, Header as PHeader, InboundHrmpMessage, OccupiedCoreAssumption, SessionIndex, ValidationCodeHash, ValidatorId, + CoreIndex, }, InboundDownwardMessage, ParaId, PersistedValidationData, }; From fd9dfee9af7525226951dd0fa3a1937e8c8b308e Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 26 Sep 2024 17:23:42 +0300 Subject: [PATCH 117/130] fix some builds Signed-off-by: Andrei Sandu --- cumulus/client/pov-recovery/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cumulus/client/pov-recovery/src/tests.rs b/cumulus/client/pov-recovery/src/tests.rs index eb6f9c437b61..4cc9f1ecd4b5 100644 --- a/cumulus/client/pov-recovery/src/tests.rs +++ b/cumulus/client/pov-recovery/src/tests.rs @@ -29,7 +29,7 @@ use cumulus_test_client::{ Sr25519Keyring, }; use futures::{channel::mpsc, SinkExt}; -use polkadot_node_primitives::AvailableData; +use polkadot_node_primitives::{CoreIndex, AvailableData}; use polkadot_node_subsystem::{messages::AvailabilityRecoveryMessage, RecoveryError, TimeoutExt}; use rstest::rstest; use sc_client_api::{ From 5bd465b135e6ca74658557f4210333ce03642e13 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 26 Sep 2024 17:37:24 +0300 Subject: [PATCH 118/130] fix the fix Signed-off-by: Andrei Sandu --- cumulus/client/consensus/aura/src/collators/mod.rs | 4 ++-- cumulus/client/pov-recovery/src/tests.rs | 4 ++-- cumulus/client/relay-chain-inprocess-interface/src/lib.rs | 3 +-- cumulus/client/relay-chain-interface/src/lib.rs | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/cumulus/client/consensus/aura/src/collators/mod.rs b/cumulus/client/consensus/aura/src/collators/mod.rs index 2346af16caac..89070607fbab 100644 --- a/cumulus/client/consensus/aura/src/collators/mod.rs +++ b/cumulus/client/consensus/aura/src/collators/mod.rs @@ -30,8 +30,8 @@ use cumulus_primitives_core::{relay_chain::Hash as ParaHash, BlockT, ClaimQueueO use cumulus_relay_chain_interface::RelayChainInterface; use polkadot_node_subsystem_util::runtime::ClaimQueueSnapshot; use polkadot_primitives::{ - AsyncBackingParams, CoreIndex, Hash as RelayHash, Id as ParaId, - OccupiedCoreAssumption, ValidationCodeHash, + AsyncBackingParams, CoreIndex, Hash as RelayHash, Id as ParaId, OccupiedCoreAssumption, + ValidationCodeHash, }; use sc_consensus_aura::{standalone as aura_internal, AuraApi}; use sp_api::ProvideRuntimeApi; diff --git a/cumulus/client/pov-recovery/src/tests.rs b/cumulus/client/pov-recovery/src/tests.rs index 4cc9f1ecd4b5..d528a92a52a8 100644 --- a/cumulus/client/pov-recovery/src/tests.rs +++ b/cumulus/client/pov-recovery/src/tests.rs @@ -18,7 +18,7 @@ use super::*; use assert_matches::assert_matches; use codec::{Decode, Encode}; use cumulus_primitives_core::relay_chain::{ - vstaging::CoreState, BlockId, CandidateCommitments, CandidateDescriptor, + vstaging::CoreState, BlockId, CandidateCommitments, CandidateDescriptor, CoreIndex, }; use cumulus_relay_chain_interface::{ InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption, PHash, PHeader, @@ -29,7 +29,7 @@ use cumulus_test_client::{ Sr25519Keyring, }; use futures::{channel::mpsc, SinkExt}; -use polkadot_node_primitives::{CoreIndex, AvailableData}; +use polkadot_node_primitives::AvailableData; use polkadot_node_subsystem::{messages::AvailabilityRecoveryMessage, RecoveryError, TimeoutExt}; use rstest::rstest; use sc_client_api::{ diff --git a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs index 24be5998e3a6..7692dfd3a157 100644 --- a/cumulus/client/relay-chain-inprocess-interface/src/lib.rs +++ b/cumulus/client/relay-chain-inprocess-interface/src/lib.rs @@ -26,9 +26,8 @@ use cumulus_primitives_core::{ relay_chain::{ runtime_api::ParachainHost, vstaging::{CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState}, - Block as PBlock, BlockId, BlockNumber, Hash as PHash, Header as PHeader, + Block as PBlock, BlockId, BlockNumber, CoreIndex, Hash as PHash, Header as PHeader, InboundHrmpMessage, OccupiedCoreAssumption, SessionIndex, ValidationCodeHash, ValidatorId, - CoreIndex, }, InboundDownwardMessage, ParaId, PersistedValidationData, }; diff --git a/cumulus/client/relay-chain-interface/src/lib.rs b/cumulus/client/relay-chain-interface/src/lib.rs index c3742167898d..4a49eada292a 100644 --- a/cumulus/client/relay-chain-interface/src/lib.rs +++ b/cumulus/client/relay-chain-interface/src/lib.rs @@ -34,8 +34,8 @@ use cumulus_primitives_core::relay_chain::{BlockId, Hash as RelayHash}; pub use cumulus_primitives_core::{ relay_chain::{ vstaging::{CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState}, - BlockNumber, Hash as PHash, Header as PHeader, InboundHrmpMessage, OccupiedCoreAssumption, - SessionIndex, ValidationCodeHash, ValidatorId, CoreIndex, + BlockNumber, CoreIndex, Hash as PHash, Header as PHeader, InboundHrmpMessage, + OccupiedCoreAssumption, SessionIndex, ValidationCodeHash, ValidatorId, }, InboundDownwardMessage, ParaId, PersistedValidationData, }; From 53bb5b8f250bc27ef2012f8ac30e4fbc9b6a75ab Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Fri, 27 Sep 2024 22:57:08 +0300 Subject: [PATCH 119/130] toml fixes Signed-off-by: Andrei Sandu --- polkadot/node/collation-generation/Cargo.toml | 1 - polkadot/node/core/backing/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/polkadot/node/collation-generation/Cargo.toml b/polkadot/node/collation-generation/Cargo.toml index df9768658443..855b6b0e86eb 100644 --- a/polkadot/node/collation-generation/Cargo.toml +++ b/polkadot/node/collation-generation/Cargo.toml @@ -29,4 +29,3 @@ assert_matches = { workspace = true } rstest = { workspace = true } sp-keyring = { workspace = true, default-features = true } polkadot-primitives = { workspace = true, features = ["test"] } - diff --git a/polkadot/node/core/backing/Cargo.toml b/polkadot/node/core/backing/Cargo.toml index 09094bfd9c68..35a93aec26c0 100644 --- a/polkadot/node/core/backing/Cargo.toml +++ b/polkadot/node/core/backing/Cargo.toml @@ -36,4 +36,3 @@ rstest = { workspace = true } polkadot-node-subsystem-test-helpers = { workspace = true } polkadot-primitives-test-helpers = { workspace = true } polkadot-primitives = { workspace = true, features = ["test"] } - From 555c91b974b9869faaf096fd4878532d6e9c506f Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 17 Oct 2024 16:24:55 +0200 Subject: [PATCH 120/130] remove bogus code Signed-off-by: Andrei Sandu --- .../runtime/parachains/src/runtime_api_impl/v10.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs index 6004867f9cae..443afdb213e5 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v10.rs @@ -452,15 +452,7 @@ pub fn backing_state( // Thus, minimum relay parent is ensured to have asynchronous backing enabled. let now = frame_system::Pallet::::block_number(); - // Workaround for issue #64. - let allowed_relay_parents = - if shared::Pallet::::on_chain_storage_version() == StorageVersion::new(0) { - shared::migration::v0::AllowedRelayParents::::get().into() - } else { - shared::AllowedRelayParents::::get() - }; - - let min_relay_parent_number = allowed_relay_parents + let min_relay_parent_number = shared::AllowedRelayParents::::get() .hypothetical_earliest_block_number(now, config.async_backing_params.allowed_ancestry_len); let required_parent = paras::Heads::::get(para_id)?; From 4b2c06fc1397ed6f94df99248c337ae159bff838 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 17 Oct 2024 17:43:51 +0200 Subject: [PATCH 121/130] fix build Signed-off-by: Andrei Sandu --- polkadot/node/core/approval-voting/src/lib.rs | 2 +- polkadot/node/core/backing/src/lib.rs | 4 ++-- polkadot/node/core/candidate-validation/src/lib.rs | 2 +- .../node/core/dispute-coordinator/src/participation/mod.rs | 2 +- polkadot/node/subsystem-types/src/messages.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index 5ecb07941d04..18e98c5a9d98 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -54,7 +54,7 @@ use polkadot_node_subsystem_util::{ use polkadot_primitives::{ vstaging::CandidateReceiptV2 as CandidateReceipt, ApprovalVoteMultipleCandidates, ApprovalVotingParams, BlockNumber, CandidateHash, CandidateIndex, CoreIndex, ExecutorParams, - GroupIndex, Hash, PvfExecKind, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, + GroupIndex, Hash, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature, }; use sc_keystore::LocalKeystore; diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs index e0b21bfc9e00..d4e742495bec 100644 --- a/polkadot/node/core/backing/src/lib.rs +++ b/polkadot/node/core/backing/src/lib.rs @@ -114,7 +114,7 @@ use polkadot_primitives::{ CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, }, CandidateCommitments, CandidateHash, CoreIndex, ExecutorParams, GroupIndex, GroupRotationInfo, - Hash, Id as ParaId, IndexedVec, NodeFeatures, PersistedValidationData, PvfExecKind, + Hash, Id as ParaId, IndexedVec, NodeFeatures, PersistedValidationData, SessionIndex, SigningContext, ValidationCode, ValidatorId, ValidatorIndex, ValidatorSignature, ValidityAttestation, }; @@ -631,7 +631,7 @@ async fn request_candidate_validation( executor_params: ExecutorParams, ) -> Result { let (tx, rx) = oneshot::channel(); - let is_system = candidate_receipt.descriptor.para_id.is_system(); + let is_system = candidate_receipt.descriptor.para_id().is_system(); sender .send_message(CandidateValidationMessage::ValidateFromExhaustive { diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index 78ab2a1b027c..b264054e60e2 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -50,7 +50,7 @@ use polkadot_primitives::{ CandidateReceiptV2 as CandidateReceipt, }, AuthorityDiscoveryId, CandidateCommitments, ExecutorParams, Hash, OccupiedCoreAssumption, - PersistedValidationData, PvfExecKind, PvfPrepKind, SessionIndex, ValidationCode, + PersistedValidationData, PvfExecKind as RuntimePvfExecKind, PvfPrepKind, SessionIndex, ValidationCode, ValidationCodeHash, ValidatorId, }; use sp_application_crypto::{AppCrypto, ByteArray}; diff --git a/polkadot/node/core/dispute-coordinator/src/participation/mod.rs b/polkadot/node/core/dispute-coordinator/src/participation/mod.rs index 1cfac560ded2..770c44f7d609 100644 --- a/polkadot/node/core/dispute-coordinator/src/participation/mod.rs +++ b/polkadot/node/core/dispute-coordinator/src/participation/mod.rs @@ -33,7 +33,7 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_util::runtime::get_validation_code_by_hash; use polkadot_primitives::{ vstaging::CandidateReceiptV2 as CandidateReceipt, BlockNumber, CandidateHash, Hash, - PvfExecKind, SessionIndex, + SessionIndex, }; use crate::LOG_TARGET; diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index 98c6b3ea5c63..e4cdb4a1f015 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -52,7 +52,7 @@ use polkadot_primitives::{ CandidateIndex, CollatorId, CoreIndex, DisputeState, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, HeadData, Header as BlockHeader, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet, NodeFeatures, OccupiedCoreAssumption, - PersistedValidationData, PvfCheckStatement, PvfExecKind, SessionIndex, SessionInfo, + PersistedValidationData, PvfCheckStatement, PvfExecKind as RuntimePvfExecKind, SessionIndex, SessionInfo, SignedAvailabilityBitfield, SignedAvailabilityBitfields, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; From 320318ab4aef495e0861b89730dceca0b16e7716 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Thu, 17 Oct 2024 17:55:26 +0200 Subject: [PATCH 122/130] fmt and feedback Signed-off-by: Andrei Sandu --- polkadot/node/core/approval-voting/src/lib.rs | 4 ++-- polkadot/node/core/backing/src/lib.rs | 4 ++-- polkadot/node/core/candidate-validation/src/lib.rs | 4 ++-- .../collator-protocol/src/validator_side/collation.rs | 5 ----- polkadot/node/subsystem-types/src/messages.rs | 6 +++--- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index 18e98c5a9d98..2176cc7675be 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -54,8 +54,8 @@ use polkadot_node_subsystem_util::{ use polkadot_primitives::{ vstaging::CandidateReceiptV2 as CandidateReceipt, ApprovalVoteMultipleCandidates, ApprovalVotingParams, BlockNumber, CandidateHash, CandidateIndex, CoreIndex, ExecutorParams, - GroupIndex, Hash, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, - ValidatorPair, ValidatorSignature, + GroupIndex, Hash, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, ValidatorPair, + ValidatorSignature, }; use sc_keystore::LocalKeystore; use sp_application_crypto::Pair; diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs index d4e742495bec..b5362d32ad88 100644 --- a/polkadot/node/core/backing/src/lib.rs +++ b/polkadot/node/core/backing/src/lib.rs @@ -114,8 +114,8 @@ use polkadot_primitives::{ CommittedCandidateReceiptV2 as CommittedCandidateReceipt, CoreState, }, CandidateCommitments, CandidateHash, CoreIndex, ExecutorParams, GroupIndex, GroupRotationInfo, - Hash, Id as ParaId, IndexedVec, NodeFeatures, PersistedValidationData, - SessionIndex, SigningContext, ValidationCode, ValidatorId, ValidatorIndex, ValidatorSignature, + Hash, Id as ParaId, IndexedVec, NodeFeatures, PersistedValidationData, SessionIndex, + SigningContext, ValidationCode, ValidatorId, ValidatorIndex, ValidatorSignature, ValidityAttestation, }; use polkadot_statement_table::{ diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index b264054e60e2..72a8d894d34a 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -50,8 +50,8 @@ use polkadot_primitives::{ CandidateReceiptV2 as CandidateReceipt, }, AuthorityDiscoveryId, CandidateCommitments, ExecutorParams, Hash, OccupiedCoreAssumption, - PersistedValidationData, PvfExecKind as RuntimePvfExecKind, PvfPrepKind, SessionIndex, ValidationCode, - ValidationCodeHash, ValidatorId, + PersistedValidationData, PvfExecKind as RuntimePvfExecKind, PvfPrepKind, SessionIndex, + ValidationCode, ValidationCodeHash, ValidatorId, }; use sp_application_crypto::{AppCrypto, ByteArray}; use sp_keystore::KeystorePtr; diff --git a/polkadot/node/network/collator-protocol/src/validator_side/collation.rs b/polkadot/node/network/collator-protocol/src/validator_side/collation.rs index fe660b313bfe..0b3e9f4b3431 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/collation.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/collation.rs @@ -71,10 +71,6 @@ pub struct FetchedCollation { pub para_id: ParaId, /// Candidate hash. pub candidate_hash: CandidateHash, - /// Id of the collator the collation was fetched from. - /// This will be missing when we create the struct from - /// a v2 candidate receipt. instance - pub collator_id: Option, } impl From<&CandidateReceipt> for FetchedCollation { @@ -84,7 +80,6 @@ impl From<&CandidateReceipt> for FetchedCollation { relay_parent: descriptor.relay_parent(), para_id: descriptor.para_id(), candidate_hash: receipt.hash(), - collator_id: descriptor.collator(), } } } diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index e4cdb4a1f015..ba1ba5755be0 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -52,9 +52,9 @@ use polkadot_primitives::{ CandidateIndex, CollatorId, CoreIndex, DisputeState, ExecutorParams, GroupIndex, GroupRotationInfo, Hash, HeadData, Header as BlockHeader, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet, NodeFeatures, OccupiedCoreAssumption, - PersistedValidationData, PvfCheckStatement, PvfExecKind as RuntimePvfExecKind, SessionIndex, SessionInfo, - SignedAvailabilityBitfield, SignedAvailabilityBitfields, ValidationCode, ValidationCodeHash, - ValidatorId, ValidatorIndex, ValidatorSignature, + PersistedValidationData, PvfCheckStatement, PvfExecKind as RuntimePvfExecKind, SessionIndex, + SessionInfo, SignedAvailabilityBitfield, SignedAvailabilityBitfields, ValidationCode, + ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; use polkadot_statement_table::v2::Misbehavior; use std::{ From dfde71ffda824635ea9db3e72fbdff09cc689a6b Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 21 Oct 2024 15:23:43 +0300 Subject: [PATCH 123/130] more fixes Signed-off-by: Andrei Sandu --- polkadot/node/core/backing/src/tests/mod.rs | 24 +++++++++---------- .../src/tests/prospective_parachains.rs | 2 +- polkadot/node/overseer/src/tests.rs | 4 ++-- polkadot/primitives/src/vstaging/mod.rs | 2 +- prdoc/pr_5679.prdoc | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/polkadot/node/core/backing/src/tests/mod.rs b/polkadot/node/core/backing/src/tests/mod.rs index 46d8e1ddd3b9..dbb974a634fe 100644 --- a/polkadot/node/core/backing/src/tests/mod.rs +++ b/polkadot/node/core/backing/src/tests/mod.rs @@ -22,7 +22,7 @@ use polkadot_node_primitives::{BlockData, InvalidCandidate, SignedFullStatement, use polkadot_node_subsystem::{ errors::RuntimeApiError, messages::{ - AllMessages, CollatorProtocolMessage, RuntimeApiMessage, RuntimeApiRequest, + AllMessages, CollatorProtocolMessage, PvfExecKind, RuntimeApiMessage, RuntimeApiRequest, ValidationFailed, }, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, TimeoutExt, @@ -30,7 +30,7 @@ use polkadot_node_subsystem::{ use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_primitives::{ node_features, vstaging::MutateDescriptorV2, CandidateDescriptor, GroupRotationInfo, HeadData, - PersistedValidationData, PvfExecKind, ScheduledCore, SessionIndex, LEGACY_MIN_BACKING_VOTES, + PersistedValidationData, ScheduledCore, SessionIndex, LEGACY_MIN_BACKING_VOTES, }; use polkadot_primitives_test_helpers::{ dummy_candidate_receipt_bad_sig, dummy_collator, dummy_collator_signature, @@ -434,7 +434,7 @@ async fn assert_validate_from_exhaustive( }, ) if validation_data == *assert_pvd && validation_code == *assert_validation_code && - *pov == *assert_pov && &candidate_receipt.descriptor == assert_candidate.descriptor && + *pov == *assert_pov && candidate_receipt.descriptor == assert_candidate.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate_receipt.commitments_hash == assert_candidate.commitments.hash() => { @@ -651,7 +651,7 @@ fn backing_works(#[case] elastic_scaling_mvp: bool) { }, ) if validation_data == pvd_ab && validation_code == validation_code_ab && - *pov == pov_ab && &candidate_receipt.descriptor == candidate_a.descriptor && + *pov == pov_ab && candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate_receipt.commitments_hash == candidate_a_commitments_hash => { @@ -1287,7 +1287,7 @@ fn backing_works_while_validation_ongoing() { }, ) if validation_data == pvd_abc && validation_code == validation_code_abc && - *pov == pov_abc && &candidate_receipt.descriptor == candidate_a.descriptor && + *pov == pov_abc && candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate_a_commitments_hash == candidate_receipt.commitments_hash => { @@ -1454,7 +1454,7 @@ fn backing_misbehavior_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate_a.descriptor && + *pov == pov_a && candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate_a_commitments_hash == candidate_receipt.commitments_hash => { @@ -1621,7 +1621,7 @@ fn backing_dont_second_invalid() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_block_a && &candidate_receipt.descriptor == candidate_a.descriptor && + *pov == pov_block_a && candidate_receipt.descriptor == candidate_a.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate_a.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1661,7 +1661,7 @@ fn backing_dont_second_invalid() { }, ) if validation_data == pvd_b && validation_code == validation_code_b && - *pov == pov_block_b && &candidate_receipt.descriptor == candidate_b.descriptor && + *pov == pov_block_b && candidate_receipt.descriptor == candidate_b.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate_b.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1788,7 +1788,7 @@ fn backing_second_after_first_fails_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && + *pov == pov_a && candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate.commitments.hash() == candidate_receipt.commitments_hash => { @@ -1932,7 +1932,7 @@ fn backing_works_after_failed_validation() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && + *pov == pov_a && candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate.commitments.hash() == candidate_receipt.commitments_hash => { @@ -2211,7 +2211,7 @@ fn retry_works() { }, ) if validation_data == pvd_a && validation_code == validation_code_a && - *pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor && + *pov == pov_a && candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate.commitments.hash() == candidate_receipt.commitments_hash ); @@ -2753,7 +2753,7 @@ fn validator_ignores_statements_from_disabled_validators() { } ) if validation_data == pvd && validation_code == expected_validation_code && - *pov == expected_pov && &candidate_receipt.descriptor == candidate.descriptor && + *pov == expected_pov && candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate_commitments_hash == candidate_receipt.commitments_hash => { diff --git a/polkadot/node/core/backing/src/tests/prospective_parachains.rs b/polkadot/node/core/backing/src/tests/prospective_parachains.rs index 5dd0d888f215..caddd2408057 100644 --- a/polkadot/node/core/backing/src/tests/prospective_parachains.rs +++ b/polkadot/node/core/backing/src/tests/prospective_parachains.rs @@ -275,7 +275,7 @@ async fn assert_validate_seconded_candidate( }) if &validation_data == assert_pvd && &validation_code == assert_validation_code && &*pov == assert_pov && - &candidate_receipt.descriptor == candidate.descriptor && + candidate_receipt.descriptor == candidate.descriptor && exec_kind == PvfExecKind::BackingSystemParas && candidate.commitments.hash() == candidate_receipt.commitments_hash => { diff --git a/polkadot/node/overseer/src/tests.rs b/polkadot/node/overseer/src/tests.rs index a19009ebbdaf..c3c47335cd3e 100644 --- a/polkadot/node/overseer/src/tests.rs +++ b/polkadot/node/overseer/src/tests.rs @@ -29,11 +29,11 @@ use polkadot_node_subsystem_types::messages::{ }; use polkadot_primitives::{ vstaging::CandidateReceiptV2, CandidateHash, CollatorPair, Id as ParaId, - InvalidDisputeStatementKind, PvfExecKind, SessionIndex, ValidDisputeStatementKind, + InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, ValidDisputeStatementKind, ValidatorIndex, }; use polkadot_primitives_test_helpers::{ - dummy_candidate_descriptor, dummy_candidate_receipt_v2, dummy_hash, + dummy_candidate_descriptor, dummy_candidate_receipt_v2, dummy_hash, dummy_validation_code, }; use crate::{ diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 01ed8fcd5e1a..265fcd899d74 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -471,7 +471,7 @@ pub enum CandidateReceiptError { macro_rules! impl_getter { ($field:ident, $type:ident) => { - /// Returns the value of `$field`` field. + /// Returns the value of `$field` field. pub fn $field(&self) -> $type { self.$field } diff --git a/prdoc/pr_5679.prdoc b/prdoc/pr_5679.prdoc index 988d6408cec0..086566001161 100644 --- a/prdoc/pr_5679.prdoc +++ b/prdoc/pr_5679.prdoc @@ -4,7 +4,7 @@ doc: - audience: Node Dev description: | This change is just plumbing work and updates all crate interfaces to use the new primitives. - Id doesn't alter any functionality and is required before implementing RFC103 on the + It doesn't alter any functionality and is required before implementing RFC103 on the node side. crates: From cb93bb62f4d3462e400ba1f1a268d15566291158 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 21 Oct 2024 15:24:42 +0300 Subject: [PATCH 124/130] delete PRDoc Signed-off-by: Andrei Sandu --- prdoc/pr_5679.prdoc | 42 ------------------------------------------ 1 file changed, 42 deletions(-) delete mode 100644 prdoc/pr_5679.prdoc diff --git a/prdoc/pr_5679.prdoc b/prdoc/pr_5679.prdoc deleted file mode 100644 index 086566001161..000000000000 --- a/prdoc/pr_5679.prdoc +++ /dev/null @@ -1,42 +0,0 @@ -title: "Switch to new `CandidateReceipt` primitives" - -doc: - - audience: Node Dev - description: | - This change is just plumbing work and updates all crate interfaces to use the new primitives. - It doesn't alter any functionality and is required before implementing RFC103 on the - node side. - -crates: - - name: polkadot-primitives - bump: minor - - name: polkadot-runtime-parachains - bump: minor - - name: cumulus-client-consensus-common - bump: major - - name: cumulus-client-pov-recovery - bump: major - - name: cumulus-relay-chain-interface - bump: major - - name: polkadot-node-core-candidate-validation - bump: major - - name: polkadot-node-core-dispute-coordinator - bump: major - - name: polkadot-node-core-parachains-inherent - bump: major - - name: polkadot-node-core-prospective-parachains - bump: major - - name: polkadot-node-core-provisioner - bump: major - - name: polkadot-node-core-runtime-api - bump: major - - name: cumulus-client-network - bump: major - - name: cumulus-relay-chain-inprocess-interface - bump: major - - name: cumulus-client-consensus-aura - bump: major - - name: cumulus-relay-chain-minimal-node - bump: major - - name: cumulus-relay-chain-rpc-interface - bump: major From a4025099a71555513314d52ec7ad762ad4ec8e7b Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 21 Oct 2024 12:30:48 +0000 Subject: [PATCH 125/130] Update from sandreim running command 'prdoc --audience node_dev runtime_dev --bump major' --- prdoc/pr_5679.prdoc | 85 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 prdoc/pr_5679.prdoc diff --git a/prdoc/pr_5679.prdoc b/prdoc/pr_5679.prdoc new file mode 100644 index 000000000000..9c8de999c8f5 --- /dev/null +++ b/prdoc/pr_5679.prdoc @@ -0,0 +1,85 @@ +title: Switch node side to v2 candidate receipts +doc: +- audience: + - Node Dev + - Runtime Dev + description: |- + on top of https://github.com/paritytech/polkadot-sdk/pull/5423 + + This PR implements the plumbing work required for https://github.com/paritytech/polkadot-sdk/issues/5047 . I also added additional helper methods gated by feature "test" in primitives. + + TODO: + - [x] PRDoc +crates: +- name: polkadot-primitives + bump: major +- name: polkadot-runtime-parachains + bump: major +- name: rococo-runtime + bump: major +- name: westend-runtime + bump: major +- name: cumulus-relay-chain-inprocess-interface + bump: major +- name: polkadot-service + bump: major +- name: polkadot-node-subsystem-types + bump: major +- name: polkadot + bump: major +- name: cumulus-client-consensus-aura + bump: major +- name: cumulus-client-network + bump: major +- name: cumulus-client-pov-recovery + bump: major +- name: cumulus-relay-chain-interface + bump: major +- name: cumulus-relay-chain-minimal-node + bump: major +- name: cumulus-relay-chain-rpc-interface + bump: major +- name: polkadot-node-collation-generation + bump: major +- name: polkadot-node-core-approval-voting + bump: major +- name: polkadot-node-core-av-store + bump: major +- name: polkadot-node-core-backing + bump: major +- name: polkadot-node-core-bitfield-signing + bump: major +- name: polkadot-node-core-candidate-validation + bump: major +- name: polkadot-node-core-dispute-coordinator + bump: major +- name: polkadot-node-core-parachains-inherent + bump: major +- name: polkadot-node-core-prospective-parachains + bump: major +- name: polkadot-node-core-provisioner + bump: major +- name: polkadot-node-core-runtime-api + bump: major +- name: polkadot-availability-distribution + bump: major +- name: polkadot-availability-recovery + bump: major +- name: polkadot-collator-protocol + bump: major +- name: polkadot-dispute-distribution + bump: major +- name: polkadot-node-network-protocol + bump: major +- name: polkadot-statement-distribution + bump: major +- name: polkadot-node-primitives + bump: major +- name: polkadot-node-subsystem-util + bump: major +- name: polkadot-statement-table + bump: major +- name: polkadot-overseer + bump: major +- name: cumulus-client-consensus-common + bump: major From 6371454b62c4d9db15e8c62d9c4eaec5b992f7dd Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Mon, 21 Oct 2024 15:41:26 +0300 Subject: [PATCH 126/130] adjust generated PRDoc Signed-off-by: Andrei Sandu --- prdoc/pr_5679.prdoc | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/prdoc/pr_5679.prdoc b/prdoc/pr_5679.prdoc index 9c8de999c8f5..59c36ecb933d 100644 --- a/prdoc/pr_5679.prdoc +++ b/prdoc/pr_5679.prdoc @@ -1,34 +1,29 @@ -title: Switch node side to v2 candidate receipts +title: Switch to new `CandidateReceipt` primitives doc: - audience: - Node Dev - Runtime Dev - description: |- - on top of https://github.com/paritytech/polkadot-sdk/pull/5423 - - This PR implements the plumbing work required for https://github.com/paritytech/polkadot-sdk/issues/5047 . I also added additional helper methods gated by feature "test" in primitives. - - TODO: - - [x] PRDoc + description: | + This change is just plumbing work and updates all crate interfaces to use the new primitives. + It doesn't alter any functionality and is required before implementing RFC103 on the + node side. crates: - name: polkadot-primitives bump: major - name: polkadot-runtime-parachains - bump: major + bump: patch - name: rococo-runtime - bump: major + bump: patch - name: westend-runtime - bump: major + bump: patch - name: cumulus-relay-chain-inprocess-interface bump: major - name: polkadot-service - bump: major + bump: patch - name: polkadot-node-subsystem-types bump: major - name: polkadot - bump: major -- name: cumulus-client-consensus-aura - bump: major + bump: patch - name: cumulus-client-network bump: major - name: cumulus-client-pov-recovery @@ -80,6 +75,6 @@ crates: - name: polkadot-statement-table bump: major - name: polkadot-overseer - bump: major + bump: patch - name: cumulus-client-consensus-common bump: major From 9c5097d845b5139f0e9f3711159e0741ae4369b9 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 22 Oct 2024 13:19:50 +0300 Subject: [PATCH 127/130] fix build again Signed-off-by: Andrei Sandu --- polkadot/node/core/candidate-validation/src/lib.rs | 2 +- .../node/network/availability-distribution/src/requester/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index 72a8d894d34a..551f6a507c8e 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -49,7 +49,7 @@ use polkadot_primitives::{ CandidateDescriptorV2 as CandidateDescriptor, CandidateEvent, CandidateReceiptV2 as CandidateReceipt, }, - AuthorityDiscoveryId, CandidateCommitments, ExecutorParams, Hash, OccupiedCoreAssumption, + AuthorityDiscoveryId, CandidateCommitments, ExecutorParams, Hash, PersistedValidationData, PvfExecKind as RuntimePvfExecKind, PvfPrepKind, SessionIndex, ValidationCode, ValidationCodeHash, ValidatorId, }; diff --git a/polkadot/node/network/availability-distribution/src/requester/mod.rs b/polkadot/node/network/availability-distribution/src/requester/mod.rs index d39a0c07ac8e..79658591b6a7 100644 --- a/polkadot/node/network/availability-distribution/src/requester/mod.rs +++ b/polkadot/node/network/availability-distribution/src/requester/mod.rs @@ -39,7 +39,7 @@ use polkadot_node_subsystem_util::{ runtime::{get_occupied_cores, RuntimeInfo}, }; use polkadot_primitives::{ - vstaging::OccupiedCore, BlockNumber, CandidateHash, CoreIndex, Hash, SessionIndex, + vstaging::OccupiedCore, CandidateHash, CoreIndex, Hash, SessionIndex, }; use super::{FatalError, Metrics, Result, LOG_TARGET}; From b2818f3e195cc7bf30d81ccba3d1be5d37f4d616 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 22 Oct 2024 13:45:26 +0300 Subject: [PATCH 128/130] fix test Signed-off-by: Andrei Sandu --- polkadot/node/core/candidate-validation/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/node/core/candidate-validation/src/tests.rs b/polkadot/node/core/candidate-validation/src/tests.rs index 9d927440f25b..e679f34792d0 100644 --- a/polkadot/node/core/candidate-validation/src/tests.rs +++ b/polkadot/node/core/candidate-validation/src/tests.rs @@ -27,7 +27,7 @@ use polkadot_node_subsystem_util::reexports::SubsystemContext; use polkadot_overseer::ActivatedLeaf; use polkadot_primitives::{ vstaging::CandidateDescriptorV2, CandidateDescriptor, CoreIndex, GroupIndex, HeadData, - Id as ParaId, SessionInfo, UpwardMessage, ValidatorId, + Id as ParaId, SessionInfo, UpwardMessage, ValidatorId, OccupiedCoreAssumption }; use polkadot_primitives_test_helpers::{ dummy_collator, dummy_collator_signature, dummy_hash, make_valid_candidate_descriptor, From 0bab530d9773c8955db2cd6e22da9172389f0a15 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Tue, 22 Oct 2024 19:36:40 +0300 Subject: [PATCH 129/130] fix inclusion emulator Signed-off-by: Andrei Sandu --- .../src/inclusion_emulator/mod.rs | 53 ++++++++++++++++--- polkadot/primitives/test-helpers/Cargo.toml | 2 +- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs b/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs index a2a6095b765c..801dcd665a06 100644 --- a/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs +++ b/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs @@ -431,9 +431,9 @@ pub struct ConstraintModifications { pub hrmp_watermark: Option, /// Outbound HRMP channel modifications. pub outbound_hrmp: HashMap, - /// The amount of UMP messages sent. + /// The amount of UMP XCM messages sent. `UMPSignal` and separator are excluded. pub ump_messages_sent: usize, - /// The amount of UMP bytes sent. + /// The amount of UMP XCM bytes sent. `UMPSignal` and separator are excluded. pub ump_bytes_sent: usize, /// The amount of DMP messages processed. pub dmp_messages_processed: usize, @@ -600,6 +600,18 @@ impl Fragment { validation_code_hash: &ValidationCodeHash, persisted_validation_data: &PersistedValidationData, ) -> Result { + // Filter UMP signals and the separator. + let upward_messages = if let Some(separator_index) = + commitments.upward_messages.iter().position(|message| message.is_empty()) + { + commitments.upward_messages.split_at(separator_index).0 + } else { + &commitments.upward_messages + }; + + let ump_messages_sent = upward_messages.len(); + let ump_bytes_sent = upward_messages.iter().map(|msg| msg.len()).sum(); + let modifications = { ConstraintModifications { required_parent: Some(commitments.head_data.clone()), @@ -632,8 +644,8 @@ impl Fragment { outbound_hrmp }, - ump_messages_sent: commitments.upward_messages.len(), - ump_bytes_sent: commitments.upward_messages.iter().map(|msg| msg.len()).sum(), + ump_messages_sent, + ump_bytes_sent, dmp_messages_processed: commitments.processed_downward_messages as _, code_upgrade_applied: operating_constraints .future_validation_code @@ -645,6 +657,7 @@ impl Fragment { &operating_constraints, &relay_parent, commitments, + ump_messages_sent, persisted_validation_data, validation_code_hash, &modifications, @@ -683,6 +696,7 @@ fn validate_against_constraints( constraints: &Constraints, relay_parent: &RelayChainBlockInfo, commitments: &CandidateCommitments, + upward_message_count: usize, persisted_validation_data: &PersistedValidationData, validation_code_hash: &ValidationCodeHash, modifications: &ConstraintModifications, @@ -750,7 +764,7 @@ fn validate_against_constraints( }) } - if commitments.upward_messages.len() > constraints.max_ump_num_per_candidate { + if upward_message_count > constraints.max_ump_num_per_candidate { return Err(FragmentValidityError::UmpMessagesPerCandidateOverflow { messages_allowed: constraints.max_ump_num_per_candidate, messages_submitted: commitments.upward_messages.len(), @@ -814,7 +828,8 @@ impl HypotheticalOrConcreteCandidate for HypotheticalCandidate { #[cfg(test)] mod tests { use super::*; - use polkadot_primitives::{HorizontalMessages, OutboundHrmpMessage, ValidationCode}; + use polkadot_primitives::{HorizontalMessages, OutboundHrmpMessage, ValidationCode, vstaging::{UMP_SEPARATOR, UMPSignal, CoreSelector, ClaimQueueOffset}}; + use codec::Encode; #[test] fn stack_modifications() { @@ -1267,6 +1282,32 @@ mod tests { ); } + #[test] + fn ump_signals_ignored() { + let relay_parent = RelayChainBlockInfo { + number: 6, + hash: Hash::repeat_byte(0xbe), + storage_root: Hash::repeat_byte(0xff), + }; + + let constraints = make_constraints(); + let mut candidate = make_candidate(&constraints, &relay_parent); + let max_ump = constraints.max_ump_num_per_candidate; + + // Fill ump queue to the limit. + candidate + .commitments + .upward_messages + .try_extend((0..max_ump).map(|i| vec![i as u8])) + .unwrap(); + + // Add ump signals.s + candidate.commitments.upward_messages.force_push(UMP_SEPARATOR); + candidate.commitments.upward_messages.force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); + + Fragment::new(relay_parent, constraints, Arc::new(candidate)).unwrap(); + } + #[test] fn fragment_relay_parent_too_old() { let relay_parent = RelayChainBlockInfo { diff --git a/polkadot/primitives/test-helpers/Cargo.toml b/polkadot/primitives/test-helpers/Cargo.toml index a44996ad6ef2..5750a368c2a7 100644 --- a/polkadot/primitives/test-helpers/Cargo.toml +++ b/polkadot/primitives/test-helpers/Cargo.toml @@ -14,5 +14,5 @@ sp-keyring = { workspace = true, default-features = true } sp-application-crypto = { workspace = true } sp-runtime = { workspace = true, default-features = true } sp-core = { features = ["std"], workspace = true, default-features = true } -polkadot-primitives = { workspace = true, default-features = true } +polkadot-primitives = { workspace = true, features=["test"]} rand = { workspace = true, default-features = true } From 77e1925db28b421cee178161a1393cab25e2ee72 Mon Sep 17 00:00:00 2001 From: Andrei Sandu Date: Wed, 23 Oct 2024 14:46:42 +0300 Subject: [PATCH 130/130] typo Signed-off-by: Andrei Sandu --- .../subsystem-util/src/inclusion_emulator/mod.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs b/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs index 801dcd665a06..c32c7198310e 100644 --- a/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs +++ b/polkadot/node/subsystem-util/src/inclusion_emulator/mod.rs @@ -611,7 +611,7 @@ impl Fragment { let ump_messages_sent = upward_messages.len(); let ump_bytes_sent = upward_messages.iter().map(|msg| msg.len()).sum(); - + let modifications = { ConstraintModifications { required_parent: Some(commitments.head_data.clone()), @@ -828,8 +828,11 @@ impl HypotheticalOrConcreteCandidate for HypotheticalCandidate { #[cfg(test)] mod tests { use super::*; - use polkadot_primitives::{HorizontalMessages, OutboundHrmpMessage, ValidationCode, vstaging::{UMP_SEPARATOR, UMPSignal, CoreSelector, ClaimQueueOffset}}; use codec::Encode; + use polkadot_primitives::{ + vstaging::{ClaimQueueOffset, CoreSelector, UMPSignal, UMP_SEPARATOR}, + HorizontalMessages, OutboundHrmpMessage, ValidationCode, + }; #[test] fn stack_modifications() { @@ -1301,10 +1304,13 @@ mod tests { .try_extend((0..max_ump).map(|i| vec![i as u8])) .unwrap(); - // Add ump signals.s + // Add ump signals. candidate.commitments.upward_messages.force_push(UMP_SEPARATOR); - candidate.commitments.upward_messages.force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); - + candidate + .commitments + .upward_messages + .force_push(UMPSignal::SelectCore(CoreSelector(0), ClaimQueueOffset(1)).encode()); + Fragment::new(relay_parent, constraints, Arc::new(candidate)).unwrap(); }