From d29fae0ad33c440f2b4b9745afb188ee086a1b7e Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 14 Jan 2021 17:01:21 +0000 Subject: [PATCH 1/6] collation-generation: use persisted validation data --- node/collation-generation/src/lib.rs | 26 +++++++++---------- node/primitives/src/lib.rs | 4 +-- .../test-parachains/adder/collator/src/lib.rs | 13 ++++------ .../node/collators/collation-generation.md | 2 +- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/node/collation-generation/src/lib.rs b/node/collation-generation/src/lib.rs index 79c08eed2749..d3155177553c 100644 --- a/node/collation-generation/src/lib.rs +++ b/node/collation-generation/src/lib.rs @@ -32,7 +32,7 @@ use polkadot_node_subsystem::{ FromOverseer, SpawnedSubsystem, Subsystem, SubsystemContext, SubsystemResult, }; use polkadot_node_subsystem_util::{ - request_availability_cores_ctx, request_full_validation_data_ctx, + request_availability_cores_ctx, request_persisted_validation_data_ctx, request_validators_ctx, metrics::{self, prometheus}, }; @@ -247,7 +247,7 @@ async fn handle_new_activations( // we get validation data synchronously for each core instead of // within the subtask loop, because we have only a single mutable handle to the // context, so the work can't really be distributed - let validation_data = match request_full_validation_data_ctx( + let validation_data = match request_persisted_validation_data_ctx( relay_parent, scheduled_core.para_id, assumption, @@ -274,7 +274,7 @@ async fn handle_new_activations( let mut task_sender = sender.clone(); let metrics = metrics.clone(); ctx.spawn("collation generation collation builder", Box::pin(async move { - let persisted_validation_data_hash = validation_data.persisted.hash(); + let persisted_validation_data_hash = validation_data.hash(); let collation = match (task_config.collator)(relay_parent, &validation_data).await { Some(collation) => collation, @@ -299,7 +299,7 @@ async fn handle_new_activations( let erasure_root = match erasure_root( n_validators, - validation_data.persisted, + validation_data, collation.proof_of_validity.clone(), ) { Ok(erasure_root) => erasure_root, @@ -465,7 +465,7 @@ mod tests { }; use polkadot_primitives::v1::{ BlockData, BlockNumber, CollatorPair, Id as ParaId, - PersistedValidationData, PoV, ScheduledCore, ValidationData, + PersistedValidationData, PoV, ScheduledCore, }; use std::pin::Pin; @@ -499,7 +499,7 @@ mod tests { fn test_config>(para_id: Id) -> Arc { Arc::new(CollationGenerationConfig { key: CollatorPair::generate().0, - collator: Box::new(|_: Hash, _vd: &ValidationData| { + collator: Box::new(|_: Hash, _vd: &PersistedValidationData| { TestCollator.boxed() }), para_id: para_id.into(), @@ -573,9 +573,9 @@ mod tests { Hash::repeat_byte(16), ]; - let requested_full_validation_data = Arc::new(Mutex::new(Vec::new())); + let requested_validation_data = Arc::new(Mutex::new(Vec::new())); - let overseer_requested_full_validation_data = requested_full_validation_data.clone(); + let overseer_requested_validation_data = requested_validation_data.clone(); let overseer = |mut handle: TestSubsystemContextHandle| async move { loop { match handle.try_recv().await { @@ -598,13 +598,13 @@ mod tests { } Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( hash, - RuntimeApiRequest::FullValidationData( + RuntimeApiRequest::PersistedValidationData( _para_id, _occupied_core_assumption, tx, ), ))) => { - overseer_requested_full_validation_data + overseer_requested_validation_data .lock() .await .push(hash); @@ -631,7 +631,7 @@ mod tests { .unwrap(); }); - let requested_full_validation_data = Arc::try_unwrap(requested_full_validation_data) + let requested_validation_data = Arc::try_unwrap(requested_validation_data) .expect("overseer should have shut down by now") .into_inner(); @@ -639,7 +639,7 @@ mod tests { // each activated hash generates two scheduled cores: one with its value * 4, one with its value * 5 // given that the test configuration has a para_id of 16, there's only one way to get that value: with the 4 // hash. - assert_eq!(requested_full_validation_data, vec![[4; 32].into()]); + assert_eq!(requested_validation_data, vec![[4; 32].into()]); } #[test] @@ -673,7 +673,7 @@ mod tests { } Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( _hash, - RuntimeApiRequest::FullValidationData( + RuntimeApiRequest::PersistedValidationData( _para_id, _occupied_core_assumption, tx, diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index fa4fe750c9ca..e2195f59e2a1 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -27,7 +27,7 @@ use parity_scale_codec::{Decode, Encode}; use polkadot_primitives::v1::{ Hash, CommittedCandidateReceipt, CandidateReceipt, CompactStatement, EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId, - UpwardMessage, ValidationCode, PersistedValidationData, ValidationData, + UpwardMessage, ValidationCode, PersistedValidationData, HeadData, PoV, CollatorPair, Id as ParaId, OutboundHrmpMessage, CandidateCommitments, CandidateHash, }; use polkadot_statement_table::{ @@ -288,7 +288,7 @@ pub struct Collation { /// block should be build on and the [`ValidationData`] that provides /// information about the state of the parachain on the relay chain. pub type CollatorFn = Box< - dyn Fn(Hash, &ValidationData) -> Pin> + Send>> + dyn Fn(Hash, &PersistedValidationData) -> Pin> + Send>> + Send + Sync, >; diff --git a/parachain/test-parachains/adder/collator/src/lib.rs b/parachain/test-parachains/adder/collator/src/lib.rs index 4c798a04c0d6..2d75597025c3 100644 --- a/parachain/test-parachains/adder/collator/src/lib.rs +++ b/parachain/test-parachains/adder/collator/src/lib.rs @@ -148,7 +148,7 @@ impl Collator { let state = self.state.clone(); Box::new(move |relay_parent, validation_data| { - let parent = HeadData::decode(&mut &validation_data.persisted.parent_head.0[..]) + let parent = HeadData::decode(&mut &validation_data.parent_head.0[..]) .expect("Decodes parent head"); let (block_data, head_data) = state.lock().unwrap().advance(parent); @@ -168,7 +168,7 @@ impl Collator { block_data: block_data.encode().into(), }, processed_downward_messages: 0, - hrmp_watermark: validation_data.persisted.block_number, + hrmp_watermark: validation_data.block_number, }; async move { Some(collation) }.boxed() @@ -196,7 +196,7 @@ mod tests { use futures::executor::block_on; use polkadot_parachain::{primitives::ValidationParams, wasm_executor::IsolationStrategy}; - use polkadot_primitives::v1::{PersistedValidationData, ValidationData}; + use polkadot_primitives::v1::PersistedValidationData; #[test] fn collator_works() { @@ -213,11 +213,8 @@ mod tests { .unwrap() .clone(); - let validation_data = ValidationData { - persisted: PersistedValidationData { - parent_head: parent_head.encode().into(), - ..Default::default() - }, + let validation_data = PersistedValidationData { + parent_head: parent_head.encode().into(), ..Default::default() }; diff --git a/roadmap/implementers-guide/src/node/collators/collation-generation.md b/roadmap/implementers-guide/src/node/collators/collation-generation.md index 56401823590d..5b9e8d6654b7 100644 --- a/roadmap/implementers-guide/src/node/collators/collation-generation.md +++ b/roadmap/implementers-guide/src/node/collators/collation-generation.md @@ -33,7 +33,7 @@ pub struct Collation { } type CollatorFn = Box< - dyn Fn(Hash, &ValidationData) -> Pin>>> + dyn Fn(Hash, &PeristedValidationData) -> Pin>>> >; struct CollationGenerationConfig { From d357217b8b38d912924c673d4f71d34c35902be3 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 14 Jan 2021 17:06:57 +0000 Subject: [PATCH 2/6] node: remote FullValidationData API --- node/core/runtime-api/src/lib.rs | 44 ------------------- node/subsystem-util/src/lib.rs | 4 +- node/subsystem/src/messages.rs | 10 +---- .../src/types/overseer-protocol.md | 6 --- 4 files changed, 2 insertions(+), 62 deletions(-) diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index 97e645a428a2..e895e29e7c15 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -193,8 +193,6 @@ fn make_runtime_api_request( Request::AvailabilityCores(sender) => query!(availability_cores(), sender), Request::PersistedValidationData(para, assumption, sender) => query!(persisted_validation_data(para, assumption), sender), - Request::FullValidationData(para, assumption, sender) => - query!(full_validation_data(para, assumption), sender), Request::CheckValidationOutputs(para, commitments, sender) => query!(check_validation_outputs(para, commitments), sender), Request::SessionIndexForChild(sender) => query!(session_index_for_child(), sender), @@ -529,48 +527,6 @@ mod tests { futures::executor::block_on(future::join(subsystem_task, test_task)); } - #[test] - fn requests_full_validation_data() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let relay_parent = [1; 32].into(); - let para_a = 5.into(); - let para_b = 6.into(); - let spawner = sp_core::testing::TaskExecutor::new(); - - let mut runtime_api = MockRuntimeApi::default(); - runtime_api.validation_data.insert(para_a, Default::default()); - let runtime_api = Arc::new(runtime_api); - - let subsystem = RuntimeApiSubsystem::new(runtime_api.clone(), Metrics(None), spawner); - let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); - let test_task = async move { - let (tx, rx) = oneshot::channel(); - - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::FullValidationData(para_a, OccupiedCoreAssumption::Included, tx) - ), - }).await; - - assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); - - let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::FullValidationData(para_b, OccupiedCoreAssumption::Included, tx) - ), - }).await; - - assert_eq!(rx.await.unwrap().unwrap(), None); - - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; - - futures::executor::block_on(future::join(subsystem_task, test_task)); - } - #[test] fn requests_check_validation_outputs() { let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); diff --git a/node/subsystem-util/src/lib.rs b/node/subsystem-util/src/lib.rs index 9ce1258e8a99..1eee4cc7f758 100644 --- a/node/subsystem-util/src/lib.rs +++ b/node/subsystem-util/src/lib.rs @@ -36,7 +36,7 @@ use parity_scale_codec::Encode; use pin_project::pin_project; use polkadot_primitives::v1::{ CandidateEvent, CommittedCandidateReceipt, CoreState, EncodeAs, PersistedValidationData, - GroupRotationInfo, Hash, Id as ParaId, ValidationData, OccupiedCoreAssumption, + GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption, SessionIndex, Signed, SigningContext, ValidationCode, ValidatorId, ValidatorIndex, SessionInfo, }; use sp_core::{traits::SpawnNamed, Public}; @@ -170,7 +170,6 @@ specialize_requests! { fn request_validators() -> Vec; Validators; fn request_validator_groups() -> (Vec>, GroupRotationInfo); ValidatorGroups; fn request_availability_cores() -> Vec; AvailabilityCores; - fn request_full_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option; FullValidationData; fn request_persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option; PersistedValidationData; fn request_session_index_for_child() -> SessionIndex; SessionIndexForChild; fn request_validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option; ValidationCode; @@ -252,7 +251,6 @@ specialize_requests_ctx! { fn request_validators_ctx() -> Vec; Validators; fn request_validator_groups_ctx() -> (Vec>, GroupRotationInfo); ValidatorGroups; fn request_availability_cores_ctx() -> Vec; AvailabilityCores; - fn request_full_validation_data_ctx(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option; FullValidationData; fn request_persisted_validation_data_ctx(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option; PersistedValidationData; fn request_session_index_for_child_ctx() -> SessionIndex; SessionIndexForChild; fn request_validation_code_ctx(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option; ValidationCode; diff --git a/node/subsystem/src/messages.rs b/node/subsystem/src/messages.rs index 995256d5d409..2bef8f74c928 100644 --- a/node/subsystem/src/messages.rs +++ b/node/subsystem/src/messages.rs @@ -36,7 +36,7 @@ use polkadot_primitives::v1::{ CollatorId, CommittedCandidateReceipt, CoreState, ErasureChunk, GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption, PersistedValidationData, PoV, SessionIndex, SignedAvailabilityBitfield, - ValidationCode, ValidatorId, ValidationData, CandidateHash, + ValidationCode, ValidatorId, CandidateHash, ValidatorIndex, ValidatorSignature, InboundDownwardMessage, InboundHrmpMessage, }; use std::{sync::Arc, collections::btree_map::BTreeMap}; @@ -399,14 +399,6 @@ pub enum RuntimeApiRequest { OccupiedCoreAssumption, RuntimeApiSender>, ), - /// Get the full validation data for a particular para, taking the given - /// `OccupiedCoreAssumption`, which will inform on how the validation data should be computed - /// if the para currently occupies a core. - FullValidationData( - ParaId, - OccupiedCoreAssumption, - RuntimeApiSender>, - ), /// Sends back `true` if the validation outputs pass all acceptance criteria checks. CheckValidationOutputs( ParaId, diff --git a/roadmap/implementers-guide/src/types/overseer-protocol.md b/roadmap/implementers-guide/src/types/overseer-protocol.md index 44d0d8064df3..341b62326bbc 100644 --- a/roadmap/implementers-guide/src/types/overseer-protocol.md +++ b/roadmap/implementers-guide/src/types/overseer-protocol.md @@ -442,12 +442,6 @@ enum RuntimeApiRequest { OccupiedCoreAssumption, ResponseChannel>, ), - /// Get the full validation data for a specific para, with the given occupied core assumption. - FullValidationData( - ParaId, - OccupiedCoreAssumption, - ResponseChannel>, - ), /// Sends back `true` if the commitments pass all acceptance criteria checks. CheckValidationOutputs( ParaId, From a37ef8ac8f95b949469dfb0b0c538f6f1663be06 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 14 Jan 2021 17:19:03 +0000 Subject: [PATCH 3/6] runtime: remove FullValidationData API --- node/core/runtime-api/src/lib.rs | 14 ++------ primitives/src/v1.rs | 9 ----- roadmap/implementers-guide/src/SUMMARY.md | 1 - .../src/runtime-api/full-validation-data.md | 7 ---- runtime/kusama/src/lib.rs | 7 +--- runtime/parachains/src/runtime_api_impl/v1.rs | 26 +------------- runtime/parachains/src/util.rs | 36 +------------------ runtime/polkadot/src/lib.rs | 7 +--- runtime/rococo/src/lib.rs | 7 +--- runtime/test-runtime/src/lib.rs | 8 +---- runtime/westend/src/lib.rs | 7 +--- 11 files changed, 10 insertions(+), 119 deletions(-) delete mode 100644 roadmap/implementers-guide/src/runtime-api/full-validation-data.md diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index e895e29e7c15..24a3a1e101ad 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -269,7 +269,7 @@ mod tests { use polkadot_primitives::v1::{ ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, PersistedValidationData, - Id as ParaId, OccupiedCoreAssumption, ValidationData, SessionIndex, ValidationCode, + Id as ParaId, OccupiedCoreAssumption, SessionIndex, ValidationCode, CommittedCandidateReceipt, CandidateEvent, InboundDownwardMessage, BlockNumber, InboundHrmpMessage, SessionInfo, }; @@ -284,7 +284,7 @@ mod tests { validator_groups: Vec>, availability_cores: Vec, availability_cores_wait: Arc>, - validation_data: HashMap, + validation_data: HashMap, session_index_for_child: SessionIndex, session_info: HashMap, validation_code: HashMap, @@ -333,15 +333,7 @@ mod tests { para: ParaId, _assumption: OccupiedCoreAssumption, ) -> Option { - self.validation_data.get(¶).map(|l| l.persisted.clone()) - } - - fn full_validation_data( - &self, - para: ParaId, - _assumption: OccupiedCoreAssumption, - ) -> Option { - self.validation_data.get(¶).map(|l| l.clone()) + self.validation_data.get(¶).cloned() } fn check_validation_outputs( diff --git a/primitives/src/v1.rs b/primitives/src/v1.rs index 099e45a336dc..1d26021705ec 100644 --- a/primitives/src/v1.rs +++ b/primitives/src/v1.rs @@ -833,15 +833,6 @@ sp_api::decl_runtime_apis! { #[skip_initialize_block] fn availability_cores() -> Vec>; - /// 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. - #[skip_initialize_block] - fn full_validation_data(para_id: Id, assumption: OccupiedCoreAssumption) - -> Option>; - /// Yields the persisted validation data for the given ParaId along with an assumption that /// should be used if the para currently occupies a core. /// diff --git a/roadmap/implementers-guide/src/SUMMARY.md b/roadmap/implementers-guide/src/SUMMARY.md index b6e0fab3be4e..90dae2162bda 100644 --- a/roadmap/implementers-guide/src/SUMMARY.md +++ b/roadmap/implementers-guide/src/SUMMARY.md @@ -24,7 +24,6 @@ - [Validator Groups](runtime-api/validator-groups.md) - [Availability Cores](runtime-api/availability-cores.md) - [Persisted Validation Data](runtime-api/persisted-validation-data.md) - - [Full Validation Data](runtime-api/full-validation-data.md) - [Session Index](runtime-api/session-index.md) - [Validation Code](runtime-api/validation-code.md) - [Candidate Pending Availability](runtime-api/candidate-pending-availability.md) diff --git a/roadmap/implementers-guide/src/runtime-api/full-validation-data.md b/roadmap/implementers-guide/src/runtime-api/full-validation-data.md deleted file mode 100644 index 884fad076e2f..000000000000 --- a/roadmap/implementers-guide/src/runtime-api/full-validation-data.md +++ /dev/null @@ -1,7 +0,0 @@ -# Full Validation Data - -Yields the full [`ValidationData`](../types/candidate.md#validationdata) at the state of a given block. - -```rust -fn full_validation_data(at: Block, ParaId, OccupiedCoreAssumption) -> Option; -``` diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index b852ba4b2c62..3b68ff4f1c2f 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -28,7 +28,7 @@ use parity_scale_codec::{Encode, Decode}; use primitives::v1::{ AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt, CoreState, GroupRotationInfo, Hash, Id, Moment, Nonce, OccupiedCoreAssumption, - PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex, + PersistedValidationData, Signature, ValidationCode, ValidatorId, ValidatorIndex, InboundDownwardMessage, InboundHrmpMessage, SessionInfo, AssignmentId, }; use runtime_common::{ @@ -1132,11 +1132,6 @@ sp_api::impl_runtime_apis! { Vec::new() } - fn full_validation_data(_: Id, _: OccupiedCoreAssumption) - -> Option> { - None - } - fn persisted_validation_data(_: Id, _: OccupiedCoreAssumption) -> Option> { None diff --git a/runtime/parachains/src/runtime_api_impl/v1.rs b/runtime/parachains/src/runtime_api_impl/v1.rs index f39e683ce2ce..f7fc8cceb39e 100644 --- a/runtime/parachains/src/runtime_api_impl/v1.rs +++ b/runtime/parachains/src/runtime_api_impl/v1.rs @@ -21,7 +21,7 @@ use sp_std::prelude::*; use sp_std::collections::btree_map::BTreeMap; use sp_runtime::traits::One; use primitives::v1::{ - ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, ValidationData, + ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, Id as ParaId, OccupiedCoreAssumption, SessionIndex, ValidationCode, CommittedCandidateReceipt, ScheduledCore, OccupiedCore, CoreOccupied, CoreIndex, GroupIndex, CandidateEvent, PersistedValidationData, SessionInfo, @@ -193,30 +193,6 @@ fn with_assumption( } } -/// Implementation for the `full_validation_data` function of the runtime API. -pub fn full_validation_data( - para_id: ParaId, - assumption: OccupiedCoreAssumption, -) -> Option> { - use parity_scale_codec::Decode as _; - let relay_parent_number = >::block_number(); - let relay_storage_root = Hash::decode(&mut &sp_io::storage::root()[..]) - .expect("storage root must decode to the Hash type; qed"); - with_assumption::(para_id, assumption, || { - Some(ValidationData { - persisted: crate::util::make_persisted_validation_data::( - para_id, - relay_parent_number, - relay_storage_root, - )?, - transient: crate::util::make_transient_validation_data::( - para_id, - relay_parent_number, - )?, - }) - }) -} - /// Implementation for the `persisted_validation_data` function of the runtime API. pub fn persisted_validation_data( para_id: ParaId, diff --git a/runtime/parachains/src/util.rs b/runtime/parachains/src/util.rs index ce041981eb1c..f2e4f6d6dd9a 100644 --- a/runtime/parachains/src/util.rs +++ b/runtime/parachains/src/util.rs @@ -17,8 +17,7 @@ //! Utilities that don't belong to any particular module but may draw //! on all modules. -use sp_runtime::traits::Saturating; -use primitives::v1::{Id as ParaId, PersistedValidationData, TransientValidationData, Hash}; +use primitives::v1::{Id as ParaId, PersistedValidationData, Hash}; use crate::{configuration, paras, dmp, hrmp}; @@ -42,36 +41,3 @@ pub fn make_persisted_validation_data( max_pov_size: config.max_pov_size, }) } - -/// Make the transient validation data for a particular parachain and a specified relay-parent. -/// -/// This ties together the storage of several modules. -pub fn make_transient_validation_data( - para_id: ParaId, - relay_parent_number: T::BlockNumber, -) -> Option> { - let config = >::config(); - - let freq = config.validation_upgrade_frequency; - let delay = config.validation_upgrade_delay; - - let last_code_upgrade = >::last_code_upgrade(para_id, true); - let can_upgrade_code = last_code_upgrade.map_or( - true, - |l| { l <= relay_parent_number && relay_parent_number.saturating_sub(l) >= freq }, - ); - - let code_upgrade_allowed = if can_upgrade_code { - Some(relay_parent_number + delay) - } else { - None - }; - - Some(TransientValidationData { - max_code_size: config.max_code_size, - max_head_data_size: config.max_head_data_size, - balance: 0, - code_upgrade_allowed, - dmq_length: >::dmq_length(para_id), - }) -} diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index bc8099229633..0bc9bd9cac03 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -35,7 +35,7 @@ use parity_scale_codec::{Encode, Decode}; use primitives::v1::{ AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt, CoreState, GroupRotationInfo, Hash, Id, Moment, Nonce, OccupiedCoreAssumption, - PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex, + PersistedValidationData, Signature, ValidationCode, ValidatorId, ValidatorIndex, InboundDownwardMessage, InboundHrmpMessage, SessionInfo, AssignmentId, }; use sp_runtime::{ @@ -1129,11 +1129,6 @@ sp_api::impl_runtime_apis! { Vec::new() } - fn full_validation_data(_: Id, _: OccupiedCoreAssumption) - -> Option> { - None - } - fn persisted_validation_data(_: Id, _: OccupiedCoreAssumption) -> Option> { None diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index b852217807bb..d63abb1a269d 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -26,7 +26,7 @@ use sp_std::collections::btree_map::BTreeMap; use parity_scale_codec::Encode; use primitives::v1::{ AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, - GroupRotationInfo, CoreState, Id, ValidationData, ValidationCode, CandidateEvent, + GroupRotationInfo, CoreState, Id, ValidationCode, CandidateEvent, ValidatorId, ValidatorIndex, CommittedCandidateReceipt, OccupiedCoreAssumption, PersistedValidationData, InboundDownwardMessage, InboundHrmpMessage, SessionInfo as SessionInfoData, @@ -696,11 +696,6 @@ sp_api::impl_runtime_apis! { runtime_api_impl::availability_cores::() } - fn full_validation_data(para_id: Id, assumption: OccupiedCoreAssumption) - -> Option> { - runtime_api_impl::full_validation_data::(para_id, assumption) - } - fn persisted_validation_data(para_id: Id, assumption: OccupiedCoreAssumption) -> Option> { runtime_api_impl::persisted_validation_data::(para_id, assumption) diff --git a/runtime/test-runtime/src/lib.rs b/runtime/test-runtime/src/lib.rs index 9a4f7494ac39..f24725715485 100644 --- a/runtime/test-runtime/src/lib.rs +++ b/runtime/test-runtime/src/lib.rs @@ -40,7 +40,7 @@ use polkadot_runtime_parachains::runtime_api_impl::v1 as runtime_impl; use primitives::v1::{ AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt, CoreState, GroupRotationInfo, Hash as HashT, Id as ParaId, Moment, Nonce, OccupiedCoreAssumption, - PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex, + PersistedValidationData, Signature, ValidationCode, ValidatorId, ValidatorIndex, InboundDownwardMessage, InboundHrmpMessage, SessionInfo as SessionInfoData, }; use runtime_common::{ @@ -639,12 +639,6 @@ sp_api::impl_runtime_apis! { runtime_impl::availability_cores::() } - fn full_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) - -> Option> - { - runtime_impl::full_validation_data::(para_id, assumption) - } - fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption) -> Option> { diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index ad3335ccd535..14cb5b512de5 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -27,7 +27,7 @@ use parity_scale_codec::{Encode, Decode}; use primitives::v1::{ AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt, CoreState, GroupRotationInfo, Hash, Id, Moment, Nonce, OccupiedCoreAssumption, - PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex, + PersistedValidationData, Signature, ValidationCode, ValidatorId, ValidatorIndex, InboundDownwardMessage, InboundHrmpMessage, SessionInfo, AssignmentId, }; use runtime_common::{ @@ -850,11 +850,6 @@ sp_api::impl_runtime_apis! { Vec::new() } - fn full_validation_data(_: Id, _: OccupiedCoreAssumption) - -> Option> { - None - } - fn persisted_validation_data(_: Id, _: OccupiedCoreAssumption) -> Option> { None From 04d2c29188a75818e495173274233efb511f7bb5 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 14 Jan 2021 17:23:22 +0000 Subject: [PATCH 4/6] backing tests: use persisted validation data --- node/core/backing/src/lib.rs | 38 +++++++++++++----------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/node/core/backing/src/lib.rs b/node/core/backing/src/lib.rs index e915d75e0e6b..7a4c68d20d80 100644 --- a/node/core/backing/src/lib.rs +++ b/node/core/backing/src/lib.rs @@ -1170,8 +1170,7 @@ mod tests { use assert_matches::assert_matches; use futures::{future, Future}; use polkadot_primitives::v1::{ - ScheduledCore, BlockData, PersistedValidationData, ValidationData, - TransientValidationData, HeadData, GroupRotationInfo, + ScheduledCore, BlockData, PersistedValidationData, HeadData, GroupRotationInfo, }; use polkadot_subsystem::{ messages::{RuntimeApiRequest, RuntimeApiMessage}, @@ -1192,7 +1191,7 @@ mod tests { keystore: SyncCryptoStorePtr, validators: Vec, validator_public: Vec, - validation_data: ValidationData, + validation_data: PersistedValidationData, validator_groups: (Vec>, GroupRotationInfo), availability_cores: Vec, head_data: HashMap, @@ -1257,22 +1256,13 @@ mod tests { parent_hash: relay_parent, }; - let validation_data = ValidationData { - persisted: PersistedValidationData { - parent_head: HeadData(vec![7, 8, 9]), - block_number: Default::default(), - hrmp_mqc_heads: Vec::new(), - dmq_mqc_head: Default::default(), - max_pov_size: 1024, - relay_storage_root: Default::default(), - }, - transient: TransientValidationData { - max_code_size: 1000, - max_head_data_size: 1000, - balance: Default::default(), - code_upgrade_allowed: None, - dmq_length: 0, - }, + let validation_data = PersistedValidationData { + parent_head: HeadData(vec![7, 8, 9]), + block_number: Default::default(), + hrmp_mqc_heads: Vec::new(), + dmq_mqc_head: Default::default(), + max_pov_size: 1024, + relay_storage_root: Default::default(), }; Self { @@ -1312,7 +1302,7 @@ mod tests { fn make_erasure_root(test: &TestState, pov: PoV) -> Hash { let available_data = AvailableData { - validation_data: test.validation_data.persisted.clone(), + validation_data: test.validation_data.clone(), pov: Arc::new(pov), }; @@ -1453,7 +1443,7 @@ mod tests { new_validation_code: None, processed_downward_messages: 0, hrmp_watermark: 0, - }, test_state.validation_data.persisted), + }, test_state.validation_data), )).unwrap(); } ); @@ -1591,7 +1581,7 @@ mod tests { new_validation_code: None, processed_downward_messages: 0, hrmp_watermark: 0, - }, test_state.validation_data.persisted), + }, test_state.validation_data), )).unwrap(); } ); @@ -1886,7 +1876,7 @@ mod tests { new_validation_code: None, processed_downward_messages: 0, hrmp_watermark: 0, - }, test_state.validation_data.persisted), + }, test_state.validation_data), )).unwrap(); } ); @@ -2071,7 +2061,7 @@ mod tests { new_validation_code: None, processed_downward_messages: 0, hrmp_watermark: 0, - }, test_state.validation_data.persisted), + }, test_state.validation_data), )).unwrap(); } ); From 0ba1489f029447a641bcdabab04b688a21adc607 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 14 Jan 2021 17:29:35 +0000 Subject: [PATCH 5/6] FullCandidateReceipt: use persisted validation data This is not a big change since this type is not used anywhere --- primitives/src/v1.rs | 2 +- roadmap/implementers-guide/src/types/candidate.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/primitives/src/v1.rs b/primitives/src/v1.rs index 1d26021705ec..09de7befb279 100644 --- a/primitives/src/v1.rs +++ b/primitives/src/v1.rs @@ -259,7 +259,7 @@ pub struct FullCandidateReceipt { /// 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, + pub validation_data: PersistedValidationData, } /// A candidate-receipt with commitments directly included. diff --git a/roadmap/implementers-guide/src/types/candidate.md b/roadmap/implementers-guide/src/types/candidate.md index c9da4b683fba..0bfd687b955a 100644 --- a/roadmap/implementers-guide/src/types/candidate.md +++ b/roadmap/implementers-guide/src/types/candidate.md @@ -33,7 +33,7 @@ struct CandidateReceipt { ## Full Candidate Receipt -This is the full receipt type. The `ValidationData` are technically redundant with the `inner.relay_parent`, which uniquely describes the 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 `PersistedValidationData` are technically redundant with the `inner.relay_parent`, which uniquely describes the 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. @@ -41,7 +41,7 @@ However, the Full Candidate Receipt type is useful as a means of avoiding the im /// All data pertaining to the execution of a para candidate. struct FullCandidateReceipt { inner: CandidateReceipt, - validation_data: ValidationData, + validation_data: PeristedValidationData, } ``` From 7b667724ccd24d5870ffd1301fb57ba89e6de52f Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 14 Jan 2021 17:41:51 +0000 Subject: [PATCH 6/6] Remove ValidationData and TransientValidationData Also update the guide --- primitives/src/v1.rs | 79 +++-------- .../implementers-guide/src/types/candidate.md | 127 ++---------------- 2 files changed, 24 insertions(+), 182 deletions(-) diff --git a/primitives/src/v1.rs b/primitives/src/v1.rs index 09de7befb279..30a4b3926560 100644 --- a/primitives/src/v1.rs +++ b/primitives/src/v1.rs @@ -317,44 +317,25 @@ impl Ord for CommittedCandidateReceipt { } } -/// The validation data provide information about how to validate both the inputs and -/// outputs of a candidate. +/// The validation data provides information about how to create the inputs for validation of a candidate. +/// 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. /// -/// There are two types of validation data: persisted and transient. -/// Their respective sections of the guide elaborate on their functionality in more detail. +/// Since this data is used to form inputs to the validation function, it needs to be persisted by the +/// availability system to avoid dependence on availability of the relay-chain state. /// -/// 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. +/// Furthermore, the validation data acts as a way to authorize the additional data the collator needs +/// to pass to the validation function. For example, the validation function can check whether the incoming +/// messages (e.g. downward messages) were actually sent by using the data provided in the validation data +/// using so called MQC heads. /// -/// 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. +/// 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. /// -/// 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, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Default))] -pub struct ValidationData { - /// The persisted validation data. - pub persisted: PersistedValidationData, - /// The transient validation data. - pub transient: TransientValidationData, -} - -/// Validation data that needs to be persisted for secondary checkers. +/// The `PersistedValidationData` should be relatively lightweight primarly because it is constructed +/// during inclusion for each candidate and therefore lies on the critical path of inclusion. #[derive(PartialEq, Eq, Clone, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug, Default))] pub struct PersistedValidationData { @@ -384,36 +365,6 @@ impl PersistedValidationData { } } -/// 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 { - /// 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, - /// Whether the parachain is allowed to upgrade its validation code. - /// - /// This is `Some` if so, and contains the number of the minimum relay-chain - /// height at which the upgrade will be applied, if an upgrade is signaled - /// now. - /// - /// A parachain should enact its side of the upgrade at the end of the first - /// parablock executing in the context of a relay-chain block with at least this - /// height. This may be equal to the current perceived relay-chain block height, in - /// which case the code upgrade should be applied at the end of the signaling - /// block. - pub code_upgrade_allowed: Option, - /// The number of messages pending of the downward message queue. - pub dmq_length: u32, -} - /// 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))] diff --git a/roadmap/implementers-guide/src/types/candidate.md b/roadmap/implementers-guide/src/types/candidate.md index 0bfd687b955a..1e65daab532f 100644 --- a/roadmap/implementers-guide/src/types/candidate.md +++ b/roadmap/implementers-guide/src/types/candidate.md @@ -88,38 +88,17 @@ struct CandidateDescriptor { } ``` -## ValidationData - -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](#persistedvalidationdata) and [transient](#transientvalidationdata). 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. - -Furthermore, the validation data acts as a way to authorize the additional data the collator needs to pass to the validation -function. For example, the validation function can check whether the incoming messages (e.g. downward messages) were actually -sent by using the data provided in the validation data using so called MQC heads. - -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. +## PersistedValidationData -Design-wise we should maintain two properties about this data structure: +The validation data provides information about how to create the inputs for validation of a candidate. 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. -1. The `ValidationData` should be relatively lightweight primarly because it is constructed during inclusion for each candidate. -1. To make contextual execution possible, `ValidationData` should be constructable only having access to the latest relay-chain state for the past `k` blocks. That implies -either that the relay-chain should maintain all the required data accessible or somehow provided indirectly with a header-chain proof and a state proof from there. +Since this data is used to form inputs to the validation function, it needs to be persisted by the availability system to avoid dependence on availability of the relay-chain state. -```rust -struct ValidationData { - persisted: PersistedValidationData, - transient: TransientValidationData, -} -``` +Furthermore, the validation data acts as a way to authorize the additional data the collator needs to pass to the validation function. For example, the validation function can check whether the incoming messages (e.g. downward messages) were actually sent by using the data provided in the validation data using so called MQC heads. -## PersistedValidationData +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. -Validation data that needs to be persisted for secondary checkers. See the section on [`ValidationData`](#validationdata) for more details. +The `PersistedValidationData` should be relatively lightweight primarly because it is constructed during inclusion for each candidate and therefore lies on the critical path of inclusion. ```rust struct PersistedValidationData { @@ -141,96 +120,8 @@ struct PersistedValidationData { /// The HRMP MQC heads will be used by the validation function to authorize the input messages passed /// by the collator. hrmp_mqc_heads: Vec<(ParaId, Hash)>, -} -``` - -## TransientValidationData - -These validation data are derived from some relay-chain state to check outputs of the validation function. - -It's worth noting that all the data is collected **before** the candidate execution. - -```rust -struct TransientValidationData { - /// The maximum code size permitted, in bytes, of a produced validation code upgrade. - /// - /// This informs a relay-chain backing check and the parachain logic. - max_code_size: u32, - /// The maximum head-data size permitted, in bytes. - /// - /// This informs a relay-chain backing check and the parachain collator. - max_head_data_size: u32, - /// The balance of the parachain at the moment of validation. - balance: Balance, - /// Whether the parachain is allowed to upgrade its validation code. - /// - /// This is `Some` if so, and contains the number of the minimum relay-chain - /// height at which the upgrade will be applied, if an upgrade is signaled - /// now. - /// - /// A parachain should enact its side of the upgrade at the end of the first - /// parablock executing in the context of a relay-chain block with at least this - /// height. This may be equal to the current perceived relay-chain block height, in - /// which case the code upgrade should be applied at the end of the signaling - /// block. - /// - /// This informs a relay-chain backing check and the parachain logic. - code_upgrade_allowed: Option, - /// A copy of `config.max_upward_message_num_per_candidate` for checking that a candidate doesn't - /// send more messages than permitted. - config_max_upward_message_num_per_candidate: u32, - /// The number of messages pending of the downward message queue. - dmq_length: u32, - /// A part of transient validation data related to HRMP. - hrmp: HrmpTransientValidationData, -} - -struct HrmpTransientValidationData { - /// A vector that enumerates the list of blocks in which there was at least one HRMP message - /// received. - /// - /// The first number in the vector, if any, is always greater than the HRMP watermark. The - /// elements are ordered by ascending the block number. The vector doesn't contain duplicates. - digest: Vec, - /// The watermark of the HRMP. That is, the block number up to which (inclusive) all HRMP messages - /// sent to the parachain are processed. - watermark: BlockNumber, - /// A mapping that specifies if the parachain can send an HRMP message to the given recipient - /// channel. A candidate can send a message only to the recipients that are present in this - /// mapping. The number elements in this vector corresponds to the number of egress channels. - /// Since it's a mapping there can't be two items with same `ParaId`. - egress_limits: Vec<(ParaId, HrmpChannelLimits)>, - /// A vector of paras that have a channel to this para. The number of elements in this vector - /// correponds to the number of ingress channels. The items are ordered ascending by `ParaId`. - /// The vector doesn't contain two entries with the same `ParaId`. - ingress_senders: Vec, - /// A vector of open requests in which the para participates either as sender or recipient. The - /// items are ordered ascending by `HrmpChannelId`. The vector doesn't contain two entries - /// with the same `HrmpChannelId`. - open_requests: Vec<(HrmpChannelId, HrmpAbridgedOpenChannelRequest)>, - /// A vector of close requests in which the para participates either as sender or recipient. - /// The vector doesn't contain two entries with the same `HrmpChannelId`. - close_requests: Vec, - /// The maximum number of inbound channels the para is allowed to have. This is a copy of either - /// `config.hrmp_max_parachain_inbound_channels` or `config.hrmp_max_parathread_inbound_channels` - /// depending on the type of this para. - config_max_inbound_channels: u32, - /// The maximum number of outbound channels the para is allowed to have. This is a copy of either - /// `config.hrmp_max_parachain_outbound_channels` or `config.hrmp_max_parathread_outbound_channels` - /// depending on the type of this para. - config_max_outbound_channels: u32, -} - -/// A shorter version of `HrmpOpenChannelRequest`. -struct HrmpAbridgedOpenChannelRequest { - confirmed: bool, -} - -struct HrmpChannelLimits { - /// Indicates if the channel is already full and cannot accept any more messages. - is_full: bool, - /// A message sent to the channel can occupy only that many bytes. - available_size: u32, + /// The maximum legal size of a POV block, in bytes. + pub max_pov_size: u32, } ``` @@ -277,4 +168,4 @@ struct SigningContext { /// The session index this signature is in the context of. session_index: SessionIndex, } -``` \ No newline at end of file +```