diff --git a/polkadot/availability-store/src/lib.rs b/polkadot/availability-store/src/lib.rs index 7abc444758f7c23409e7cc726ccff8c53ecd4bcc..4b973c7d027114101e1e4b0510ffe565ded5ea69 100644 --- a/polkadot/availability-store/src/lib.rs +++ b/polkadot/availability-store/src/lib.rs @@ -25,12 +25,10 @@ use futures::prelude::*; use futures::channel::{mpsc, oneshot}; use keystore::KeyStorePtr; -use polkadot_primitives::{ +use polkadot_primitives::v0::{ Hash, Block, - parachain::{ - PoVBlock, AbridgedCandidateReceipt, ErasureChunk, - ParachainHost, AvailableData, OmittedValidationData, - }, + PoVBlock, AbridgedCandidateReceipt, ErasureChunk, + ParachainHost, AvailableData, OmittedValidationData, }; use sp_runtime::traits::HashFor; use sp_blockchain::Result as ClientResult; diff --git a/polkadot/availability-store/src/store.rs b/polkadot/availability-store/src/store.rs index 851beabc6ac87888436e5ef08a1bb42d04960193..cd76de5d44adb9ebddf28d16db69fe9e2b15b8b2 100644 --- a/polkadot/availability-store/src/store.rs +++ b/polkadot/availability-store/src/store.rs @@ -19,11 +19,8 @@ use kvdb_rocksdb::{Database, DatabaseConfig}; use kvdb::{KeyValueDB, DBTransaction}; use codec::{Encode, Decode}; use polkadot_erasure_coding as erasure; -use polkadot_primitives::{ - Hash, - parachain::{ - ErasureChunk, AvailableData, AbridgedCandidateReceipt, - }, +use polkadot_primitives::v0::{ + Hash, ErasureChunk, AvailableData, AbridgedCandidateReceipt, }; use parking_lot::Mutex; @@ -273,7 +270,7 @@ impl Store { // If there are no block data in the store at this point, // check that they can be reconstructed now and add them to store if they can. if self.execution_data(&candidate_hash).is_none() { - if let Ok(available_data) = erasure::reconstruct( + if let Ok(available_data) = erasure::reconstruct_v0( n_validators as usize, v.iter().map(|chunk| (chunk.chunk.as_ref(), chunk.index as usize)), ) @@ -390,7 +387,7 @@ impl Store { mod tests { use super::*; use polkadot_erasure_coding::{self as erasure}; - use polkadot_primitives::parachain::{ + use polkadot_primitives::v0::{ Id as ParaId, BlockData, AvailableData, PoVBlock, OmittedValidationData, }; @@ -489,7 +486,7 @@ mod tests { let available_data = available_data(&[42; 8]); let n_validators = 5; - let erasure_chunks = erasure::obtain_chunks( + let erasure_chunks = erasure::obtain_chunks_v0( n_validators, &available_data, ).unwrap(); diff --git a/polkadot/availability-store/src/worker.rs b/polkadot/availability-store/src/worker.rs index 8a3898579f54e736f0704728f4ceb4935e1c3e9c..a7cf7ec41dae3a01aa0c83e4ff7c17938dcfb233 100644 --- a/polkadot/availability-store/src/worker.rs +++ b/polkadot/availability-store/src/worker.rs @@ -33,8 +33,8 @@ use consensus_common::{ import_queue::CacheKeyId, }; use sp_core::traits::SpawnNamed; -use polkadot_primitives::{Block, BlockId, Hash}; -use polkadot_primitives::parachain::{ +use polkadot_primitives::v0::{ + Block, BlockId, Hash, ParachainHost, ValidatorId, AbridgedCandidateReceipt, AvailableData, ValidatorPair, ErasureChunk, }; diff --git a/polkadot/collator/src/lib.rs b/polkadot/collator/src/lib.rs index 0215b33ee6a1899c85523b3a04bc6430ee72eaf5..663cb825bfc1adb5d8ce747b81b330c91c4e262e 100644 --- a/polkadot/collator/src/lib.rs +++ b/polkadot/collator/src/lib.rs @@ -55,12 +55,11 @@ use log::warn; use sc_client_api::{StateBackend, BlockchainEvents}; use sp_blockchain::HeaderBackend; use sp_core::Pair; -use polkadot_primitives::{ +use polkadot_primitives::v0::{ BlockId, Hash, Block, DownwardMessage, - parachain::{ - self, BlockData, DutyRoster, HeadData, Id as ParaId, - PoVBlock, ValidatorId, CollatorPair, LocalValidationData, GlobalValidationSchedule, - } + BlockData, DutyRoster, HeadData, Id as ParaId, + PoVBlock, ValidatorId, CollatorPair, LocalValidationData, GlobalValidationSchedule, + Collation, CollationInfo, collator_signature_payload, }; use polkadot_cli::{ ProvideRuntimeApi, ParachainHost, IdentifyVariant, @@ -69,7 +68,7 @@ use polkadot_cli::{ pub use polkadot_cli::service::Configuration; pub use polkadot_cli::Cli; pub use polkadot_validation::SignedStatement; -pub use polkadot_primitives::parachain::CollatorId; +pub use polkadot_primitives::v0::CollatorId; pub use sc_network::PeerId; pub use service::RuntimeApiCollection; pub use sc_cli::SubstrateCli; @@ -164,7 +163,7 @@ pub async fn collate<P>( downward_messages: Vec<DownwardMessage>, mut para_context: P, key: Arc<CollatorPair>, -) -> Option<parachain::Collation> +) -> Option<Collation> where P: ParachainContext, P::ProduceCandidate: Send, @@ -181,13 +180,13 @@ pub async fn collate<P>( }; let pov_block_hash = pov_block.hash(); - let signature = key.sign(¶chain::collator_signature_payload( + let signature = key.sign(&collator_signature_payload( &relay_parent, &local_id, &pov_block_hash, )); - let info = parachain::CollationInfo { + let info = CollationInfo { parachain_index: local_id, relay_parent, collator: key.public(), @@ -196,7 +195,7 @@ pub async fn collate<P>( pov_block_hash, }; - let collation = parachain::Collation { + let collation = Collation { info, pov: pov_block, }; @@ -456,7 +455,7 @@ where #[cfg(not(feature = "service-rewr"))] fn compute_targets(para_id: ParaId, session_keys: &[ValidatorId], roster: DutyRoster) -> HashSet<ValidatorId> { - use polkadot_primitives::parachain::Chain; + use polkadot_primitives::v0::Chain; roster.validator_duty.iter().enumerate() .filter(|&(_, c)| c == &Chain::Parachain(para_id)) diff --git a/polkadot/core-primitives/src/lib.rs b/polkadot/core-primitives/src/lib.rs index d91ed3cfc1973871613e589a6426f95a769d9ea8..ffb346467d9e53c0c64ebca4438a9260492fdd8e 100644 --- a/polkadot/core-primitives/src/lib.rs +++ b/polkadot/core-primitives/src/lib.rs @@ -94,3 +94,8 @@ pub enum DownwardMessage<AccountId = crate::AccountId> { /// XCMP message for the Parachain. XCMPMessage(sp_std::vec::Vec<u8>), } + +/// V1 primitives. +pub mod v1 { + pub use super::*; +} diff --git a/polkadot/erasure-coding/src/lib.rs b/polkadot/erasure-coding/src/lib.rs index 98a2776d8848a543b31e170e9cb3f56ff4906929..708a167d627675abaf3ec13befed01400bce219c 100644 --- a/polkadot/erasure-coding/src/lib.rs +++ b/polkadot/erasure-coding/src/lib.rs @@ -26,8 +26,8 @@ use codec::{Encode, Decode}; use reed_solomon::galois_16::{self, ReedSolomon}; -use primitives::{Hash as H256, BlakeTwo256, HashT}; -use primitives::parachain::AvailableData; +use primitives::v0::{self, Hash as H256, BlakeTwo256, HashT}; +use primitives::v1; use sp_core::Blake2Hasher; use trie::{EMPTY_PREFIX, MemoryDB, Trie, TrieMut, trie_types::{TrieDBMut, TrieDB}}; @@ -124,14 +124,32 @@ fn code_params(n_validators: usize) -> Result<CodeParams, Error> { }) } +/// Obtain erasure-coded chunks for v0 `AvailableData`, one for each validator. +/// +/// Works only up to 65536 validators, and `n_validators` must be non-zero. +pub fn obtain_chunks_v0(n_validators: usize, data: &v0::AvailableData) + -> Result<Vec<Vec<u8>>, Error> +{ + obtain_chunks(n_validators, data) +} + +/// Obtain erasure-coded chunks for v1 `AvailableData`, one for each validator. +/// +/// Works only up to 65536 validators, and `n_validators` must be non-zero. +pub fn obtain_chunks_v1(n_validators: usize, data: &v1::AvailableData) + -> Result<Vec<Vec<u8>>, Error> +{ + obtain_chunks(n_validators, data) +} + /// Obtain erasure-coded chunks, one for each validator. /// /// Works only up to 65536 validators, and `n_validators` must be non-zero. -pub fn obtain_chunks(n_validators: usize, available_data: &AvailableData) +fn obtain_chunks<T: Encode>(n_validators: usize, data: &T) -> Result<Vec<Vec<u8>>, Error> { let params = code_params(n_validators)?; - let encoded = available_data.encode(); + let encoded = data.encode(); if encoded.is_empty() { return Err(Error::BadPayload); @@ -145,15 +163,42 @@ pub fn obtain_chunks(n_validators: usize, available_data: &AvailableData) Ok(shards.into_iter().map(|w| w.into_inner()).collect()) } -/// Reconstruct the block data from a set of chunks. +/// Reconstruct the v0 available data from a set of chunks. +/// +/// Provide an iterator containing chunk data and the corresponding index. +/// The indices of the present chunks must be indicated. If too few chunks +/// are provided, recovery is not possible. +/// +/// Works only up to 65536 validators, and `n_validators` must be non-zero. +pub fn reconstruct_v0<'a, I: 'a>(n_validators: usize, chunks: I) + -> Result<v0::AvailableData, Error> + where I: IntoIterator<Item=(&'a [u8], usize)> +{ + reconstruct(n_validators, chunks) +} + +/// Reconstruct the v1 available data from a set of chunks. +/// +/// Provide an iterator containing chunk data and the corresponding index. +/// The indices of the present chunks must be indicated. If too few chunks +/// are provided, recovery is not possible. +/// +/// Works only up to 65536 validators, and `n_validators` must be non-zero. +pub fn reconstruct_v1<'a, I: 'a>(n_validators: usize, chunks: I) + -> Result<v1::AvailableData, Error> + where I: IntoIterator<Item=(&'a [u8], usize)> +{ + reconstruct(n_validators, chunks) +} + +/// Reconstruct decodable data from a set of chunks. /// /// Provide an iterator containing chunk data and the corresponding index. /// The indices of the present chunks must be indicated. If too few chunks /// are provided, recovery is not possible. /// /// Works only up to 65536 validators, and `n_validators` must be non-zero. -pub fn reconstruct<'a, I: 'a>(n_validators: usize, chunks: I) - -> Result<AvailableData, Error> +fn reconstruct<'a, I: 'a, T: Decode>(n_validators: usize, chunks: I) -> Result<T, Error> where I: IntoIterator<Item=(&'a [u8], usize)> { let params = code_params(n_validators)?; @@ -343,7 +388,7 @@ impl<'a, I: Iterator<Item=&'a [u8]>> codec::Input for ShardInput<'a, I> { #[cfg(test)] mod tests { use super::*; - use primitives::parachain::{BlockData, PoVBlock}; + use primitives::v0::{AvailableData, BlockData, PoVBlock}; #[test] fn field_order_is_right_size() { @@ -420,7 +465,7 @@ mod tests { assert_eq!(chunks.len(), 10); // any 4 chunks should work. - let reconstructed = reconstruct( + let reconstructed: AvailableData = reconstruct( 10, [ (&*chunks[1], 1), diff --git a/polkadot/network/src/legacy/collator_pool.rs b/polkadot/network/src/legacy/collator_pool.rs index a0c0a0458e908eeb396883aa80304a29a47095ab..f2b168e0f592b3c85cf11c8948995d9f88e68465 100644 --- a/polkadot/network/src/legacy/collator_pool.rs +++ b/polkadot/network/src/legacy/collator_pool.rs @@ -17,8 +17,7 @@ //! Bridge between the network and consensus service for getting collations to it. use codec::{Encode, Decode}; -use polkadot_primitives::Hash; -use polkadot_primitives::parachain::{CollatorId, Id as ParaId, Collation}; +use polkadot_primitives::v0::{Hash, CollatorId, Id as ParaId, Collation}; use sc_network::PeerId; use futures::channel::oneshot; @@ -236,7 +235,7 @@ impl CollatorPool { mod tests { use super::*; use sp_core::crypto::UncheckedInto; - use polkadot_primitives::parachain::{CollationInfo, BlockData, PoVBlock}; + use polkadot_primitives::v0::{CollationInfo, BlockData, PoVBlock}; use futures::executor::block_on; fn make_pov(block_data: Vec<u8>) -> PoVBlock { diff --git a/polkadot/network/src/legacy/gossip/attestation.rs b/polkadot/network/src/legacy/gossip/attestation.rs index a47f75288bf40220bcc639003d30c38ab1e492fb..2d20ce63b995450fbcc229a9363691739397175e 100644 --- a/polkadot/network/src/legacy/gossip/attestation.rs +++ b/polkadot/network/src/legacy/gossip/attestation.rs @@ -33,7 +33,7 @@ use sc_network_gossip::{ValidationResult as GossipValidationResult}; use sc_network::ReputationChange; use polkadot_validation::GenericStatement; -use polkadot_primitives::Hash; +use polkadot_primitives::v0::Hash; use std::collections::HashMap; diff --git a/polkadot/network/src/legacy/gossip/mod.rs b/polkadot/network/src/legacy/gossip/mod.rs index 7dea99656667920363f315a07bf517b00dfd5275..9e18d7ce217109f8449740baffb69a37ce73308d 100644 --- a/polkadot/network/src/legacy/gossip/mod.rs +++ b/polkadot/network/src/legacy/gossip/mod.rs @@ -58,8 +58,8 @@ use sc_network_gossip::{ ValidatorContext, MessageIntent, }; use polkadot_validation::{SignedStatement}; -use polkadot_primitives::{Block, Hash}; -use polkadot_primitives::parachain::{ +use polkadot_primitives::v0::{ + Block, Hash, ParachainHost, ValidatorId, ErasureChunk as PrimitiveChunk, SigningContext, PoVBlock, }; use polkadot_erasure_coding::{self as erasure}; @@ -755,7 +755,7 @@ mod tests { use sc_network_gossip::Validator as ValidatorT; use std::sync::mpsc; use parking_lot::Mutex; - use polkadot_primitives::parachain::{AbridgedCandidateReceipt, BlockData}; + use polkadot_primitives::v0::{AbridgedCandidateReceipt, BlockData}; use sp_core::sr25519::Signature as Sr25519Signature; use polkadot_validation::GenericStatement; diff --git a/polkadot/network/src/legacy/local_collations.rs b/polkadot/network/src/legacy/local_collations.rs index 6bc9b985a7c1a81b2fe0b5edc764015b808546c5..d85911548613bf4558755ec53386f0c2619e9360 100644 --- a/polkadot/network/src/legacy/local_collations.rs +++ b/polkadot/network/src/legacy/local_collations.rs @@ -19,7 +19,7 @@ //! Collations are attempted to be repropagated when a new validator connects, //! a validator changes his session key, or when they are generated. -use polkadot_primitives::{Hash, parachain::{ValidatorId}}; +use polkadot_primitives::v0::{Hash, ValidatorId}; use crate::legacy::collator_pool::Role; use std::collections::{HashMap, HashSet}; use std::time::Duration; @@ -144,7 +144,7 @@ impl<C: Clone> LocalCollations<C> { mod tests { use super::*; use sp_core::crypto::UncheckedInto; - use polkadot_primitives::parachain::ValidatorId; + use polkadot_primitives::v0::ValidatorId; #[test] fn add_validator_with_ready_collation() { diff --git a/polkadot/network/src/legacy/mod.rs b/polkadot/network/src/legacy/mod.rs index 28ea77a6bdc10cac191bb184ae70f4f234071602..42698657c05355e2a2736fb0965d726c31dbfddb 100644 --- a/polkadot/network/src/legacy/mod.rs +++ b/polkadot/network/src/legacy/mod.rs @@ -25,7 +25,7 @@ pub mod gossip; use codec::Decode; use futures::prelude::*; -use polkadot_primitives::Hash; +use polkadot_primitives::v0::Hash; use sc_network::PeerId; use sc_network_gossip::TopicNotification; use log::debug; diff --git a/polkadot/network/src/lib.rs b/polkadot/network/src/lib.rs index 5048f09adaf51d17dd108686f783cb7c7d41d037..eaed7b34d2cb11af22d2dc996c86a456af2163bc 100644 --- a/polkadot/network/src/lib.rs +++ b/polkadot/network/src/lib.rs @@ -21,7 +21,7 @@ #![recursion_limit="256"] -use polkadot_primitives::{Block, Hash, BlakeTwo256, HashT}; +use polkadot_primitives::v0::{Block, Hash, BlakeTwo256, HashT}; pub mod legacy; pub mod protocol; diff --git a/polkadot/network/src/protocol/mod.rs b/polkadot/network/src/protocol/mod.rs index 9a94065e5be6cbf8bc25335a3e64c7e70a923416..22e72dcfd6e46f5fda64558bea660dabf93eabb4 100644 --- a/polkadot/network/src/protocol/mod.rs +++ b/polkadot/network/src/protocol/mod.rs @@ -30,12 +30,10 @@ use futures::task::{Context, Poll}; use futures::stream::{FuturesUnordered, StreamFuture}; use log::{debug, trace}; -use polkadot_primitives::{ +use polkadot_primitives::v0::{ Hash, Block, - parachain::{ - PoVBlock, ValidatorId, ValidatorIndex, Collation, AbridgedCandidateReceipt, - ErasureChunk, ParachainHost, Id as ParaId, CollatorId, - }, + PoVBlock, ValidatorId, ValidatorIndex, Collation, AbridgedCandidateReceipt, + ErasureChunk, ParachainHost, Id as ParaId, CollatorId, }; use polkadot_validation::{ SharedTable, TableRouter, Network as ParachainNetwork, Validated, GenericStatement, Collators, diff --git a/polkadot/network/src/protocol/tests.rs b/polkadot/network/src/protocol/tests.rs index 049af3f5aca703934db4482deca1aa4e2ebeba8c..711906797be4e63c8afab4aa6c60f416f6d354e5 100644 --- a/polkadot/network/src/protocol/tests.rs +++ b/polkadot/network/src/protocol/tests.rs @@ -17,8 +17,8 @@ use super::*; use crate::legacy::gossip::GossipPoVBlock; use parking_lot::Mutex; -use polkadot_primitives::Block; -use polkadot_primitives::parachain::{ +use polkadot_primitives::v0::{ + Block, Id as ParaId, Chain, DutyRoster, ParachainHost, ValidatorId, Retriable, CollatorId, AbridgedCandidateReceipt, GlobalValidationSchedule, LocalValidationData, ErasureChunk, SigningContext, @@ -198,7 +198,7 @@ sp_api::mock_impl_runtime_apis! { parent_hash: Default::default(), } } - fn downward_messages(_: ParaId) -> Vec<polkadot_primitives::DownwardMessage> { + fn downward_messages(_: ParaId) -> Vec<polkadot_primitives::v0::DownwardMessage> { Vec::new() } } diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs index e4490d20d3f1f299a2e2c02451bb27517c2a2ac0..281147847e19ef678ec9e28acd9896bc607e00de 100644 --- a/polkadot/node/core/backing/src/lib.rs +++ b/polkadot/node/core/backing/src/lib.rs @@ -21,6 +21,7 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryFrom; use std::pin::Pin; +use std::sync::Arc; use std::time::Duration; use bitvec::vec::BitVec; @@ -36,17 +37,15 @@ use streamunordered::{StreamUnordered, StreamYield}; use primitives::Pair; use keystore::KeyStorePtr; -use polkadot_primitives::{ - Hash, - parachain::{ - AbridgedCandidateReceipt, BackedCandidate, Id as ParaId, ValidatorPair, ValidatorId, - ValidatorIndex, HeadData, SigningContext, PoVBlock, OmittedValidationData, - CandidateDescriptor, LocalValidationData, GlobalValidationSchedule, AvailableData, - ErasureChunk, - }, +use polkadot_primitives::v1::{ + CommittedCandidateReceipt, BackedCandidate, Id as ParaId, ValidatorPair, ValidatorId, + ValidatorIndex, SigningContext, PoV, OmittedValidationData, + CandidateDescriptor, AvailableData, ErasureChunk, ValidatorSignature, Hash, CandidateReceipt, + CandidateCommitments, }; use polkadot_node_primitives::{ FromTableMisbehavior, Statement, SignedFullStatement, MisbehaviorReport, ValidationResult, + ValidationOutputs, }; use polkadot_subsystem::{ FromOverseer, OverseerSignal, Subsystem, SubsystemContext, SpawnedSubsystem, @@ -59,8 +58,12 @@ use polkadot_subsystem::messages::{ }; use statement_table::{ generic::AttestedCandidate as TableAttestedCandidate, - Table, Context as TableContextTrait, Statement as TableStatement, - SignedStatement as TableSignedStatement, Summary as TableSummary, + Context as TableContextTrait, + Table, + v1::{ + Statement as TableStatement, + SignedStatement as TableSignedStatement, Summary as TableSummary, + }, }; #[derive(Debug, derive_more::From)] @@ -90,8 +93,6 @@ struct CandidateBackingJob { /// Outbound message channel sending part. tx_from: mpsc::Sender<FromJob>, - /// `HeadData`s of the parachains that this validator is assigned to. - head_data: HeadData, /// The `ParaId`s assigned to this validator. assignment: ParaId, /// We issued `Valid` or `Invalid` statements on about these candidates. @@ -118,8 +119,22 @@ struct TableContext { } impl TableContextTrait for TableContext { - fn is_member_of(&self, authority: ValidatorIndex, group: &ParaId) -> bool { - self.groups.get(group).map_or(false, |g| g.iter().position(|&a| a == authority).is_some()) + type AuthorityId = ValidatorIndex; + type Digest = Hash; + type GroupId = ParaId; + type Signature = ValidatorSignature; + type Candidate = CommittedCandidateReceipt; + + fn candidate_digest(candidate: &CommittedCandidateReceipt) -> Hash { + candidate.hash() + } + + fn candidate_group(candidate: &CommittedCandidateReceipt) -> ParaId { + candidate.descriptor().para_id + } + + fn is_member_of(&self, authority: &ValidatorIndex, group: &ParaId) -> bool { + self.groups.get(group).map_or(false, |g| g.iter().position(|a| a == authority).is_some()) } fn requisite_votes(&self, group: &ParaId) -> usize { @@ -221,7 +236,7 @@ impl CandidateBackingJob { async fn issue_candidate_invalid_message( &mut self, - candidate: AbridgedCandidateReceipt, + candidate: CandidateReceipt, ) -> Result<(), Error> { self.tx_from.send(FromJob::CandidateSelection( CandidateSelectionMessage::Invalid(self.parent, candidate) @@ -231,34 +246,69 @@ impl CandidateBackingJob { } /// Validate the candidate that is requested to be `Second`ed and distribute validation result. + /// + /// Returns `Ok(true)` if we issued a `Seconded` statement about this candidate. async fn validate_and_second( &mut self, - candidate: AbridgedCandidateReceipt, - pov: PoVBlock, - ) -> Result<ValidationResult, Error> { - let valid = self.request_candidate_validation(candidate.clone(), pov.clone()).await?; - let statement = match valid.0 { - ValidationResult::Valid => { + candidate: &CandidateReceipt, + pov: PoV, + ) -> Result<bool, Error> { + let valid = self.request_candidate_validation( + candidate.descriptor().clone(), + Arc::new(pov.clone()), + ).await?; + + let candidate_hash = candidate.hash(); + + let statement = match valid { + ValidationResult::Valid(outputs) => { // make PoV available for later distribution. Send data to the availability // store to keep. Sign and dispatch `valid` statement to network if we // have not seconded the given candidate. - self.make_pov_available(pov, valid.1, valid.2).await?; - self.issued_statements.insert(candidate.hash()); - Statement::Seconded(candidate) + // + // If the commitments hash produced by validation is not the same as given by + // the collator, do not make available and report the collator. + let commitments_check = self.make_pov_available( + pov, + outputs, + |commitments| if commitments.hash() == candidate.commitments_hash { + Ok(CommittedCandidateReceipt { + descriptor: candidate.descriptor().clone(), + commitments, + }) + } else { + Err(()) + }, + ).await?; + + match commitments_check { + Ok(candidate) => { + self.issued_statements.insert(candidate_hash); + Some(Statement::Seconded(candidate)) + } + Err(()) => { + self.issue_candidate_invalid_message(candidate.clone()).await?; + None + } + } } ValidationResult::Invalid => { - let candidate_hash = candidate.hash(); - self.issue_candidate_invalid_message(candidate).await?; - Statement::Invalid(candidate_hash) + // no need to issue a statement about this if we aren't seconding it. + // + // there's an infinite amount of garbage out there. no need to acknowledge + // all of it. + self.issue_candidate_invalid_message(candidate.clone()).await?; + None } }; - if let Some(signed_statement) = self.sign_statement(statement) { + let issued_statement = statement.is_some(); + if let Some(signed_statement) = statement.and_then(|s| self.sign_statement(s)) { self.import_statement(&signed_statement).await?; self.distribute_signed_statement(signed_statement).await?; } - Ok(valid.0) + Ok(issued_statement) } fn get_backed(&self) -> Vec<NewBackedCandidate> { @@ -303,7 +353,7 @@ impl CandidateBackingJob { } /// Check if there have happened any new misbehaviors and issue necessary messages. - /// + /// /// TODO: Report multiple misbehaviors (https://github.com/paritytech/polkadot/issues/1387) async fn issue_new_misbehaviors(&mut self) -> Result<(), Error> { let mut reports = Vec::new(); @@ -354,7 +404,7 @@ impl CandidateBackingJob { match msg { CandidateBackingMessage::Second(_, candidate, pov) => { // Sanity check that candidate is from our assignment. - if candidate.parachain_index != self.assignment { + if candidate.descriptor().para_id != self.assignment { return Ok(()); } @@ -367,8 +417,8 @@ impl CandidateBackingJob { let candidate_hash = candidate.hash(); if !self.issued_statements.contains(&candidate_hash) { - if let Ok(ValidationResult::Valid) = self.validate_and_second( - candidate, + if let Ok(true) = self.validate_and_second( + &candidate, pov, ).await { self.seconded = Some(candidate_hash); @@ -397,17 +447,40 @@ impl CandidateBackingJob { async fn kick_off_validation_work( &mut self, summary: TableSummary, - ) -> Result<ValidationResult, Error> { - let candidate = self.table.get_candidate(&summary.candidate).ok_or(Error::CandidateNotFound)?; - let candidate = candidate.clone(); - let descriptor = candidate.to_descriptor(); - let candidate_hash = candidate.hash(); - let pov = self.request_pov_from_distribution(descriptor).await?; - let v = self.request_candidate_validation(candidate, pov).await?; + ) -> Result<(), Error> { + let candidate_hash = summary.candidate.clone(); + + if self.issued_statements.contains(&candidate_hash) { + return Ok(()) + } + + // We clone the commitments here because there are borrowck + // errors relating to this being a struct and methods borrowing the entirety of self + // and not just those things that the function uses. + let candidate = self.table.get_candidate(&candidate_hash).ok_or(Error::CandidateNotFound)?; + let expected_commitments = candidate.commitments.clone(); + + let descriptor = candidate.descriptor().clone(); + let pov = self.request_pov_from_distribution(descriptor.clone()).await?; + let v = self.request_candidate_validation(descriptor, pov.clone()).await?; + + let statement = match v { + ValidationResult::Valid(outputs) => { + // If validation produces a new set of commitments, we vote the candidate as invalid. + let commitments_check = self.make_pov_available( + (&*pov).clone(), + outputs, + |commitments| if commitments == expected_commitments { + Ok(()) + } else { + Err(()) + } + ).await?; - let statement = match v.0 { - ValidationResult::Valid => { - Statement::Valid(candidate_hash) + match commitments_check { + Ok(()) => Statement::Valid(candidate_hash), + Err(()) => Statement::Invalid(candidate_hash), + } } ValidationResult::Invalid => { Statement::Invalid(candidate_hash) @@ -420,7 +493,7 @@ impl CandidateBackingJob { self.distribute_signed_statement(signed_statement).await?; } - Ok(v.0) + Ok(()) } /// Import the statement and kick off validation work if it is a part of our assignment. @@ -478,29 +551,26 @@ impl CandidateBackingJob { async fn request_pov_from_distribution( &mut self, descriptor: CandidateDescriptor, - ) -> Result<PoVBlock, Error> { + ) -> Result<Arc<PoV>, Error> { let (tx, rx) = oneshot::channel(); self.tx_from.send(FromJob::PoVDistribution( PoVDistributionMessage::FetchPoV(self.parent, descriptor, tx) )).await?; - let pov = rx.await?; - Ok((*pov).clone()) + Ok(rx.await?) } async fn request_candidate_validation( &mut self, - candidate: AbridgedCandidateReceipt, - pov: PoVBlock, - ) -> Result<(ValidationResult, GlobalValidationSchedule, LocalValidationData), Error> { + candidate: CandidateDescriptor, + pov: Arc<PoV>, + ) -> Result<ValidationResult, Error> { let (tx, rx) = oneshot::channel(); self.tx_from.send(FromJob::CandidateValidation( - CandidateValidationMessage::Validate( - self.parent, + CandidateValidationMessage::ValidateFromChainState( candidate, - self.head_data.clone(), pov, tx, ) @@ -523,32 +593,51 @@ impl CandidateBackingJob { Ok(()) } - async fn make_pov_available( + // Compute the erasure-coding and make it available. + // + // This calls an inspection function before making the PoV available for any last checks + // that need to be done. If the inspection function returns an error, this function returns + // early without making the PoV available. + async fn make_pov_available<T, E>( &mut self, - pov_block: PoVBlock, - global_validation: GlobalValidationSchedule, - local_validation: LocalValidationData, - ) -> Result<(), Error> { + pov: PoV, + outputs: ValidationOutputs, + with_commitments: impl FnOnce(CandidateCommitments) -> Result<T, E>, + ) -> Result<Result<T, E>, Error> { let omitted_validation = OmittedValidationData { - global_validation, - local_validation, + global_validation: outputs.global_validation_schedule, + local_validation: outputs.local_validation_data, }; let available_data = AvailableData { - pov_block, + pov, omitted_validation, }; - let chunks = erasure_coding::obtain_chunks( + let chunks = erasure_coding::obtain_chunks_v1( self.table_context.validators.len(), &available_data, )?; let branches = erasure_coding::branches(chunks.as_ref()); + let erasure_root = branches.root(); + + let commitments = CandidateCommitments { + fees: outputs.fees, + upward_messages: outputs.upward_messages, + erasure_root, + new_validation_code: outputs.new_validation_code, + head_data: outputs.head_data, + }; - for (index, (chunk, proof)) in chunks.iter().zip(branches.map(|(proof, _)| proof)).enumerate() { + let res = match with_commitments(commitments) { + Ok(x) => x, + Err(e) => return Ok(Err(e)), + }; + + for (index, (proof, chunk)) in branches.enumerate() { let chunk = ErasureChunk { - chunk: chunk.clone(), + chunk: chunk.to_vec(), index: index as u32, proof, }; @@ -556,7 +645,7 @@ impl CandidateBackingJob { self.store_chunk(index as ValidatorIndex, chunk).await?; } - Ok(()) + Ok(Ok(res)) } async fn distribute_signed_statement(&mut self, s: SignedFullStatement) -> Result<(), Error> { @@ -635,13 +724,7 @@ async fn run_job( } } - let ( - head_data, - signing_context, - ) = futures::try_join!( - request_head_data(parent, &mut tx_from, assignment).await?, - request_signing_context(parent, &mut tx_from).await?, - )?; + let signing_context = request_signing_context(parent, &mut tx_from).await?.await?; let table_context = TableContext { signing_context, @@ -654,7 +737,6 @@ async fn run_job( parent, rx_to, tx_from, - head_data, assignment, issued_statements: HashSet::new(), seconded: None, @@ -714,23 +796,6 @@ async fn request_signing_context( Ok(rx) } -/// Request `HeadData` for some `ParaId` from `RuntimeApi`. -async fn request_head_data( - parent: Hash, - s: &mut mpsc::Sender<FromJob>, - id: ParaId, -) -> Result<oneshot::Receiver<HeadData>, Error> { - let (tx, rx) = oneshot::channel(); - - s.send(FromJob::RuntimeApiMessage(RuntimeApiMessage::Request( - parent, - RuntimeApiRequest::HeadData(id, tx), - ) - )).await?; - - Ok(rx) -} - impl<S: Spawn> Jobs<S> { fn new(spawner: S) -> Self { Self { @@ -910,8 +975,9 @@ mod tests { use std::collections::HashMap; use std::sync::Arc; use sp_keyring::Sr25519Keyring; - use polkadot_primitives::parachain::{ + use polkadot_primitives::v1::{ AssignmentKind, CollatorId, CoreAssignment, BlockData, CoreIndex, GroupIndex, ValidityAttestation, + CandidateCommitments, LocalValidationData, GlobalValidationSchedule, HeadData, }; use assert_matches::assert_matches; @@ -1006,6 +1072,7 @@ mod tests { parent_head: HeadData(vec![7, 8, 9]), balance: Default::default(), code_upgrade_allowed: None, + validation_code_hash: Default::default(), }; let global_validation_schedule = GlobalValidationSchedule { @@ -1050,6 +1117,48 @@ mod tests { executor::block_on(future::select(test_fut, subsystem)); } + fn make_erasure_root(test: &TestState, pov: PoV) -> Hash { + let omitted_validation = OmittedValidationData { + global_validation: test.global_validation_schedule.clone(), + local_validation: test.local_validation_data.clone(), + }; + + let available_data = AvailableData { + omitted_validation, + pov, + }; + + let chunks = erasure_coding::obtain_chunks_v1(test.validators.len(), &available_data).unwrap(); + erasure_coding::branches(&chunks).root() + } + + #[derive(Default)] + struct TestCandidateBuilder { + para_id: ParaId, + head_data: HeadData, + pov_hash: Hash, + relay_parent: Hash, + erasure_root: Hash, + } + + impl TestCandidateBuilder { + fn build(self) -> CommittedCandidateReceipt { + CommittedCandidateReceipt { + descriptor: CandidateDescriptor { + para_id: self.para_id, + pov_hash: self.pov_hash, + relay_parent: self.relay_parent, + ..Default::default() + }, + commitments: CandidateCommitments { + head_data: self.head_data, + erasure_root: self.erasure_root, + ..Default::default() + }, + } + } + } + // Tests that the subsystem performs actions that are requied on startup. async fn test_startup( virtual_overseer: &mut subsystem_test::TestSubsystemContextHandle<CandidateBackingMessage>, @@ -1080,16 +1189,6 @@ mod tests { } ); - // Check that subsystem job issues a request for the head data. - assert_matches!( - virtual_overseer.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request(parent, RuntimeApiRequest::HeadData(id, tx)) - ) if parent == test_state.relay_parent => { - tx.send(test_state.head_data.get(&id).unwrap().clone()).unwrap(); - } - ); - // Check that subsystem job issues a request for the signing context. assert_matches!( virtual_overseer.recv().await, @@ -1108,49 +1207,53 @@ mod tests { let test_state = TestState::default(); test_harness(test_state.keystore.clone(), |test_harness| async move { let TestHarness { mut virtual_overseer } = test_harness; - + test_startup(&mut virtual_overseer, &test_state).await; - - let pov_block = PoVBlock { + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]), }; - let pov_block_hash = pov_block.hash(); - let candidate = AbridgedCandidateReceipt { - parachain_index: test_state.chain_ids[0], + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], relay_parent: test_state.relay_parent, - pov_block_hash, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }; + }.build(); let second = CandidateBackingMessage::Second( test_state.relay_parent, - candidate.clone(), - pov_block.clone(), + candidate.to_plain(), + pov.clone(), ); virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; - let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); assert_matches!( virtual_overseer.recv().await, AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( - parent_hash, + CandidateValidationMessage::ValidateFromChainState( c, - head_data, pov, tx, ) - ) if parent_hash == test_state.relay_parent && - pov == pov_block && c == candidate => { - assert_eq!(head_data, *expected_head_data); - tx.send(Ok(( - ValidationResult::Valid, - test_state.global_validation_schedule, - test_state.local_validation_data, - ))).unwrap(); + ) if pov == pov && &c == candidate.descriptor() => { + tx.send(Ok( + ValidationResult::Valid(ValidationOutputs { + global_validation_schedule: test_state.global_validation_schedule, + local_validation_data: test_state.local_validation_data, + head_data: expected_head_data.clone(), + upward_messages: Vec::new(), + fees: Default::default(), + new_validation_code: None, + }), + )).unwrap(); } ); @@ -1193,18 +1296,22 @@ mod tests { test_startup(&mut virtual_overseer, &test_state).await; - let pov_block = PoVBlock { + let pov = PoV { block_data: BlockData(vec![1, 2, 3]), }; - let pov_block_hash = pov_block.hash(); + let pov_hash = pov.hash(); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); - let candidate_a = AbridgedCandidateReceipt { - parachain_index: test_state.chain_ids[0], + let candidate_a = TestCandidateBuilder { + para_id: test_state.chain_ids[0], relay_parent: test_state.relay_parent, - pov_block_hash, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }; + }.build(); let candidate_a_hash = candidate_a.hash(); @@ -1227,39 +1334,38 @@ mod tests { virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; // Sending a `Statement::Seconded` for our assignment will start - // validation process. The first thing requested is PoVBlock from the + // validation process. The first thing requested is PoV from the // `PoVDistribution`. assert_matches!( virtual_overseer.recv().await, AllMessages::PoVDistribution( PoVDistributionMessage::FetchPoV(relay_parent, _, tx) ) if relay_parent == test_state.relay_parent => { - tx.send(Arc::new(pov_block.clone())).unwrap(); + tx.send(Arc::new(pov.clone())).unwrap(); } ); - let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); - // The next step is the actual request to Validation subsystem // to validate the `Seconded` candidate. assert_matches!( virtual_overseer.recv().await, AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( - relay_parent, - candidate, - head_data, + CandidateValidationMessage::ValidateFromChainState( + c, pov, tx, ) - ) if relay_parent == test_state.relay_parent && candidate == candidate_a => { - assert_eq!(head_data, *expected_head_data); - assert_eq!(pov, pov_block); - tx.send(Ok(( - ValidationResult::Valid, - test_state.global_validation_schedule, - test_state.local_validation_data, - ))).unwrap(); + ) if pov == pov && &c == candidate_a.descriptor() => { + tx.send(Ok( + ValidationResult::Valid(ValidationOutputs { + global_validation_schedule: test_state.global_validation_schedule, + local_validation_data: test_state.local_validation_data, + head_data: expected_head_data.clone(), + upward_messages: Vec::new(), + fees: Default::default(), + new_validation_code: None, + }), + )).unwrap(); } ); @@ -1309,17 +1415,22 @@ mod tests { test_startup(&mut virtual_overseer, &test_state).await; - let pov_block = PoVBlock { + let pov = PoV { block_data: BlockData(vec![1, 2, 3]), }; - let pov_block_hash = pov_block.hash(); - let candidate_a = AbridgedCandidateReceipt { - parachain_index: test_state.chain_ids[0], + let pov_hash = pov.hash(); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let candidate_a = TestCandidateBuilder { + para_id: test_state.chain_ids[0], relay_parent: test_state.relay_parent, - pov_block_hash, + pov_hash, + erasure_root: make_erasure_root(&test_state, pov.clone()), + head_data: expected_head_data.clone(), ..Default::default() - }; + }.build(); let candidate_a_hash = candidate_a.hash(); @@ -1353,33 +1464,41 @@ mod tests { AllMessages::PoVDistribution( PoVDistributionMessage::FetchPoV(relay_parent, _, tx) ) if relay_parent == test_state.relay_parent => { - tx.send(Arc::new(pov_block.clone())).unwrap(); + tx.send(Arc::new(pov.clone())).unwrap(); } ); - let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); - assert_matches!( virtual_overseer.recv().await, AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( - relay_parent, - candidate, - head_data, + CandidateValidationMessage::ValidateFromChainState( + c, pov, tx, ) - ) if relay_parent == test_state.relay_parent && candidate == candidate_a => { - assert_eq!(pov, pov_block); - assert_eq!(head_data, *expected_head_data); - tx.send(Ok(( - ValidationResult::Valid, - test_state.global_validation_schedule, - test_state.local_validation_data, - ))).unwrap(); + ) if pov == pov && &c == candidate_a.descriptor() => { + tx.send(Ok( + ValidationResult::Valid(ValidationOutputs { + global_validation_schedule: test_state.global_validation_schedule, + local_validation_data: test_state.local_validation_data, + head_data: expected_head_data.clone(), + upward_messages: Vec::new(), + fees: Default::default(), + new_validation_code: None, + }), + )).unwrap(); } ); + for _ in 0..test_state.validators.len() { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreChunk(parent_hash, _, _) + ) if parent_hash == test_state.relay_parent + ); + } + assert_matches!( virtual_overseer.recv().await, AllMessages::StatementDistribution( @@ -1440,86 +1559,68 @@ mod tests { test_startup(&mut virtual_overseer, &test_state).await; - let pov_block_a = PoVBlock { + let pov_block_a = PoV { block_data: BlockData(vec![42, 43, 44]), }; - let pov_block_b = PoVBlock { + let pov_block_b = PoV { block_data: BlockData(vec![45, 46, 47]), }; - let pov_block_hash_a = pov_block_a.hash(); - let pov_block_hash_b = pov_block_b.hash(); + let pov_hash_a = pov_block_a.hash(); + let pov_hash_b = pov_block_b.hash(); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); - let candidate_a = AbridgedCandidateReceipt { - parachain_index: test_state.chain_ids[0], + let candidate_a = TestCandidateBuilder { + para_id: test_state.chain_ids[0], relay_parent: test_state.relay_parent, - pov_block_hash: pov_block_hash_a, + pov_hash: pov_hash_a, + erasure_root: make_erasure_root(&test_state, pov_block_a.clone()), ..Default::default() - }; - - let candidate_a_hash = candidate_a.hash(); + }.build(); - let candidate_b = AbridgedCandidateReceipt { - parachain_index: test_state.chain_ids[0], + let candidate_b = TestCandidateBuilder { + para_id: test_state.chain_ids[0], relay_parent: test_state.relay_parent, - pov_block_hash: pov_block_hash_b, + pov_hash: pov_hash_b, + erasure_root: make_erasure_root(&test_state, pov_block_b.clone()), + head_data: expected_head_data.clone(), ..Default::default() - }; + }.build(); let second = CandidateBackingMessage::Second( test_state.relay_parent, - candidate_a.clone(), + candidate_a.to_plain(), pov_block_a.clone(), ); virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; - let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); assert_matches!( virtual_overseer.recv().await, AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( - parent_hash, + CandidateValidationMessage::ValidateFromChainState( c, - head_data, pov, tx, ) - ) if parent_hash == test_state.relay_parent && - pov == pov_block_a && c == candidate_a => { - assert_eq!(head_data, *expected_head_data); - tx.send(Ok(( - ValidationResult::Invalid, - test_state.global_validation_schedule.clone(), - test_state.local_validation_data.clone(), - ))).unwrap(); + ) if pov == pov && &c == candidate_a.descriptor() => { + tx.send(Ok(ValidationResult::Invalid)).unwrap(); } ); assert_matches!( virtual_overseer.recv().await, AllMessages::CandidateSelection( - CandidateSelectionMessage::Invalid(parent_hash, candidate) - ) if parent_hash == test_state.relay_parent && candidate == candidate_a - ); - - assert_matches!( - virtual_overseer.recv().await, - AllMessages::StatementDistribution( - StatementDistributionMessage::Share( - relay_parent, - statement, - ) - ) if relay_parent == test_state.relay_parent => { - assert_eq!(*statement.payload(), Statement::Invalid(candidate_a_hash)); - } + CandidateSelectionMessage::Invalid(parent_hash, c) + ) if parent_hash == test_state.relay_parent && c == candidate_a.to_plain() ); let second = CandidateBackingMessage::Second( test_state.relay_parent, - candidate_b.clone(), + candidate_b.to_plain(), pov_block_b.clone(), ); @@ -1530,21 +1631,22 @@ mod tests { assert_matches!( virtual_overseer.recv().await, AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( - parent_hash, + CandidateValidationMessage::ValidateFromChainState( c, - head_data, pov, tx, ) - ) if parent_hash == test_state.relay_parent && - pov == pov_block_b && c == candidate_b => { - assert_eq!(head_data, *expected_head_data); - tx.send(Ok(( - ValidationResult::Valid, - test_state.global_validation_schedule, - test_state.local_validation_data, - ))).unwrap(); + ) if pov == pov && &c == candidate_b.descriptor() => { + tx.send(Ok( + ValidationResult::Valid(ValidationOutputs { + global_validation_schedule: test_state.global_validation_schedule, + local_validation_data: test_state.local_validation_data, + head_data: expected_head_data.clone(), + upward_messages: Vec::new(), + fees: Default::default(), + new_validation_code: None, + }), + )).unwrap(); } ); @@ -1590,18 +1692,19 @@ mod tests { test_startup(&mut virtual_overseer, &test_state).await; - let pov_block = PoVBlock { + let pov = PoV { block_data: BlockData(vec![42, 43, 44]), }; - let pov_block_hash = pov_block.hash(); + let pov_hash = pov.hash(); - let candidate = AbridgedCandidateReceipt { - parachain_index: test_state.chain_ids[0], + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], relay_parent: test_state.relay_parent, - pov_block_hash, + pov_hash, + erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }; + }.build(); let candidate_hash = candidate.hash(); @@ -1627,33 +1730,22 @@ mod tests { PoVDistributionMessage::FetchPoV(relay_parent, _, tx) ) => { assert_eq!(relay_parent, test_state.relay_parent); - tx.send(Arc::new(pov_block.clone())).unwrap(); + tx.send(Arc::new(pov.clone())).unwrap(); } ); - let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); // Tell subsystem that this candidate is invalid. assert_matches!( virtual_overseer.recv().await, AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( - relay_parent, - candidate_recvd, - head_data, + CandidateValidationMessage::ValidateFromChainState( + c, pov, tx, ) - ) => { - assert_eq!(relay_parent, test_state.relay_parent); - assert_eq!(candidate_recvd, candidate); - assert_eq!(head_data, *expected_head_data); - assert_eq!(pov, pov_block); - tx.send(Ok(( - ValidationResult::Invalid, - test_state.global_validation_schedule, - test_state.local_validation_data, - ))).unwrap(); + ) if pov == pov && &c == candidate.descriptor() => { + tx.send(Ok(ValidationResult::Invalid)).unwrap(); } ); @@ -1679,28 +1771,29 @@ mod tests { // This should emit no actions from subsystem. let second = CandidateBackingMessage::Second( test_state.relay_parent, - candidate.clone(), - pov_block.clone(), + candidate.to_plain(), + pov.clone(), ); virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; - let pov_to_second = PoVBlock { + let pov_to_second = PoV { block_data: BlockData(vec![3, 2, 1]), }; - let pov_block_hash = pov_to_second.hash(); + let pov_hash = pov_to_second.hash(); - let candidate_to_second = AbridgedCandidateReceipt { - parachain_index: test_state.chain_ids[0], + let candidate_to_second = TestCandidateBuilder { + para_id: test_state.chain_ids[0], relay_parent: test_state.relay_parent, - pov_block_hash, + pov_hash, + erasure_root: make_erasure_root(&test_state, pov_to_second.clone()), ..Default::default() - }; + }.build(); let second = CandidateBackingMessage::Second( test_state.relay_parent, - candidate_to_second.clone(), + candidate_to_second.to_plain(), pov_to_second.clone(), ); @@ -1712,16 +1805,13 @@ mod tests { assert_matches!( virtual_overseer.recv().await, AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( - relay_parent, - _, + CandidateValidationMessage::ValidateFromChainState( _, pov, _, ) ) => { - assert_eq!(relay_parent, test_state.relay_parent); - assert_eq!(pov, pov_to_second); + assert_eq!(&*pov, &pov_to_second); } ); }); diff --git a/polkadot/node/core/proposer/src/lib.rs b/polkadot/node/core/proposer/src/lib.rs index b53ac5729fa949a0176969bae47b5ad05b390b57..d43810227ba4ddd5e1c76f5001261966c39720af 100644 --- a/polkadot/node/core/proposer/src/lib.rs +++ b/polkadot/node/core/proposer/src/lib.rs @@ -2,9 +2,7 @@ use futures::prelude::*; use futures::select; use polkadot_node_subsystem::{messages::{AllMessages, ProvisionerInherentData, ProvisionerMessage}, SubsystemError}; use polkadot_overseer::OverseerHandler; -use polkadot_primitives::{ - inclusion_inherent, - parachain::ParachainHost, +use polkadot_primitives::v1::{ Block, Hash, Header, }; use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider}; @@ -53,7 +51,7 @@ where + Send + Sync, Client::Api: - ParachainHost<Block> + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, Backend: 'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>, // Rust bug: https://github.com/rust-lang/rust/issues/24159 @@ -104,7 +102,7 @@ where + Send + Sync, Client::Api: - ParachainHost<Block> + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, Backend: 'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>, // Rust bug: https://github.com/rust-lang/rust/issues/24159 @@ -155,7 +153,7 @@ where + Send + Sync, Client::Api: - ParachainHost<Block> + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, Backend: 'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>, // Rust bug: https://github.com/rust-lang/rust/issues/24159 @@ -186,7 +184,7 @@ where }; inherent_data.put_data( - inclusion_inherent::INHERENT_IDENTIFIER, + polkadot_primitives::v1::INCLUSION_INHERENT_IDENTIFIER, &provisioner_data, )?; diff --git a/polkadot/node/network/bridge/src/lib.rs b/polkadot/node/network/bridge/src/lib.rs index 6f90779afe62c17058ecb2b4d2a7a800e8672b64..46b9dbd84024674706b95e779f963042c0aa1c76 100644 --- a/polkadot/node/network/bridge/src/lib.rs +++ b/polkadot/node/network/bridge/src/lib.rs @@ -33,7 +33,7 @@ use polkadot_subsystem::{ }; use polkadot_subsystem::messages::{NetworkBridgeEvent, NetworkBridgeMessage, AllMessages}; use node_primitives::{ProtocolId, View}; -use polkadot_primitives::{Block, Hash}; +use polkadot_primitives::v1::{Block, Hash}; use std::collections::btree_map::{BTreeMap, Entry as BEntry}; use std::collections::hash_map::{HashMap, Entry as HEntry}; diff --git a/polkadot/node/network/pov-distribution/src/lib.rs b/polkadot/node/network/pov-distribution/src/lib.rs index 589e33fde0d6cbf525890cebe06f7129be8e950d..84d6e803d2c7c8323503362a88a24d390ba4d585 100644 --- a/polkadot/node/network/pov-distribution/src/lib.rs +++ b/polkadot/node/network/pov-distribution/src/lib.rs @@ -19,8 +19,7 @@ //! This is a gossip implementation of code that is responsible for distributing PoVs //! among validators. -use polkadot_primitives::Hash; -use polkadot_primitives::parachain::{PoVBlock as PoV, CandidateDescriptor}; +use polkadot_primitives::v1::{Hash, PoV, CandidateDescriptor}; use polkadot_subsystem::{ OverseerSignal, SubsystemContext, Subsystem, SubsystemResult, FromOverseer, SpawnedSubsystem, }; @@ -550,7 +549,7 @@ async fn run( mod tests { use super::*; use futures::executor::{self, ThreadPool}; - use polkadot_primitives::parachain::BlockData; + use polkadot_primitives::v1::BlockData; use assert_matches::assert_matches; fn make_pov(data: Vec<u8>) -> PoV { diff --git a/polkadot/node/network/statement-distribution/src/lib.rs b/polkadot/node/network/statement-distribution/src/lib.rs index f3d2653266f739e689beec98df18806349a8ea9d..cef499eae98b2c0247d6ff24cf85832c2c2001cc 100644 --- a/polkadot/node/network/statement-distribution/src/lib.rs +++ b/polkadot/node/network/statement-distribution/src/lib.rs @@ -29,9 +29,8 @@ use polkadot_subsystem::messages::{ RuntimeApiRequest, }; use node_primitives::{ProtocolId, View, SignedFullStatement}; -use polkadot_primitives::Hash; -use polkadot_primitives::parachain::{ - CompactStatement, ValidatorIndex, ValidatorId, SigningContext, ValidatorSignature, +use polkadot_primitives::v1::{ + Hash, CompactStatement, ValidatorIndex, ValidatorId, SigningContext, ValidatorSignature, }; use parity_scale_codec::{Encode, Decode}; @@ -891,7 +890,7 @@ mod tests { use super::*; use sp_keyring::Sr25519Keyring; use node_primitives::Statement; - use polkadot_primitives::parachain::{AbridgedCandidateReceipt}; + use polkadot_primitives::v1::CommittedCandidateReceipt; use assert_matches::assert_matches; use futures::executor::{self, ThreadPool}; @@ -911,23 +910,23 @@ mod tests { }; let candidate_a = { - let mut c = AbridgedCandidateReceipt::default(); - c.relay_parent = parent_hash; - c.parachain_index = 1.into(); + let mut c = CommittedCandidateReceipt::default(); + c.descriptor.relay_parent = parent_hash; + c.descriptor.para_id = 1.into(); c }; let candidate_b = { - let mut c = AbridgedCandidateReceipt::default(); - c.relay_parent = parent_hash; - c.parachain_index = 2.into(); + let mut c = CommittedCandidateReceipt::default(); + c.descriptor.relay_parent = parent_hash; + c.descriptor.para_id = 2.into(); c }; let candidate_c = { - let mut c = AbridgedCandidateReceipt::default(); - c.relay_parent = parent_hash; - c.parachain_index = 3.into(); + let mut c = CommittedCandidateReceipt::default(); + c.descriptor.relay_parent = parent_hash; + c.descriptor.para_id = 3.into(); c }; @@ -1140,9 +1139,9 @@ mod tests { let hash_c = [3; 32].into(); let candidate = { - let mut c = AbridgedCandidateReceipt::default(); - c.relay_parent = hash_c; - c.parachain_index = 1.into(); + let mut c = CommittedCandidateReceipt::default(); + c.descriptor.relay_parent = hash_c; + c.descriptor.para_id = 1.into(); c }; let candidate_hash = candidate.hash(); @@ -1275,9 +1274,9 @@ mod tests { let hash_c = [3; 32].into(); let candidate = { - let mut c = AbridgedCandidateReceipt::default(); - c.relay_parent = hash_b; - c.parachain_index = 1.into(); + let mut c = CommittedCandidateReceipt::default(); + c.descriptor.relay_parent = hash_b; + c.descriptor.para_id = 1.into(); c }; diff --git a/polkadot/node/overseer/examples/minimal-example.rs b/polkadot/node/overseer/examples/minimal-example.rs index 21e8eb3ab8fa90504d65cabdb29e43d4f4ea0817..d5f7f043ff43afc80f627ee4966893792cf35ad1 100644 --- a/polkadot/node/overseer/examples/minimal-example.rs +++ b/polkadot/node/overseer/examples/minimal-example.rs @@ -27,11 +27,11 @@ use futures::{ use futures_timer::Delay; use kv_log_macro as log; -use polkadot_primitives::parachain::{BlockData, PoVBlock}; +use polkadot_primitives::v1::{BlockData, PoV}; use polkadot_overseer::{Overseer, AllSubsystems}; use polkadot_subsystem::{ - Subsystem, SubsystemContext, DummySubsystem, + Subsystem, SubsystemContext, DummySubsystem, SpawnedSubsystem, FromOverseer, }; use polkadot_subsystem::messages::{ @@ -61,13 +61,11 @@ impl Subsystem1 { let (tx, _) = oneshot::channel(); ctx.send_message(AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( + CandidateValidationMessage::ValidateFromChainState( Default::default(), - Default::default(), - Default::default(), - PoVBlock { + PoV { block_data: BlockData(Vec::new()), - }, + }.into(), tx, ) )).await.unwrap(); diff --git a/polkadot/node/overseer/src/lib.rs b/polkadot/node/overseer/src/lib.rs index 458aae91e871e53271282c12912752c6ac18b1cd..91fceb0d3bb0409388c0e7bf29d4c3ba948ff7e9 100644 --- a/polkadot/node/overseer/src/lib.rs +++ b/polkadot/node/overseer/src/lib.rs @@ -72,7 +72,7 @@ use futures::{ use futures_timer::Delay; use streamunordered::{StreamYield, StreamUnordered}; -use polkadot_primitives::{Block, BlockNumber, Hash}; +use polkadot_primitives::v1::{Block, BlockNumber, Hash}; use client::{BlockImportNotification, BlockchainEvents, FinalityNotification}; use polkadot_subsystem::messages::{ @@ -932,7 +932,7 @@ fn spawn<S: Spawn, M: Send + 'static>( mod tests { use futures::{executor, pin_mut, select, channel::mpsc, FutureExt}; - use polkadot_primitives::parachain::{BlockData, PoVBlock}; + use polkadot_primitives::v1::{BlockData, PoV}; use polkadot_subsystem::DummySubsystem; use super::*; @@ -977,13 +977,11 @@ mod tests { let (tx, _) = oneshot::channel(); ctx.send_message( AllMessages::CandidateValidation( - CandidateValidationMessage::Validate( + CandidateValidationMessage::ValidateFromChainState( Default::default(), - Default::default(), - Default::default(), - PoVBlock { + PoV { block_data: BlockData(Vec::new()), - }, + }.into(), tx, ) ) diff --git a/polkadot/node/primitives/src/lib.rs b/polkadot/node/primitives/src/lib.rs index 25313c09154e985932d371af71b732675022f00e..f29be5737450ace1bcbd41e240fb3b785e435a25 100644 --- a/polkadot/node/primitives/src/lib.rs +++ b/polkadot/node/primitives/src/lib.rs @@ -21,26 +21,31 @@ //! there. use parity_scale_codec::{Decode, Encode}; -use polkadot_primitives::{Hash, - parachain::{ - AbridgedCandidateReceipt, CompactStatement, - EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId, - } +use polkadot_primitives::v1::{ + Hash, CommittedCandidateReceipt, CandidateReceipt, CompactStatement, + EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId, + UpwardMessage, Balance, ValidationCode, GlobalValidationSchedule, LocalValidationData, + HeadData, }; use polkadot_statement_table::{ generic::{ ValidityDoubleVote as TableValidityDoubleVote, MultipleCandidates as TableMultipleCandidates, }, - Misbehavior as TableMisbehavior, + v1::Misbehavior as TableMisbehavior, }; /// A statement, where the candidate receipt is included in the `Seconded` variant. +/// +/// This is the committed candidate receipt instead of the bare candidate receipt. As such, +/// it gives access to the commitments to validators who have not executed the candidate. This +/// is necessary to allow a block-producing validator to include candidates from outside of the para +/// it is assigned to. #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)] pub enum Statement { /// A statement that a validator seconds a candidate. #[codec(index = "1")] - Seconded(AbridgedCandidateReceipt), + Seconded(CommittedCandidateReceipt), /// A statement that a validator has deemed a candidate valid. #[codec(index = "2")] Valid(Hash), @@ -50,6 +55,8 @@ pub enum Statement { } impl Statement { + /// Transform this statement into its compact version, which references only the hash + /// of the candidate. pub fn to_compact(&self) -> CompactStatement { match *self { Statement::Seconded(ref c) => CompactStatement::Candidate(c.hash()), @@ -84,9 +91,9 @@ pub enum MisbehaviorReport { /// this message should be dispatched with all of them, in arbitrary order. /// /// This variant is also used when our own validity checks disagree with others'. - CandidateValidityDisagreement(AbridgedCandidateReceipt, Vec<SignedFullStatement>), + CandidateValidityDisagreement(CandidateReceipt, Vec<SignedFullStatement>), /// I've noticed a peer contradicting itself about a particular candidate - SelfContradiction(AbridgedCandidateReceipt, SignedFullStatement, SignedFullStatement), + SelfContradiction(CandidateReceipt, SignedFullStatement, SignedFullStatement), /// This peer has seconded more than one parachain candidate for this relay parent head DoubleVote(SignedFullStatement, SignedFullStatement), } @@ -103,11 +110,28 @@ pub struct FromTableMisbehavior { pub key: ValidatorId, } +/// Outputs of validating a candidate. +#[derive(Debug)] +pub struct ValidationOutputs { + /// The head-data produced by validation. + pub head_data: HeadData, + /// The global validation schedule. + pub global_validation_schedule: GlobalValidationSchedule, + /// The local validation data. + pub local_validation_data: LocalValidationData, + /// Upward messages to the relay chain. + pub upward_messages: Vec<UpwardMessage>, + /// Fees paid to the validators of the relay-chain. + pub fees: Balance, + /// The new validation code submitted by the execution, if any. + pub new_validation_code: Option<ValidationCode>, +} + /// Result of the validation of the candidate. #[derive(Debug)] pub enum ValidationResult { - /// Candidate is valid. - Valid, + /// Candidate is valid. The validation process yields these outputs. + Valid(ValidationOutputs), /// Candidate is invalid. Invalid, } @@ -136,7 +160,7 @@ impl std::convert::TryFrom<FromTableMisbehavior> for MisbehaviorReport { &f.key, ).ok_or(())?; - Ok(MisbehaviorReport::SelfContradiction(receipt, signed_1, signed_2)) + Ok(MisbehaviorReport::SelfContradiction(receipt.to_plain(), signed_1, signed_2)) } TableMisbehavior::ValidityDoubleVote( TableValidityDoubleVote::IssuedAndInvalidity((c, s1), (d, s2)) @@ -157,7 +181,7 @@ impl std::convert::TryFrom<FromTableMisbehavior> for MisbehaviorReport { &f.key, ).ok_or(())?; - Ok(MisbehaviorReport::SelfContradiction(receipt, signed_1, signed_2)) + Ok(MisbehaviorReport::SelfContradiction(receipt.to_plain(), signed_1, signed_2)) } TableMisbehavior::ValidityDoubleVote( TableValidityDoubleVote::ValidityAndInvalidity(c, s1, s2) @@ -177,7 +201,7 @@ impl std::convert::TryFrom<FromTableMisbehavior> for MisbehaviorReport { &f.key, ).ok_or(())?; - Ok(MisbehaviorReport::SelfContradiction(c, signed_1, signed_2)) + Ok(MisbehaviorReport::SelfContradiction(c.to_plain(), signed_1, signed_2)) } TableMisbehavior::MultipleCandidates( TableMultipleCandidates { diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index 0659d08083016a953407ad4aa7c532ff4898d76c..db9d9c5dded9bf6bd2cf277792fb727b1c2f5aa2 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -17,7 +17,7 @@ //! Polkadot chain configurations. use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; -use polkadot_primitives::{AccountId, AccountPublic, parachain::ValidatorId}; +use polkadot_primitives::v1::{AccountId, AccountPublic, ValidatorId}; use polkadot_runtime as polkadot; use kusama_runtime as kusama; use westend_runtime as westend; @@ -48,9 +48,9 @@ const DEFAULT_PROTOCOL_ID: &str = "dot"; #[serde(rename_all = "camelCase")] pub struct Extensions { /// Block numbers with known hashes. - pub fork_blocks: sc_client_api::ForkBlocks<polkadot_primitives::Block>, + pub fork_blocks: sc_client_api::ForkBlocks<polkadot_primitives::v1::Block>, /// Known bad block hashes. - pub bad_blocks: sc_client_api::BadBlocks<polkadot_primitives::Block>, + pub bad_blocks: sc_client_api::BadBlocks<polkadot_primitives::v1::Block>, } /// The `ChainSpec parametrised for polkadot runtime`. diff --git a/polkadot/node/service/src/grandpa_support.rs b/polkadot/node/service/src/grandpa_support.rs index 806a189d9fe530a75e65d1fecf092fc316c45229..2a9b73b0868e5af977fecb060d9c1c0f3b36857e 100644 --- a/polkadot/node/service/src/grandpa_support.rs +++ b/polkadot/node/service/src/grandpa_support.rs @@ -16,7 +16,7 @@ //! Polkadot-specific GRANDPA integration utilities. -use polkadot_primitives::Hash; +use polkadot_primitives::v1::Hash; use sp_runtime::traits::{Block as BlockT, NumberFor}; /// A custom GRANDPA voting rule that "pauses" voting (i.e. keeps voting for the @@ -98,7 +98,7 @@ impl<Block, B> grandpa::VotingRule<Block, B> for PauseAfterBlockFor<NumberFor<Bl /// #1500988). pub(crate) fn kusama_hard_forks() -> Vec<( grandpa_primitives::SetId, - (Hash, polkadot_primitives::BlockNumber), + (Hash, polkadot_primitives::v1::BlockNumber), grandpa_primitives::AuthorityList, )> { use sp_core::crypto::Ss58Codec; diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs index 8a435e6b595b193a5976cc4c7d0eb36f4f437f3e..1205d9f3ef19f22f4aaebc6a30d3619b0a9e0b72 100644 --- a/polkadot/node/service/src/lib.rs +++ b/polkadot/node/service/src/lib.rs @@ -22,7 +22,7 @@ mod client; use std::sync::Arc; use std::time::Duration; -use polkadot_primitives::{parachain, AccountId, Nonce, Balance}; +use polkadot_primitives::v1::{AccountId, Nonce, Balance}; #[cfg(feature = "full-node")] use service::{error::Error as ServiceError, ServiceBuilder}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; @@ -45,8 +45,7 @@ pub use sc_consensus::LongestChain; pub use sp_api::{ApiRef, Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend}; pub use sp_runtime::traits::{DigestFor, HashFor, NumberFor}; pub use consensus_common::{Proposal, SelectChain, BlockImport, RecordProof, block_validation::Chain}; -pub use polkadot_primitives::parachain::{CollatorId, ParachainHost}; -pub use polkadot_primitives::{Block, BlockId}; +pub use polkadot_primitives::v1::{Block, BlockId, CollatorId, Id as ParaId}; pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256}; pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec}; #[cfg(feature = "full-node")] @@ -84,7 +83,6 @@ pub trait RuntimeApiCollection<Extrinsic: codec::Codec + Send + Sync + 'static>: + sp_api::ApiExt<Block, Error = sp_blockchain::Error> + babe_primitives::BabeApi<Block> + grandpa_primitives::GrandpaApi<Block> - + ParachainHost<Block> + sp_block_builder::BlockBuilder<Block> + system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance, Extrinsic> @@ -104,7 +102,6 @@ where + sp_api::ApiExt<Block, Error = sp_blockchain::Error> + babe_primitives::BabeApi<Block> + grandpa_primitives::GrandpaApi<Block> - + ParachainHost<Block> + sp_block_builder::BlockBuilder<Block> + system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance, Extrinsic> @@ -578,7 +575,7 @@ macro_rules! new_light { /// Builds a new object suitable for chain operations. pub fn new_chain_ops<Runtime, Dispatch, Extrinsic>(mut config: Configuration) -> Result< ( - Arc<service::TFullClient<Block, Runtime, Dispatch>>, + Arc<service::TFullClient<Block, Runtime, Dispatch>>, Arc<TFullBackend<Block>>, consensus_common::import_queue::BasicQueue<Block, PrefixedMemoryDB<BlakeTwo256>>, TaskManager, @@ -601,7 +598,7 @@ where #[cfg(feature = "full-node")] pub fn polkadot_new_full( mut config: Configuration, - collating_for: Option<(CollatorId, parachain::Id)>, + collating_for: Option<(CollatorId, ParaId)>, _max_block_data_size: Option<u64>, _authority_discovery_enabled: bool, _slot_duration: u64, @@ -633,7 +630,7 @@ pub fn polkadot_new_full( #[cfg(feature = "full-node")] pub fn kusama_new_full( mut config: Configuration, - collating_for: Option<(CollatorId, parachain::Id)>, + collating_for: Option<(CollatorId, ParaId)>, _max_block_data_size: Option<u64>, _authority_discovery_enabled: bool, _slot_duration: u64, @@ -665,7 +662,7 @@ pub fn kusama_new_full( #[cfg(feature = "full-node")] pub fn westend_new_full( mut config: Configuration, - collating_for: Option<(CollatorId, parachain::Id)>, + collating_for: Option<(CollatorId, ParaId)>, _max_block_data_size: Option<u64>, _authority_discovery_enabled: bool, _slot_duration: u64, diff --git a/polkadot/node/subsystem/src/lib.rs b/polkadot/node/subsystem/src/lib.rs index db9a0629cfd407a53c8add8f277329304a108b64..e374eb9cfcdd60a631893617fb3f74f607aaf59a 100644 --- a/polkadot/node/subsystem/src/lib.rs +++ b/polkadot/node/subsystem/src/lib.rs @@ -26,7 +26,7 @@ use futures::prelude::*; use futures::channel::{mpsc, oneshot}; use futures::future::BoxFuture; -use polkadot_primitives::Hash; +use polkadot_primitives::v1::Hash; use async_trait::async_trait; use crate::messages::AllMessages; diff --git a/polkadot/node/subsystem/src/messages.rs b/polkadot/node/subsystem/src/messages.rs index 36c293e49fe9e8d606f4b1cc5ad47d4561618fe9..10c861f1410cf8e7bbb15b26cb3bcd1c21b18837 100644 --- a/polkadot/node/subsystem/src/messages.rs +++ b/polkadot/node/subsystem/src/messages.rs @@ -24,12 +24,12 @@ use futures::channel::{mpsc, oneshot}; -use polkadot_primitives::{BlockNumber, Hash, Signature}; -use polkadot_primitives::parachain::{ - AbridgedCandidateReceipt, PoVBlock, ErasureChunk, BackedCandidate, Id as ParaId, +use polkadot_primitives::v1::{ + BlockNumber, Hash, + CandidateReceipt, PoV, ErasureChunk, BackedCandidate, Id as ParaId, SignedAvailabilityBitfield, SigningContext, ValidatorId, ValidationCode, ValidatorIndex, - CoreAssignment, CoreOccupied, HeadData, CandidateDescriptor, GlobalValidationSchedule, - LocalValidationData, + CoreAssignment, CoreOccupied, HeadData, CandidateDescriptor, + ValidatorSignature, OmittedValidationData, }; use polkadot_node_primitives::{ MisbehaviorReport, SignedFullStatement, View, ProtocolId, ValidationResult, @@ -48,7 +48,7 @@ pub struct NewBackedCandidate(pub BackedCandidate); pub enum CandidateSelectionMessage { /// We recommended a particular candidate to be seconded, but it was invalid; penalize the collator. /// The hash is the relay parent. - Invalid(Hash, AbridgedCandidateReceipt), + Invalid(Hash, CandidateReceipt), } /// Messages received by the Candidate Backing subsystem. @@ -59,7 +59,7 @@ pub enum CandidateBackingMessage { GetBackedCandidates(Hash, oneshot::Sender<Vec<NewBackedCandidate>>), /// Note that the Candidate Backing subsystem should second the given candidate in the context of the /// given relay-parent (ref. by hash). This candidate must be validated. - Second(Hash, AbridgedCandidateReceipt, PoVBlock), + Second(Hash, CandidateReceipt, PoV), /// Note a validator's statement about a particular candidate. Disagreements about validity must be escalated /// to a broader check by Misbehavior Arbitration. Agreements are simply tallied until a quorum is reached. Statement(Hash, SignedFullStatement), @@ -69,22 +69,36 @@ pub enum CandidateBackingMessage { #[derive(Debug)] pub struct ValidationFailed; -/// Messages received by the Validation subsystem +/// Messages received by the Validation subsystem. +/// +/// ## Validation Requests +/// +/// Validation requests made to the subsystem should return an error only on internal error. +/// Otherwise, they should return either `Ok(ValidationResult::Valid(_))` +/// or `Ok(ValidationResult::Invalid)`. #[derive(Debug)] pub enum CandidateValidationMessage { - /// Validate a candidate, sending a side-channel response of valid or invalid. + /// Validate a candidate with provided parameters using relay-chain state. + /// + /// This will implicitly attempt to gather the `OmittedValidationData` and `ValidationCode` + /// from the runtime API of the chain, based on the `relay_parent` + /// of the `CandidateDescriptor`. + /// If there is no state available which can provide this data, an error is returned. + ValidateFromChainState( + CandidateDescriptor, + Arc<PoV>, + oneshot::Sender<Result<ValidationResult, ValidationFailed>>, + ), + /// Validate a candidate with provided, exhaustive parameters for validation. /// - /// Provide the relay-parent in whose context this should be validated, the full candidate receipt, - /// and the PoV. - Validate( - Hash, - AbridgedCandidateReceipt, - HeadData, - PoVBlock, - oneshot::Sender<Result< - (ValidationResult, GlobalValidationSchedule, LocalValidationData), - ValidationFailed, - >>, + /// Explicitly provide the `OmittedValidationData` and `ValidationCode` so this can do full + /// validation without needing to access the state of the relay-chain. + ValidateFromExhaustive( + OmittedValidationData, + ValidationCode, + CandidateDescriptor, + Arc<PoV>, + oneshot::Sender<Result<ValidationResult, ValidationFailed>>, ), } @@ -146,8 +160,8 @@ pub enum BitfieldDistributionMessage { /// Availability store subsystem message. #[derive(Debug)] pub enum AvailabilityStoreMessage { - /// Query a `PoVBlock` from the AV store. - QueryPoV(Hash, oneshot::Sender<Option<PoVBlock>>), + /// Query a `PoV` from the AV store. + QueryPoV(Hash, oneshot::Sender<Option<PoV>>), /// Query an `ErasureChunk` from the AV store. QueryChunk(Hash, ValidatorIndex, oneshot::Sender<ErasureChunk>), @@ -213,7 +227,7 @@ pub enum ProvisionableData { /// Misbehavior reports are self-contained proofs of validator misbehavior. MisbehaviorReport(Hash, MisbehaviorReport), /// Disputes trigger a broad dispute resolution process. - Dispute(Hash, Signature), + Dispute(Hash, ValidatorSignature), } /// This data needs to make its way from the provisioner into the InherentData. @@ -246,10 +260,10 @@ pub enum PoVDistributionMessage { /// /// This `CandidateDescriptor` should correspond to a candidate seconded under the provided /// relay-parent hash. - FetchPoV(Hash, CandidateDescriptor, oneshot::Sender<Arc<PoVBlock>>), + FetchPoV(Hash, CandidateDescriptor, oneshot::Sender<Arc<PoV>>), /// Distribute a PoV for the given relay-parent and CandidateDescriptor. /// The PoV should correctly hash to the PoV hash mentioned in the CandidateDescriptor - DistributePoV(Hash, CandidateDescriptor, Arc<PoVBlock>), + DistributePoV(Hash, CandidateDescriptor, Arc<PoV>), /// An update from the network bridge. NetworkBridgeUpdate(NetworkBridgeEvent), } diff --git a/polkadot/node/test-service/src/chain_spec.rs b/polkadot/node/test-service/src/chain_spec.rs index cbb08c470f07003b9682b0e3f6f299045302fa37..e81050afdbbe5f9c3a8cc0dc1440b81bcfb3f036 100644 --- a/polkadot/node/test-service/src/chain_spec.rs +++ b/polkadot/node/test-service/src/chain_spec.rs @@ -17,7 +17,7 @@ use babe_primitives::AuthorityId as BabeId; use grandpa::AuthorityId as GrandpaId; use pallet_staking::Forcing; -use polkadot_primitives::{parachain::ValidatorId, AccountId}; +use polkadot_primitives::v0::{ValidatorId, AccountId}; use polkadot_service::chain_spec::{get_account_id_from_seed, get_from_seed, Extensions}; use polkadot_test_runtime::constants::currency::DOTS; use sc_chain_spec::{ChainSpec, ChainType}; diff --git a/polkadot/node/test-service/src/lib.rs b/polkadot/node/test-service/src/lib.rs index 7fc75d9f3719c7731228eeaff7959e3de48ecf58..751373265fc33690cb2d199e5e750d2e29d38a85 100644 --- a/polkadot/node/test-service/src/lib.rs +++ b/polkadot/node/test-service/src/lib.rs @@ -26,9 +26,8 @@ use futures::future::Future; use grandpa::FinalityProofProvider as GrandpaFinalityProofProvider; use log::info; use polkadot_network::{legacy::gossip::Known, protocol as network_protocol}; -use polkadot_primitives::{ - parachain::{self, CollatorId}, - Block, BlockId, Hash, +use polkadot_primitives::v0::{ + Block, BlockId, Hash, CollatorId, Id as ParaId, }; use polkadot_runtime_common::{parachains, registrar, BlockHashCount}; use polkadot_service::{ @@ -68,7 +67,7 @@ native_executor_instance!( /// Create a new Polkadot test service for a full node. pub fn polkadot_test_new_full( config: Configuration, - collating_for: Option<(CollatorId, parachain::Id)>, + collating_for: Option<(CollatorId, ParaId)>, max_block_data_size: Option<u64>, authority_discovery_enabled: bool, slot_duration: u64, @@ -287,7 +286,7 @@ where let extrinsic = polkadot_test_runtime::UncheckedExtrinsic::new_signed( function.clone(), polkadot_test_runtime::Address::Id(caller.public().into()), - polkadot_primitives::Signature::Sr25519(signature.clone()), + polkadot_primitives::v0::Signature::Sr25519(signature.clone()), extra.clone(), ); diff --git a/polkadot/parachain/test-parachains/adder/collator/src/main.rs b/polkadot/parachain/test-parachains/adder/collator/src/main.rs index 42c3c824004a730ea41171a0660e18a787f2d837..ec5b626883c1296c44d1ee27c526db656218575b 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/main.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/main.rs @@ -22,9 +22,9 @@ use std::sync::Arc; use adder::{HeadData as AdderHead, BlockData as AdderBody}; use sp_core::Pair; use codec::{Encode, Decode}; -use primitives::{ +use primitives::v0::{ Hash, DownwardMessage, - parachain::{HeadData, BlockData, Id as ParaId, LocalValidationData, GlobalValidationSchedule}, + HeadData, BlockData, Id as ParaId, LocalValidationData, GlobalValidationSchedule, }; use collator::{ParachainContext, Network, BuildParachainContext, Cli, SubstrateCli}; use parking_lot::Mutex; diff --git a/polkadot/primitives/src/inclusion_inherent.rs b/polkadot/primitives/src/inclusion_inherent.rs deleted file mode 100644 index ca3f5ec23a16c9d6d9daedbdb76a136a77ea3061..0000000000000000000000000000000000000000 --- a/polkadot/primitives/src/inclusion_inherent.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. - -//! Inclusion Inherent primitives define types and constants which can be imported -//! without needing to import the entire inherent module. - -use inherents::InherentIdentifier; - -/// Unique identifier for the Inclusion Inherent -pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"inclusn0"; diff --git a/polkadot/primitives/src/lib.rs b/polkadot/primitives/src/lib.rs index 6f0a0986c933c698c3097ca522ea5025f2994dbd..82a5e7ca2e03988dd94d5d50616e7bfd31e11739 100644 --- a/polkadot/primitives/src/lib.rs +++ b/polkadot/primitives/src/lib.rs @@ -20,58 +20,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify, IdentifyAccount}; -pub use polkadot_core_primitives::*; - -pub mod inclusion_inherent; -pub mod parachain; - -pub use parity_scale_codec::Compact; - -/// Custom validity errors used in Polkadot while validating transactions. -#[repr(u8)] -pub enum ValidityError { - /// The Ethereum signature is invalid. - InvalidEthereumSignature = 0, - /// The signer has no claim. - SignerHasNoClaim = 1, - /// No permission to execute the call. - NoPermission = 2, - /// An invalid statement was made for a claim. - InvalidStatement = 3, -} - -impl From<ValidityError> for u8 { - fn from(err: ValidityError) -> Self { - err as u8 - } -} - -/// App-specific crypto used for reporting equivocation/misbehavior in BABE, -/// GRANDPA and Parachains, described in the white paper as the fisherman role. -/// Any rewards for misbehavior reporting will be paid out to this account. -pub mod fisherman { - use super::{Signature, Verify}; - use primitives::crypto::KeyTypeId; - - /// Key type for the reporting module. Used for reporting BABE, GRANDPA - /// and Parachain equivocations. - pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"fish"); - - mod app { - use application_crypto::{app_crypto, sr25519}; - app_crypto!(sr25519, super::KEY_TYPE); - } - - /// Identity of the equivocation/misbehavior reporter. - pub type FishermanId = app::Public; - - /// An `AppCrypto` type to allow submitting signed transactions using the fisherman - /// application key as signer. - pub struct FishermanAppCrypto; - impl frame_system::offchain::AppCrypto<<Signature as Verify>::Signer, Signature> for FishermanAppCrypto { - type RuntimeAppPublic = FishermanId; - type GenericSignature = primitives::sr25519::Signature; - type GenericPublic = primitives::sr25519::Public; - } -} +pub mod v0; +pub mod v1; diff --git a/polkadot/primitives/src/parachain.rs b/polkadot/primitives/src/v0.rs similarity index 83% rename from polkadot/primitives/src/parachain.rs rename to polkadot/primitives/src/v0.rs index 19937798c64647d44b7e5df1f1e3c35dc5c94c7f..e1ec3a55463c6d18503abf998e6f5f72382d4f8e 100644 --- a/polkadot/primitives/src/parachain.rs +++ b/polkadot/primitives/src/v0.rs @@ -21,18 +21,20 @@ use sp_std::prelude::*; use sp_std::cmp::Ordering; use parity_scale_codec::{Encode, Decode}; use bitvec::vec::BitVec; -use super::{Hash, Balance, BlockNumber}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; #[cfg(feature = "std")] -use primitives::{bytes, crypto::Pair}; +use primitives::crypto::Pair; use primitives::RuntimeDebug; use runtime_primitives::traits::{AppVerify, Block as BlockT}; use inherents::InherentIdentifier; use application_crypto::KeyTypeId; -use polkadot_core_primitives::DownwardMessage; + +pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify, IdentifyAccount}; +pub use polkadot_core_primitives::*; +pub use parity_scale_codec::Compact; pub use polkadot_parachain::primitives::{ Id, ParachainDispatchOrigin, LOWEST_USER_ID, UpwardMessage, HeadData, BlockData, @@ -171,100 +173,6 @@ pub struct DutyRoster { pub validator_duty: Vec<Chain>, } -/// The unique (during session) index of a core. -#[derive(Encode, Decode, Default, PartialOrd, Ord, Eq, PartialEq, Clone, Copy)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct CoreIndex(pub u32); - -impl From<u32> for CoreIndex { - fn from(i: u32) -> CoreIndex { - CoreIndex(i) - } -} - -/// The unique (during session) index of a validator group. -#[derive(Encode, Decode, Default, Clone, Copy)] -#[cfg_attr(feature = "std", derive(Eq, Hash, PartialEq, Debug))] -pub struct GroupIndex(pub u32); - -impl From<u32> for GroupIndex { - fn from(i: u32) -> GroupIndex { - GroupIndex(i) - } -} - -/// A claim on authoring the next block for a given parathread. -#[derive(Clone, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(PartialEq, Debug))] -pub struct ParathreadClaim(pub Id, pub CollatorId); - -/// An entry tracking a claim to ensure it does not pass the maximum number of retries. -#[derive(Clone, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(PartialEq, Debug))] -pub struct ParathreadEntry { - /// The claim. - pub claim: ParathreadClaim, - /// Number of retries. - pub retries: u32, -} - -/// What is occupying a specific availability core. -#[derive(Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(PartialEq, Debug))] -pub enum CoreOccupied { - /// A parathread. - Parathread(ParathreadEntry), - /// A parachain. - Parachain, -} - -/// The assignment type. -#[derive(Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(PartialEq, Debug))] -pub enum AssignmentKind { - /// A parachain. - Parachain, - /// A parathread. - Parathread(CollatorId, u32), -} - -/// How a free core is scheduled to be assigned. -#[derive(Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(PartialEq, Debug))] -pub struct CoreAssignment { - /// The core that is assigned. - pub core: CoreIndex, - /// The unique ID of the para that is assigned to the core. - pub para_id: Id, - /// The kind of the assignment. - pub kind: AssignmentKind, - /// The index of the validator group assigned to the core. - pub group_idx: GroupIndex, -} - -impl CoreAssignment { - /// Get the ID of a collator who is required to collate this block. - pub fn required_collator(&self) -> Option<&CollatorId> { - match self.kind { - AssignmentKind::Parachain => None, - AssignmentKind::Parathread(ref id, _) => Some(id), - } - } - - /// Get the `CoreOccupied` from this. - pub fn to_core_occupied(&self) -> CoreOccupied { - match self.kind { - AssignmentKind::Parachain => CoreOccupied::Parachain, - AssignmentKind::Parathread(ref collator, retries) => CoreOccupied::Parathread( - ParathreadEntry { - claim: ParathreadClaim(self.para_id, collator.clone()), - retries, - } - ), - } - } -} - /// Extra data that is needed along with the other fields in a `CandidateReceipt` /// to fully validate the candidate. /// @@ -505,7 +413,6 @@ impl<H: AsRef<[u8]> + Encode> AbridgedCandidateReceipt<H> { /// the relay-chain block in which context it should be executed, which implies /// any blockchain state that must be referenced. pub fn hash(&self) -> Hash { - use runtime_primitives::traits::{BlakeTwo256, Hash}; BlakeTwo256::hash_of(self) } } @@ -687,7 +594,6 @@ impl PoVBlock { /// Compute hash of block data. #[cfg(feature = "std")] pub fn hash(&self) -> Hash { - use runtime_primitives::traits::{BlakeTwo256, Hash}; BlakeTwo256::hash_of(&self) } } @@ -716,16 +622,6 @@ pub struct ErasureChunk { pub proof: Vec<Vec<u8>>, } -/// Parachain header raw bytes wrapper type. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub struct Header(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>); - -/// Activity bit field. -#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub struct Activity(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>); - /// Statements that can be made about parachain candidates. These are the /// actual values that are signed. #[derive(Clone, PartialEq, Eq, Encode, Decode, Hash)] @@ -854,87 +750,6 @@ impl FeeSchedule { } } -/// A bitfield concerning availability of backed candidates. -#[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct AvailabilityBitfield(pub BitVec<bitvec::order::Lsb0, u8>); - -impl From<BitVec<bitvec::order::Lsb0, u8>> for AvailabilityBitfield { - fn from(inner: BitVec<bitvec::order::Lsb0, u8>) -> Self { - AvailabilityBitfield(inner) - } -} - -/// A bitfield signed by a particular validator about the availability of pending candidates. -pub type SignedAvailabilityBitfield = Signed<AvailabilityBitfield>; - -/// A set of signed availability bitfields. Should be sorted by validator index, ascending. -pub type SignedAvailabilityBitfields = Vec<SignedAvailabilityBitfield>; - -/// A backed (or backable, depending on context) candidate. -// TODO: yes, this is roughly the same as AttestedCandidate. -// After https://github.com/paritytech/polkadot/issues/1250 -// they should be unified to this type. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct BackedCandidate<H = Hash> { - /// The candidate referred to. - pub candidate: AbridgedCandidateReceipt<H>, - /// The validity votes themselves, expressed as signatures. - pub validity_votes: Vec<ValidityAttestation>, - /// The indices of the validators within the group, expressed as a bitfield. - pub validator_indices: BitVec<bitvec::order::Lsb0, u8>, -} - -/// Verify the backing of the given candidate. -/// -/// Provide a lookup from the index of a validator within the group assigned to this para, -/// as opposed to the index of the validator within the overall validator set, as well as -/// the number of validators in the group. -/// -/// Also provide the signing context. -/// -/// Returns either an error, indicating that one of the signatures was invalid or that the index -/// was out-of-bounds, or the number of signatures checked. -pub fn check_candidate_backing<H: AsRef<[u8]> + Encode>( - backed: &BackedCandidate<H>, - signing_context: &SigningContext<H>, - group_len: usize, - validator_lookup: impl Fn(usize) -> Option<ValidatorId>, -) -> Result<usize, ()> { - if backed.validator_indices.len() != group_len { - return Err(()) - } - - if backed.validity_votes.len() > group_len { - return Err(()) - } - - // this is known, even in runtime, to be blake2-256. - let hash: Hash = backed.candidate.hash(); - - let mut signed = 0; - for ((val_in_group_idx, _), attestation) in backed.validator_indices.iter().enumerate() - .filter(|(_, signed)| **signed) - .zip(backed.validity_votes.iter()) - { - let validator_id = validator_lookup(val_in_group_idx).ok_or(())?; - let payload = attestation.signed_payload(hash.clone(), signing_context); - let sig = attestation.signature(); - - if sig.verify(&payload[..], &validator_id) { - signed += 1; - } else { - return Err(()) - } - } - - if signed != backed.validity_votes.len() { - return Err(()) - } - - Ok(signed) -} - sp_api::decl_runtime_apis! { /// The API for querying the state of parachains on-chain. #[api_version(3)] @@ -1098,6 +913,55 @@ impl<Payload: EncodeAs<RealPayload>, RealPayload: Encode> Signed<Payload, RealPa } } +/// Custom validity errors used in Polkadot while validating transactions. +#[repr(u8)] +pub enum ValidityError { + /// The Ethereum signature is invalid. + InvalidEthereumSignature = 0, + /// The signer has no claim. + SignerHasNoClaim = 1, + /// No permission to execute the call. + NoPermission = 2, + /// An invalid statement was made for a claim. + InvalidStatement = 3, +} + +impl From<ValidityError> for u8 { + fn from(err: ValidityError) -> Self { + err as u8 + } +} + +/// App-specific crypto used for reporting equivocation/misbehavior in BABE, +/// GRANDPA and Parachains, described in the white paper as the fisherman role. +/// Any rewards for misbehavior reporting will be paid out to this account. +pub mod fisherman { + use super::{Signature, Verify}; + use primitives::crypto::KeyTypeId; + + /// Key type for the reporting module. Used for reporting BABE, GRANDPA + /// and Parachain equivocations. + pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"fish"); + + mod app { + use application_crypto::{app_crypto, sr25519}; + app_crypto!(sr25519, super::KEY_TYPE); + } + + /// Identity of the equivocation/misbehavior reporter. + pub type FishermanId = app::Public; + + /// An `AppCrypto` type to allow submitting signed transactions using the fisherman + /// application key as signer. + pub struct FishermanAppCrypto; + impl frame_system::offchain::AppCrypto<<Signature as Verify>::Signer, Signature> for FishermanAppCrypto { + type RuntimeAppPublic = FishermanId; + type GenericSignature = primitives::sr25519::Signature; + type GenericPublic = primitives::sr25519::Public; + } +} + + #[cfg(test)] mod tests { use super::*; diff --git a/polkadot/primitives/src/v1.rs b/polkadot/primitives/src/v1.rs new file mode 100644 index 0000000000000000000000000000000000000000..9fb3d1662ec772526191d12beb4af89619447ba8 --- /dev/null +++ b/polkadot/primitives/src/v1.rs @@ -0,0 +1,478 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. + +//! V1 Primitives. + +use sp_std::prelude::*; +use parity_scale_codec::{Encode, Decode}; +use bitvec::vec::BitVec; + +use primitives::RuntimeDebug; +use runtime_primitives::traits::AppVerify; +use inherents::InherentIdentifier; + +use runtime_primitives::traits::{BlakeTwo256, Hash as HashT}; + +// Export some core primitives. +pub use polkadot_core_primitives::v1::{ + BlockNumber, Moment, Signature, AccountPublic, AccountId, AccountIndex, + ChainId, Hash, Nonce, Balance, Header, Block, BlockId, UncheckedExtrinsic, + Remark, DownwardMessage, +}; + +// Export some polkadot-parachain primitives +pub use polkadot_parachain::primitives::{ + Id, ParachainDispatchOrigin, LOWEST_USER_ID, UpwardMessage, HeadData, BlockData, + ValidationCode, +}; + +// Export some basic parachain primitives from v0. +pub use crate::v0::{ + CollatorId, CollatorSignature, PARACHAIN_KEY_TYPE_ID, ValidatorId, ValidatorIndex, + ValidatorSignature, SigningContext, Signed, ValidityAttestation, + CompactStatement, SignedStatement, ErasureChunk, EncodeAs, +}; + +// More exports from v0 for std. +#[cfg(feature = "std")] +pub use crate::v0::{ValidatorPair, CollatorPair}; + +/// Unique identifier for the Inclusion Inherent +pub const INCLUSION_INHERENT_IDENTIFIER: InherentIdentifier = *b"inclusn0"; + +/// Get a collator signature payload on a relay-parent, block-data combo. +pub fn collator_signature_payload<H: AsRef<[u8]>>( + relay_parent: &H, + para_id: &Id, + pov_hash: &Hash, +) -> [u8; 68] { + // 32-byte hash length is protected in a test below. + let mut payload = [0u8; 68]; + + 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 +} + +fn check_collator_signature<H: AsRef<[u8]>>( + relay_parent: &H, + para_id: &Id, + pov_hash: &Hash, + collator: &CollatorId, + signature: &CollatorSignature, +) -> Result<(),()> { + let payload = collator_signature_payload(relay_parent, para_id, pov_hash); + if signature.verify(&payload[..], collator) { + Ok(()) + } else { + Err(()) + } +} + +/// A unique descriptor of the candidate receipt. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Default))] +pub struct CandidateDescriptor<H = Hash> { + /// The ID of the para this is a candidate for. + pub para_id: Id, + /// The hash of the relay-chain block this is executed in the context of. + pub relay_parent: H, + /// The 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 pov. + pub pov_hash: Hash, +} + +impl<H: AsRef<[u8]>> CandidateDescriptor<H> { + /// Check the signature of the collator within this descriptor. + pub fn check_collator_signature(&self) -> Result<(), ()> { + check_collator_signature( + &self.relay_parent, + &self.para_id, + &self.pov_hash, + &self.collator, + &self.signature, + ) + } +} + +/// A candidate-receipt. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Default))] +pub struct CandidateReceipt<H = Hash> { + /// The descriptor of the candidate. + pub descriptor: CandidateDescriptor<H>, + /// The hash of the encoded commitments made as a result of candidate execution. + pub commitments_hash: Hash, +} + +impl<H> CandidateReceipt<H> { + /// Get a reference to the candidate descriptor. + pub fn descriptor(&self) -> &CandidateDescriptor<H> { + &self.descriptor + } + + /// Computes the blake2-256 hash of the receipt. + pub fn hash(&self) -> Hash where H: Encode { + BlakeTwo256::hash_of(self) + } +} + +/// All data pertaining to the execution of a para candidate. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Default))] +pub struct FullCandidateReceipt<H = Hash> { + /// The inner candidate receipt. + pub inner: CandidateReceipt<H>, + /// The global validation schedule. + pub global_validation: GlobalValidationSchedule, + /// The local validation data. + pub local_validation: LocalValidationData, +} + +/// A candidate-receipt with commitments directly included. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Default))] +pub struct CommittedCandidateReceipt<H = Hash> { + /// The descriptor of the candidate. + pub descriptor: CandidateDescriptor<H>, + /// The commitments of the candidate receipt. + pub commitments: CandidateCommitments, +} + +impl<H> CommittedCandidateReceipt<H> { + /// Get a reference to the candidate descriptor. + pub fn descriptor(&self) -> &CandidateDescriptor<H> { + &self.descriptor + } +} + +impl<H: Clone> CommittedCandidateReceipt<H> { + /// Transforms this into a plain CandidateReceipt. + pub fn to_plain(&self) -> CandidateReceipt<H> { + CandidateReceipt { + descriptor: self.descriptor.clone(), + commitments_hash: self.commitments.hash(), + } + } + + /// Computes the hash of the committed candidate receipt. + /// + /// This computes the canonical hash, not the hash of the directly encoded data. + /// Thus this is a shortcut for `candidate.to_plain().hash()`. + pub fn hash(&self) -> Hash where H: Encode { + self.to_plain().hash() + } +} + +impl PartialOrd for CommittedCandidateReceipt { + fn partial_cmp(&self, other: &Self) -> Option<sp_std::cmp::Ordering> { + Some(self.cmp(other)) + } +} + +impl Ord for CommittedCandidateReceipt { + fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { + // TODO: compare signatures or something more sane + // https://github.com/paritytech/polkadot/issues/222 + self.descriptor().para_id.cmp(&other.descriptor().para_id) + .then_with(|| self.commitments.head_data.cmp(&other.commitments.head_data)) + } +} + +/// Extra data that is needed along with the other fields in a `CandidateReceipt` +/// to fully validate the candidate. These fields are parachain-specific. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug, Default))] +pub struct LocalValidationData { + /// The parent head-data. + pub parent_head: HeadData, + /// 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 + /// 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<BlockNumber>, +} + +/// 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 GlobalValidationSchedule { + /// 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: BlockNumber, +} + +/// 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))] +pub struct CandidateCommitments { + /// Fees paid from the chain to the relay chain validators. + pub fees: Balance, + /// Messages destined to be interpreted by the Relay chain itself. + pub upward_messages: Vec<UpwardMessage>, + /// The root of a block's erasure encoding Merkle tree. + pub erasure_root: Hash, + /// New validation code. + pub new_validation_code: Option<ValidationCode>, + /// The head-data produced as a result of execution. + pub head_data: HeadData, +} + +impl CandidateCommitments { + /// Compute the blake2-256 hash of the commitments. + pub fn hash(&self) -> Hash { + BlakeTwo256::hash_of(self) + } +} + +/// A Proof-of-Validity +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct PoV { + /// The block witness data. + pub block_data: BlockData, +} + +impl PoV { + /// Get the blake2-256 hash of the PoV. + #[cfg(feature = "std")] + pub fn hash(&self) -> Hash { + BlakeTwo256::hash_of(self) + } +} + +/// A bitfield concerning availability of backed candidates. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct AvailabilityBitfield(pub BitVec<bitvec::order::Lsb0, u8>); + +impl From<BitVec<bitvec::order::Lsb0, u8>> for AvailabilityBitfield { + fn from(inner: BitVec<bitvec::order::Lsb0, u8>) -> Self { + AvailabilityBitfield(inner) + } +} + +/// A bitfield signed by a particular validator about the availability of pending candidates. +pub type SignedAvailabilityBitfield = Signed<AvailabilityBitfield>; + +/// A set of signed availability bitfields. Should be sorted by validator index, ascending. +pub type SignedAvailabilityBitfields = Vec<SignedAvailabilityBitfield>; + +/// A backed (or backable, depending on context) candidate. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct BackedCandidate<H = Hash> { + /// The candidate referred to. + pub candidate: CommittedCandidateReceipt<H>, + /// The validity votes themselves, expressed as signatures. + pub validity_votes: Vec<ValidityAttestation>, + /// The indices of the validators within the group, expressed as a bitfield. + pub validator_indices: BitVec<bitvec::order::Lsb0, u8>, +} + +impl<H> BackedCandidate<H> { + /// Get a reference to the descriptor of the para. + pub fn descriptor(&self) -> &CandidateDescriptor<H> { + &self.candidate.descriptor + } +} + +/// Verify the backing of the given candidate. +/// +/// Provide a lookup from the index of a validator within the group assigned to this para, +/// as opposed to the index of the validator within the overall validator set, as well as +/// the number of validators in the group. +/// +/// Also provide the signing context. +/// +/// Returns either an error, indicating that one of the signatures was invalid or that the index +/// was out-of-bounds, or the number of signatures checked. +pub fn check_candidate_backing<H: AsRef<[u8]> + Clone + Encode>( + backed: &BackedCandidate<H>, + signing_context: &SigningContext<H>, + group_len: usize, + validator_lookup: impl Fn(usize) -> Option<ValidatorId>, +) -> Result<usize, ()> { + if backed.validator_indices.len() != group_len { + return Err(()) + } + + if backed.validity_votes.len() > group_len { + return Err(()) + } + + // this is known, even in runtime, to be blake2-256. + let hash: Hash = backed.candidate.hash(); + + let mut signed = 0; + for ((val_in_group_idx, _), attestation) in backed.validator_indices.iter().enumerate() + .filter(|(_, signed)| **signed) + .zip(backed.validity_votes.iter()) + { + let validator_id = validator_lookup(val_in_group_idx).ok_or(())?; + let payload = attestation.signed_payload(hash.clone(), signing_context); + let sig = attestation.signature(); + + if sig.verify(&payload[..], &validator_id) { + signed += 1; + } else { + return Err(()) + } + } + + if signed != backed.validity_votes.len() { + return Err(()) + } + + Ok(signed) +} + +/// The unique (during session) index of a core. +#[derive(Encode, Decode, Default, PartialOrd, Ord, Eq, PartialEq, Clone, Copy)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct CoreIndex(pub u32); + +impl From<u32> for CoreIndex { + fn from(i: u32) -> CoreIndex { + CoreIndex(i) + } +} + +/// The unique (during session) index of a validator group. +#[derive(Encode, Decode, Default, Clone, Copy)] +#[cfg_attr(feature = "std", derive(Eq, Hash, PartialEq, Debug))] +pub struct GroupIndex(pub u32); + +impl From<u32> for GroupIndex { + fn from(i: u32) -> GroupIndex { + GroupIndex(i) + } +} + +/// A claim on authoring the next block for a given parathread. +#[derive(Clone, Encode, Decode, Default)] +#[cfg_attr(feature = "std", derive(PartialEq, Debug))] +pub struct ParathreadClaim(pub Id, pub CollatorId); + +/// An entry tracking a claim to ensure it does not pass the maximum number of retries. +#[derive(Clone, Encode, Decode, Default)] +#[cfg_attr(feature = "std", derive(PartialEq, Debug))] +pub struct ParathreadEntry { + /// The claim. + pub claim: ParathreadClaim, + /// Number of retries. + pub retries: u32, +} + +/// What is occupying a specific availability core. +#[derive(Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(PartialEq, Debug))] +pub enum CoreOccupied { + /// A parathread. + Parathread(ParathreadEntry), + /// A parachain. + Parachain, +} + +/// The assignment type. +#[derive(Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(PartialEq, Debug))] +pub enum AssignmentKind { + /// A parachain. + Parachain, + /// A parathread. + Parathread(CollatorId, u32), +} + +/// How a free core is scheduled to be assigned. +#[derive(Clone, Encode, Decode)] +#[cfg_attr(feature = "std", derive(PartialEq, Debug))] +pub struct CoreAssignment { + /// The core that is assigned. + pub core: CoreIndex, + /// The unique ID of the para that is assigned to the core. + pub para_id: Id, + /// The kind of the assignment. + pub kind: AssignmentKind, + /// The index of the validator group assigned to the core. + pub group_idx: GroupIndex, +} + +impl CoreAssignment { + /// Get the ID of a collator who is required to collate this block. + pub fn required_collator(&self) -> Option<&CollatorId> { + match self.kind { + AssignmentKind::Parachain => None, + AssignmentKind::Parathread(ref id, _) => Some(id), + } + } + + /// Get the `CoreOccupied` from this. + pub fn to_core_occupied(&self) -> CoreOccupied { + match self.kind { + AssignmentKind::Parachain => CoreOccupied::Parachain, + AssignmentKind::Parathread(ref collator, retries) => CoreOccupied::Parathread( + ParathreadEntry { + claim: ParathreadClaim(self.para_id, collator.clone()), + retries, + } + ), + } + } +} + +/// 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))] +pub struct OmittedValidationData { + /// The global validation schedule. + pub global_validation: GlobalValidationSchedule, + /// 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, +} diff --git a/polkadot/roadmap/implementers-guide/src/types/availability.md b/polkadot/roadmap/implementers-guide/src/types/availability.md index 3362908d6b63f659a09c0885bacafc6c32b59aa1..be42c7a9278a0e9016150155741453137eeed073 100644 --- a/polkadot/roadmap/implementers-guide/src/types/availability.md +++ b/polkadot/roadmap/implementers-guide/src/types/availability.md @@ -9,7 +9,7 @@ A bitfield [signed](backing.md#signed-wrapper) by a particular validator about t ```rust -pub type SignedAvailabilityBitfield = Signed<Bitvec>; +type SignedAvailabilityBitfield = Signed<Bitvec>; struct Bitfields(Vec<(SignedAvailabilityBitfield)>), // bitfields sorted by validator index, ascending ``` @@ -21,3 +21,50 @@ Often referred to as PoV, this is a type-safe wrapper around bytes (`Vec<u8>`) w ```rust struct PoV(Vec<u8>); ``` + +## Omitted Validation Data + +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) + +```rust +struct OmittedValidationData { + /// The global validation schedule. + global_validation: GlobalValidationSchedule, + /// The local validation data. + local_validation: LocalValidationData, +} +``` + + +## Available Data + +This is the data we want to keep available for each [candidate](candidate.md) included in the relay chain. + +```rust +struct AvailableData { + /// The Proof-of-Validation of the candidate. + pov: PoV, + /// The omitted validation data. + omitted_validation: OmittedValidationData, +} +``` + +> TODO: With XCMP, we also need to keep available the outgoing messages as a result of para-validation. + +## Erasure Chunk + +The [`AvailableData`](#availabledata) is split up into an erasure-coding as part of the availability process. Each validator gets a chunk. This describes one of those chunks, along with its proof against a merkle root hash, which should be apparent from context, and is the `erasure_root` field of a [`CandidateDescriptor`](candidate.md#candidatedescriptor). + + +```rust +struct ErasureChunk { + /// The erasure-encoded chunk of data belonging to the candidate block. + chunk: Vec<u8>, + /// The index of this erasure-encoded chunk of data. + index: u32, + /// Proof for this chunk's branch in the Merkle tree. + proof: Vec<Vec<u8>>, +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/candidate.md b/polkadot/roadmap/implementers-guide/src/types/candidate.md index fdba6919e57ce340df8eab39be92798a376fd1ef..0ed38590a733cc31f830e9e22d84610c4895215f 100644 --- a/polkadot/roadmap/implementers-guide/src/types/candidate.md +++ b/polkadot/roadmap/implementers-guide/src/types/candidate.md @@ -1,6 +1,7 @@ # Candidate Types Para candidates are some of the most common types, both within the runtime and on the Node-side. +Candidates are the fundamental datatype for advancing parachains and parathreads, encapsulating the collator's signature, the context of the parablock, the commitments to the output, and a commitment to the data which proves it valid. In a way, this entire guide is about these candidates: how they are scheduled, constructed, backed, included, and challenged. @@ -179,3 +180,24 @@ struct SigningContext { session_index: SessionIndex, } ``` + +## Validation Outputs + +This struct encapsulates the outputs of candidate validation. + +```rust +struct ValidationOutputs { + /// The head-data produced by validation. + head_data: HeadData, + /// The global validation schedule. + global_validation_schedule: GlobalValidationSchedule, + /// The local validation data. + local_validation_data: LocalValidationData, + /// Upwards messages to the relay chain. + upwards_messages: Vec<UpwardsMessage>, + /// Fees paid to the validators of the relay-chain. + fees: Balance, + /// The new validation code submitted by the execution, if any. + new_validation_code: Option<ValidationCode>, +} +``` diff --git a/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md b/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md index 1e59eedff8db0970ae9762bfc3aa9a25e8b10a77..b822508f4a3ea9dc934cc49af0e67dc773697e54 100644 --- a/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md +++ b/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md @@ -91,6 +91,7 @@ enum CandidateBackingMessage { GetBackedCandidates(Hash, ResponseChannel<Vec<NewBackedCandidate>>), /// Note that the Candidate Backing subsystem should second the given candidate in the context of the /// given relay-parent (ref. by hash). This candidate must be validated using the provided PoV. + /// The PoV is expected to match the `pov_hash` in the descriptor. Second(Hash, CandidateReceipt, PoV), /// Note a peer validator's statement about a particular candidate. Disagreements about validity must be escalated /// to a broader check by Misbehavior Arbitration. Agreements are simply tallied until a quorum is reached. @@ -282,29 +283,41 @@ enum StatementDistributionMessage { ## Validation Request Type -Various modules request that the [Candidate Validation subsystem](../node/utility/candidate-validation.md) validate a block with this message +Various modules request that the [Candidate Validation subsystem](../node/utility/candidate-validation.md) validate a block with this message. It returns [`ValidationOutputs`](candidate.md#validationoutputs) for successful validation. ```rust /// Result of the validation of the candidate. enum ValidationResult { - /// Candidate is valid. - Valid, + /// Candidate is valid, and here are the outputs. In practice, this should be a shared type + /// so that validation caching can be done. + Valid(ValidationOutputs), /// Candidate is invalid. Invalid, } +/// Messages issued to the candidate validation subsystem. +/// +/// ## Validation Requests +/// +/// Validation requests made to the subsystem should return an error only on internal error. +/// Otherwise, they should return either `Ok(ValidationResult::Valid(_))` or `Ok(ValidationResult::Invalid)`. enum CandidateValidationMessage { - /// Validate a candidate with provided parameters. Returns `Err` if an only if an internal - /// error is encountered. - /// In case no internal error was encontered it returns a tuple containing the result of - /// validation and `GlobalValidationSchedule` and `LocalValidationData` structures that - /// may be used by the caller to make the candidate available. - /// A bad candidate will return `Ok((ValidationResult::Invalid, _, _)`, while a good one will - /// return `Ok((ValidationResult::Valid, _, _))`. - Validate( - Hash, CandidateReceipt, HeadData, PoV, ResponseChannel< - Result<(ValidationResult, GlobalValidationSchedule, LocalValidationData)> - >), + /// Validate a candidate with provided parameters. This will implicitly attempt to gather the + /// `OmittedValidationData` and `ValidationCode` from the runtime API of the chain, + /// based on the `relay_parent` of the `CandidateDescriptor`. + /// If there is no state available which can provide this data, an error is returned. + ValidateFromChainState(CandidateDescriptor, PoV, ResponseChannel<Result<ValidationResult>>), + + /// Validate a candidate with provided parameters. Explicitly provide the `OmittedValidationData` + /// and `ValidationCode` so this can do full validation without needing to access the state of + /// the relay-chain. + ValidateFromExhaustive( + OmittedValidationData, + ValidationCode, + CandidateDescriptor, + PoV, + ResponseChannel<Result<ValidationResult>>, + ), } ``` diff --git a/polkadot/rpc/src/lib.rs b/polkadot/rpc/src/lib.rs index 6bddc8ad8dafeccb39f4d8248aa21c06224d3959..c73b478329ee6a5e0e17e499c1355b79a78b7fec 100644 --- a/polkadot/rpc/src/lib.rs +++ b/polkadot/rpc/src/lib.rs @@ -20,7 +20,7 @@ use std::sync::Arc; -use polkadot_primitives::{Block, BlockNumber, AccountId, Nonce, Balance, Hash}; +use polkadot_primitives::v0::{Block, BlockNumber, AccountId, Nonce, Balance, Hash}; use sp_api::ProvideRuntimeApi; use txpool_api::TransactionPool; use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as BlockChainError}; diff --git a/polkadot/runtime/common/src/attestations.rs b/polkadot/runtime/common/src/attestations.rs index f27874117aaad1b898b6614fd787c3ff067a4f5b..e7a6854bbb132258baaae5d87c38cc4fd25e3921 100644 --- a/polkadot/runtime/common/src/attestations.rs +++ b/polkadot/runtime/common/src/attestations.rs @@ -28,7 +28,7 @@ use frame_support::{ weights::DispatchClass, }; -use primitives::{Hash, parachain::{AttestedCandidate, AbridgedCandidateReceipt, Id as ParaId}}; +use primitives::v0::{Hash, AttestedCandidate, AbridgedCandidateReceipt, Id as ParaId}; use sp_runtime::RuntimeDebug; use sp_staking::SessionIndex; diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index fd8c1c1c880a06eb00983fb898b79ea631aff005..6efc3d31d75de4831436a68c521570395660ae87 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -35,7 +35,7 @@ use sp_runtime::{ TransactionSource, TransactionValidityError, }, }; -use primitives::ValidityError; +use primitives::v0::ValidityError; type CurrencyOf<T> = <<T as Trait>::VestingSchedule as VestingSchedule<<T as system::Trait>::AccountId>>::Currency; type BalanceOf<T> = <CurrencyOf<T> as Currency<<T as system::Trait>::AccountId>>::Balance; diff --git a/polkadot/runtime/common/src/crowdfund.rs b/polkadot/runtime/common/src/crowdfund.rs index ee2b740745b7d5c80a54b3c2a0d8e0caf0dc70e9..fc233d107abe147e688c17f43c29e17e67ae62f6 100644 --- a/polkadot/runtime/common/src/crowdfund.rs +++ b/polkadot/runtime/common/src/crowdfund.rs @@ -79,7 +79,7 @@ use sp_runtime::{ModuleId, use crate::slots; use codec::{Encode, Decode}; use sp_std::vec::Vec; -use primitives::parachain::{Id as ParaId, HeadData}; +use primitives::v0::{Id as ParaId, HeadData}; pub type BalanceOf<T> = <<T as slots::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance; @@ -568,7 +568,7 @@ mod tests { }; use frame_support::traits::{Contains, ContainsLengthBound}; use sp_core::H256; - use primitives::parachain::{Info as ParaInfo, Id as ParaId, Scheduling, ValidationCode}; + use primitives::v0::{Info as ParaInfo, Id as ParaId, Scheduling, ValidationCode}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. use sp_runtime::{ diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 543e2c739adb1cc1bf340f67b2e3170c88b740c6..7e3b6d917f776998b171338aac4ac6bc99dfa244 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -26,8 +26,8 @@ pub struct ToAuthor<R>(sp_std::marker::PhantomData<R>); impl<R> OnUnbalanced<NegativeImbalance<R>> for ToAuthor<R> where R: balances::Trait + authorship::Trait, - <R as system::Trait>::AccountId: From<primitives::AccountId>, - <R as system::Trait>::AccountId: Into<primitives::AccountId>, + <R as system::Trait>::AccountId: From<primitives::v0::AccountId>, + <R as system::Trait>::AccountId: Into<primitives::v0::AccountId>, <R as system::Trait>::Event: From<balances::RawEvent< <R as system::Trait>::AccountId, <R as balances::Trait>::Balance, diff --git a/polkadot/runtime/common/src/lib.rs b/polkadot/runtime/common/src/lib.rs index da6fc5fcc27bd27005700f5c11c5926ab1497a1c..d32db38e05be96f23f3a33ffdcfb5cb86581b5ef 100644 --- a/polkadot/runtime/common/src/lib.rs +++ b/polkadot/runtime/common/src/lib.rs @@ -27,7 +27,7 @@ pub mod slots; pub mod crowdfund; pub mod impls; -use primitives::BlockNumber; +use primitives::v0::BlockNumber; use sp_runtime::{Perquintill, Perbill, FixedPointNumber, traits::Saturating}; use frame_support::{ parameter_types, traits::{Currency}, diff --git a/polkadot/runtime/common/src/parachains.rs b/polkadot/runtime/common/src/parachains.rs index 25d93b6fde78e99e36b4c461bc9feb6eabcc667b..b0228a5a53c8b426793d2018cbc96349ad649940 100644 --- a/polkadot/runtime/common/src/parachains.rs +++ b/polkadot/runtime/common/src/parachains.rs @@ -37,16 +37,13 @@ use frame_support::{ dispatch::IsSubType, weights::{DispatchClass, Weight}, }; -use primitives::{ - Balance, - BlockNumber, - parachain::{ - Id as ParaId, Chain, DutyRoster, AttestedCandidate, CompactStatement as Statement, ParachainDispatchOrigin, - UpwardMessage, ValidatorId, ActiveParas, CollatorId, Retriable, OmittedValidationData, - CandidateReceipt, GlobalValidationSchedule, AbridgedCandidateReceipt, - LocalValidationData, Scheduling, ValidityAttestation, NEW_HEADS_IDENTIFIER, PARACHAIN_KEY_TYPE_ID, - ValidatorSignature, SigningContext, HeadData, ValidationCode, - }, +use primitives::v0::{ + Balance, BlockNumber, + Id as ParaId, Chain, DutyRoster, AttestedCandidate, CompactStatement as Statement, ParachainDispatchOrigin, + UpwardMessage, ValidatorId, ActiveParas, CollatorId, Retriable, OmittedValidationData, + CandidateReceipt, GlobalValidationSchedule, AbridgedCandidateReceipt, + LocalValidationData, Scheduling, ValidityAttestation, NEW_HEADS_IDENTIFIER, PARACHAIN_KEY_TYPE_ID, + ValidatorSignature, SigningContext, HeadData, ValidationCode, Remark, DownwardMessage }; use frame_support::{ @@ -329,7 +326,7 @@ pub trait Trait: CreateSignedTransaction<Call<Self>> + attestations::Trait + ses >; /// A type that converts the opaque hash type to exact one. - type BlockHashConversion: Convert<Self::Hash, primitives::Hash>; + type BlockHashConversion: Convert<Self::Hash, primitives::v0::Hash>; } /// Origin for the parachains module. @@ -1681,13 +1678,10 @@ mod tests { }, testing::TestXt, }; - use primitives::{ - parachain::{ - CandidateReceipt, ValidityAttestation, ValidatorId, Info as ParaInfo, - Scheduling, CandidateCommitments, - }, - BlockNumber, - Header, + use primitives::v0::{ + CandidateReceipt, ValidityAttestation, ValidatorId, Info as ParaInfo, + Scheduling, CandidateCommitments, + BlockNumber, Header, }; use keyring::Sr25519Keyring; use frame_support::{ @@ -1819,7 +1813,7 @@ mod tests { } mod time { - use primitives::{Moment, BlockNumber}; + use primitives::v0::{Moment, BlockNumber}; pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 1 * HOURS; // These time units are defined in number of blocks. @@ -2246,7 +2240,7 @@ mod tests { println!("session index {}", i); Staking::on_finalize(System::block_number()); System::set_block_number((i + 1).into()); - Timestamp::set_timestamp(System::block_number() as primitives::Moment * 6000); + Timestamp::set_timestamp(System::block_number() as primitives::v0::Moment * 6000); // In order to be able to use `System::parent_hash()` in the tests // we need to first get it via `System::finalize` and then set it diff --git a/polkadot/runtime/common/src/registrar.rs b/polkadot/runtime/common/src/registrar.rs index de152d9379b530924f0fbeceb60cf1340abfeecf..d7b9cb40caf9c7a1edee3f58d498a1b965b3d6f8 100644 --- a/polkadot/runtime/common/src/registrar.rs +++ b/polkadot/runtime/common/src/registrar.rs @@ -34,7 +34,7 @@ use frame_support::{ weights::{DispatchClass, Weight}, }; use system::{self, ensure_root, ensure_signed}; -use primitives::parachain::{ +use primitives::v0::{ Id as ParaId, CollatorId, Scheduling, LOWEST_USER_ID, SwapAux, Info as ParaInfo, ActiveParas, Retriable, ValidationCode, HeadData, }; @@ -213,7 +213,7 @@ fn build<T: Trait>(config: &GenesisConfig<T>) { Parachains::put(&only_ids); for (id, code, genesis) in p { - Paras::insert(id, &primitives::parachain::PARACHAIN_INFO); + Paras::insert(id, &primitives::v0::PARACHAIN_INFO); // no ingress -- a chain cannot be routed to until it is live. <parachains::Code>::insert(&id, &code); <parachains::Heads>::insert(&id, &genesis); @@ -670,12 +670,10 @@ mod tests { AccountIdConversion, Extrinsic as ExtrinsicT, }, testing::{UintAuthorityId, TestXt}, KeyTypeId, Perbill, curve::PiecewiseLinear, }; - use primitives::{ - parachain::{ - ValidatorId, Info as ParaInfo, Scheduling, LOWEST_USER_ID, AttestedCandidate, - CandidateReceipt, HeadData, ValidityAttestation, CompactStatement as Statement, Chain, - CollatorPair, CandidateCommitments, - }, + use primitives::v0::{ + ValidatorId, Info as ParaInfo, Scheduling, LOWEST_USER_ID, AttestedCandidate, + CandidateReceipt, HeadData, ValidityAttestation, CompactStatement as Statement, Chain, + CollatorPair, CandidateCommitments, Balance, BlockNumber, Header, Signature, }; use frame_support::{ @@ -869,7 +867,7 @@ mod tests { // This is needed for a custom `AccountId` type which is `u64` in testing here. pub mod test_keys { use sp_core::{crypto::KeyTypeId, sr25519}; - use primitives::Signature; + use primitives::v0::Signature; pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"test"); diff --git a/polkadot/runtime/common/src/slots.rs b/polkadot/runtime/common/src/slots.rs index 5618a680c5a0ab06982d8b653e8a4d7525a60fec..eb0a7aff7d72e80bb05b162df1bbb81a31d589cf 100644 --- a/polkadot/runtime/common/src/slots.rs +++ b/polkadot/runtime/common/src/slots.rs @@ -28,7 +28,7 @@ use frame_support::{ traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get, Randomness}, weights::{DispatchClass, Weight}, }; -use primitives::parachain::{ +use primitives::v0::{ SwapAux, PARACHAIN_INFO, Id as ParaId, ValidationCode, HeadData, }; use system::{ensure_signed, ensure_root}; @@ -890,8 +890,7 @@ mod tests { traits::{OnInitialize, OnFinalize} }; use balances; - use primitives::{BlockNumber, Header}; - use primitives::parachain::{Id as ParaId, Info as ParaInfo, Scheduling}; + use primitives::v0::{BlockNumber, Header, Id as ParaId, Info as ParaInfo, Scheduling}; impl_outer_origin! { pub enum Origin for Test {} diff --git a/polkadot/runtime/kusama/src/constants.rs b/polkadot/runtime/kusama/src/constants.rs index e06325d1bb95eca4ecbbfd6736fc161a2e603601..560d83347d9bf85accbc9c364986fa930feef7be 100644 --- a/polkadot/runtime/kusama/src/constants.rs +++ b/polkadot/runtime/kusama/src/constants.rs @@ -16,7 +16,7 @@ /// Money matters. pub mod currency { - use primitives::Balance; + use primitives::v0::Balance; pub const DOTS: Balance = 1_000_000_000_000; pub const DOLLARS: Balance = DOTS / 6; @@ -30,7 +30,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::{Moment, BlockNumber}; + use primitives::v0::{Moment, BlockNumber}; // Kusama & mainnet pub const MILLISECS_PER_BLOCK: Moment = 6000; // Testnet @@ -55,7 +55,7 @@ pub mod time { /// Fee-related. pub mod fee { pub use sp_runtime::Perbill; - use primitives::Balance; + use primitives::v0::Balance; use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs index ee25e8961decc88f231617029365afeb84011d8d..569d055ccafe8d1795b7818cdfdc416da84f1611 100644 --- a/polkadot/runtime/kusama/src/lib.rs +++ b/polkadot/runtime/kusama/src/lib.rs @@ -23,9 +23,10 @@ use sp_std::prelude::*; use sp_core::u32_trait::{_1, _2, _3, _4, _5}; use codec::{Encode, Decode}; -use primitives::{ +use primitives::v0::{ + self as parachain, AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, - parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, + ActiveParas, AbridgedCandidateReceipt, SigningContext, }; use runtime_common::{ attestations, claims, parachains, registrar, slots, SlowAdjustingFeeUpdate, @@ -560,7 +561,7 @@ impl grandpa::Trait for Runtime { type HandleEquivocation = grandpa::EquivocationHandler< Self::KeyOwnerIdentification, - primitives::fisherman::FishermanAppCrypto, + primitives::v0::fisherman::FishermanAppCrypto, Runtime, Offences, >; @@ -596,7 +597,7 @@ parameter_types! { } impl parachains::Trait for Runtime { - type AuthorityId = primitives::fisherman::FishermanAppCrypto; + type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto; type Origin = Origin; type Call = Call; type ParachainCurrency = Balances; @@ -939,7 +940,7 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade { construct_runtime! { pub enum Runtime where Block = Block, - NodeBlock = primitives::Block, + NodeBlock = primitives::v0::Block, UncheckedExtrinsic = UncheckedExtrinsic { // Basic stuff; balances is uncallable initially. @@ -1147,7 +1148,7 @@ sp_api::impl_runtime_apis! { fn signing_context() -> SigningContext { Parachains::signing_context() } - fn downward_messages(id: parachain::Id) -> Vec<primitives::DownwardMessage> { + fn downward_messages(id: parachain::Id) -> Vec<primitives::v0::DownwardMessage> { Parachains::downward_messages(id) } } diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs index 792dfe89a7b2d0ea85140e67e63b969de7f0ca36..40688041b265de8d1f24456e16606c2e499b44a2 100644 --- a/polkadot/runtime/parachains/src/configuration.rs +++ b/polkadot/runtime/parachains/src/configuration.rs @@ -19,9 +19,7 @@ //! Configuration can change only at session boundaries and is buffered until then. use sp_std::prelude::*; -use primitives::{ - parachain::{ValidatorId}, -}; +use primitives::v1::ValidatorId; use frame_support::{ decl_storage, decl_module, decl_error, dispatch::DispatchResult, diff --git a/polkadot/runtime/parachains/src/inclusion.rs b/polkadot/runtime/parachains/src/inclusion.rs index 33a5e2d1e919483ad8ef0eb728410195aa3c8dd9..a2480f1c80345dff98d9f189d76de73dbe1fa33e 100644 --- a/polkadot/runtime/parachains/src/inclusion.rs +++ b/polkadot/runtime/parachains/src/inclusion.rs @@ -21,12 +21,10 @@ //! to included. use sp_std::prelude::*; -use primitives::{ - parachain::{ - ValidatorId, AbridgedCandidateReceipt, ValidatorIndex, Id as ParaId, - AvailabilityBitfield as AvailabilityBitfield, SignedAvailabilityBitfields, SigningContext, - BackedCandidate, CoreIndex, GroupIndex, CoreAssignment, - }, +use primitives::v1::{ + ValidatorId, CommittedCandidateReceipt, ValidatorIndex, Id as ParaId, + AvailabilityBitfield as AvailabilityBitfield, SignedAvailabilityBitfields, SigningContext, + BackedCandidate, CoreIndex, GroupIndex, CoreAssignment, }; use frame_support::{ decl_storage, decl_module, decl_error, ensure, dispatch::DispatchResult, IterableStorageMap, @@ -53,13 +51,15 @@ pub struct AvailabilityBitfieldRecord<N> { } /// A backed candidate pending availability. +// TODO: split this type and change this to hold a plain `CandidateReceipt`. +// https://github.com/paritytech/polkadot/issues/1357 #[derive(Encode, Decode, PartialEq)] #[cfg_attr(test, derive(Debug))] pub struct CandidatePendingAvailability<H, N> { /// The availability core this is assigned to. core: CoreIndex, /// The candidate receipt itself. - receipt: AbridgedCandidateReceipt<H>, + receipt: CommittedCandidateReceipt<H>, /// The received availability votes. One bit per validator. availability_votes: BitVec<BitOrderLsb0, u8>, /// The block number of the relay-parent of the receipt. @@ -213,7 +213,10 @@ impl<T: Trait> Module<T> { let validator_public = &validators[signed_bitfield.validator_index() as usize]; - signed_bitfield.check_signature(&signing_context, validator_public).map_err(|_| Error::<T>::InvalidBitfieldSignature)?; + signed_bitfield.check_signature( + &signing_context, + validator_public, + ).map_err(|_| Error::<T>::InvalidBitfieldSignature)?; last_index = Some(signed_bitfield.validator_index()); } @@ -331,11 +334,11 @@ impl<T: Trait> Module<T> { // list. 'a: for candidate in &candidates { - let para_id = candidate.candidate.parachain_index; + let para_id = candidate.descriptor().para_id; // we require that the candidate is in the context of the parent block. ensure!( - candidate.candidate.relay_parent == parent_hash, + candidate.descriptor().relay_parent == parent_hash, Error::<T>::CandidateNotInParentContext, ); @@ -348,17 +351,17 @@ impl<T: Trait> Module<T> { ensure!(code_upgrade_allowed, Error::<T>::PrematureCodeUpgrade); ensure!( - candidate.candidate.check_signature().is_ok(), + candidate.descriptor().check_collator_signature().is_ok(), Error::<T>::NotCollatorSigned, ); for (i, assignment) in scheduled[skip..].iter().enumerate() { check_assignment_in_order(assignment)?; - if candidate.candidate.parachain_index == assignment.para_id { + if candidate.descriptor().para_id == assignment.para_id { if let Some(required_collator) = assignment.required_collator() { ensure!( - required_collator == &candidate.candidate.collator, + required_collator == &candidate.descriptor().collator, Error::<T>::WrongCollator, ); } @@ -377,7 +380,7 @@ impl<T: Trait> Module<T> { // check the signatures in the backing and that it is a majority. { let maybe_amount_validated - = primitives::parachain::check_candidate_backing( + = primitives::v1::check_candidate_backing( &candidate, &signing_context, group_vals.len(), @@ -419,7 +422,7 @@ impl<T: Trait> Module<T> { // one more sweep for actually writing to storage. for (candidate, core) in candidates.into_iter().zip(core_indices.iter().cloned()) { - let para_id = candidate.candidate.parachain_index; + let para_id = candidate.descriptor().para_id; // initialize all availability votes to 0. let availability_votes: BitVec<BitOrderLsb0, u8> @@ -438,7 +441,7 @@ impl<T: Trait> Module<T> { fn enact_candidate( relay_parent_number: T::BlockNumber, - receipt: AbridgedCandidateReceipt<T::Hash>, + receipt: CommittedCandidateReceipt<T::Hash>, ) -> Weight { let commitments = receipt.commitments; let config = <configuration::Module<T>>::config(); @@ -447,15 +450,15 @@ impl<T: Trait> Module<T> { let mut weight = T::DbWeight::get().reads_writes(1, 0); if let Some(new_code) = commitments.new_validation_code { weight += <paras::Module<T>>::schedule_code_upgrade( - receipt.parachain_index, + receipt.descriptor.para_id, new_code, relay_parent_number + config.validation_upgrade_delay, ); } weight + <paras::Module<T>>::note_new_head( - receipt.parachain_index, - receipt.head_data, + receipt.descriptor.para_id, + commitments.head_data, relay_parent_number, ) } @@ -495,10 +498,11 @@ const fn availability_threshold(n_validators: usize) -> usize { mod tests { use super::*; - use primitives::{BlockNumber, Hash}; - use primitives::parachain::{ + use primitives::v1::{BlockNumber, Hash}; + use primitives::v1::{ SignedAvailabilityBitfield, CompactStatement as Statement, ValidityAttestation, CollatorId, - CandidateCommitments, SignedStatement, AssignmentKind, + CandidateCommitments, SignedStatement, CandidateDescriptor, HeadData, ValidationCode, + AssignmentKind, }; use frame_support::traits::{OnFinalize, OnInitialize}; use keyring::Sr25519Keyring; @@ -545,22 +549,22 @@ mod tests { fn collator_sign_candidate( collator: Sr25519Keyring, - candidate: &mut AbridgedCandidateReceipt, + candidate: &mut CommittedCandidateReceipt, ) { - candidate.collator = collator.public().into(); + candidate.descriptor.collator = collator.public().into(); - let payload = primitives::parachain::collator_signature_payload( - &candidate.relay_parent, - &candidate.parachain_index, - &candidate.pov_block_hash, + let payload = primitives::v1::collator_signature_payload( + &candidate.descriptor.relay_parent, + &candidate.descriptor.para_id, + &candidate.descriptor.pov_hash, ); - candidate.signature = collator.sign(&payload[..]).into(); - assert!(candidate.check_signature().is_ok()); + candidate.descriptor.signature = collator.sign(&payload[..]).into(); + assert!(candidate.descriptor().check_collator_signature().is_ok()); } fn back_candidate( - candidate: AbridgedCandidateReceipt, + candidate: CommittedCandidateReceipt, validators: &[Sr25519Keyring], group: &[ValidatorIndex], signing_context: &SigningContext, @@ -603,7 +607,7 @@ mod tests { BackingKind::Lacking => false, }; - let successfully_backed = primitives::parachain::check_candidate_backing( + let successfully_backed = primitives::v1::check_candidate_backing( &backed, signing_context, group.len(), @@ -674,6 +678,33 @@ mod tests { ) } + #[derive(Default)] + struct TestCandidateBuilder { + para_id: ParaId, + head_data: HeadData, + pov_hash: Hash, + relay_parent: Hash, + new_validation_code: Option<ValidationCode>, + } + + impl TestCandidateBuilder { + fn build(self) -> CommittedCandidateReceipt { + CommittedCandidateReceipt { + descriptor: CandidateDescriptor { + para_id: self.para_id, + pov_hash: self.pov_hash, + relay_parent: self.relay_parent, + ..Default::default() + }, + commitments: CandidateCommitments { + head_data: self.head_data, + new_validation_code: self.new_validation_code, + ..Default::default() + }, + } + } + } + #[test] fn collect_pending_cleans_up_pending() { let chain_a = ParaId::from(1); @@ -895,11 +926,11 @@ mod tests { <PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability { core: CoreIndex::from(0), - receipt: AbridgedCandidateReceipt { - parachain_index: chain_a, + receipt: TestCandidateBuilder { + para_id: chain_a, head_data: vec![1, 2, 3, 4].into(), ..Default::default() - }, + }.build(), availability_votes: default_availability_votes(), relay_parent_number: 0, backed_in_number: 0, @@ -907,11 +938,11 @@ mod tests { <PendingAvailability<Test>>::insert(chain_b, CandidatePendingAvailability { core: CoreIndex::from(1), - receipt: AbridgedCandidateReceipt { - parachain_index: chain_b, + receipt: TestCandidateBuilder { + para_id: chain_b, head_data: vec![5, 6, 7, 8].into(), ..Default::default() - }, + }.build(), availability_votes: default_availability_votes(), relay_parent_number: 0, backed_in_number: 0, @@ -1043,12 +1074,12 @@ mod tests { // unscheduled candidate. { - let mut candidate = AbridgedCandidateReceipt { - parachain_index: chain_a, + let mut candidate = TestCandidateBuilder { + para_id: chain_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([1; 32]), + pov_hash: Hash::from([1; 32]), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::One, &mut candidate, @@ -1071,18 +1102,18 @@ mod tests { // candidates out of order. { - let mut candidate_a = AbridgedCandidateReceipt { - parachain_index: chain_a, + let mut candidate_a = TestCandidateBuilder { + para_id: chain_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([1; 32]), + pov_hash: Hash::from([1; 32]), ..Default::default() - }; - let mut candidate_b = AbridgedCandidateReceipt { - parachain_index: chain_b, + }.build(); + let mut candidate_b = TestCandidateBuilder { + para_id: chain_b, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([2; 32]), + pov_hash: Hash::from([2; 32]), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::One, @@ -1119,12 +1150,12 @@ mod tests { // candidate not backed. { - let mut candidate = AbridgedCandidateReceipt { - parachain_index: chain_a, + let mut candidate = TestCandidateBuilder { + para_id: chain_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([1; 32]), + pov_hash: Hash::from([1; 32]), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::One, &mut candidate, @@ -1150,12 +1181,12 @@ mod tests { let wrong_parent_hash = Hash::from([222; 32]); assert!(System::parent_hash() != wrong_parent_hash); - let mut candidate = AbridgedCandidateReceipt { - parachain_index: chain_a, + let mut candidate = TestCandidateBuilder { + para_id: chain_a, relay_parent: wrong_parent_hash, - pov_block_hash: Hash::from([1; 32]), + pov_hash: Hash::from([1; 32]), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::One, &mut candidate, @@ -1178,12 +1209,12 @@ mod tests { // candidate has wrong collator. { - let mut candidate = AbridgedCandidateReceipt { - parachain_index: thread_a, + let mut candidate = TestCandidateBuilder { + para_id: thread_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([1; 32]), + pov_hash: Hash::from([1; 32]), ..Default::default() - }; + }.build(); assert!(CollatorId::from(Sr25519Keyring::One.public()) != thread_collator); collator_sign_candidate( @@ -1212,12 +1243,12 @@ mod tests { // candidate not well-signed by collator. { - let mut candidate = AbridgedCandidateReceipt { - parachain_index: thread_a, + let mut candidate = TestCandidateBuilder { + para_id: thread_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([1; 32]), + pov_hash: Hash::from([1; 32]), ..Default::default() - }; + }.build(); assert_eq!(CollatorId::from(Sr25519Keyring::Two.public()), thread_collator); collator_sign_candidate( @@ -1225,7 +1256,8 @@ mod tests { &mut candidate, ); - candidate.pov_block_hash = Hash::from([2; 32]); + // change the candidate after signing. + candidate.descriptor.pov_hash = Hash::from([2; 32]); let backed = back_candidate( candidate, @@ -1244,12 +1276,12 @@ mod tests { // para occupied - reject. { - let mut candidate = AbridgedCandidateReceipt { - parachain_index: chain_a, + let mut candidate = TestCandidateBuilder { + para_id: chain_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([1; 32]), + pov_hash: Hash::from([1; 32]), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::One, @@ -1283,16 +1315,13 @@ mod tests { // interfering code upgrade - reject { - let mut candidate = AbridgedCandidateReceipt { - parachain_index: chain_a, + let mut candidate = TestCandidateBuilder { + para_id: chain_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([1; 32]), - commitments: CandidateCommitments { - new_validation_code: Some(vec![5, 6, 7, 8].into()), - ..Default::default() - }, + pov_hash: Hash::from([1; 32]), + new_validation_code: Some(vec![5, 6, 7, 8].into()), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::One, @@ -1381,34 +1410,34 @@ mod tests { group_idx: GroupIndex::from(2), }; - let mut candidate_a = AbridgedCandidateReceipt { - parachain_index: chain_a, + let mut candidate_a = TestCandidateBuilder { + para_id: chain_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([1; 32]), + pov_hash: Hash::from([1; 32]), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::One, &mut candidate_a, ); - let mut candidate_b = AbridgedCandidateReceipt { - parachain_index: chain_b, + let mut candidate_b = TestCandidateBuilder { + para_id: chain_b, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([2; 32]), + pov_hash: Hash::from([2; 32]), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::One, &mut candidate_b, ); - let mut candidate_c = AbridgedCandidateReceipt { - parachain_index: thread_a, + let mut candidate_c = TestCandidateBuilder { + para_id: thread_a, relay_parent: System::parent_hash(), - pov_block_hash: Hash::from([3; 32]), + pov_hash: Hash::from([3; 32]), ..Default::default() - }; + }.build(); collator_sign_candidate( Sr25519Keyring::Two, &mut candidate_c, diff --git a/polkadot/runtime/parachains/src/inclusion_inherent.rs b/polkadot/runtime/parachains/src/inclusion_inherent.rs index 282b6f3b8a21b6dd898fcd49e75b51cf7f442c1d..6d06961b461a16dfdc8c73cc893d66e1abac8c7c 100644 --- a/polkadot/runtime/parachains/src/inclusion_inherent.rs +++ b/polkadot/runtime/parachains/src/inclusion_inherent.rs @@ -22,9 +22,8 @@ //! this module. use sp_std::prelude::*; -use primitives::{ - inclusion_inherent, - parachain::{BackedCandidate, SignedAvailabilityBitfields}, +use primitives::v1::{ + BackedCandidate, SignedAvailabilityBitfields, INCLUSION_INHERENT_IDENTIFIER, }; use frame_support::{ decl_error, decl_module, decl_storage, ensure, @@ -127,7 +126,7 @@ decl_module! { impl<T: Trait> ProvideInherent for Module<T> { type Call = Call<T>; type Error = MakeFatalError<()>; - const INHERENT_IDENTIFIER: InherentIdentifier = inclusion_inherent::INHERENT_IDENTIFIER; + const INHERENT_IDENTIFIER: InherentIdentifier = INCLUSION_INHERENT_IDENTIFIER; fn create_inherent(data: &InherentData) -> Option<Self::Call> { data.get_data(&Self::INHERENT_IDENTIFIER) diff --git a/polkadot/runtime/parachains/src/initializer.rs b/polkadot/runtime/parachains/src/initializer.rs index 9c0cda29697a5c401a12e923aaf0334fe6bf6e41..0c4f83cccea10db2c8436146f4199168f6364a4d 100644 --- a/polkadot/runtime/parachains/src/initializer.rs +++ b/polkadot/runtime/parachains/src/initializer.rs @@ -21,9 +21,7 @@ use sp_std::prelude::*; use frame_support::weights::Weight; -use primitives::{ - parachain::{ValidatorId}, -}; +use primitives::v1::ValidatorId; use frame_support::{ decl_storage, decl_module, decl_error, traits::Randomness, }; diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index 9cc9f2329b8f1e28240236b1739f4e349860a172..8eb45359da4870be25a58ccba94f77911c637d19 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -24,10 +24,7 @@ use sp_runtime::{ BlakeTwo256, IdentityLookup, }, }; -use primitives::{ - BlockNumber, - Header, -}; +use primitives::v1::{BlockNumber, Header}; use frame_support::{ impl_outer_origin, impl_outer_dispatch, parameter_types, weights::Weight, traits::Randomness as RandomnessT, diff --git a/polkadot/runtime/parachains/src/paras.rs b/polkadot/runtime/parachains/src/paras.rs index 8c095751b3f6766a673ce43a99359fd662ec602d..0117089f11063b3c7650e664c3f36663b11413ad 100644 --- a/polkadot/runtime/parachains/src/paras.rs +++ b/polkadot/runtime/parachains/src/paras.rs @@ -26,8 +26,8 @@ use sp_std::prelude::*; use sp_std::marker::PhantomData; use sp_runtime::traits::One; -use primitives::{ - parachain::{Id as ParaId, ValidationCode, HeadData}, +use primitives::v1::{ + Id as ParaId, ValidationCode, HeadData, }; use frame_support::{ decl_storage, decl_module, decl_error, @@ -541,7 +541,7 @@ impl<T: Trait> Module<T> { #[cfg(test)] mod tests { use super::*; - use primitives::BlockNumber; + use primitives::v1::BlockNumber; use frame_support::traits::{OnFinalize, OnInitialize}; use crate::mock::{new_test_ext, Paras, System, GenesisConfig as MockGenesisConfig}; diff --git a/polkadot/runtime/parachains/src/scheduler.rs b/polkadot/runtime/parachains/src/scheduler.rs index 772ab25cf4fd8793a725dfdb31a95805e043d8c1..9cc2bd72bd810c4463be1b3c49ee15141c8b3e91 100644 --- a/polkadot/runtime/parachains/src/scheduler.rs +++ b/polkadot/runtime/parachains/src/scheduler.rs @@ -37,11 +37,9 @@ use sp_std::prelude::*; use sp_std::convert::TryInto; -use primitives::{ - parachain::{ - Id as ParaId, ValidatorIndex, CoreAssignment, CoreOccupied, CoreIndex, AssignmentKind, - GroupIndex, ParathreadClaim, ParathreadEntry, - }, +use primitives::v1::{ + Id as ParaId, ValidatorIndex, CoreAssignment, CoreOccupied, CoreIndex, AssignmentKind, + GroupIndex, ParathreadClaim, ParathreadEntry, }; use frame_support::{ decl_storage, decl_module, decl_error, @@ -586,7 +584,7 @@ impl<T: Trait> Module<T> { mod tests { use super::*; - use primitives::{BlockNumber, parachain::{CollatorId, ValidatorId}}; + use primitives::v1::{BlockNumber, ValidatorId, CollatorId}; use frame_support::traits::{OnFinalize, OnInitialize}; use keyring::Sr25519Keyring; diff --git a/polkadot/runtime/polkadot/src/constants.rs b/polkadot/runtime/polkadot/src/constants.rs index 331d97f364cf52ac7597c571d5f7e93ba661c0c1..8ad5478bcab89af3638439ace72aebc7b1b5695f 100644 --- a/polkadot/runtime/polkadot/src/constants.rs +++ b/polkadot/runtime/polkadot/src/constants.rs @@ -16,7 +16,7 @@ /// Money matters. pub mod currency { - use primitives::Balance; + use primitives::v0::Balance; pub const DOTS: Balance = 1_000_000_000_000; pub const DOLLARS: Balance = DOTS / 100; // 10_000_000_000 @@ -30,7 +30,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::{Moment, BlockNumber}; + use primitives::v0::{Moment, BlockNumber}; pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 4 * HOURS; @@ -47,7 +47,7 @@ pub mod time { /// Fee-related. pub mod fee { pub use sp_runtime::Perbill; - use primitives::Balance; + use primitives::v0::Balance; use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs index abd9687164c23e74de0f5e71bbe9c57627155e8f..258a7b4781b4ce8abc50223b8921464372265fc3 100644 --- a/polkadot/runtime/polkadot/src/lib.rs +++ b/polkadot/runtime/polkadot/src/lib.rs @@ -31,9 +31,10 @@ use runtime_common::{ use sp_std::prelude::*; use sp_core::u32_trait::{_1, _2, _3, _4, _5}; use codec::{Encode, Decode}; -use primitives::{ +use primitives::v0::{ + self as parachain, AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, - parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, + ActiveParas, AbridgedCandidateReceipt, SigningContext, }; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, ModuleId, @@ -629,7 +630,7 @@ impl grandpa::Trait for Runtime { type HandleEquivocation = grandpa::EquivocationHandler< Self::KeyOwnerIdentification, - primitives::fisherman::FishermanAppCrypto, + primitives::v0::fisherman::FishermanAppCrypto, Runtime, Offences, >; @@ -666,7 +667,7 @@ parameter_types! { } impl parachains::Trait for Runtime { - type AuthorityId = primitives::fisherman::FishermanAppCrypto; + type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto; type Origin = Origin; type Call = Call; type ParachainCurrency = Balances; @@ -943,7 +944,7 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade { construct_runtime! { pub enum Runtime where Block = Block, - NodeBlock = primitives::Block, + NodeBlock = primitives::v0::Block, UncheckedExtrinsic = UncheckedExtrinsic { // Basic stuff; balances is uncallable initially. @@ -1147,7 +1148,7 @@ sp_api::impl_runtime_apis! { fn signing_context() -> SigningContext { Parachains::signing_context() } - fn downward_messages(id: parachain::Id) -> Vec<primitives::DownwardMessage> { + fn downward_messages(id: parachain::Id) -> Vec<primitives::v0::DownwardMessage> { Parachains::downward_messages(id) } } diff --git a/polkadot/runtime/polkadot/tests/weights.rs b/polkadot/runtime/polkadot/tests/weights.rs index 533783a4e4917b9a92a40c6c5550b528c299e78f..3cdb71995801dd57f64ba87707471110c013d05d 100644 --- a/polkadot/runtime/polkadot/tests/weights.rs +++ b/polkadot/runtime/polkadot/tests/weights.rs @@ -29,7 +29,7 @@ use frame_support::{ use keyring::AccountKeyring; use polkadot_runtime::constants::currency::*; use polkadot_runtime::{self, Runtime}; -use primitives::AccountId; +use primitives::v0::AccountId; use runtime_common::MaximumBlockWeight; use democracy::Call as DemocracyCall; diff --git a/polkadot/runtime/test-runtime/client/src/lib.rs b/polkadot/runtime/test-runtime/client/src/lib.rs index 2554f4f1c8249aaca5627ce88cf9cd6b205250de..58282d32b46b2104eae1b866795dacc9bd7cc158 100644 --- a/polkadot/runtime/test-runtime/client/src/lib.rs +++ b/polkadot/runtime/test-runtime/client/src/lib.rs @@ -326,7 +326,7 @@ pub fn new_native_executor() -> sc_executor::NativeExecutor<LocalExecutor> { /// The index of the block must be provided to calculate a valid timestamp for the block. The value starts at 0 and /// should be incremented by one for every block produced. pub fn needed_extrinsics( - heads: Vec<polkadot_primitives::parachain::AttestedCandidate>, + heads: Vec<polkadot_primitives::v0::AttestedCandidate>, i: u64, ) -> Vec<polkadot_test_runtime::UncheckedExtrinsic> { use polkadot_runtime_common::parachains; diff --git a/polkadot/runtime/test-runtime/src/constants.rs b/polkadot/runtime/test-runtime/src/constants.rs index b0431e55f26820379765bdad0a89efebf431cf42..ac90417b214c5a987eb18a87faeee39e205e302a 100644 --- a/polkadot/runtime/test-runtime/src/constants.rs +++ b/polkadot/runtime/test-runtime/src/constants.rs @@ -16,7 +16,7 @@ /// Money matters. pub mod currency { - use primitives::Balance; + use primitives::v0::Balance; pub const DOTS: Balance = 1_000_000_000_000; pub const DOLLARS: Balance = DOTS; @@ -26,7 +26,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::{Moment, BlockNumber}; + use primitives::v0::{Moment, BlockNumber}; // Testnet pub const MILLISECS_PER_BLOCK: Moment = 1000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; @@ -45,7 +45,7 @@ pub mod time { /// Fee-related. pub mod fee { pub use sp_runtime::Perbill; - use primitives::Balance; + use primitives::v0::Balance; use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 57ceffa4a96f6f4ebf8e6c9053209a55181101dc..45d5a04c313fb3835a139641c0080b1d7d129679 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -22,9 +22,10 @@ use rstd::prelude::*; use codec::{Encode, Decode}; -use primitives::{ +use primitives::v0::{ + self as parachain, AccountId, AccountIndex, Balance, BlockNumber, Hash as HashT, Nonce, Signature, Moment, - parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, ValidityError, + ActiveParas, AbridgedCandidateReceipt, SigningContext, ValidityError, }; use runtime_common::{ attestations, claims, parachains, registrar, slots, SlowAdjustingFeeUpdate, @@ -375,7 +376,7 @@ parameter_types! { } impl parachains::Trait for Runtime { - type AuthorityId = primitives::fisherman::FishermanAppCrypto; + type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto; type Origin = Origin; type Call = Call; type ParachainCurrency = Balances; @@ -521,7 +522,7 @@ impl sudo::Trait for Runtime { construct_runtime! { pub enum Runtime where Block = Block, - NodeBlock = primitives::Block, + NodeBlock = primitives::v0::Block, UncheckedExtrinsic = UncheckedExtrinsic { // Basic stuff; balances is uncallable initially. @@ -702,7 +703,7 @@ sp_api::impl_runtime_apis! { fn signing_context() -> SigningContext { Parachains::signing_context() } - fn downward_messages(id: parachain::Id) -> Vec<primitives::DownwardMessage> { + fn downward_messages(id: parachain::Id) -> Vec<primitives::v0::DownwardMessage> { Parachains::downward_messages(id) } } diff --git a/polkadot/runtime/westend/src/constants.rs b/polkadot/runtime/westend/src/constants.rs index ac25d621d8561d527bf1f595566bb8da571afd91..f59a384fba8b7a75eda91ad01c90ae53dbfcebac 100644 --- a/polkadot/runtime/westend/src/constants.rs +++ b/polkadot/runtime/westend/src/constants.rs @@ -16,7 +16,7 @@ /// Money matters. pub mod currency { - use primitives::Balance; + use primitives::v0::Balance; pub const DOTS: Balance = 1_000_000_000_000; pub const DOLLARS: Balance = DOTS; @@ -30,7 +30,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::{Moment, BlockNumber}; + use primitives::v0::{Moment, BlockNumber}; pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 1 * HOURS; @@ -47,7 +47,7 @@ pub mod time { /// Fee-related. pub mod fee { pub use sp_runtime::Perbill; - use primitives::Balance; + use primitives::v0::Balance; use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 41613bbb011873069c420c7362dabf4cf2011751..a40c4e3dd5a71c32a8ed29361937996c13d53408 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -22,9 +22,10 @@ use sp_std::prelude::*; use codec::{Encode, Decode}; -use primitives::{ +use primitives::v0::{ + self as parachain, AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, - parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, + ActiveParas, AbridgedCandidateReceipt, SigningContext, }; use runtime_common::{ attestations, parachains, registrar, SlowAdjustingFeeUpdate, @@ -385,7 +386,7 @@ impl grandpa::Trait for Runtime { type HandleEquivocation = grandpa::EquivocationHandler< Self::KeyOwnerIdentification, - primitives::fisherman::FishermanAppCrypto, + primitives::v0::fisherman::FishermanAppCrypto, Runtime, Offences, >; @@ -421,7 +422,7 @@ parameter_types! { } impl parachains::Trait for Runtime { - type AuthorityId = primitives::fisherman::FishermanAppCrypto; + type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto; type Origin = Origin; type Call = Call; type ParachainCurrency = Balances; @@ -698,7 +699,7 @@ impl proxy::Trait for Runtime { construct_runtime! { pub enum Runtime where Block = Block, - NodeBlock = primitives::Block, + NodeBlock = primitives::v0::Block, UncheckedExtrinsic = UncheckedExtrinsic { // Basic stuff; balances is uncallable initially. @@ -887,7 +888,7 @@ sp_api::impl_runtime_apis! { fn signing_context() -> SigningContext { Parachains::signing_context() } - fn downward_messages(id: parachain::Id) -> Vec<primitives::DownwardMessage> { + fn downward_messages(id: parachain::Id) -> Vec<primitives::v0::DownwardMessage> { Parachains::downward_messages(id) } } diff --git a/polkadot/service/src/chain_spec.rs b/polkadot/service/src/chain_spec.rs index 5e1bfbbdbab0c24a926453b793a2d4edbec0b4ae..fe8d98d0553fe58ab4649ff7ed1e7ad46f4732bb 100644 --- a/polkadot/service/src/chain_spec.rs +++ b/polkadot/service/src/chain_spec.rs @@ -17,7 +17,7 @@ //! Polkadot chain configurations. use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; -use polkadot_primitives::{AccountId, AccountPublic, parachain::ValidatorId}; +use polkadot_primitives::v0::{AccountId, AccountPublic, ValidatorId}; use polkadot_runtime as polkadot; use kusama_runtime as kusama; use westend_runtime as westend; @@ -48,9 +48,9 @@ const DEFAULT_PROTOCOL_ID: &str = "dot"; #[serde(rename_all = "camelCase")] pub struct Extensions { /// Block numbers with known hashes. - pub fork_blocks: sc_client_api::ForkBlocks<polkadot_primitives::Block>, + pub fork_blocks: sc_client_api::ForkBlocks<polkadot_primitives::v0::Block>, /// Known bad block hashes. - pub bad_blocks: sc_client_api::BadBlocks<polkadot_primitives::Block>, + pub bad_blocks: sc_client_api::BadBlocks<polkadot_primitives::v0::Block>, } /// The `ChainSpec parametrised for polkadot runtime`. diff --git a/polkadot/service/src/grandpa_support.rs b/polkadot/service/src/grandpa_support.rs index 794b4e4fc180e8f782a200c8f0feaa4350473e65..89a0691b360d4f2d80529378d31bc50019cf3154 100644 --- a/polkadot/service/src/grandpa_support.rs +++ b/polkadot/service/src/grandpa_support.rs @@ -16,7 +16,7 @@ //! Polkadot-specific GRANDPA integration utilities. -use polkadot_primitives::Hash; +use polkadot_primitives::v0::Hash; use sp_runtime::traits::{Block as BlockT, NumberFor}; /// A custom GRANDPA voting rule that "pauses" voting (i.e. keeps voting for the @@ -98,7 +98,7 @@ impl<Block, B> grandpa::VotingRule<Block, B> for PauseAfterBlockFor<NumberFor<Bl /// #1500988). pub(crate) fn kusama_hard_forks() -> Vec<( grandpa_primitives::SetId, - (Hash, polkadot_primitives::BlockNumber), + (Hash, polkadot_primitives::v0::BlockNumber), grandpa_primitives::AuthorityList, )> { use sp_core::crypto::Ss58Codec; diff --git a/polkadot/service/src/lib.rs b/polkadot/service/src/lib.rs index eaa5f9682f0c4e03fd24ef59d4ef94b3be680f04..d0b443ea7d88c886d5761d334bfefc3ad3f20d9d 100644 --- a/polkadot/service/src/lib.rs +++ b/polkadot/service/src/lib.rs @@ -22,7 +22,7 @@ mod client; use std::sync::Arc; use std::time::Duration; -use polkadot_primitives::{parachain, Hash, BlockId, AccountId, Nonce, Balance}; +use polkadot_primitives::v0::{self as parachain, Hash, BlockId, AccountId, Nonce, Balance}; #[cfg(feature = "full-node")] use polkadot_network::{legacy::gossip::Known, protocol as network_protocol}; use service::{error::Error as ServiceError, ServiceBuilder}; @@ -42,8 +42,7 @@ pub use sc_consensus::LongestChain; pub use sp_api::{Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend}; pub use sp_runtime::traits::{HashFor, NumberFor}; pub use consensus_common::{SelectChain, BlockImport, block_validation::Chain}; -pub use polkadot_primitives::parachain::{CollatorId, ParachainHost}; -pub use polkadot_primitives::Block; +pub use polkadot_primitives::v0::{Block, CollatorId, ParachainHost}; pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256}; pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec}; #[cfg(feature = "full-node")] diff --git a/polkadot/statement-table/src/generic.rs b/polkadot/statement-table/src/generic.rs index 11c6a3c024787e56f1cc3092889d7801859163e0..cb95d74d62237f48fd38aa25d0cc8bcf3456cda8 100644 --- a/polkadot/statement-table/src/generic.rs +++ b/polkadot/statement-table/src/generic.rs @@ -28,7 +28,7 @@ use std::collections::hash_map::{HashMap, Entry}; use std::hash::Hash; use std::fmt::Debug; -use primitives::parachain::{ValidityAttestation as PrimitiveValidityAttestation, ValidatorSignature}; +use primitives::v1::{ValidityAttestation as PrimitiveValidityAttestation, ValidatorSignature}; use codec::{Encode, Decode}; diff --git a/polkadot/statement-table/src/lib.rs b/polkadot/statement-table/src/lib.rs index 97d0cda76344c9a3a14321f4753f426a5252ce25..fed60ded0da2a08a60e82d37ec80c3951e1a810b 100644 --- a/polkadot/statement-table/src/lib.rs +++ b/polkadot/statement-table/src/lib.rs @@ -16,75 +16,87 @@ pub mod generic; -pub use generic::Table; - -use primitives::parachain::{ - Id, AbridgedCandidateReceipt, CompactStatement as PrimitiveStatement, ValidatorSignature, ValidatorIndex, -}; -use primitives::Hash; - -/// Statements about candidates on the network. -pub type Statement = generic::Statement<AbridgedCandidateReceipt, Hash>; - -/// Signed statements about candidates. -pub type SignedStatement = generic::SignedStatement< - AbridgedCandidateReceipt, - Hash, - ValidatorIndex, - ValidatorSignature, ->; - -/// Kinds of misbehavior, along with proof. -pub type Misbehavior = generic::Misbehavior< - AbridgedCandidateReceipt, - Hash, - ValidatorIndex, - ValidatorSignature, ->; - -/// A summary of import of a statement. -pub type Summary = generic::Summary<Hash, Id>; - -/// Context necessary to construct a table. -pub trait Context { - /// Whether a authority is a member of a group. - /// Members are meant to submit candidates and vote on validity. - fn is_member_of(&self, authority: ValidatorIndex, group: &Id) -> bool; - - /// requisite number of votes for validity from a group. - fn requisite_votes(&self, group: &Id) -> usize; -} - -impl<C: Context> generic::Context for C { - type AuthorityId = ValidatorIndex; - type Digest = Hash; - type GroupId = Id; - type Signature = ValidatorSignature; - type Candidate = AbridgedCandidateReceipt; - - fn candidate_digest(candidate: &AbridgedCandidateReceipt) -> Hash { - candidate.hash() - } - - fn candidate_group(candidate: &AbridgedCandidateReceipt) -> Id { - candidate.parachain_index.clone() - } - - fn is_member_of(&self, authority: &Self::AuthorityId, group: &Id) -> bool { - Context::is_member_of(self, *authority, group) - } - - fn requisite_votes(&self, group: &Id) -> usize { - Context::requisite_votes(self, group) +pub use generic::{Table, Context}; + +/// Concrete instantiations suitable for v0 primitives. +pub mod v0 { + use crate::generic; + use primitives::v0::{ + Hash, + Id, AbridgedCandidateReceipt, CompactStatement as PrimitiveStatement, ValidatorSignature, ValidatorIndex, + }; + + /// Statements about candidates on the network. + pub type Statement = generic::Statement<AbridgedCandidateReceipt, Hash>; + + /// Signed statements about candidates. + pub type SignedStatement = generic::SignedStatement< + AbridgedCandidateReceipt, + Hash, + ValidatorIndex, + ValidatorSignature, + >; + + /// Kinds of misbehavior, along with proof. + pub type Misbehavior = generic::Misbehavior< + AbridgedCandidateReceipt, + Hash, + ValidatorIndex, + ValidatorSignature, + >; + + /// A summary of import of a statement. + pub type Summary = generic::Summary<Hash, Id>; + + impl<'a> From<&'a Statement> for PrimitiveStatement { + fn from(s: &'a Statement) -> PrimitiveStatement { + match *s { + generic::Statement::Valid(s) => PrimitiveStatement::Valid(s), + generic::Statement::Invalid(s) => PrimitiveStatement::Invalid(s), + generic::Statement::Candidate(ref s) => PrimitiveStatement::Candidate(s.hash()), + } + } } } -impl<'a> From<&'a Statement> for PrimitiveStatement { - fn from(s: &'a Statement) -> PrimitiveStatement { - match *s { - generic::Statement::Valid(s) => PrimitiveStatement::Valid(s), - generic::Statement::Invalid(s) => PrimitiveStatement::Invalid(s), - generic::Statement::Candidate(ref s) => PrimitiveStatement::Candidate(s.hash()), +/// Concrete instantiations suitable for v1 primitives. +pub mod v1 { + use crate::generic; + use primitives::v1::{ + Hash, + Id, CommittedCandidateReceipt, CompactStatement as PrimitiveStatement, + ValidatorSignature, ValidatorIndex, + }; + + /// Statements about candidates on the network. + pub type Statement = generic::Statement<CommittedCandidateReceipt, Hash>; + + /// Signed statements about candidates. + pub type SignedStatement = generic::SignedStatement< + CommittedCandidateReceipt, + Hash, + ValidatorIndex, + ValidatorSignature, + >; + + /// Kinds of misbehavior, along with proof. + pub type Misbehavior = generic::Misbehavior< + CommittedCandidateReceipt, + Hash, + ValidatorIndex, + ValidatorSignature, + >; + + /// A summary of import of a statement. + pub type Summary = generic::Summary<Hash, Id>; + + impl<'a> From<&'a Statement> for PrimitiveStatement { + fn from(s: &'a Statement) -> PrimitiveStatement { + match *s { + generic::Statement::Valid(s) => PrimitiveStatement::Valid(s), + generic::Statement::Invalid(s) => PrimitiveStatement::Invalid(s), + generic::Statement::Candidate(ref s) => PrimitiveStatement::Candidate(s.hash()), + } } } } diff --git a/polkadot/validation/src/block_production.rs b/polkadot/validation/src/block_production.rs index 30b7ac3ccd46b979acb9cf91a337a729b10c0334..4804ba230c96d025ef3389c66aed548aa9d3a6e7 100644 --- a/polkadot/validation/src/block_production.rs +++ b/polkadot/validation/src/block_production.rs @@ -28,8 +28,8 @@ use std::{ use sp_blockchain::HeaderBackend; use block_builder::{BlockBuilderApi, BlockBuilderProvider}; use consensus::{Proposal, RecordProof}; -use polkadot_primitives::{Block, Header}; -use polkadot_primitives::parachain::{ +use polkadot_primitives::v0::{Block, Header}; +use polkadot_primitives::v0::{ ParachainHost, NEW_HEADS_IDENTIFIER, }; use runtime_primitives::traits::{DigestFor, HashFor}; diff --git a/polkadot/validation/src/collation.rs b/polkadot/validation/src/collation.rs index a2e682a066d68e07a369bb3aa0660decde88dae3..b79b049b225f37e32a3e2304fe301611369f5e04 100644 --- a/polkadot/validation/src/collation.rs +++ b/polkadot/validation/src/collation.rs @@ -21,11 +21,9 @@ use std::sync::Arc; -use polkadot_primitives::{ +use polkadot_primitives::v0::{ BlakeTwo256, Block, Hash, HashT, - parachain::{ - CollatorId, ParachainHost, Id as ParaId, Collation, ErasureChunk, CollationInfo, - }, + CollatorId, ParachainHost, Id as ParaId, Collation, ErasureChunk, CollationInfo, }; use polkadot_erasure_coding as erasure; use sp_api::ProvideRuntimeApi; diff --git a/polkadot/validation/src/error.rs b/polkadot/validation/src/error.rs index 83b51ed23670625ff7589ee4231c8e5f2bbe843e..5fd990a0713327469277910242d7a48c9375a2a4 100644 --- a/polkadot/validation/src/error.rs +++ b/polkadot/validation/src/error.rs @@ -16,7 +16,7 @@ //! Errors that can occur during the validation process. -use polkadot_primitives::{parachain::ValidatorId, Hash}; +use polkadot_primitives::v0::{ValidatorId, Hash}; /// Error type for validation #[derive(Debug, derive_more::Display, derive_more::From)] @@ -77,7 +77,7 @@ pub enum Error { CommitmentsMismatch, /// The parachain for which validation work is being done is not active. #[display(fmt = "Parachain {:?} is not active", _0)] - InactiveParachain(polkadot_primitives::parachain::Id), + InactiveParachain(polkadot_primitives::v0::Id), /// Block data is too big #[display(fmt = "Block data is too big (maximum allowed size: {}, actual size: {})", size, max_size)] BlockDataTooBig { size: u64, max_size: u64 }, diff --git a/polkadot/validation/src/lib.rs b/polkadot/validation/src/lib.rs index 667f66e275a9d738213d37ef9de68ff135542563..a5b1c1d5c2df349f486efac583bd3f067ac8e5ce 100644 --- a/polkadot/validation/src/lib.rs +++ b/polkadot/validation/src/lib.rs @@ -34,7 +34,7 @@ use std::{ sync::Arc, }; use codec::Encode; -use polkadot_primitives::parachain::{ +use polkadot_primitives::v0::{ Id as ParaId, Chain, DutyRoster, AbridgedCandidateReceipt, CompactStatement as PrimitiveStatement, PoVBlock, ErasureChunk, ValidatorSignature, ValidatorIndex, diff --git a/polkadot/validation/src/pipeline.rs b/polkadot/validation/src/pipeline.rs index b29285716dd36ea5ac587f3143702fd35d8561da..f2a705ba101daf41aa9b59fed9c609a9b3848ed8 100644 --- a/polkadot/validation/src/pipeline.rs +++ b/polkadot/validation/src/pipeline.rs @@ -19,12 +19,12 @@ use codec::Encode; use polkadot_erasure_coding as erasure; -use polkadot_primitives::parachain::{ +use polkadot_primitives::v0::{ CollationInfo, PoVBlock, LocalValidationData, GlobalValidationSchedule, OmittedValidationData, AvailableData, FeeSchedule, CandidateCommitments, ErasureChunk, ParachainHost, Id as ParaId, AbridgedCandidateReceipt, ValidationCode, }; -use polkadot_primitives::{Block, BlockId, Balance, Hash}; +use polkadot_primitives::v0::{Block, BlockId, Balance, Hash}; use parachain::{ wasm_executor::{self, ExecutionMode}, primitives::{UpwardMessage, ValidationParams}, @@ -125,7 +125,7 @@ impl<'a> ValidatedCandidate<'a> { omitted_validation, }; - let erasure_chunks = erasure::obtain_chunks( + let erasure_chunks = erasure::obtain_chunks_v0( n_validators, &available_data, )?; diff --git a/polkadot/validation/src/shared_table/includable.rs b/polkadot/validation/src/shared_table/includable.rs index 1396f66c596724c8ba50e045816a7c55242fc2cc..317b9e0f7bfed87b36a615a9aa01598024526e7c 100644 --- a/polkadot/validation/src/shared_table/includable.rs +++ b/polkadot/validation/src/shared_table/includable.rs @@ -18,7 +18,7 @@ use std::collections::HashMap; use futures::channel::oneshot; -use polkadot_primitives::Hash; +use polkadot_primitives::v0::Hash; /// Track includability of a set of candidates, pub(super) fn track<I: IntoIterator<Item=(Hash, bool)>>(candidates: I) diff --git a/polkadot/validation/src/shared_table/mod.rs b/polkadot/validation/src/shared_table/mod.rs index fd6702a7e640c30d7028b25247963e38538ac5c9..d42c9b7e561c1a4c4d8c7732c33b58b7df0fdcad 100644 --- a/polkadot/validation/src/shared_table/mod.rs +++ b/polkadot/validation/src/shared_table/mod.rs @@ -21,11 +21,12 @@ use std::collections::hash_map::{HashMap, Entry}; use std::sync::Arc; use availability_store::{Store as AvailabilityStore}; -use table::{self, Table, Context as TableContextTrait}; -use polkadot_primitives::{Block, Hash}; -use polkadot_primitives::parachain::{ +use table::{v0 as table_v0, Table, Context as TableContextTrait}; +use polkadot_primitives::v0::{ + Block, Hash, Id as ParaId, AbridgedCandidateReceipt, ValidatorPair, ValidatorId, AttestedCandidate, ParachainHost, PoVBlock, ValidatorIndex, SigningContext, + ValidatorSignature, }; use parking_lot::Mutex; @@ -44,7 +45,7 @@ use crate::Error; mod includable; -pub use table::{SignedStatement, Statement}; +pub use table_v0::{SignedStatement, Statement}; pub use table::generic::Statement as GenericStatement; struct TableContext { @@ -54,9 +55,23 @@ struct TableContext { validators: Vec<ValidatorId>, } -impl table::Context for TableContext { - fn is_member_of(&self, authority: ValidatorIndex, group: &ParaId) -> bool { - let key = match self.validators.get(authority as usize) { +impl TableContextTrait for TableContext { + type AuthorityId = ValidatorIndex; + type Digest = Hash; + type GroupId = ParaId; + type Signature = ValidatorSignature; + type Candidate = AbridgedCandidateReceipt; + + fn candidate_digest(candidate: &AbridgedCandidateReceipt) -> Hash { + candidate.hash() + } + + fn candidate_group(candidate: &AbridgedCandidateReceipt) -> ParaId { + candidate.parachain_index + } + + fn is_member_of(&self, authority: &ValidatorIndex, group: &ParaId) -> bool { + let key = match self.validators.get(*authority as usize) { Some(val) => val, None => return false, }; @@ -84,7 +99,7 @@ impl TableContext { ) } - fn sign_statement(&self, statement: table::Statement) -> Option<table::SignedStatement> { + fn sign_statement(&self, statement: table_v0::Statement) -> Option<table_v0::SignedStatement> { self.local_index().and_then(move |sender| self.key.as_ref() .map(|key| crate::sign_table_statement( @@ -93,7 +108,7 @@ impl TableContext { &self.signing_context, ).into() ) - .map(move |signature| table::SignedStatement { statement, signature, sender }) + .map(move |signature| table_v0::SignedStatement { statement, signature, sender }) ) } } @@ -145,7 +160,7 @@ impl SharedTableInner { &mut self, context: &TableContext, fetch_pov_block: impl Fn(&AbridgedCandidateReceipt) -> Fetch, - statement: table::SignedStatement, + statement: table_v0::SignedStatement, max_block_data_size: Option<u64>, ) -> Option<ParachainWork< Fetch, @@ -154,7 +169,7 @@ impl SharedTableInner { self.update_trackers(&summary.candidate, context); let local_index = context.local_index()?; - let para_member = context.is_member_of(local_index, &summary.group_id); + let para_member = context.is_member_of(&local_index, &summary.group_id); let digest = &summary.candidate; // TODO: consider a strategy based on the number of candidate votes as well. @@ -216,7 +231,7 @@ impl SharedTableInner { /// Produced after validating a candidate. pub struct Validated { /// A statement about the validity of the candidate. - statement: table::Statement, + statement: table_v0::Statement, /// The result of validation. result: Validation, } @@ -461,7 +476,7 @@ impl SharedTable { pub fn import_remote_statement<Fetch>( &self, fetch_pov_block: impl Fn(&AbridgedCandidateReceipt) -> Fetch, - statement: table::SignedStatement, + statement: table_v0::SignedStatement, ) -> Option<ParachainWork< Fetch, >> { @@ -487,7 +502,7 @@ impl SharedTable { iterable: I, ) -> U where - I: IntoIterator<Item=table::SignedStatement>, + I: IntoIterator<Item=table_v0::SignedStatement>, U: ::std::iter::FromIterator<Option<ParachainWork< Fetch, >>>, @@ -539,7 +554,7 @@ impl SharedTable { /// Get a set of candidates that can be proposed. pub fn proposed_set(&self) -> Vec<AttestedCandidate> { use table::generic::{ValidityAttestation as GAttestation}; - use polkadot_primitives::parachain::ValidityAttestation; + use polkadot_primitives::v0::ValidityAttestation; // we transform the types of the attestations gathered from the table // into the type expected by the runtime. This may do signature @@ -583,7 +598,7 @@ impl SharedTable { } /// Get all witnessed misbehavior. - pub fn get_misbehavior(&self) -> HashMap<ValidatorIndex, table::Misbehavior> { + pub fn get_misbehavior(&self) -> HashMap<ValidatorIndex, table_v0::Misbehavior> { self.inner.lock().table.get_misbehavior().clone() } @@ -615,7 +630,7 @@ impl SharedTable { mod tests { use super::*; use sp_keyring::Sr25519Keyring; - use polkadot_primitives::parachain::{ + use polkadot_primitives::v0::{ BlockData, ErasureChunk, AvailableData, }; use polkadot_erasure_coding::{self as erasure}; @@ -706,7 +721,7 @@ mod tests { &validity_other_key.into(), &signing_context, ); - let signed_statement = ::table::generic::SignedStatement { + let signed_statement = table::generic::SignedStatement { statement: candidate_statement, signature: signature.into(), sender: validity_other_index, @@ -763,7 +778,7 @@ mod tests { &validity_other_key.into(), &signing_context, ); - let signed_statement = ::table::generic::SignedStatement { + let signed_statement = table::generic::SignedStatement { statement: candidate_statement, signature: signature.into(), sender: validity_other_index, @@ -860,7 +875,7 @@ mod tests { omitted_validation: Default::default(), }; - let chunks = erasure::obtain_chunks(n_validators, &available_data).unwrap(); + let chunks = erasure::obtain_chunks_v0(n_validators, &available_data).unwrap(); store.note_validator_index_and_n_validators( &relay_parent, @@ -947,7 +962,7 @@ mod tests { &validity_other_key.into(), &signing_context, ); - let signed_statement = ::table::generic::SignedStatement { + let signed_statement = table::generic::SignedStatement { statement: candidate_statement, signature: signature.into(), sender: validity_other_index, diff --git a/polkadot/validation/src/validation_service/mod.rs b/polkadot/validation/src/validation_service/mod.rs index d84b1be078ad299afbc1ad865af1290778fe2e75..7f332f4c0d1aa73b783d159b18264e8bf8cf90c9 100644 --- a/polkadot/validation/src/validation_service/mod.rs +++ b/polkadot/validation/src/validation_service/mod.rs @@ -32,8 +32,8 @@ use crate::pipeline::FullOutput; use sc_client_api::{BlockchainEvents, BlockBackend}; use consensus::SelectChain; use futures::prelude::*; -use polkadot_primitives::{Block, Hash, BlockId}; -use polkadot_primitives::parachain::{ +use polkadot_primitives::v0::{ + Block, Hash, BlockId, Chain, ParachainHost, Id as ParaId, ValidatorIndex, ValidatorId, ValidatorPair, CollationInfo, SigningContext, }; @@ -545,7 +545,7 @@ mod tests { use super::*; use futures::{executor, future::ready, channel::mpsc}; use availability_store::ErasureNetworking; - use polkadot_primitives::parachain::{ + use polkadot_primitives::v0::{ PoVBlock, AbridgedCandidateReceipt, ErasureChunk, ValidatorIndex, CollationInfo, DutyRoster, GlobalValidationSchedule, LocalValidationData, Retriable, CollatorId, BlockData, Chain, AvailableData, SigningContext, ValidationCode, @@ -706,7 +706,7 @@ mod tests { fn signing_context() -> SigningContext { Default::default() } - fn downward_messages(_: ParaId) -> Vec<polkadot_primitives::DownwardMessage> { + fn downward_messages(_: ParaId) -> Vec<polkadot_primitives::v0::DownwardMessage> { Vec::new() } }