mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 17:31:03 +00:00
Ensure that para_head hash matches the actual head (#3808)
* Ensure that `para_head` hash matches the actual head This ensures that the `para_head` hash in the `CandidateDescriptor` matches the actual `head` in the candidate commitments. * Enable the code for `no_std` * Formatting
This commit is contained in:
@@ -45,7 +45,6 @@ pub use polkadot_core_primitives::BlockNumber as RelayChainBlockNumber;
|
|||||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Default, Hash, MallocSizeOf))]
|
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Default, Hash, MallocSizeOf))]
|
||||||
pub struct HeadData(#[cfg_attr(feature = "std", serde(with = "bytes"))] pub Vec<u8>);
|
pub struct HeadData(#[cfg_attr(feature = "std", serde(with = "bytes"))] pub Vec<u8>);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl HeadData {
|
impl HeadData {
|
||||||
/// Returns the hash of this head data.
|
/// Returns the hash of this head data.
|
||||||
pub fn hash(&self) -> Hash {
|
pub fn hash(&self) -> Hash {
|
||||||
|
|||||||
@@ -194,6 +194,9 @@ pub mod pallet {
|
|||||||
InvalidOutboundHrmp,
|
InvalidOutboundHrmp,
|
||||||
/// The validation code hash of the candidate is not valid.
|
/// The validation code hash of the candidate is not valid.
|
||||||
InvalidValidationCodeHash,
|
InvalidValidationCodeHash,
|
||||||
|
/// The `para_head` hash in the candidate descriptor doesn't match the hash of the actual para head in the
|
||||||
|
/// commitments.
|
||||||
|
ParaHeadMismatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The latest bitfield for each validator, referred to by their index in the validator set.
|
/// The latest bitfield for each validator, referred to by their index in the validator set.
|
||||||
@@ -465,6 +468,12 @@ impl<T: Config> Pallet<T> {
|
|||||||
Error::<T>::InvalidValidationCodeHash,
|
Error::<T>::InvalidValidationCodeHash,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ensure!(
|
||||||
|
candidate.descriptor().para_head ==
|
||||||
|
candidate.candidate.commitments.head_data.hash(),
|
||||||
|
Error::<T>::ParaHeadMismatch,
|
||||||
|
);
|
||||||
|
|
||||||
if let Err(err) = check_cx.check_validation_outputs(
|
if let Err(err) = check_cx.check_validation_outputs(
|
||||||
para_id,
|
para_id,
|
||||||
&candidate.candidate.commitments.head_data,
|
&candidate.candidate.commitments.head_data,
|
||||||
@@ -1169,6 +1178,7 @@ mod tests {
|
|||||||
struct TestCandidateBuilder {
|
struct TestCandidateBuilder {
|
||||||
para_id: ParaId,
|
para_id: ParaId,
|
||||||
head_data: HeadData,
|
head_data: HeadData,
|
||||||
|
para_head_hash: Option<Hash>,
|
||||||
pov_hash: Hash,
|
pov_hash: Hash,
|
||||||
relay_parent: Hash,
|
relay_parent: Hash,
|
||||||
persisted_validation_data_hash: Hash,
|
persisted_validation_data_hash: Hash,
|
||||||
@@ -1186,6 +1196,7 @@ mod tests {
|
|||||||
relay_parent: self.relay_parent,
|
relay_parent: self.relay_parent,
|
||||||
persisted_validation_data_hash: self.persisted_validation_data_hash,
|
persisted_validation_data_hash: self.persisted_validation_data_hash,
|
||||||
validation_code_hash: self.validation_code.hash(),
|
validation_code_hash: self.validation_code.hash(),
|
||||||
|
para_head: self.para_head_hash.unwrap_or_else(|| self.head_data.hash()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
commitments: CandidateCommitments {
|
commitments: CandidateCommitments {
|
||||||
@@ -2214,6 +2225,41 @@ mod tests {
|
|||||||
Err(Error::<Test>::InvalidValidationCodeHash.into()),
|
Err(Error::<Test>::InvalidValidationCodeHash.into()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Para head hash in descriptor doesn't match head data
|
||||||
|
{
|
||||||
|
let mut candidate = TestCandidateBuilder {
|
||||||
|
para_id: chain_a,
|
||||||
|
relay_parent: System::parent_hash(),
|
||||||
|
pov_hash: Hash::repeat_byte(1),
|
||||||
|
persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(),
|
||||||
|
hrmp_watermark: RELAY_PARENT_NUM,
|
||||||
|
para_head_hash: Some(Hash::random()),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.build();
|
||||||
|
|
||||||
|
collator_sign_candidate(Sr25519Keyring::One, &mut candidate);
|
||||||
|
|
||||||
|
let backed = block_on(back_candidate(
|
||||||
|
candidate,
|
||||||
|
&validators,
|
||||||
|
group_validators(GroupIndex::from(0)).unwrap().as_ref(),
|
||||||
|
&keystore,
|
||||||
|
&signing_context,
|
||||||
|
BackingKind::Threshold,
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
ParaInclusion::process_candidates(
|
||||||
|
Default::default(),
|
||||||
|
vec![backed],
|
||||||
|
vec![chain_a_assignment.clone()],
|
||||||
|
&group_validators,
|
||||||
|
),
|
||||||
|
Err(Error::<Test>::ParaHeadMismatch.into()),
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user