mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
Implement validation data refactor (#1585)
* update primitives * correct parent_head field * make hrmp field pub * refactor validation data: runtime * refactor validation data: messages * add arguments to full_validation_data runtime API * port runtime API * mostly port over candidate validation * remove some parameters from ValidationParams * guide: update candidate validation * update candidate outputs * update ValidationOutputs in primitives * port over candidate validation * add a new test for no-transient behavior * update util runtime API wrappers * candidate backing * fix missing imports * change some fields of validation data around * runtime API impl * update candidate validation * fix backing tests * grumbles from review * fix av-store tests * fix some more crates * fix provisioner tests * fix availability distribution tests * port collation-generation to new validation data * fix overseer tests * Update roadmap/implementers-guide/src/node/utility/candidate-validation.md Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
3395044402
commit
262574fc49
@@ -60,7 +60,7 @@ pub const INCLUSION_INHERENT_IDENTIFIER: InherentIdentifier = *b"inclusn0";
|
||||
pub fn collator_signature_payload<H: AsRef<[u8]>>(
|
||||
relay_parent: &H,
|
||||
para_id: &Id,
|
||||
validation_data_hash: &Hash,
|
||||
persisted_validation_data_hash: &Hash,
|
||||
pov_hash: &Hash,
|
||||
) -> [u8; 100] {
|
||||
// 32-byte hash length is protected in a test below.
|
||||
@@ -68,7 +68,7 @@ pub fn collator_signature_payload<H: AsRef<[u8]>>(
|
||||
|
||||
payload[0..32].copy_from_slice(relay_parent.as_ref());
|
||||
u32::from(*para_id).using_encoded(|s| payload[32..32 + s.len()].copy_from_slice(s));
|
||||
payload[36..68].copy_from_slice(validation_data_hash.as_ref());
|
||||
payload[36..68].copy_from_slice(persisted_validation_data_hash.as_ref());
|
||||
payload[68..100].copy_from_slice(pov_hash.as_ref());
|
||||
|
||||
payload
|
||||
@@ -77,7 +77,7 @@ pub fn collator_signature_payload<H: AsRef<[u8]>>(
|
||||
fn check_collator_signature<H: AsRef<[u8]>>(
|
||||
relay_parent: &H,
|
||||
para_id: &Id,
|
||||
validation_data_hash: &Hash,
|
||||
persisted_validation_data_hash: &Hash,
|
||||
pov_hash: &Hash,
|
||||
collator: &CollatorId,
|
||||
signature: &CollatorSignature,
|
||||
@@ -85,7 +85,7 @@ fn check_collator_signature<H: AsRef<[u8]>>(
|
||||
let payload = collator_signature_payload(
|
||||
relay_parent,
|
||||
para_id,
|
||||
validation_data_hash,
|
||||
persisted_validation_data_hash,
|
||||
pov_hash,
|
||||
);
|
||||
|
||||
@@ -96,14 +96,6 @@ fn check_collator_signature<H: AsRef<[u8]>>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute the `validation_data_hash` from global & local validation data.
|
||||
pub fn validation_data_hash<N: Encode>(
|
||||
global: &GlobalValidationData<N>,
|
||||
local: &LocalValidationData<N>,
|
||||
) -> Hash {
|
||||
BlakeTwo256::hash_of(&(global, local))
|
||||
}
|
||||
|
||||
/// A unique descriptor of the candidate receipt.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Default, Hash))]
|
||||
@@ -114,16 +106,15 @@ pub struct CandidateDescriptor<H = Hash> {
|
||||
pub relay_parent: H,
|
||||
/// The collator's sr25519 public key.
|
||||
pub collator: CollatorId,
|
||||
/// The blake2-256 hash of the validation data. This is extra data derived from
|
||||
/// 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 validation_data_hash: Hash,
|
||||
pub persisted_validation_data_hash: Hash,
|
||||
/// The blake2-256 hash of the pov.
|
||||
pub pov_hash: Hash,
|
||||
/// Signature on blake2-256 of components of this receipt:
|
||||
/// The parachain index, the relay parent, the validation data hash, and the pov_hash.
|
||||
pub signature: CollatorSignature,
|
||||
|
||||
}
|
||||
|
||||
impl<H: AsRef<[u8]>> CandidateDescriptor<H> {
|
||||
@@ -132,7 +123,7 @@ impl<H: AsRef<[u8]>> CandidateDescriptor<H> {
|
||||
check_collator_signature(
|
||||
&self.relay_parent,
|
||||
&self.para_id,
|
||||
&self.validation_data_hash,
|
||||
&self.persisted_validation_data_hash,
|
||||
&self.pov_hash,
|
||||
&self.collator,
|
||||
&self.signature,
|
||||
@@ -168,10 +159,11 @@ impl<H> CandidateReceipt<H> {
|
||||
pub struct FullCandidateReceipt<H = Hash, N = BlockNumber> {
|
||||
/// The inner candidate receipt.
|
||||
pub inner: CandidateReceipt<H>,
|
||||
/// The global validation schedule.
|
||||
pub global_validation: GlobalValidationData<N>,
|
||||
/// The local validation data.
|
||||
pub local_validation: LocalValidationData<N>,
|
||||
/// The validation data derived from the relay-chain state at that
|
||||
/// point. The hash of the persisted validation data should
|
||||
/// match the `persisted_validation_data_hash` in the descriptor
|
||||
/// of the receipt.
|
||||
pub validation_data: ValidationData<N>,
|
||||
}
|
||||
|
||||
/// A candidate-receipt with commitments directly included.
|
||||
@@ -224,17 +216,78 @@ impl Ord for CommittedCandidateReceipt {
|
||||
}
|
||||
}
|
||||
|
||||
/// Extra data that is needed along with the other fields in a `CandidateReceipt`
|
||||
/// to fully validate the candidate. These fields are parachain-specific.
|
||||
/// The validation data provide information about how to validate both the inputs and
|
||||
/// outputs of a candidate.
|
||||
///
|
||||
/// There are two types of validation data: persisted and transient.
|
||||
/// Their respective sections of the guide elaborate on their functionality in more detail.
|
||||
///
|
||||
/// This information is derived from the chain state and will vary from para to para,
|
||||
/// although some of the fields may be the same for every para.
|
||||
///
|
||||
/// Persisted validation data are generally derived from some relay-chain state to form inputs
|
||||
/// to the validation function, and as such need to be persisted by the availability system to
|
||||
/// avoid dependence on availability of the relay-chain state. The backing phase of the
|
||||
/// inclusion pipeline ensures that everything that is included in a valid fork of the
|
||||
/// relay-chain already adheres to the transient constraints.
|
||||
///
|
||||
/// The validation data also serve the purpose of giving collators a means of ensuring that
|
||||
/// their produced candidate and the commitments submitted to the relay-chain alongside it
|
||||
/// will pass the checks done by the relay-chain when backing, and give validators
|
||||
/// the same understanding when determining whether to second or attest to a candidate.
|
||||
///
|
||||
/// Since the commitments of the validation function are checked by the
|
||||
/// relay-chain, secondary checkers can rely on the invariant that the relay-chain
|
||||
/// only includes para-blocks for which these checks have already been done. As such,
|
||||
/// there is no need for the validation data used to inform validators and collators about
|
||||
/// the checks the relay-chain will perform to be persisted by the availability system.
|
||||
/// Nevertheless, we expose it so the backing validators can validate the outputs of a
|
||||
/// candidate before voting to submit it to the relay-chain and so collators can
|
||||
/// collate candidates that satisfy the criteria implied these transient validation data.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Default))]
|
||||
pub struct LocalValidationData<N = BlockNumber> {
|
||||
pub struct ValidationData<N = BlockNumber> {
|
||||
/// The persisted validation data.
|
||||
pub persisted: PersistedValidationData<N>,
|
||||
/// The transient validation data.
|
||||
pub transient: TransientValidationData<N>,
|
||||
}
|
||||
|
||||
/// Validation data that needs to be persisted for secondary checkers.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Default))]
|
||||
pub struct PersistedValidationData<N = BlockNumber> {
|
||||
/// The parent head-data.
|
||||
pub parent_head: HeadData,
|
||||
/// The relay-chain block number this is in the context of.
|
||||
pub block_number: N,
|
||||
/// The list of MQC heads for the inbound channels paired with the sender para ids. This
|
||||
/// vector is sorted ascending by the para id and doesn't contain multiple entries with the same
|
||||
/// sender.
|
||||
pub hrmp_mqc_heads: Vec<(Id, Hash)>,
|
||||
}
|
||||
|
||||
impl<N: Encode> PersistedValidationData<N> {
|
||||
/// Compute the blake2-256 hash of the persisted validation data.
|
||||
pub fn hash(&self) -> Hash {
|
||||
BlakeTwo256::hash_of(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Validation data for checking outputs of the validation-function.
|
||||
/// As such, they also inform the collator about how to construct the candidate.
|
||||
///
|
||||
/// These are transient because they are not necessary beyond the point where the
|
||||
/// candidate is backed.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Default))]
|
||||
pub struct TransientValidationData<N = BlockNumber> {
|
||||
/// The maximum code size permitted, in bytes.
|
||||
pub max_code_size: u32,
|
||||
/// The maximum head-data size permitted, in bytes.
|
||||
pub max_head_data_size: u32,
|
||||
/// The balance of the parachain at the moment of validation.
|
||||
pub balance: Balance,
|
||||
/// The blake2-256 hash of the validation code used to execute the candidate.
|
||||
pub validation_code_hash: Hash,
|
||||
/// Whether the parachain is allowed to upgrade its validation code.
|
||||
///
|
||||
/// This is `Some` if so, and contains the number of the minimum relay-chain
|
||||
@@ -249,21 +302,6 @@ pub struct LocalValidationData<N = BlockNumber> {
|
||||
pub code_upgrade_allowed: Option<N>,
|
||||
}
|
||||
|
||||
/// Extra data that is needed along with the other fields in a `CandidateReceipt`
|
||||
/// to fully validate the candidate.
|
||||
///
|
||||
/// These are global parameters that apply to all candidates in a block.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Default))]
|
||||
pub struct GlobalValidationData<N = BlockNumber> {
|
||||
/// The maximum code size permitted, in bytes.
|
||||
pub max_code_size: u32,
|
||||
/// The maximum head-data size permitted, in bytes.
|
||||
pub max_head_data_size: u32,
|
||||
/// The relay-chain block number this is in the context of.
|
||||
pub block_number: N,
|
||||
}
|
||||
|
||||
/// Commitments made in a `CandidateReceipt`. Many of these are outputs of validation.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Default, Hash))]
|
||||
@@ -434,25 +472,14 @@ pub enum CoreOccupied {
|
||||
Parachain,
|
||||
}
|
||||
|
||||
/// Validation data omitted from most candidate descriptor structs, as it can be derived from the
|
||||
/// relay-parent.
|
||||
#[derive(Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(PartialEq, Debug, Default))]
|
||||
pub struct OmittedValidationData {
|
||||
/// The global validation schedule.
|
||||
pub global_validation: GlobalValidationData,
|
||||
/// The local validation data.
|
||||
pub local_validation: LocalValidationData,
|
||||
}
|
||||
|
||||
/// This is the data we keep available for each candidate included in the relay chain.
|
||||
#[derive(Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(PartialEq, Debug))]
|
||||
pub struct AvailableData {
|
||||
/// The Proof-of-Validation of the candidate.
|
||||
pub pov: PoV,
|
||||
/// The omitted validation data.
|
||||
pub omitted_validation: OmittedValidationData,
|
||||
/// The persisted validation data needed for secondary checks.
|
||||
pub validation_data: PersistedValidationData,
|
||||
}
|
||||
|
||||
/// A helper data-type for tracking validator-group rotations.
|
||||
@@ -622,17 +649,21 @@ sp_api::decl_runtime_apis! {
|
||||
/// cores can have paras assigned to them.
|
||||
fn availability_cores() -> Vec<CoreState<N>>;
|
||||
|
||||
/// Yields the GlobalValidationData. This applies to all para candidates with the
|
||||
/// relay-parent equal to the block in which context this is invoked in.
|
||||
fn global_validation_data() -> GlobalValidationData<N>;
|
||||
/// Yields the full validation data for the given ParaId along with an assumption that
|
||||
/// should be used if the para currently occupieds a core.
|
||||
///
|
||||
/// Returns `None` if either the para is not registered or the assumption is `Freed`
|
||||
/// and the para already occupies a core.
|
||||
fn full_validation_data(para_id: Id, assumption: OccupiedCoreAssumption)
|
||||
-> Option<ValidationData<N>>;
|
||||
|
||||
/// Yields the LocalValidationData for the given ParaId along with an assumption that
|
||||
/// Yields the persisted validation data for the given ParaId along with an assumption that
|
||||
/// should be used if the para currently occupies a core.
|
||||
///
|
||||
/// Returns `None` if either the para is not registered or the assumption is `Freed`
|
||||
/// and the para already occupies a core.
|
||||
fn local_validation_data(para_id: Id, assumption: OccupiedCoreAssumption)
|
||||
-> Option<LocalValidationData<N>>;
|
||||
fn persisted_validation_data(para_id: Id, assumption: OccupiedCoreAssumption)
|
||||
-> Option<PersistedValidationData<N>>;
|
||||
|
||||
/// Returns the session index expected at a child of the block.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user