Unverified Commit cce0a950 authored by asynchronous rob's avatar asynchronous rob Committed by GitHub
Browse files

Include a reference to the validation data in the candidate descriptor (#1442)

* rename GlobalValidationSchedule to GlobalValidationData

* guide: update candidate descriptor to contain validation data hash

* guide: add note in inclusion module about checking validation data hash

* primitives: update CandidateDescriptor to contain new hash

* fix payload computation

* add helpers for computing validation data to runtime modules

* guide: note routines

* inclusion: check validation data hash and fix local_validation_data bug

* add a case to candidate_checks and improve that test substantially

* bump versions

* address review comments

* add a test for including code upgrade

* bump kusama version

* bump westend & polkadot versions
parent 9637baea
Pipeline #101533 passed with stages
in 25 minutes and 48 seconds
......@@ -58,7 +58,7 @@ use sp_core::Pair;
use polkadot_primitives::v0::{
BlockId, Hash, Block, DownwardMessage,
BlockData, DutyRoster, HeadData, Id as ParaId,
PoVBlock, ValidatorId, CollatorPair, LocalValidationData, GlobalValidationSchedule,
PoVBlock, ValidatorId, CollatorPair, LocalValidationData, GlobalValidationData,
Collation, CollationInfo, collator_signature_payload,
};
use polkadot_cli::{
......@@ -148,7 +148,7 @@ pub trait ParachainContext: Clone {
fn produce_candidate(
&mut self,
relay_parent: Hash,
global_validation: GlobalValidationSchedule,
global_validation: GlobalValidationData,
local_validation: LocalValidationData,
downward_messages: Vec<DownwardMessage>,
) -> Self::ProduceCandidate;
......@@ -158,7 +158,7 @@ pub trait ParachainContext: Clone {
pub async fn collate<P>(
relay_parent: Hash,
local_id: ParaId,
global_validation: GlobalValidationSchedule,
global_validation: GlobalValidationData,
local_validation_data: LocalValidationData,
downward_messages: Vec<DownwardMessage>,
mut para_context: P,
......@@ -315,7 +315,7 @@ fn build_collator_service<P, C, R, Extrinsic>(
let work = future::lazy(move |_| {
let api = client.runtime_api();
let global_validation = try_fr!(api.global_validation_schedule(&id));
let global_validation = try_fr!(api.global_validation_data(&id));
let local_validation = match try_fr!(api.local_validation_data(&id, para_id)) {
Some(local_validation) => local_validation,
None => return future::Either::Left(future::ok(())),
......@@ -477,7 +477,7 @@ mod tests {
fn produce_candidate(
&mut self,
_relay_parent: Hash,
_global: GlobalValidationSchedule,
_global: GlobalValidationData,
_local_validation: LocalValidationData,
_: Vec<DownwardMessage>,
) -> Self::ProduceCandidate {
......
......@@ -21,7 +21,7 @@ use polkadot_primitives::v0::{
Block,
Id as ParaId, Chain, DutyRoster, ParachainHost, ValidatorId,
Retriable, CollatorId, AbridgedCandidateReceipt,
GlobalValidationSchedule, LocalValidationData, ErasureChunk, SigningContext,
GlobalValidationData, LocalValidationData, ErasureChunk, SigningContext,
PoVBlock, BlockData, ValidationCode,
};
use polkadot_validation::{SharedTable, TableRouter};
......@@ -180,7 +180,7 @@ sp_api::mock_impl_runtime_apis! {
Some(ValidationCode(Vec::new()))
}
fn global_validation_schedule() -> GlobalValidationSchedule {
fn global_validation_data() -> GlobalValidationData {
Default::default()
}
......
......@@ -606,7 +606,7 @@ impl CandidateBackingJob {
with_commitments: impl FnOnce(CandidateCommitments) -> Result<T, E>,
) -> Result<Result<T, E>, Error> {
let omitted_validation = OmittedValidationData {
global_validation: outputs.global_validation_schedule,
global_validation: outputs.global_validation_data,
local_validation: outputs.local_validation_data,
};
......@@ -773,7 +773,7 @@ mod tests {
use futures::{executor, future, Future};
use polkadot_primitives::v1::{
AssignmentKind, BlockData, CandidateCommitments, CollatorId, CoreAssignment, CoreIndex,
LocalValidationData, GlobalValidationSchedule, GroupIndex, HeadData,
LocalValidationData, GlobalValidationData, GroupIndex, HeadData,
ValidatorPair, ValidityAttestation,
};
use polkadot_subsystem::{
......@@ -792,7 +792,7 @@ mod tests {
keystore: KeyStorePtr,
validators: Vec<Sr25519Keyring>,
validator_public: Vec<ValidatorId>,
global_validation_schedule: GlobalValidationSchedule,
global_validation_data: GlobalValidationData,
local_validation_data: LocalValidationData,
roster: SchedulerRoster,
head_data: HashMap<ParaId, HeadData>,
......@@ -877,7 +877,7 @@ mod tests {
validation_code_hash: Default::default(),
};
let global_validation_schedule = GlobalValidationSchedule {
let global_validation_data = GlobalValidationData {
max_code_size: 1000,
max_head_data_size: 1000,
block_number: Default::default(),
......@@ -891,7 +891,7 @@ mod tests {
roster,
head_data,
local_validation_data,
global_validation_schedule,
global_validation_data,
signing_context,
relay_parent,
}
......@@ -921,7 +921,7 @@ mod tests {
fn make_erasure_root(test: &TestState, pov: PoV) -> Hash {
let omitted_validation = OmittedValidationData {
global_validation: test.global_validation_schedule.clone(),
global_validation: test.global_validation_data.clone(),
local_validation: test.local_validation_data.clone(),
};
......@@ -1048,7 +1048,7 @@ mod tests {
) if pov == pov && &c == candidate.descriptor() => {
tx.send(Ok(
ValidationResult::Valid(ValidationOutputs {
global_validation_schedule: test_state.global_validation_schedule,
global_validation_data: test_state.global_validation_data,
local_validation_data: test_state.local_validation_data,
head_data: expected_head_data.clone(),
upward_messages: Vec::new(),
......@@ -1160,7 +1160,7 @@ mod tests {
) if pov == pov && &c == candidate_a.descriptor() => {
tx.send(Ok(
ValidationResult::Valid(ValidationOutputs {
global_validation_schedule: test_state.global_validation_schedule,
global_validation_data: test_state.global_validation_data,
local_validation_data: test_state.local_validation_data,
head_data: expected_head_data.clone(),
upward_messages: Vec::new(),
......@@ -1281,7 +1281,7 @@ mod tests {
) if pov == pov && &c == candidate_a.descriptor() => {
tx.send(Ok(
ValidationResult::Valid(ValidationOutputs {
global_validation_schedule: test_state.global_validation_schedule,
global_validation_data: test_state.global_validation_data,
local_validation_data: test_state.local_validation_data,
head_data: expected_head_data.clone(),
upward_messages: Vec::new(),
......@@ -1438,7 +1438,7 @@ mod tests {
) if pov == pov && &c == candidate_b.descriptor() => {
tx.send(Ok(
ValidationResult::Valid(ValidationOutputs {
global_validation_schedule: test_state.global_validation_schedule,
global_validation_data: test_state.global_validation_data,
local_validation_data: test_state.local_validation_data,
head_data: expected_head_data.clone(),
upward_messages: Vec::new(),
......
......@@ -24,7 +24,7 @@ use parity_scale_codec::{Decode, Encode};
use polkadot_primitives::v1::{
Hash, CommittedCandidateReceipt, CandidateReceipt, CompactStatement,
EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId,
UpwardMessage, Balance, ValidationCode, GlobalValidationSchedule, LocalValidationData,
UpwardMessage, Balance, ValidationCode, GlobalValidationData, LocalValidationData,
HeadData,
};
use polkadot_statement_table::{
......@@ -118,7 +118,7 @@ pub struct ValidationOutputs {
/// The head-data produced by validation.
pub head_data: HeadData,
/// The global validation schedule.
pub global_validation_schedule: GlobalValidationSchedule,
pub global_validation_data: GlobalValidationData,
/// The local validation data.
pub local_validation_data: LocalValidationData,
/// Upward messages to the relay chain.
......
......@@ -24,7 +24,7 @@ use sp_core::Pair;
use codec::{Encode, Decode};
use primitives::v0::{
Hash, DownwardMessage,
HeadData, BlockData, Id as ParaId, LocalValidationData, GlobalValidationSchedule,
HeadData, BlockData, Id as ParaId, LocalValidationData, GlobalValidationData,
};
use collator::{ParachainContext, Network, BuildParachainContext, Cli, SubstrateCli};
use parking_lot::Mutex;
......@@ -58,7 +58,7 @@ impl ParachainContext for AdderContext {
fn produce_candidate(
&mut self,
_relay_parent: Hash,
_global_validation: GlobalValidationSchedule,
_global_validation: GlobalValidationData,
local_validation: LocalValidationData,
_: Vec<DownwardMessage>,
) -> Self::ProduceCandidate
......
......@@ -179,7 +179,7 @@ pub struct DutyRoster {
/// These are global parameters that apply to all parachain candidates in a block.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Default))]
pub struct GlobalValidationSchedule<N = BlockNumber> {
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.
......@@ -278,7 +278,7 @@ pub struct CandidateReceipt<H = Hash, N = BlockNumber> {
/// The hash of the PoV-block.
pub pov_block_hash: H,
/// The global validation schedule.
pub global_validation: GlobalValidationSchedule<N>,
pub global_validation: GlobalValidationData<N>,
/// The local validation data.
pub local_validation: LocalValidationData<N>,
/// Commitments made as a result of validation.
......@@ -352,7 +352,7 @@ impl Ord for CandidateReceipt {
#[cfg_attr(feature = "std", derive(Debug, Default))]
pub struct OmittedValidationData<N = BlockNumber> {
/// The global validation schedule.
pub global_validation: GlobalValidationSchedule<N>,
pub global_validation: GlobalValidationData<N>,
/// The local validation data.
pub local_validation: LocalValidationData<N>,
}
......@@ -762,7 +762,7 @@ sp_api::decl_runtime_apis! {
fn active_parachains() -> Vec<(Id, Option<(CollatorId, Retriable)>)>;
/// Get the global validation schedule that all parachains should
/// be validated under.
fn global_validation_schedule() -> GlobalValidationSchedule;
fn global_validation_data() -> GlobalValidationData;
/// Get the local validation data for a particular parachain.
fn local_validation_data(id: Id) -> Option<LocalValidationData>;
/// Get the given parachain's head code blob.
......
......@@ -60,14 +60,16 @@ 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,
pov_hash: &Hash,
) -> [u8; 68] {
) -> [u8; 100] {
// 32-byte hash length is protected in a test below.
let mut payload = [0u8; 68];
let mut payload = [0u8; 100];
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(pov_hash.as_ref());
payload[36..68].copy_from_slice(validation_data_hash.as_ref());
payload[68..100].copy_from_slice(pov_hash.as_ref());
payload
}
......@@ -75,11 +77,18 @@ 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,
pov_hash: &Hash,
collator: &CollatorId,
signature: &CollatorSignature,
) -> Result<(),()> {
let payload = collator_signature_payload(relay_parent, para_id, pov_hash);
let payload = collator_signature_payload(
relay_parent,
para_id,
validation_data_hash,
pov_hash,
);
if signature.verify(&payload[..], collator) {
Ok(())
} else {
......@@ -87,6 +96,14 @@ 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))]
......@@ -97,11 +114,16 @@ pub struct CandidateDescriptor<H = Hash> {
pub relay_parent: H,
/// The collator's sr25519 public key.
pub collator: CollatorId,
/// Signature on blake2-256 of components of this receipt:
/// The parachain index, the relay parent, and the pov_hash.
pub signature: CollatorSignature,
/// The blake2-256 hash of the 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,
/// 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> {
......@@ -110,6 +132,7 @@ impl<H: AsRef<[u8]>> CandidateDescriptor<H> {
check_collator_signature(
&self.relay_parent,
&self.para_id,
&self.validation_data_hash,
&self.pov_hash,
&self.collator,
&self.signature,
......@@ -146,7 +169,7 @@ pub struct FullCandidateReceipt<H = Hash, N = BlockNumber> {
/// The inner candidate receipt.
pub inner: CandidateReceipt<H>,
/// The global validation schedule.
pub global_validation: GlobalValidationSchedule<N>,
pub global_validation: GlobalValidationData<N>,
/// The local validation data.
pub local_validation: LocalValidationData<N>,
}
......@@ -232,7 +255,7 @@ pub struct LocalValidationData<N = BlockNumber> {
/// 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 GlobalValidationSchedule<N = BlockNumber> {
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.
......@@ -465,7 +488,7 @@ impl CoreAssignment {
#[cfg_attr(feature = "std", derive(PartialEq, Debug))]
pub struct OmittedValidationData {
/// The global validation schedule.
pub global_validation: GlobalValidationSchedule,
pub global_validation: GlobalValidationData,
/// The local validation data.
pub local_validation: LocalValidationData,
}
......@@ -636,9 +659,9 @@ sp_api::decl_runtime_apis! {
/// cores can have paras assigned to them.
fn availability_cores() -> Vec<CoreState<N>>;
/// Yields the GlobalValidationSchedule. This applies to all para candidates with the
/// 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_schedule() -> GlobalValidationSchedule<N>;
fn global_validation_data() -> GlobalValidationData<N>;
/// Yields the LocalValidationData for the given ParaId along with an assumption that
/// should be used if the para currently occupies a core.
......@@ -696,4 +719,18 @@ mod tests {
assert_eq!(info.next_rotation_at(), 0);
assert_eq!(info.last_rotation_at(), 0);
}
#[test]
fn collator_signature_payload_is_valid() {
// if this fails, collator signature verification code has to be updated.
let h = Hash::default();
assert_eq!(h.as_ref().len(), 32);
let _payload = collator_signature_payload(
&Hash::from([1; 32]),
&5u32.into(),
&Hash::from([2; 32]),
&Hash::from([3; 32]),
);
}
}
......@@ -137,10 +137,10 @@ enum CoreState {
## Global Validation Schedule
Yields the [`GlobalValidationSchedule`](../types/candidate.md#globalvalidationschedule) at the state of a given block. This applies to all para candidates with the relay-parent equal to that block.
Yields the [`GlobalValidationData`](../types/candidate.md#globalvalidationschedule) at the state of a given block. This applies to all para candidates with the relay-parent equal to that block.
```rust
fn global_validation_schedule(at: Block) -> GlobalValidationSchedule;
fn global_validation_data(at: Block) -> GlobalValidationData;
```
## Local Validation Data
......
......@@ -35,6 +35,9 @@ fn update_configuration(f: impl FnOnce(&mut HostConfiguration)) {
*pending = Some(x);
})
}
/// Get the GlobalValidationData, assuming the context is the parent block.
fn global_validation_data() -> GlobalValidationData;
```
## Entry-points
......
......@@ -62,6 +62,7 @@ All failed checks should lead to an unrecoverable error making the block invalid
1. check that each candidate corresponds to a scheduled core and that they are ordered in the same order the cores appear in assignments in `scheduled`.
1. check that `scheduled` is sorted ascending by `CoreIndex`, without duplicates.
1. check that there is no candidate pending availability for any scheduled `ParaId`.
1. check that each candidate's `validation_data_hash` corresponds to a `(LocalValidationData, GlobalValidationData)` computed from the current state.
1. If the core assignment includes a specific collator, ensure the backed candidate is issued by that collator.
1. Ensure that any code upgrade scheduled by the candidate does not happen within `config.validation_upgrade_frequency` 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.
......
......@@ -112,6 +112,7 @@ OutgoingParas: Vec<ParaId>;
* `is_parathread(ParaId) -> bool`: Returns true if the para ID references any live parathread.
* `last_code_upgrade(id: ParaId, include_future: bool) -> Option<BlockNumber>`: The block number of the last scheduled upgrade of the requested para. Includes future upgrades if the flag is set. This is the `expected_at` number, not the `activated_at` number.
* `local_validation_data(id: ParaId) -> Option<LocalValidationData>`: Get the LocalValidationData of the given para, assuming the context is the parent block. Returns `None` if the para is not known.
## Finalization
......
......@@ -26,12 +26,12 @@ struct PoV(Vec<u8>);
Validation data that is often omitted from types describing candidates as it can be derived from the relay-parent of the candidate. However, with the expectation of state pruning, these are best kept available elsewhere as well.
This contains the [`GlobalValidationSchedule`](candidate.md#globalvalidationschedule) and [`LocalValidationData`](candidate.md#localvalidationdata)
This contains the [`GlobalValidationData`](candidate.md#globalvalidationschedule) and [`LocalValidationData`](candidate.md#localvalidationdata)
```rust
struct OmittedValidationData {
/// The global validation schedule.
global_validation: GlobalValidationSchedule,
global_validation: GlobalValidationData,
/// The local validation data.
local_validation: LocalValidationData,
}
......
......@@ -33,7 +33,7 @@ struct CandidateReceipt {
## Full Candidate Receipt
This is the full receipt type. The `GlobalValidationSchedule` and the `LocalValidationData` are technically redundant with the `inner.relay_parent`, which uniquely describes the a block in the blockchain from whose state these values are derived. The [`CandidateReceipt`](#candidate-receipt) variant is often used instead for this reason.
This is the full receipt type. The `GlobalValidationData` and the `LocalValidationData` are technically redundant with the `inner.relay_parent`, which uniquely describes the a block in the blockchain from whose state these values are derived. The [`CandidateReceipt`](#candidate-receipt) variant is often used instead for this reason.
However, the Full Candidate Receipt type is useful as a means of avoiding the implicit dependency on availability of old blockchain state. In situations such as availability and approval, having the full description of the candidate within a self-contained struct is convenient.
......@@ -42,7 +42,7 @@ However, the Full Candidate Receipt type is useful as a means of avoiding the im
struct FullCandidateReceipt {
inner: CandidateReceipt,
/// The global validation schedule.
global_validation: GlobalValidationSchedule,
global_validation: GlobalValidationData,
/// The local validation data.
local_validation: LocalValidationData,
}
......@@ -77,16 +77,19 @@ struct CandidateDescriptor {
relay_parent: Hash,
/// The collator's sr25519 public key.
collator: CollatorId,
/// Signature on blake2-256 of components of this receipt:
/// The parachain index, the relay parent, and the pov_hash.
signature: CollatorSignature,
/// The blake2-256 hash of the validation data. These are extra parameters
/// derived from relay-chain state that influence the validity of the block.
validation_data_hash: Hash,
/// The blake2-256 hash of the pov-block.
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.
signature: CollatorSignature,
}
```
## GlobalValidationSchedule
## GlobalValidationData
The global validation schedule comprises of information describing the global environment for para execution, as derived from a particular relay-parent. These are parameters that will apply to all parablocks executed in the context of this relay-parent.
......@@ -95,7 +98,7 @@ The global validation schedule comprises of information describing the global en
/// to fully validate the candidate.
///
/// These are global parameters that apply to all candidates in a block.
struct GlobalValidationSchedule {
struct GlobalValidationData {
/// The maximum code size permitted, in bytes.
max_code_size: u32,
/// The maximum head-data size permitted, in bytes.
......@@ -197,7 +200,7 @@ struct ValidationOutputs {
/// The head-data produced by validation.
head_data: HeadData,
/// The global validation schedule.
global_validation_schedule: GlobalValidationSchedule,
global_validation_data: GlobalValidationData,
/// The local validation data.
local_validation_data: LocalValidationData,
/// Upwards messages to the relay chain.
......
......@@ -255,7 +255,7 @@ enum RuntimeApiRequest {
/// Get the validation code for a specific para, using the given occupied core assumption.
ValidationCode(ParaId, OccupiedCoreAssumption, ResponseChannel<Option<ValidationCode>>),
/// Get the global validation schedule at the state of a given block.
GlobalValidationSchedule(ResponseChannel<GlobalValidationSchedule>),
GlobalValidationData(ResponseChannel<GlobalValidationData>),
/// Get the local validation data for a specific para, with the given occupied core assumption.
LocalValidationData(
ParaId,
......
......@@ -41,7 +41,7 @@ use primitives::v0::{
Balance, BlockNumber,
Id as ParaId, Chain, DutyRoster, AttestedCandidate, CompactStatement as Statement, ParachainDispatchOrigin,
UpwardMessage, ValidatorId, ActiveParas, CollatorId, Retriable, OmittedValidationData,
CandidateReceipt, GlobalValidationSchedule, AbridgedCandidateReceipt,
CandidateReceipt, GlobalValidationData, AbridgedCandidateReceipt,
LocalValidationData, Scheduling, ValidityAttestation, NEW_HEADS_IDENTIFIER, PARACHAIN_KEY_TYPE_ID,
ValidatorSignature, SigningContext, HeadData, ValidationCode,
Remark, DownwardMessage
......@@ -601,7 +601,7 @@ decl_module! {
let mut proceeded = Vec::with_capacity(heads.len());
let schedule = Self::global_validation_schedule();
let schedule = Self::global_validation_data();
if !active_parachains.is_empty() {
// perform integrity checks before writing to storage.
......@@ -1168,9 +1168,9 @@ impl<T: Trait> Module<T> {
}
/// Get the global validation schedule for all parachains.
pub fn global_validation_schedule() -> GlobalValidationSchedule {
pub fn global_validation_data() -> GlobalValidationData {
let now = <system::Module<T>>::block_number();
GlobalValidationSchedule {
GlobalValidationData {
max_code_size: T::MaxCodeSize::get(),
max_head_data_size: T::MaxHeadDataSize::get(),
block_number: T::BlockNumberConversion::convert(if now.is_zero() {
......@@ -1322,7 +1322,7 @@ impl<T: Trait> Module<T> {
// check the attestations on these candidates. The candidates should have been checked
// that each candidates' chain ID is valid.
fn check_candidates(
schedule: &GlobalValidationSchedule,
schedule: &GlobalValidationData,
attested_candidates: &[AttestedCandidate],
active_parachains: &[(ParaId, Option<(CollatorId, Retriable)>)]
) -> sp_std::result::Result<IncludedBlocks<T>, sp_runtime::DispatchError> {
......@@ -2157,7 +2157,7 @@ mod tests {
collator: Default::default(),
signature: Default::default(),
pov_block_hash: Default::default(),
global_validation: Parachains::global_validation_schedule(),
global_validation: Parachains::global_validation_data(),
local_validation: Parachains::current_local_validation_data(&para_id).unwrap(),
commitments: CandidateCommitments::default(),
}
......
......@@ -1070,7 +1070,7 @@ mod tests {
collator: collator.public(),
signature: pov_block_hash.using_encoded(|d| collator.sign(d)),
pov_block_hash,
global_validation: Parachains::global_validation_schedule(),
global_validation: Parachains::global_validation_data(),
local_validation: Parachains::current_local_validation_data(&id).unwrap(),
commitments: CandidateCommitments {
fees: 0,
......
......@@ -87,7 +87,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("kusama"),
impl_name: create_runtime_str!("parity-kusama"),
authoring_version: 2,
spec_version: 2019,
spec_version: 2020,
impl_version: 0,
#[cfg(not(feature = "disable-runtime-api"))]
apis: RUNTIME_API_VERSIONS,
......@@ -1115,8 +1115,8 @@ sp_api::impl_runtime_apis! {
fn active_parachains() -> Vec<(parachain::Id, Option<(parachain::CollatorId, parachain::Retriable)>)> {
Registrar::active_paras()
}
fn global_validation_schedule() -> parachain::GlobalValidationSchedule {
Parachains::global_validation_schedule()
fn global_validation_data() -> parachain::GlobalValidationData {
Parachains::global_validation_data()
}
fn local_validation_data(id: parachain::Id) -> Option<parachain::LocalValidationData> {
Parachains::current_local_validation_data(&id)
......
......@@ -19,12 +19,13 @@
//! Configuration can change only at session boundaries and is buffered until then.
use sp_std::prelude::*;
use primitives::v1::ValidatorId;
use primitives::v1::{ValidatorId, GlobalValidationData};
use frame_support::{
decl_storage, decl_module, decl_error,
dispatch::DispatchResult,
weights::{DispatchClass, Weight},
};
use sp_runtime::traits::One;
use codec::{Encode, Decode};
use system::ensure_root;
......@@ -219,6 +220,16 @@ impl<T: Trait> Module<T> {
<Self as Store>::PendingConfig::set(Some(prev));
}
}
/// Computes the global validation-data, assuming the context of the parent block.
pub(crate) fn global_validation_data() -> GlobalValidationData<T::BlockNumber> {
let config = Self::config();
GlobalValidationData {
max_code_size: config.max_code_size,
max_head_data_size: config.max_head_data_size,
block_number: <system::Module<T>>::block_number() - One::one(),
}
}
}
#[cfg(test)]
......
......@@ -22,6 +22,7 @@
use sp_std::prelude::*;
use primitives::v1::{
validation_data_hash,
ValidatorId, CandidateCommitments, CandidateDescriptor, ValidatorIndex, Id as ParaId,
AvailabilityBitfield as AvailabilityBitfield, SignedAvailabilityBitfields, SigningContext,
BackedCandidate, CoreIndex, GroupIndex, CoreAssignment, CommittedCandidateReceipt,
......@@ -145,6 +146,8 @@ decl_error! {
InvalidBacking,
/// Collator did not sign PoV.
NotCollatorSigned,