Refactor primitives (#1383)

* create a v1 primitives module

* Improve guide on availability types

* punctuate

* new parachains runtime uses new primitives

* tests of new runtime now use new primitives

* add ErasureChunk to guide

* export erasure chunk from v1 primitives

* subsystem crate uses v1 primitives

* node-primitives uses new v1 primitives

* port overseer to new primitives

* new-proposer uses v1 primitives (no ParachainHost anymore)

* fix no-std compilation for primitives

* service-new uses v1 primitives

* network-bridge uses new primitives

* statement distribution uses v1 primitives

* PoV distribution uses v1 primitives; add PoV::hash fn

* move parachain to v0

* remove inclusion_inherent module and place into v1

* remove everything from primitives crate root

* remove some unused old types from v0 primitives

* point everything else at primitives::v0

* squanch some warns up

* add RuntimeDebug import to no-std as well

* port over statement-table and validation

* fix final errors in validation and node-primitives

* add dummy Ord impl to committed candidate receipt

* guide: update CandidateValidationMessage

* add primitive for validationoutputs

* expand CandidateValidationMessage further

* bikeshed

* add some impls to omitted-validation-data and available-data

* expand CandidateValidationMessage

* make erasure-coding generic over v1/v0

* update usages of erasure-coding

* implement commitments.hash()

* use Arc<Pov> for CandidateValidation

* improve new erasure-coding method names

* fix up candidate backing

* update docs a bit

* fix most tests and add short-circuiting to make_pov_available

* fix remainder of candidate backing tests

* squanching warns

* squanch it up

* some fallout

* overseer fallout

* free from polkadot-test-service hell
This commit is contained in:
Robert Habermeier
2020-07-09 21:23:03 -04:00
committed by GitHub
parent 6957847b6b
commit 3b13cd9a85
76 changed files with 1542 additions and 999 deletions
+1 -3
View File
@@ -25,12 +25,10 @@
use futures::prelude::*; use futures::prelude::*;
use futures::channel::{mpsc, oneshot}; use futures::channel::{mpsc, oneshot};
use keystore::KeyStorePtr; use keystore::KeyStorePtr;
use polkadot_primitives::{ use polkadot_primitives::v0::{
Hash, Block, Hash, Block,
parachain::{
PoVBlock, AbridgedCandidateReceipt, ErasureChunk, PoVBlock, AbridgedCandidateReceipt, ErasureChunk,
ParachainHost, AvailableData, OmittedValidationData, ParachainHost, AvailableData, OmittedValidationData,
},
}; };
use sp_runtime::traits::HashFor; use sp_runtime::traits::HashFor;
use sp_blockchain::Result as ClientResult; use sp_blockchain::Result as ClientResult;
+5 -8
View File
@@ -19,11 +19,8 @@ use kvdb_rocksdb::{Database, DatabaseConfig};
use kvdb::{KeyValueDB, DBTransaction}; use kvdb::{KeyValueDB, DBTransaction};
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use polkadot_erasure_coding as erasure; use polkadot_erasure_coding as erasure;
use polkadot_primitives::{ use polkadot_primitives::v0::{
Hash, Hash, ErasureChunk, AvailableData, AbridgedCandidateReceipt,
parachain::{
ErasureChunk, AvailableData, AbridgedCandidateReceipt,
},
}; };
use parking_lot::Mutex; use parking_lot::Mutex;
@@ -273,7 +270,7 @@ impl Store {
// If there are no block data in the store at this point, // 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. // check that they can be reconstructed now and add them to store if they can.
if self.execution_data(&candidate_hash).is_none() { 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, n_validators as usize,
v.iter().map(|chunk| (chunk.chunk.as_ref(), chunk.index as usize)), v.iter().map(|chunk| (chunk.chunk.as_ref(), chunk.index as usize)),
) )
@@ -390,7 +387,7 @@ impl Store {
mod tests { mod tests {
use super::*; use super::*;
use polkadot_erasure_coding::{self as erasure}; use polkadot_erasure_coding::{self as erasure};
use polkadot_primitives::parachain::{ use polkadot_primitives::v0::{
Id as ParaId, BlockData, AvailableData, PoVBlock, OmittedValidationData, Id as ParaId, BlockData, AvailableData, PoVBlock, OmittedValidationData,
}; };
@@ -489,7 +486,7 @@ mod tests {
let available_data = available_data(&[42; 8]); let available_data = available_data(&[42; 8]);
let n_validators = 5; let n_validators = 5;
let erasure_chunks = erasure::obtain_chunks( let erasure_chunks = erasure::obtain_chunks_v0(
n_validators, n_validators,
&available_data, &available_data,
).unwrap(); ).unwrap();
+2 -2
View File
@@ -33,8 +33,8 @@ use consensus_common::{
import_queue::CacheKeyId, import_queue::CacheKeyId,
}; };
use sp_core::traits::SpawnNamed; use sp_core::traits::SpawnNamed;
use polkadot_primitives::{Block, BlockId, Hash}; use polkadot_primitives::v0::{
use polkadot_primitives::parachain::{ Block, BlockId, Hash,
ParachainHost, ValidatorId, AbridgedCandidateReceipt, AvailableData, ParachainHost, ValidatorId, AbridgedCandidateReceipt, AvailableData,
ValidatorPair, ErasureChunk, ValidatorPair, ErasureChunk,
}; };
+9 -10
View File
@@ -55,12 +55,11 @@ use log::warn;
use sc_client_api::{StateBackend, BlockchainEvents}; use sc_client_api::{StateBackend, BlockchainEvents};
use sp_blockchain::HeaderBackend; use sp_blockchain::HeaderBackend;
use sp_core::Pair; use sp_core::Pair;
use polkadot_primitives::{ use polkadot_primitives::v0::{
BlockId, Hash, Block, DownwardMessage, BlockId, Hash, Block, DownwardMessage,
parachain::{ BlockData, DutyRoster, HeadData, Id as ParaId,
self, BlockData, DutyRoster, HeadData, Id as ParaId,
PoVBlock, ValidatorId, CollatorPair, LocalValidationData, GlobalValidationSchedule, PoVBlock, ValidatorId, CollatorPair, LocalValidationData, GlobalValidationSchedule,
} Collation, CollationInfo, collator_signature_payload,
}; };
use polkadot_cli::{ use polkadot_cli::{
ProvideRuntimeApi, ParachainHost, IdentifyVariant, ProvideRuntimeApi, ParachainHost, IdentifyVariant,
@@ -69,7 +68,7 @@ use polkadot_cli::{
pub use polkadot_cli::service::Configuration; pub use polkadot_cli::service::Configuration;
pub use polkadot_cli::Cli; pub use polkadot_cli::Cli;
pub use polkadot_validation::SignedStatement; pub use polkadot_validation::SignedStatement;
pub use polkadot_primitives::parachain::CollatorId; pub use polkadot_primitives::v0::CollatorId;
pub use sc_network::PeerId; pub use sc_network::PeerId;
pub use service::RuntimeApiCollection; pub use service::RuntimeApiCollection;
pub use sc_cli::SubstrateCli; pub use sc_cli::SubstrateCli;
@@ -164,7 +163,7 @@ pub async fn collate<P>(
downward_messages: Vec<DownwardMessage>, downward_messages: Vec<DownwardMessage>,
mut para_context: P, mut para_context: P,
key: Arc<CollatorPair>, key: Arc<CollatorPair>,
) -> Option<parachain::Collation> ) -> Option<Collation>
where where
P: ParachainContext, P: ParachainContext,
P::ProduceCandidate: Send, P::ProduceCandidate: Send,
@@ -181,13 +180,13 @@ pub async fn collate<P>(
}; };
let pov_block_hash = pov_block.hash(); let pov_block_hash = pov_block.hash();
let signature = key.sign(&parachain::collator_signature_payload( let signature = key.sign(&collator_signature_payload(
&relay_parent, &relay_parent,
&local_id, &local_id,
&pov_block_hash, &pov_block_hash,
)); ));
let info = parachain::CollationInfo { let info = CollationInfo {
parachain_index: local_id, parachain_index: local_id,
relay_parent, relay_parent,
collator: key.public(), collator: key.public(),
@@ -196,7 +195,7 @@ pub async fn collate<P>(
pov_block_hash, pov_block_hash,
}; };
let collation = parachain::Collation { let collation = Collation {
info, info,
pov: pov_block, pov: pov_block,
}; };
@@ -456,7 +455,7 @@ where
#[cfg(not(feature = "service-rewr"))] #[cfg(not(feature = "service-rewr"))]
fn compute_targets(para_id: ParaId, session_keys: &[ValidatorId], roster: DutyRoster) -> HashSet<ValidatorId> { 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() roster.validator_duty.iter().enumerate()
.filter(|&(_, c)| c == &Chain::Parachain(para_id)) .filter(|&(_, c)| c == &Chain::Parachain(para_id))
+5
View File
@@ -94,3 +94,8 @@ pub enum DownwardMessage<AccountId = crate::AccountId> {
/// XCMP message for the Parachain. /// XCMP message for the Parachain.
XCMPMessage(sp_std::vec::Vec<u8>), XCMPMessage(sp_std::vec::Vec<u8>),
} }
/// V1 primitives.
pub mod v1 {
pub use super::*;
}
+54 -9
View File
@@ -26,8 +26,8 @@
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use reed_solomon::galois_16::{self, ReedSolomon}; use reed_solomon::galois_16::{self, ReedSolomon};
use primitives::{Hash as H256, BlakeTwo256, HashT}; use primitives::v0::{self, Hash as H256, BlakeTwo256, HashT};
use primitives::parachain::AvailableData; use primitives::v1;
use sp_core::Blake2Hasher; use sp_core::Blake2Hasher;
use trie::{EMPTY_PREFIX, MemoryDB, Trie, TrieMut, trie_types::{TrieDBMut, TrieDB}}; 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. /// Obtain erasure-coded chunks, one for each validator.
/// ///
/// Works only up to 65536 validators, and `n_validators` must be non-zero. /// 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> -> Result<Vec<Vec<u8>>, Error>
{ {
let params = code_params(n_validators)?; let params = code_params(n_validators)?;
let encoded = available_data.encode(); let encoded = data.encode();
if encoded.is_empty() { if encoded.is_empty() {
return Err(Error::BadPayload); 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()) 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. /// Provide an iterator containing chunk data and the corresponding index.
/// The indices of the present chunks must be indicated. If too few chunks /// The indices of the present chunks must be indicated. If too few chunks
/// are provided, recovery is not possible. /// are provided, recovery is not possible.
/// ///
/// Works only up to 65536 validators, and `n_validators` must be non-zero. /// Works only up to 65536 validators, and `n_validators` must be non-zero.
pub fn reconstruct<'a, I: 'a>(n_validators: usize, chunks: I) pub fn reconstruct_v0<'a, I: 'a>(n_validators: usize, chunks: I)
-> Result<AvailableData, Error> -> 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.
fn reconstruct<'a, I: 'a, T: Decode>(n_validators: usize, chunks: I) -> Result<T, Error>
where I: IntoIterator<Item=(&'a [u8], usize)> where I: IntoIterator<Item=(&'a [u8], usize)>
{ {
let params = code_params(n_validators)?; 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use primitives::parachain::{BlockData, PoVBlock}; use primitives::v0::{AvailableData, BlockData, PoVBlock};
#[test] #[test]
fn field_order_is_right_size() { fn field_order_is_right_size() {
@@ -420,7 +465,7 @@ mod tests {
assert_eq!(chunks.len(), 10); assert_eq!(chunks.len(), 10);
// any 4 chunks should work. // any 4 chunks should work.
let reconstructed = reconstruct( let reconstructed: AvailableData = reconstruct(
10, 10,
[ [
(&*chunks[1], 1), (&*chunks[1], 1),
+2 -3
View File
@@ -17,8 +17,7 @@
//! Bridge between the network and consensus service for getting collations to it. //! Bridge between the network and consensus service for getting collations to it.
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use polkadot_primitives::Hash; use polkadot_primitives::v0::{Hash, CollatorId, Id as ParaId, Collation};
use polkadot_primitives::parachain::{CollatorId, Id as ParaId, Collation};
use sc_network::PeerId; use sc_network::PeerId;
use futures::channel::oneshot; use futures::channel::oneshot;
@@ -236,7 +235,7 @@ impl CollatorPool {
mod tests { mod tests {
use super::*; use super::*;
use sp_core::crypto::UncheckedInto; use sp_core::crypto::UncheckedInto;
use polkadot_primitives::parachain::{CollationInfo, BlockData, PoVBlock}; use polkadot_primitives::v0::{CollationInfo, BlockData, PoVBlock};
use futures::executor::block_on; use futures::executor::block_on;
fn make_pov(block_data: Vec<u8>) -> PoVBlock { fn make_pov(block_data: Vec<u8>) -> PoVBlock {
@@ -33,7 +33,7 @@
use sc_network_gossip::{ValidationResult as GossipValidationResult}; use sc_network_gossip::{ValidationResult as GossipValidationResult};
use sc_network::ReputationChange; use sc_network::ReputationChange;
use polkadot_validation::GenericStatement; use polkadot_validation::GenericStatement;
use polkadot_primitives::Hash; use polkadot_primitives::v0::Hash;
use std::collections::HashMap; use std::collections::HashMap;
+3 -3
View File
@@ -58,8 +58,8 @@ use sc_network_gossip::{
ValidatorContext, MessageIntent, ValidatorContext, MessageIntent,
}; };
use polkadot_validation::{SignedStatement}; use polkadot_validation::{SignedStatement};
use polkadot_primitives::{Block, Hash}; use polkadot_primitives::v0::{
use polkadot_primitives::parachain::{ Block, Hash,
ParachainHost, ValidatorId, ErasureChunk as PrimitiveChunk, SigningContext, PoVBlock, ParachainHost, ValidatorId, ErasureChunk as PrimitiveChunk, SigningContext, PoVBlock,
}; };
use polkadot_erasure_coding::{self as erasure}; use polkadot_erasure_coding::{self as erasure};
@@ -755,7 +755,7 @@ mod tests {
use sc_network_gossip::Validator as ValidatorT; use sc_network_gossip::Validator as ValidatorT;
use std::sync::mpsc; use std::sync::mpsc;
use parking_lot::Mutex; use parking_lot::Mutex;
use polkadot_primitives::parachain::{AbridgedCandidateReceipt, BlockData}; use polkadot_primitives::v0::{AbridgedCandidateReceipt, BlockData};
use sp_core::sr25519::Signature as Sr25519Signature; use sp_core::sr25519::Signature as Sr25519Signature;
use polkadot_validation::GenericStatement; use polkadot_validation::GenericStatement;
@@ -19,7 +19,7 @@
//! Collations are attempted to be repropagated when a new validator connects, //! Collations are attempted to be repropagated when a new validator connects,
//! a validator changes his session key, or when they are generated. //! 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 crate::legacy::collator_pool::Role;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::time::Duration; use std::time::Duration;
@@ -144,7 +144,7 @@ impl<C: Clone> LocalCollations<C> {
mod tests { mod tests {
use super::*; use super::*;
use sp_core::crypto::UncheckedInto; use sp_core::crypto::UncheckedInto;
use polkadot_primitives::parachain::ValidatorId; use polkadot_primitives::v0::ValidatorId;
#[test] #[test]
fn add_validator_with_ready_collation() { fn add_validator_with_ready_collation() {
+1 -1
View File
@@ -25,7 +25,7 @@ pub mod gossip;
use codec::Decode; use codec::Decode;
use futures::prelude::*; use futures::prelude::*;
use polkadot_primitives::Hash; use polkadot_primitives::v0::Hash;
use sc_network::PeerId; use sc_network::PeerId;
use sc_network_gossip::TopicNotification; use sc_network_gossip::TopicNotification;
use log::debug; use log::debug;
+1 -1
View File
@@ -21,7 +21,7 @@
#![recursion_limit="256"] #![recursion_limit="256"]
use polkadot_primitives::{Block, Hash, BlakeTwo256, HashT}; use polkadot_primitives::v0::{Block, Hash, BlakeTwo256, HashT};
pub mod legacy; pub mod legacy;
pub mod protocol; pub mod protocol;
+1 -3
View File
@@ -30,12 +30,10 @@ use futures::task::{Context, Poll};
use futures::stream::{FuturesUnordered, StreamFuture}; use futures::stream::{FuturesUnordered, StreamFuture};
use log::{debug, trace}; use log::{debug, trace};
use polkadot_primitives::{ use polkadot_primitives::v0::{
Hash, Block, Hash, Block,
parachain::{
PoVBlock, ValidatorId, ValidatorIndex, Collation, AbridgedCandidateReceipt, PoVBlock, ValidatorId, ValidatorIndex, Collation, AbridgedCandidateReceipt,
ErasureChunk, ParachainHost, Id as ParaId, CollatorId, ErasureChunk, ParachainHost, Id as ParaId, CollatorId,
},
}; };
use polkadot_validation::{ use polkadot_validation::{
SharedTable, TableRouter, Network as ParachainNetwork, Validated, GenericStatement, Collators, SharedTable, TableRouter, Network as ParachainNetwork, Validated, GenericStatement, Collators,
+3 -3
View File
@@ -17,8 +17,8 @@ use super::*;
use crate::legacy::gossip::GossipPoVBlock; use crate::legacy::gossip::GossipPoVBlock;
use parking_lot::Mutex; use parking_lot::Mutex;
use polkadot_primitives::Block; use polkadot_primitives::v0::{
use polkadot_primitives::parachain::{ Block,
Id as ParaId, Chain, DutyRoster, ParachainHost, ValidatorId, Id as ParaId, Chain, DutyRoster, ParachainHost, ValidatorId,
Retriable, CollatorId, AbridgedCandidateReceipt, Retriable, CollatorId, AbridgedCandidateReceipt,
GlobalValidationSchedule, LocalValidationData, ErasureChunk, SigningContext, GlobalValidationSchedule, LocalValidationData, ErasureChunk, SigningContext,
@@ -198,7 +198,7 @@ sp_api::mock_impl_runtime_apis! {
parent_hash: Default::default(), parent_hash: Default::default(),
} }
} }
fn downward_messages(_: ParaId) -> Vec<polkadot_primitives::DownwardMessage> { fn downward_messages(_: ParaId) -> Vec<polkadot_primitives::v0::DownwardMessage> {
Vec::new() Vec::new()
} }
} }
+341 -251
View File
@@ -21,6 +21,7 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::pin::Pin; use std::pin::Pin;
use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use bitvec::vec::BitVec; use bitvec::vec::BitVec;
@@ -36,17 +37,15 @@ use streamunordered::{StreamUnordered, StreamYield};
use primitives::Pair; use primitives::Pair;
use keystore::KeyStorePtr; use keystore::KeyStorePtr;
use polkadot_primitives::{ use polkadot_primitives::v1::{
Hash, CommittedCandidateReceipt, BackedCandidate, Id as ParaId, ValidatorPair, ValidatorId,
parachain::{ ValidatorIndex, SigningContext, PoV, OmittedValidationData,
AbridgedCandidateReceipt, BackedCandidate, Id as ParaId, ValidatorPair, ValidatorId, CandidateDescriptor, AvailableData, ErasureChunk, ValidatorSignature, Hash, CandidateReceipt,
ValidatorIndex, HeadData, SigningContext, PoVBlock, OmittedValidationData, CandidateCommitments,
CandidateDescriptor, LocalValidationData, GlobalValidationSchedule, AvailableData,
ErasureChunk,
},
}; };
use polkadot_node_primitives::{ use polkadot_node_primitives::{
FromTableMisbehavior, Statement, SignedFullStatement, MisbehaviorReport, ValidationResult, FromTableMisbehavior, Statement, SignedFullStatement, MisbehaviorReport, ValidationResult,
ValidationOutputs,
}; };
use polkadot_subsystem::{ use polkadot_subsystem::{
FromOverseer, OverseerSignal, Subsystem, SubsystemContext, SpawnedSubsystem, FromOverseer, OverseerSignal, Subsystem, SubsystemContext, SpawnedSubsystem,
@@ -59,8 +58,12 @@ use polkadot_subsystem::messages::{
}; };
use statement_table::{ use statement_table::{
generic::AttestedCandidate as TableAttestedCandidate, generic::AttestedCandidate as TableAttestedCandidate,
Table, Context as TableContextTrait, Statement as TableStatement, Context as TableContextTrait,
Table,
v1::{
Statement as TableStatement,
SignedStatement as TableSignedStatement, Summary as TableSummary, SignedStatement as TableSignedStatement, Summary as TableSummary,
},
}; };
#[derive(Debug, derive_more::From)] #[derive(Debug, derive_more::From)]
@@ -90,8 +93,6 @@ struct CandidateBackingJob {
/// Outbound message channel sending part. /// Outbound message channel sending part.
tx_from: mpsc::Sender<FromJob>, 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. /// The `ParaId`s assigned to this validator.
assignment: ParaId, assignment: ParaId,
/// We issued `Valid` or `Invalid` statements on about these candidates. /// We issued `Valid` or `Invalid` statements on about these candidates.
@@ -118,8 +119,22 @@ struct TableContext {
} }
impl TableContextTrait for TableContext { impl TableContextTrait for TableContext {
fn is_member_of(&self, authority: ValidatorIndex, group: &ParaId) -> bool { type AuthorityId = ValidatorIndex;
self.groups.get(group).map_or(false, |g| g.iter().position(|&a| a == authority).is_some()) 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 { fn requisite_votes(&self, group: &ParaId) -> usize {
@@ -221,7 +236,7 @@ impl CandidateBackingJob {
async fn issue_candidate_invalid_message( async fn issue_candidate_invalid_message(
&mut self, &mut self,
candidate: AbridgedCandidateReceipt, candidate: CandidateReceipt,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.tx_from.send(FromJob::CandidateSelection( self.tx_from.send(FromJob::CandidateSelection(
CandidateSelectionMessage::Invalid(self.parent, candidate) 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. /// 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( async fn validate_and_second(
&mut self, &mut self,
candidate: AbridgedCandidateReceipt, candidate: &CandidateReceipt,
pov: PoVBlock, pov: PoV,
) -> Result<ValidationResult, Error> { ) -> Result<bool, Error> {
let valid = self.request_candidate_validation(candidate.clone(), pov.clone()).await?; let valid = self.request_candidate_validation(
let statement = match valid.0 { candidate.descriptor().clone(),
ValidationResult::Valid => { 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 // make PoV available for later distribution. Send data to the availability
// store to keep. Sign and dispatch `valid` statement to network if we // store to keep. Sign and dispatch `valid` statement to network if we
// have not seconded the given candidate. // have not seconded the given candidate.
self.make_pov_available(pov, valid.1, valid.2).await?; //
self.issued_statements.insert(candidate.hash()); // If the commitments hash produced by validation is not the same as given by
Statement::Seconded(candidate) // 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 => { ValidationResult::Invalid => {
let candidate_hash = candidate.hash(); // no need to issue a statement about this if we aren't seconding it.
self.issue_candidate_invalid_message(candidate).await?; //
Statement::Invalid(candidate_hash) // 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.import_statement(&signed_statement).await?;
self.distribute_signed_statement(signed_statement).await?; self.distribute_signed_statement(signed_statement).await?;
} }
Ok(valid.0) Ok(issued_statement)
} }
fn get_backed(&self) -> Vec<NewBackedCandidate> { fn get_backed(&self) -> Vec<NewBackedCandidate> {
@@ -354,7 +404,7 @@ impl CandidateBackingJob {
match msg { match msg {
CandidateBackingMessage::Second(_, candidate, pov) => { CandidateBackingMessage::Second(_, candidate, pov) => {
// Sanity check that candidate is from our assignment. // Sanity check that candidate is from our assignment.
if candidate.parachain_index != self.assignment { if candidate.descriptor().para_id != self.assignment {
return Ok(()); return Ok(());
} }
@@ -367,8 +417,8 @@ impl CandidateBackingJob {
let candidate_hash = candidate.hash(); let candidate_hash = candidate.hash();
if !self.issued_statements.contains(&candidate_hash) { if !self.issued_statements.contains(&candidate_hash) {
if let Ok(ValidationResult::Valid) = self.validate_and_second( if let Ok(true) = self.validate_and_second(
candidate, &candidate,
pov, pov,
).await { ).await {
self.seconded = Some(candidate_hash); self.seconded = Some(candidate_hash);
@@ -397,17 +447,40 @@ impl CandidateBackingJob {
async fn kick_off_validation_work( async fn kick_off_validation_work(
&mut self, &mut self,
summary: TableSummary, summary: TableSummary,
) -> Result<ValidationResult, Error> { ) -> Result<(), Error> {
let candidate = self.table.get_candidate(&summary.candidate).ok_or(Error::CandidateNotFound)?; let candidate_hash = summary.candidate.clone();
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?;
let statement = match v.0 { if self.issued_statements.contains(&candidate_hash) {
ValidationResult::Valid => { return Ok(())
Statement::Valid(candidate_hash) }
// 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?;
match commitments_check {
Ok(()) => Statement::Valid(candidate_hash),
Err(()) => Statement::Invalid(candidate_hash),
}
} }
ValidationResult::Invalid => { ValidationResult::Invalid => {
Statement::Invalid(candidate_hash) Statement::Invalid(candidate_hash)
@@ -420,7 +493,7 @@ impl CandidateBackingJob {
self.distribute_signed_statement(signed_statement).await?; 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. /// 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( async fn request_pov_from_distribution(
&mut self, &mut self,
descriptor: CandidateDescriptor, descriptor: CandidateDescriptor,
) -> Result<PoVBlock, Error> { ) -> Result<Arc<PoV>, Error> {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
self.tx_from.send(FromJob::PoVDistribution( self.tx_from.send(FromJob::PoVDistribution(
PoVDistributionMessage::FetchPoV(self.parent, descriptor, tx) PoVDistributionMessage::FetchPoV(self.parent, descriptor, tx)
)).await?; )).await?;
let pov = rx.await?; Ok(rx.await?)
Ok((*pov).clone())
} }
async fn request_candidate_validation( async fn request_candidate_validation(
&mut self, &mut self,
candidate: AbridgedCandidateReceipt, candidate: CandidateDescriptor,
pov: PoVBlock, pov: Arc<PoV>,
) -> Result<(ValidationResult, GlobalValidationSchedule, LocalValidationData), Error> { ) -> Result<ValidationResult, Error> {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
self.tx_from.send(FromJob::CandidateValidation( self.tx_from.send(FromJob::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
self.parent,
candidate, candidate,
self.head_data.clone(),
pov, pov,
tx, tx,
) )
@@ -523,32 +593,51 @@ impl CandidateBackingJob {
Ok(()) 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, &mut self,
pov_block: PoVBlock, pov: PoV,
global_validation: GlobalValidationSchedule, outputs: ValidationOutputs,
local_validation: LocalValidationData, with_commitments: impl FnOnce(CandidateCommitments) -> Result<T, E>,
) -> Result<(), Error> { ) -> Result<Result<T, E>, Error> {
let omitted_validation = OmittedValidationData { let omitted_validation = OmittedValidationData {
global_validation, global_validation: outputs.global_validation_schedule,
local_validation, local_validation: outputs.local_validation_data,
}; };
let available_data = AvailableData { let available_data = AvailableData {
pov_block, pov,
omitted_validation, omitted_validation,
}; };
let chunks = erasure_coding::obtain_chunks( let chunks = erasure_coding::obtain_chunks_v1(
self.table_context.validators.len(), self.table_context.validators.len(),
&available_data, &available_data,
)?; )?;
let branches = erasure_coding::branches(chunks.as_ref()); let branches = erasure_coding::branches(chunks.as_ref());
let erasure_root = branches.root();
for (index, (chunk, proof)) in chunks.iter().zip(branches.map(|(proof, _)| proof)).enumerate() { 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,
};
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 { let chunk = ErasureChunk {
chunk: chunk.clone(), chunk: chunk.to_vec(),
index: index as u32, index: index as u32,
proof, proof,
}; };
@@ -556,7 +645,7 @@ impl CandidateBackingJob {
self.store_chunk(index as ValidatorIndex, chunk).await?; self.store_chunk(index as ValidatorIndex, chunk).await?;
} }
Ok(()) Ok(Ok(res))
} }
async fn distribute_signed_statement(&mut self, s: SignedFullStatement) -> Result<(), Error> { async fn distribute_signed_statement(&mut self, s: SignedFullStatement) -> Result<(), Error> {
@@ -635,13 +724,7 @@ async fn run_job(
} }
} }
let ( let signing_context = request_signing_context(parent, &mut tx_from).await?.await?;
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 table_context = TableContext { let table_context = TableContext {
signing_context, signing_context,
@@ -654,7 +737,6 @@ async fn run_job(
parent, parent,
rx_to, rx_to,
tx_from, tx_from,
head_data,
assignment, assignment,
issued_statements: HashSet::new(), issued_statements: HashSet::new(),
seconded: None, seconded: None,
@@ -714,23 +796,6 @@ async fn request_signing_context(
Ok(rx) 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> { impl<S: Spawn> Jobs<S> {
fn new(spawner: S) -> Self { fn new(spawner: S) -> Self {
Self { Self {
@@ -910,8 +975,9 @@ mod tests {
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use sp_keyring::Sr25519Keyring; use sp_keyring::Sr25519Keyring;
use polkadot_primitives::parachain::{ use polkadot_primitives::v1::{
AssignmentKind, CollatorId, CoreAssignment, BlockData, CoreIndex, GroupIndex, ValidityAttestation, AssignmentKind, CollatorId, CoreAssignment, BlockData, CoreIndex, GroupIndex, ValidityAttestation,
CandidateCommitments, LocalValidationData, GlobalValidationSchedule, HeadData,
}; };
use assert_matches::assert_matches; use assert_matches::assert_matches;
@@ -1006,6 +1072,7 @@ mod tests {
parent_head: HeadData(vec![7, 8, 9]), parent_head: HeadData(vec![7, 8, 9]),
balance: Default::default(), balance: Default::default(),
code_upgrade_allowed: None, code_upgrade_allowed: None,
validation_code_hash: Default::default(),
}; };
let global_validation_schedule = GlobalValidationSchedule { let global_validation_schedule = GlobalValidationSchedule {
@@ -1050,6 +1117,48 @@ mod tests {
executor::block_on(future::select(test_fut, subsystem)); 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. // Tests that the subsystem performs actions that are requied on startup.
async fn test_startup( async fn test_startup(
virtual_overseer: &mut subsystem_test::TestSubsystemContextHandle<CandidateBackingMessage>, 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. // Check that subsystem job issues a request for the signing context.
assert_matches!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
@@ -1111,46 +1210,50 @@ mod tests {
test_startup(&mut virtual_overseer, &test_state).await; test_startup(&mut virtual_overseer, &test_state).await;
let pov_block = PoVBlock { let pov = PoV {
block_data: BlockData(vec![42, 43, 44]), block_data: BlockData(vec![42, 43, 44]),
}; };
let pov_block_hash = pov_block.hash(); let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap();
let candidate = AbridgedCandidateReceipt {
parachain_index: test_state.chain_ids[0], let pov_hash = pov.hash();
let candidate = TestCandidateBuilder {
para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent, 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() ..Default::default()
}; }.build();
let second = CandidateBackingMessage::Second( let second = CandidateBackingMessage::Second(
test_state.relay_parent, test_state.relay_parent,
candidate.clone(), candidate.to_plain(),
pov_block.clone(), pov.clone(),
); );
virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; 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!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::CandidateValidation( AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
parent_hash,
c, c,
head_data,
pov, pov,
tx, tx,
) )
) if parent_hash == test_state.relay_parent && ) if pov == pov && &c == candidate.descriptor() => {
pov == pov_block && c == candidate => { tx.send(Ok(
assert_eq!(head_data, *expected_head_data); ValidationResult::Valid(ValidationOutputs {
tx.send(Ok(( global_validation_schedule: test_state.global_validation_schedule,
ValidationResult::Valid, local_validation_data: test_state.local_validation_data,
test_state.global_validation_schedule, head_data: expected_head_data.clone(),
test_state.local_validation_data, upward_messages: Vec::new(),
))).unwrap(); fees: Default::default(),
new_validation_code: None,
}),
)).unwrap();
} }
); );
@@ -1193,18 +1296,22 @@ mod tests {
test_startup(&mut virtual_overseer, &test_state).await; test_startup(&mut virtual_overseer, &test_state).await;
let pov_block = PoVBlock { let pov = PoV {
block_data: BlockData(vec![1, 2, 3]), block_data: BlockData(vec![1, 2, 3]),
}; };
let pov_block_hash = pov_block.hash(); let pov_hash = pov.hash();
let candidate_a = AbridgedCandidateReceipt { let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap();
parachain_index: test_state.chain_ids[0],
let candidate_a = TestCandidateBuilder {
para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent, 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() ..Default::default()
}; }.build();
let candidate_a_hash = candidate_a.hash(); let candidate_a_hash = candidate_a.hash();
@@ -1227,39 +1334,38 @@ mod tests {
virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await;
// Sending a `Statement::Seconded` for our assignment will start // 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`. // `PoVDistribution`.
assert_matches!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::PoVDistribution( AllMessages::PoVDistribution(
PoVDistributionMessage::FetchPoV(relay_parent, _, tx) PoVDistributionMessage::FetchPoV(relay_parent, _, tx)
) if relay_parent == test_state.relay_parent => { ) 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 // The next step is the actual request to Validation subsystem
// to validate the `Seconded` candidate. // to validate the `Seconded` candidate.
assert_matches!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::CandidateValidation( AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
relay_parent, c,
candidate,
head_data,
pov, pov,
tx, tx,
) )
) if relay_parent == test_state.relay_parent && candidate == candidate_a => { ) if pov == pov && &c == candidate_a.descriptor() => {
assert_eq!(head_data, *expected_head_data); tx.send(Ok(
assert_eq!(pov, pov_block); ValidationResult::Valid(ValidationOutputs {
tx.send(Ok(( global_validation_schedule: test_state.global_validation_schedule,
ValidationResult::Valid, local_validation_data: test_state.local_validation_data,
test_state.global_validation_schedule, head_data: expected_head_data.clone(),
test_state.local_validation_data, upward_messages: Vec::new(),
))).unwrap(); fees: Default::default(),
new_validation_code: None,
}),
)).unwrap();
} }
); );
@@ -1309,17 +1415,22 @@ mod tests {
test_startup(&mut virtual_overseer, &test_state).await; test_startup(&mut virtual_overseer, &test_state).await;
let pov_block = PoVBlock { let pov = PoV {
block_data: BlockData(vec![1, 2, 3]), block_data: BlockData(vec![1, 2, 3]),
}; };
let pov_block_hash = pov_block.hash(); let pov_hash = pov.hash();
let candidate_a = AbridgedCandidateReceipt {
parachain_index: test_state.chain_ids[0], 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, 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() ..Default::default()
}; }.build();
let candidate_a_hash = candidate_a.hash(); let candidate_a_hash = candidate_a.hash();
@@ -1353,33 +1464,41 @@ mod tests {
AllMessages::PoVDistribution( AllMessages::PoVDistribution(
PoVDistributionMessage::FetchPoV(relay_parent, _, tx) PoVDistributionMessage::FetchPoV(relay_parent, _, tx)
) if relay_parent == test_state.relay_parent => { ) 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!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::CandidateValidation( AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
relay_parent, c,
candidate,
head_data,
pov, pov,
tx, tx,
) )
) if relay_parent == test_state.relay_parent && candidate == candidate_a => { ) if pov == pov && &c == candidate_a.descriptor() => {
assert_eq!(pov, pov_block); tx.send(Ok(
assert_eq!(head_data, *expected_head_data); ValidationResult::Valid(ValidationOutputs {
tx.send(Ok(( global_validation_schedule: test_state.global_validation_schedule,
ValidationResult::Valid, local_validation_data: test_state.local_validation_data,
test_state.global_validation_schedule, head_data: expected_head_data.clone(),
test_state.local_validation_data, upward_messages: Vec::new(),
))).unwrap(); 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!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::StatementDistribution( AllMessages::StatementDistribution(
@@ -1440,86 +1559,68 @@ mod tests {
test_startup(&mut virtual_overseer, &test_state).await; 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]), block_data: BlockData(vec![42, 43, 44]),
}; };
let pov_block_b = PoVBlock { let pov_block_b = PoV {
block_data: BlockData(vec![45, 46, 47]), block_data: BlockData(vec![45, 46, 47]),
}; };
let pov_block_hash_a = pov_block_a.hash(); let pov_hash_a = pov_block_a.hash();
let pov_block_hash_b = pov_block_b.hash(); let pov_hash_b = pov_block_b.hash();
let candidate_a = AbridgedCandidateReceipt { let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap();
parachain_index: test_state.chain_ids[0],
let candidate_a = TestCandidateBuilder {
para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent, 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() ..Default::default()
}; }.build();
let candidate_a_hash = candidate_a.hash(); let candidate_b = TestCandidateBuilder {
para_id: test_state.chain_ids[0],
let candidate_b = AbridgedCandidateReceipt {
parachain_index: test_state.chain_ids[0],
relay_parent: test_state.relay_parent, 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() ..Default::default()
}; }.build();
let second = CandidateBackingMessage::Second( let second = CandidateBackingMessage::Second(
test_state.relay_parent, test_state.relay_parent,
candidate_a.clone(), candidate_a.to_plain(),
pov_block_a.clone(), pov_block_a.clone(),
); );
virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; 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!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::CandidateValidation( AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
parent_hash,
c, c,
head_data,
pov, pov,
tx, tx,
) )
) if parent_hash == test_state.relay_parent && ) if pov == pov && &c == candidate_a.descriptor() => {
pov == pov_block_a && c == candidate_a => { tx.send(Ok(ValidationResult::Invalid)).unwrap();
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();
} }
); );
assert_matches!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::CandidateSelection( AllMessages::CandidateSelection(
CandidateSelectionMessage::Invalid(parent_hash, candidate) CandidateSelectionMessage::Invalid(parent_hash, c)
) if parent_hash == test_state.relay_parent && candidate == candidate_a ) if parent_hash == test_state.relay_parent && c == candidate_a.to_plain()
);
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));
}
); );
let second = CandidateBackingMessage::Second( let second = CandidateBackingMessage::Second(
test_state.relay_parent, test_state.relay_parent,
candidate_b.clone(), candidate_b.to_plain(),
pov_block_b.clone(), pov_block_b.clone(),
); );
@@ -1530,21 +1631,22 @@ mod tests {
assert_matches!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::CandidateValidation( AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
parent_hash,
c, c,
head_data,
pov, pov,
tx, tx,
) )
) if parent_hash == test_state.relay_parent && ) if pov == pov && &c == candidate_b.descriptor() => {
pov == pov_block_b && c == candidate_b => { tx.send(Ok(
assert_eq!(head_data, *expected_head_data); ValidationResult::Valid(ValidationOutputs {
tx.send(Ok(( global_validation_schedule: test_state.global_validation_schedule,
ValidationResult::Valid, local_validation_data: test_state.local_validation_data,
test_state.global_validation_schedule, head_data: expected_head_data.clone(),
test_state.local_validation_data, upward_messages: Vec::new(),
))).unwrap(); fees: Default::default(),
new_validation_code: None,
}),
)).unwrap();
} }
); );
@@ -1590,18 +1692,19 @@ mod tests {
test_startup(&mut virtual_overseer, &test_state).await; test_startup(&mut virtual_overseer, &test_state).await;
let pov_block = PoVBlock { let pov = PoV {
block_data: BlockData(vec![42, 43, 44]), block_data: BlockData(vec![42, 43, 44]),
}; };
let pov_block_hash = pov_block.hash(); let pov_hash = pov.hash();
let candidate = AbridgedCandidateReceipt { let candidate = TestCandidateBuilder {
parachain_index: test_state.chain_ids[0], para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent, relay_parent: test_state.relay_parent,
pov_block_hash, pov_hash,
erasure_root: make_erasure_root(&test_state, pov.clone()),
..Default::default() ..Default::default()
}; }.build();
let candidate_hash = candidate.hash(); let candidate_hash = candidate.hash();
@@ -1627,33 +1730,22 @@ mod tests {
PoVDistributionMessage::FetchPoV(relay_parent, _, tx) PoVDistributionMessage::FetchPoV(relay_parent, _, tx)
) => { ) => {
assert_eq!(relay_parent, test_state.relay_parent); 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. // Tell subsystem that this candidate is invalid.
assert_matches!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::CandidateValidation( AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
relay_parent, c,
candidate_recvd,
head_data,
pov, pov,
tx, tx,
) )
) => { ) if pov == pov && &c == candidate.descriptor() => {
assert_eq!(relay_parent, test_state.relay_parent); tx.send(Ok(ValidationResult::Invalid)).unwrap();
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();
} }
); );
@@ -1679,28 +1771,29 @@ mod tests {
// This should emit no actions from subsystem. // This should emit no actions from subsystem.
let second = CandidateBackingMessage::Second( let second = CandidateBackingMessage::Second(
test_state.relay_parent, test_state.relay_parent,
candidate.clone(), candidate.to_plain(),
pov_block.clone(), pov.clone(),
); );
virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; 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]), 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 { let candidate_to_second = TestCandidateBuilder {
parachain_index: test_state.chain_ids[0], para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent, relay_parent: test_state.relay_parent,
pov_block_hash, pov_hash,
erasure_root: make_erasure_root(&test_state, pov_to_second.clone()),
..Default::default() ..Default::default()
}; }.build();
let second = CandidateBackingMessage::Second( let second = CandidateBackingMessage::Second(
test_state.relay_parent, test_state.relay_parent,
candidate_to_second.clone(), candidate_to_second.to_plain(),
pov_to_second.clone(), pov_to_second.clone(),
); );
@@ -1712,16 +1805,13 @@ mod tests {
assert_matches!( assert_matches!(
virtual_overseer.recv().await, virtual_overseer.recv().await,
AllMessages::CandidateValidation( AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
relay_parent,
_,
_, _,
pov, pov,
_, _,
) )
) => { ) => {
assert_eq!(relay_parent, test_state.relay_parent); assert_eq!(&*pov, &pov_to_second);
assert_eq!(pov, pov_to_second);
} }
); );
}); });
+5 -7
View File
@@ -2,9 +2,7 @@ use futures::prelude::*;
use futures::select; use futures::select;
use polkadot_node_subsystem::{messages::{AllMessages, ProvisionerInherentData, ProvisionerMessage}, SubsystemError}; use polkadot_node_subsystem::{messages::{AllMessages, ProvisionerInherentData, ProvisionerMessage}, SubsystemError};
use polkadot_overseer::OverseerHandler; use polkadot_overseer::OverseerHandler;
use polkadot_primitives::{ use polkadot_primitives::v1::{
inclusion_inherent,
parachain::ParachainHost,
Block, Hash, Header, Block, Hash, Header,
}; };
use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider}; use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider};
@@ -53,7 +51,7 @@ where
+ Send + Send
+ Sync, + Sync,
Client::Api: Client::Api:
ParachainHost<Block> + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>,
Backend: Backend:
'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>, 'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>,
// Rust bug: https://github.com/rust-lang/rust/issues/24159 // Rust bug: https://github.com/rust-lang/rust/issues/24159
@@ -104,7 +102,7 @@ where
+ Send + Send
+ Sync, + Sync,
Client::Api: Client::Api:
ParachainHost<Block> + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>,
Backend: Backend:
'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>, 'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>,
// Rust bug: https://github.com/rust-lang/rust/issues/24159 // Rust bug: https://github.com/rust-lang/rust/issues/24159
@@ -155,7 +153,7 @@ where
+ Send + Send
+ Sync, + Sync,
Client::Api: Client::Api:
ParachainHost<Block> + BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>, BlockBuilderApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>,
Backend: Backend:
'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>, 'static + sc_client_api::Backend<Block, State = sp_api::StateBackendFor<Client, Block>>,
// Rust bug: https://github.com/rust-lang/rust/issues/24159 // Rust bug: https://github.com/rust-lang/rust/issues/24159
@@ -186,7 +184,7 @@ where
}; };
inherent_data.put_data( inherent_data.put_data(
inclusion_inherent::INHERENT_IDENTIFIER, polkadot_primitives::v1::INCLUSION_INHERENT_IDENTIFIER,
&provisioner_data, &provisioner_data,
)?; )?;
+1 -1
View File
@@ -33,7 +33,7 @@ use polkadot_subsystem::{
}; };
use polkadot_subsystem::messages::{NetworkBridgeEvent, NetworkBridgeMessage, AllMessages}; use polkadot_subsystem::messages::{NetworkBridgeEvent, NetworkBridgeMessage, AllMessages};
use node_primitives::{ProtocolId, View}; 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::btree_map::{BTreeMap, Entry as BEntry};
use std::collections::hash_map::{HashMap, Entry as HEntry}; use std::collections::hash_map::{HashMap, Entry as HEntry};
@@ -19,8 +19,7 @@
//! This is a gossip implementation of code that is responsible for distributing PoVs //! This is a gossip implementation of code that is responsible for distributing PoVs
//! among validators. //! among validators.
use polkadot_primitives::Hash; use polkadot_primitives::v1::{Hash, PoV, CandidateDescriptor};
use polkadot_primitives::parachain::{PoVBlock as PoV, CandidateDescriptor};
use polkadot_subsystem::{ use polkadot_subsystem::{
OverseerSignal, SubsystemContext, Subsystem, SubsystemResult, FromOverseer, SpawnedSubsystem, OverseerSignal, SubsystemContext, Subsystem, SubsystemResult, FromOverseer, SpawnedSubsystem,
}; };
@@ -550,7 +549,7 @@ async fn run(
mod tests { mod tests {
use super::*; use super::*;
use futures::executor::{self, ThreadPool}; use futures::executor::{self, ThreadPool};
use polkadot_primitives::parachain::BlockData; use polkadot_primitives::v1::BlockData;
use assert_matches::assert_matches; use assert_matches::assert_matches;
fn make_pov(data: Vec<u8>) -> PoV { fn make_pov(data: Vec<u8>) -> PoV {
@@ -29,9 +29,8 @@ use polkadot_subsystem::messages::{
RuntimeApiRequest, RuntimeApiRequest,
}; };
use node_primitives::{ProtocolId, View, SignedFullStatement}; use node_primitives::{ProtocolId, View, SignedFullStatement};
use polkadot_primitives::Hash; use polkadot_primitives::v1::{
use polkadot_primitives::parachain::{ Hash, CompactStatement, ValidatorIndex, ValidatorId, SigningContext, ValidatorSignature,
CompactStatement, ValidatorIndex, ValidatorId, SigningContext, ValidatorSignature,
}; };
use parity_scale_codec::{Encode, Decode}; use parity_scale_codec::{Encode, Decode};
@@ -891,7 +890,7 @@ mod tests {
use super::*; use super::*;
use sp_keyring::Sr25519Keyring; use sp_keyring::Sr25519Keyring;
use node_primitives::Statement; use node_primitives::Statement;
use polkadot_primitives::parachain::{AbridgedCandidateReceipt}; use polkadot_primitives::v1::CommittedCandidateReceipt;
use assert_matches::assert_matches; use assert_matches::assert_matches;
use futures::executor::{self, ThreadPool}; use futures::executor::{self, ThreadPool};
@@ -911,23 +910,23 @@ mod tests {
}; };
let candidate_a = { let candidate_a = {
let mut c = AbridgedCandidateReceipt::default(); let mut c = CommittedCandidateReceipt::default();
c.relay_parent = parent_hash; c.descriptor.relay_parent = parent_hash;
c.parachain_index = 1.into(); c.descriptor.para_id = 1.into();
c c
}; };
let candidate_b = { let candidate_b = {
let mut c = AbridgedCandidateReceipt::default(); let mut c = CommittedCandidateReceipt::default();
c.relay_parent = parent_hash; c.descriptor.relay_parent = parent_hash;
c.parachain_index = 2.into(); c.descriptor.para_id = 2.into();
c c
}; };
let candidate_c = { let candidate_c = {
let mut c = AbridgedCandidateReceipt::default(); let mut c = CommittedCandidateReceipt::default();
c.relay_parent = parent_hash; c.descriptor.relay_parent = parent_hash;
c.parachain_index = 3.into(); c.descriptor.para_id = 3.into();
c c
}; };
@@ -1140,9 +1139,9 @@ mod tests {
let hash_c = [3; 32].into(); let hash_c = [3; 32].into();
let candidate = { let candidate = {
let mut c = AbridgedCandidateReceipt::default(); let mut c = CommittedCandidateReceipt::default();
c.relay_parent = hash_c; c.descriptor.relay_parent = hash_c;
c.parachain_index = 1.into(); c.descriptor.para_id = 1.into();
c c
}; };
let candidate_hash = candidate.hash(); let candidate_hash = candidate.hash();
@@ -1275,9 +1274,9 @@ mod tests {
let hash_c = [3; 32].into(); let hash_c = [3; 32].into();
let candidate = { let candidate = {
let mut c = AbridgedCandidateReceipt::default(); let mut c = CommittedCandidateReceipt::default();
c.relay_parent = hash_b; c.descriptor.relay_parent = hash_b;
c.parachain_index = 1.into(); c.descriptor.para_id = 1.into();
c c
}; };
@@ -27,7 +27,7 @@ use futures::{
use futures_timer::Delay; use futures_timer::Delay;
use kv_log_macro as log; 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_overseer::{Overseer, AllSubsystems};
use polkadot_subsystem::{ use polkadot_subsystem::{
@@ -61,13 +61,11 @@ impl Subsystem1 {
let (tx, _) = oneshot::channel(); let (tx, _) = oneshot::channel();
ctx.send_message(AllMessages::CandidateValidation( ctx.send_message(AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
Default::default(), Default::default(),
Default::default(), PoV {
Default::default(),
PoVBlock {
block_data: BlockData(Vec::new()), block_data: BlockData(Vec::new()),
}, }.into(),
tx, tx,
) )
)).await.unwrap(); )).await.unwrap();
+5 -7
View File
@@ -72,7 +72,7 @@ use futures::{
use futures_timer::Delay; use futures_timer::Delay;
use streamunordered::{StreamYield, StreamUnordered}; use streamunordered::{StreamYield, StreamUnordered};
use polkadot_primitives::{Block, BlockNumber, Hash}; use polkadot_primitives::v1::{Block, BlockNumber, Hash};
use client::{BlockImportNotification, BlockchainEvents, FinalityNotification}; use client::{BlockImportNotification, BlockchainEvents, FinalityNotification};
use polkadot_subsystem::messages::{ use polkadot_subsystem::messages::{
@@ -932,7 +932,7 @@ fn spawn<S: Spawn, M: Send + 'static>(
mod tests { mod tests {
use futures::{executor, pin_mut, select, channel::mpsc, FutureExt}; 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 polkadot_subsystem::DummySubsystem;
use super::*; use super::*;
@@ -977,13 +977,11 @@ mod tests {
let (tx, _) = oneshot::channel(); let (tx, _) = oneshot::channel();
ctx.send_message( ctx.send_message(
AllMessages::CandidateValidation( AllMessages::CandidateValidation(
CandidateValidationMessage::Validate( CandidateValidationMessage::ValidateFromChainState(
Default::default(), Default::default(),
Default::default(), PoV {
Default::default(),
PoVBlock {
block_data: BlockData(Vec::new()), block_data: BlockData(Vec::new()),
}, }.into(),
tx, tx,
) )
) )
+37 -13
View File
@@ -21,26 +21,31 @@
//! there. //! there.
use parity_scale_codec::{Decode, Encode}; use parity_scale_codec::{Decode, Encode};
use polkadot_primitives::{Hash, use polkadot_primitives::v1::{
parachain::{ Hash, CommittedCandidateReceipt, CandidateReceipt, CompactStatement,
AbridgedCandidateReceipt, CompactStatement,
EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId, EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId,
} UpwardMessage, Balance, ValidationCode, GlobalValidationSchedule, LocalValidationData,
HeadData,
}; };
use polkadot_statement_table::{ use polkadot_statement_table::{
generic::{ generic::{
ValidityDoubleVote as TableValidityDoubleVote, ValidityDoubleVote as TableValidityDoubleVote,
MultipleCandidates as TableMultipleCandidates, MultipleCandidates as TableMultipleCandidates,
}, },
Misbehavior as TableMisbehavior, v1::Misbehavior as TableMisbehavior,
}; };
/// A statement, where the candidate receipt is included in the `Seconded` variant. /// 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)] #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub enum Statement { pub enum Statement {
/// A statement that a validator seconds a candidate. /// A statement that a validator seconds a candidate.
#[codec(index = "1")] #[codec(index = "1")]
Seconded(AbridgedCandidateReceipt), Seconded(CommittedCandidateReceipt),
/// A statement that a validator has deemed a candidate valid. /// A statement that a validator has deemed a candidate valid.
#[codec(index = "2")] #[codec(index = "2")]
Valid(Hash), Valid(Hash),
@@ -50,6 +55,8 @@ pub enum Statement {
} }
impl Statement { impl Statement {
/// Transform this statement into its compact version, which references only the hash
/// of the candidate.
pub fn to_compact(&self) -> CompactStatement { pub fn to_compact(&self) -> CompactStatement {
match *self { match *self {
Statement::Seconded(ref c) => CompactStatement::Candidate(c.hash()), 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 message should be dispatched with all of them, in arbitrary order.
/// ///
/// This variant is also used when our own validity checks disagree with others'. /// 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 /// 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 /// This peer has seconded more than one parachain candidate for this relay parent head
DoubleVote(SignedFullStatement, SignedFullStatement), DoubleVote(SignedFullStatement, SignedFullStatement),
} }
@@ -103,11 +110,28 @@ pub struct FromTableMisbehavior {
pub key: ValidatorId, 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. /// Result of the validation of the candidate.
#[derive(Debug)] #[derive(Debug)]
pub enum ValidationResult { pub enum ValidationResult {
/// Candidate is valid. /// Candidate is valid. The validation process yields these outputs.
Valid, Valid(ValidationOutputs),
/// Candidate is invalid. /// Candidate is invalid.
Invalid, Invalid,
} }
@@ -136,7 +160,7 @@ impl std::convert::TryFrom<FromTableMisbehavior> for MisbehaviorReport {
&f.key, &f.key,
).ok_or(())?; ).ok_or(())?;
Ok(MisbehaviorReport::SelfContradiction(receipt, signed_1, signed_2)) Ok(MisbehaviorReport::SelfContradiction(receipt.to_plain(), signed_1, signed_2))
} }
TableMisbehavior::ValidityDoubleVote( TableMisbehavior::ValidityDoubleVote(
TableValidityDoubleVote::IssuedAndInvalidity((c, s1), (d, s2)) TableValidityDoubleVote::IssuedAndInvalidity((c, s1), (d, s2))
@@ -157,7 +181,7 @@ impl std::convert::TryFrom<FromTableMisbehavior> for MisbehaviorReport {
&f.key, &f.key,
).ok_or(())?; ).ok_or(())?;
Ok(MisbehaviorReport::SelfContradiction(receipt, signed_1, signed_2)) Ok(MisbehaviorReport::SelfContradiction(receipt.to_plain(), signed_1, signed_2))
} }
TableMisbehavior::ValidityDoubleVote( TableMisbehavior::ValidityDoubleVote(
TableValidityDoubleVote::ValidityAndInvalidity(c, s1, s2) TableValidityDoubleVote::ValidityAndInvalidity(c, s1, s2)
@@ -177,7 +201,7 @@ impl std::convert::TryFrom<FromTableMisbehavior> for MisbehaviorReport {
&f.key, &f.key,
).ok_or(())?; ).ok_or(())?;
Ok(MisbehaviorReport::SelfContradiction(c, signed_1, signed_2)) Ok(MisbehaviorReport::SelfContradiction(c.to_plain(), signed_1, signed_2))
} }
TableMisbehavior::MultipleCandidates( TableMisbehavior::MultipleCandidates(
TableMultipleCandidates { TableMultipleCandidates {
+3 -3
View File
@@ -17,7 +17,7 @@
//! Polkadot chain configurations. //! Polkadot chain configurations.
use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; 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 polkadot_runtime as polkadot;
use kusama_runtime as kusama; use kusama_runtime as kusama;
use westend_runtime as westend; use westend_runtime as westend;
@@ -48,9 +48,9 @@ const DEFAULT_PROTOCOL_ID: &str = "dot";
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Extensions { pub struct Extensions {
/// Block numbers with known hashes. /// 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. /// 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`. /// The `ChainSpec parametrised for polkadot runtime`.
+2 -2
View File
@@ -16,7 +16,7 @@
//! Polkadot-specific GRANDPA integration utilities. //! Polkadot-specific GRANDPA integration utilities.
use polkadot_primitives::Hash; use polkadot_primitives::v1::Hash;
use sp_runtime::traits::{Block as BlockT, NumberFor}; use sp_runtime::traits::{Block as BlockT, NumberFor};
/// A custom GRANDPA voting rule that "pauses" voting (i.e. keeps voting for the /// 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). /// #1500988).
pub(crate) fn kusama_hard_forks() -> Vec<( pub(crate) fn kusama_hard_forks() -> Vec<(
grandpa_primitives::SetId, grandpa_primitives::SetId,
(Hash, polkadot_primitives::BlockNumber), (Hash, polkadot_primitives::v1::BlockNumber),
grandpa_primitives::AuthorityList, grandpa_primitives::AuthorityList,
)> { )> {
use sp_core::crypto::Ss58Codec; use sp_core::crypto::Ss58Codec;
+5 -8
View File
@@ -22,7 +22,7 @@ mod client;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use polkadot_primitives::{parachain, AccountId, Nonce, Balance}; use polkadot_primitives::v1::{AccountId, Nonce, Balance};
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
use service::{error::Error as ServiceError, ServiceBuilder}; use service::{error::Error as ServiceError, ServiceBuilder};
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; 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_api::{ApiRef, Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend};
pub use sp_runtime::traits::{DigestFor, HashFor, NumberFor}; pub use sp_runtime::traits::{DigestFor, HashFor, NumberFor};
pub use consensus_common::{Proposal, SelectChain, BlockImport, RecordProof, block_validation::Chain}; pub use consensus_common::{Proposal, SelectChain, BlockImport, RecordProof, block_validation::Chain};
pub use polkadot_primitives::parachain::{CollatorId, ParachainHost}; pub use polkadot_primitives::v1::{Block, BlockId, CollatorId, Id as ParaId};
pub use polkadot_primitives::{Block, BlockId};
pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256}; pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256};
pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec}; pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec};
#[cfg(feature = "full-node")] #[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> + sp_api::ApiExt<Block, Error = sp_blockchain::Error>
+ babe_primitives::BabeApi<Block> + babe_primitives::BabeApi<Block>
+ grandpa_primitives::GrandpaApi<Block> + grandpa_primitives::GrandpaApi<Block>
+ ParachainHost<Block>
+ sp_block_builder::BlockBuilder<Block> + sp_block_builder::BlockBuilder<Block>
+ system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> + system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance, Extrinsic> + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance, Extrinsic>
@@ -104,7 +102,6 @@ where
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error> + sp_api::ApiExt<Block, Error = sp_blockchain::Error>
+ babe_primitives::BabeApi<Block> + babe_primitives::BabeApi<Block>
+ grandpa_primitives::GrandpaApi<Block> + grandpa_primitives::GrandpaApi<Block>
+ ParachainHost<Block>
+ sp_block_builder::BlockBuilder<Block> + sp_block_builder::BlockBuilder<Block>
+ system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> + system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance, Extrinsic> + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance, Extrinsic>
@@ -601,7 +598,7 @@ where
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
pub fn polkadot_new_full( pub fn polkadot_new_full(
mut config: Configuration, mut config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>, collating_for: Option<(CollatorId, ParaId)>,
_max_block_data_size: Option<u64>, _max_block_data_size: Option<u64>,
_authority_discovery_enabled: bool, _authority_discovery_enabled: bool,
_slot_duration: u64, _slot_duration: u64,
@@ -633,7 +630,7 @@ pub fn polkadot_new_full(
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
pub fn kusama_new_full( pub fn kusama_new_full(
mut config: Configuration, mut config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>, collating_for: Option<(CollatorId, ParaId)>,
_max_block_data_size: Option<u64>, _max_block_data_size: Option<u64>,
_authority_discovery_enabled: bool, _authority_discovery_enabled: bool,
_slot_duration: u64, _slot_duration: u64,
@@ -665,7 +662,7 @@ pub fn kusama_new_full(
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
pub fn westend_new_full( pub fn westend_new_full(
mut config: Configuration, mut config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>, collating_for: Option<(CollatorId, ParaId)>,
_max_block_data_size: Option<u64>, _max_block_data_size: Option<u64>,
_authority_discovery_enabled: bool, _authority_discovery_enabled: bool,
_slot_duration: u64, _slot_duration: u64,
+1 -1
View File
@@ -26,7 +26,7 @@ use futures::prelude::*;
use futures::channel::{mpsc, oneshot}; use futures::channel::{mpsc, oneshot};
use futures::future::BoxFuture; use futures::future::BoxFuture;
use polkadot_primitives::Hash; use polkadot_primitives::v1::Hash;
use async_trait::async_trait; use async_trait::async_trait;
use crate::messages::AllMessages; use crate::messages::AllMessages;
+39 -25
View File
@@ -24,12 +24,12 @@
use futures::channel::{mpsc, oneshot}; use futures::channel::{mpsc, oneshot};
use polkadot_primitives::{BlockNumber, Hash, Signature}; use polkadot_primitives::v1::{
use polkadot_primitives::parachain::{ BlockNumber, Hash,
AbridgedCandidateReceipt, PoVBlock, ErasureChunk, BackedCandidate, Id as ParaId, CandidateReceipt, PoV, ErasureChunk, BackedCandidate, Id as ParaId,
SignedAvailabilityBitfield, SigningContext, ValidatorId, ValidationCode, ValidatorIndex, SignedAvailabilityBitfield, SigningContext, ValidatorId, ValidationCode, ValidatorIndex,
CoreAssignment, CoreOccupied, HeadData, CandidateDescriptor, GlobalValidationSchedule, CoreAssignment, CoreOccupied, HeadData, CandidateDescriptor,
LocalValidationData, ValidatorSignature, OmittedValidationData,
}; };
use polkadot_node_primitives::{ use polkadot_node_primitives::{
MisbehaviorReport, SignedFullStatement, View, ProtocolId, ValidationResult, MisbehaviorReport, SignedFullStatement, View, ProtocolId, ValidationResult,
@@ -48,7 +48,7 @@ pub struct NewBackedCandidate(pub BackedCandidate);
pub enum CandidateSelectionMessage { pub enum CandidateSelectionMessage {
/// We recommended a particular candidate to be seconded, but it was invalid; penalize the collator. /// We recommended a particular candidate to be seconded, but it was invalid; penalize the collator.
/// The hash is the relay parent. /// The hash is the relay parent.
Invalid(Hash, AbridgedCandidateReceipt), Invalid(Hash, CandidateReceipt),
} }
/// Messages received by the Candidate Backing subsystem. /// Messages received by the Candidate Backing subsystem.
@@ -59,7 +59,7 @@ pub enum CandidateBackingMessage {
GetBackedCandidates(Hash, oneshot::Sender<Vec<NewBackedCandidate>>), GetBackedCandidates(Hash, oneshot::Sender<Vec<NewBackedCandidate>>),
/// Note that the Candidate Backing subsystem should second the given candidate in the context of the /// 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. /// 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 /// 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. /// to a broader check by Misbehavior Arbitration. Agreements are simply tallied until a quorum is reached.
Statement(Hash, SignedFullStatement), Statement(Hash, SignedFullStatement),
@@ -69,22 +69,36 @@ pub enum CandidateBackingMessage {
#[derive(Debug)] #[derive(Debug)]
pub struct ValidationFailed; 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)] #[derive(Debug)]
pub enum CandidateValidationMessage { 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.
/// ///
/// Provide the relay-parent in whose context this should be validated, the full candidate receipt, /// This will implicitly attempt to gather the `OmittedValidationData` and `ValidationCode`
/// and the PoV. /// from the runtime API of the chain, based on the `relay_parent`
Validate( /// of the `CandidateDescriptor`.
Hash, /// If there is no state available which can provide this data, an error is returned.
AbridgedCandidateReceipt, ValidateFromChainState(
HeadData, CandidateDescriptor,
PoVBlock, Arc<PoV>,
oneshot::Sender<Result< oneshot::Sender<Result<ValidationResult, ValidationFailed>>,
(ValidationResult, GlobalValidationSchedule, LocalValidationData), ),
ValidationFailed, /// Validate a candidate with provided, exhaustive parameters for validation.
>>, ///
/// 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. /// Availability store subsystem message.
#[derive(Debug)] #[derive(Debug)]
pub enum AvailabilityStoreMessage { pub enum AvailabilityStoreMessage {
/// Query a `PoVBlock` from the AV store. /// Query a `PoV` from the AV store.
QueryPoV(Hash, oneshot::Sender<Option<PoVBlock>>), QueryPoV(Hash, oneshot::Sender<Option<PoV>>),
/// Query an `ErasureChunk` from the AV store. /// Query an `ErasureChunk` from the AV store.
QueryChunk(Hash, ValidatorIndex, oneshot::Sender<ErasureChunk>), QueryChunk(Hash, ValidatorIndex, oneshot::Sender<ErasureChunk>),
@@ -213,7 +227,7 @@ pub enum ProvisionableData {
/// Misbehavior reports are self-contained proofs of validator misbehavior. /// Misbehavior reports are self-contained proofs of validator misbehavior.
MisbehaviorReport(Hash, MisbehaviorReport), MisbehaviorReport(Hash, MisbehaviorReport),
/// Disputes trigger a broad dispute resolution process. /// 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. /// 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 /// This `CandidateDescriptor` should correspond to a candidate seconded under the provided
/// relay-parent hash. /// 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. /// Distribute a PoV for the given relay-parent and CandidateDescriptor.
/// The PoV should correctly hash to the PoV hash mentioned in the 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. /// An update from the network bridge.
NetworkBridgeUpdate(NetworkBridgeEvent), NetworkBridgeUpdate(NetworkBridgeEvent),
} }
+1 -1
View File
@@ -17,7 +17,7 @@
use babe_primitives::AuthorityId as BabeId; use babe_primitives::AuthorityId as BabeId;
use grandpa::AuthorityId as GrandpaId; use grandpa::AuthorityId as GrandpaId;
use pallet_staking::Forcing; 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_service::chain_spec::{get_account_id_from_seed, get_from_seed, Extensions};
use polkadot_test_runtime::constants::currency::DOTS; use polkadot_test_runtime::constants::currency::DOTS;
use sc_chain_spec::{ChainSpec, ChainType}; use sc_chain_spec::{ChainSpec, ChainType};
+4 -5
View File
@@ -26,9 +26,8 @@ use futures::future::Future;
use grandpa::FinalityProofProvider as GrandpaFinalityProofProvider; use grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
use log::info; use log::info;
use polkadot_network::{legacy::gossip::Known, protocol as network_protocol}; use polkadot_network::{legacy::gossip::Known, protocol as network_protocol};
use polkadot_primitives::{ use polkadot_primitives::v0::{
parachain::{self, CollatorId}, Block, BlockId, Hash, CollatorId, Id as ParaId,
Block, BlockId, Hash,
}; };
use polkadot_runtime_common::{parachains, registrar, BlockHashCount}; use polkadot_runtime_common::{parachains, registrar, BlockHashCount};
use polkadot_service::{ use polkadot_service::{
@@ -68,7 +67,7 @@ native_executor_instance!(
/// Create a new Polkadot test service for a full node. /// Create a new Polkadot test service for a full node.
pub fn polkadot_test_new_full( pub fn polkadot_test_new_full(
config: Configuration, config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>, collating_for: Option<(CollatorId, ParaId)>,
max_block_data_size: Option<u64>, max_block_data_size: Option<u64>,
authority_discovery_enabled: bool, authority_discovery_enabled: bool,
slot_duration: u64, slot_duration: u64,
@@ -287,7 +286,7 @@ where
let extrinsic = polkadot_test_runtime::UncheckedExtrinsic::new_signed( let extrinsic = polkadot_test_runtime::UncheckedExtrinsic::new_signed(
function.clone(), function.clone(),
polkadot_test_runtime::Address::Id(caller.public().into()), polkadot_test_runtime::Address::Id(caller.public().into()),
polkadot_primitives::Signature::Sr25519(signature.clone()), polkadot_primitives::v0::Signature::Sr25519(signature.clone()),
extra.clone(), extra.clone(),
); );
@@ -22,9 +22,9 @@ use std::sync::Arc;
use adder::{HeadData as AdderHead, BlockData as AdderBody}; use adder::{HeadData as AdderHead, BlockData as AdderBody};
use sp_core::Pair; use sp_core::Pair;
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use primitives::{ use primitives::v0::{
Hash, DownwardMessage, 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 collator::{ParachainContext, Network, BuildParachainContext, Cli, SubstrateCli};
use parking_lot::Mutex; use parking_lot::Mutex;
@@ -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";
+2 -55
View File
@@ -20,58 +20,5 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify, IdentifyAccount}; pub mod v0;
pub use polkadot_core_primitives::*; pub mod v1;
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;
}
}
@@ -21,18 +21,20 @@ use sp_std::prelude::*;
use sp_std::cmp::Ordering; use sp_std::cmp::Ordering;
use parity_scale_codec::{Encode, Decode}; use parity_scale_codec::{Encode, Decode};
use bitvec::vec::BitVec; use bitvec::vec::BitVec;
use super::{Hash, Balance, BlockNumber};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use primitives::{bytes, crypto::Pair}; use primitives::crypto::Pair;
use primitives::RuntimeDebug; use primitives::RuntimeDebug;
use runtime_primitives::traits::{AppVerify, Block as BlockT}; use runtime_primitives::traits::{AppVerify, Block as BlockT};
use inherents::InherentIdentifier; use inherents::InherentIdentifier;
use application_crypto::KeyTypeId; 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::{ pub use polkadot_parachain::primitives::{
Id, ParachainDispatchOrigin, LOWEST_USER_ID, UpwardMessage, HeadData, BlockData, Id, ParachainDispatchOrigin, LOWEST_USER_ID, UpwardMessage, HeadData, BlockData,
@@ -171,100 +173,6 @@ pub struct DutyRoster {
pub validator_duty: Vec<Chain>, 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` /// Extra data that is needed along with the other fields in a `CandidateReceipt`
/// to fully validate the candidate. /// 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 /// the relay-chain block in which context it should be executed, which implies
/// any blockchain state that must be referenced. /// any blockchain state that must be referenced.
pub fn hash(&self) -> Hash { pub fn hash(&self) -> Hash {
use runtime_primitives::traits::{BlakeTwo256, Hash};
BlakeTwo256::hash_of(self) BlakeTwo256::hash_of(self)
} }
} }
@@ -687,7 +594,6 @@ impl PoVBlock {
/// Compute hash of block data. /// Compute hash of block data.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn hash(&self) -> Hash { pub fn hash(&self) -> Hash {
use runtime_primitives::traits::{BlakeTwo256, Hash};
BlakeTwo256::hash_of(&self) BlakeTwo256::hash_of(&self)
} }
} }
@@ -716,16 +622,6 @@ pub struct ErasureChunk {
pub proof: Vec<Vec<u8>>, 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 /// Statements that can be made about parachain candidates. These are the
/// actual values that are signed. /// actual values that are signed.
#[derive(Clone, PartialEq, Eq, Encode, Decode, Hash)] #[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! { sp_api::decl_runtime_apis! {
/// The API for querying the state of parachains on-chain. /// The API for querying the state of parachains on-chain.
#[api_version(3)] #[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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
+478
View File
@@ -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,
}
@@ -9,7 +9,7 @@ A bitfield [signed](backing.md#signed-wrapper) by a particular validator about t
```rust ```rust
pub type SignedAvailabilityBitfield = Signed<Bitvec>; type SignedAvailabilityBitfield = Signed<Bitvec>;
struct Bitfields(Vec<(SignedAvailabilityBitfield)>), // bitfields sorted by validator index, ascending 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 ```rust
struct PoV(Vec<u8>); 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>>,
}
```
@@ -1,6 +1,7 @@
# Candidate Types # Candidate Types
Para candidates are some of the most common types, both within the runtime and on the Node-side. 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. 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, 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>,
}
```
@@ -91,6 +91,7 @@ enum CandidateBackingMessage {
GetBackedCandidates(Hash, ResponseChannel<Vec<NewBackedCandidate>>), GetBackedCandidates(Hash, ResponseChannel<Vec<NewBackedCandidate>>),
/// Note that the Candidate Backing subsystem should second the given candidate in the context of the /// 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. /// 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), Second(Hash, CandidateReceipt, PoV),
/// Note a peer validator's statement about a particular candidate. Disagreements about validity must be escalated /// 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. /// 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 ## 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 ```rust
/// Result of the validation of the candidate. /// Result of the validation of the candidate.
enum ValidationResult { enum ValidationResult {
/// Candidate is valid. /// Candidate is valid, and here are the outputs. In practice, this should be a shared type
Valid, /// so that validation caching can be done.
Valid(ValidationOutputs),
/// Candidate is invalid. /// Candidate is invalid.
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 { enum CandidateValidationMessage {
/// Validate a candidate with provided parameters. Returns `Err` if an only if an internal /// Validate a candidate with provided parameters. This will implicitly attempt to gather the
/// error is encountered. /// `OmittedValidationData` and `ValidationCode` from the runtime API of the chain,
/// In case no internal error was encontered it returns a tuple containing the result of /// based on the `relay_parent` of the `CandidateDescriptor`.
/// validation and `GlobalValidationSchedule` and `LocalValidationData` structures that /// If there is no state available which can provide this data, an error is returned.
/// may be used by the caller to make the candidate available. ValidateFromChainState(CandidateDescriptor, PoV, ResponseChannel<Result<ValidationResult>>),
/// A bad candidate will return `Ok((ValidationResult::Invalid, _, _)`, while a good one will
/// return `Ok((ValidationResult::Valid, _, _))`. /// Validate a candidate with provided parameters. Explicitly provide the `OmittedValidationData`
Validate( /// and `ValidationCode` so this can do full validation without needing to access the state of
Hash, CandidateReceipt, HeadData, PoV, ResponseChannel< /// the relay-chain.
Result<(ValidationResult, GlobalValidationSchedule, LocalValidationData)> ValidateFromExhaustive(
>), OmittedValidationData,
ValidationCode,
CandidateDescriptor,
PoV,
ResponseChannel<Result<ValidationResult>>,
),
} }
``` ```
+1 -1
View File
@@ -20,7 +20,7 @@
use std::sync::Arc; 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 sp_api::ProvideRuntimeApi;
use txpool_api::TransactionPool; use txpool_api::TransactionPool;
use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as BlockChainError}; use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as BlockChainError};
+1 -1
View File
@@ -28,7 +28,7 @@ use frame_support::{
weights::DispatchClass, 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_runtime::RuntimeDebug;
use sp_staking::SessionIndex; use sp_staking::SessionIndex;
+1 -1
View File
@@ -35,7 +35,7 @@ use sp_runtime::{
TransactionSource, TransactionValidityError, 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 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; type BalanceOf<T> = <CurrencyOf<T> as Currency<<T as system::Trait>::AccountId>>::Balance;
+2 -2
View File
@@ -79,7 +79,7 @@ use sp_runtime::{ModuleId,
use crate::slots; use crate::slots;
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use sp_std::vec::Vec; use sp_std::vec::Vec;
use primitives::parachain::{Id as ParaId, HeadData}; use primitives::v0::{Id as ParaId, HeadData};
pub type BalanceOf<T> = pub type BalanceOf<T> =
<<T as slots::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance; <<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 frame_support::traits::{Contains, ContainsLengthBound};
use sp_core::H256; 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 // 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. // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
use sp_runtime::{ use sp_runtime::{
+2 -2
View File
@@ -26,8 +26,8 @@ pub struct ToAuthor<R>(sp_std::marker::PhantomData<R>);
impl<R> OnUnbalanced<NegativeImbalance<R>> for ToAuthor<R> impl<R> OnUnbalanced<NegativeImbalance<R>> for ToAuthor<R>
where where
R: balances::Trait + authorship::Trait, R: balances::Trait + authorship::Trait,
<R as system::Trait>::AccountId: From<primitives::AccountId>, <R as system::Trait>::AccountId: From<primitives::v0::AccountId>,
<R as system::Trait>::AccountId: Into<primitives::AccountId>, <R as system::Trait>::AccountId: Into<primitives::v0::AccountId>,
<R as system::Trait>::Event: From<balances::RawEvent< <R as system::Trait>::Event: From<balances::RawEvent<
<R as system::Trait>::AccountId, <R as system::Trait>::AccountId,
<R as balances::Trait>::Balance, <R as balances::Trait>::Balance,
+1 -1
View File
@@ -27,7 +27,7 @@ pub mod slots;
pub mod crowdfund; pub mod crowdfund;
pub mod impls; pub mod impls;
use primitives::BlockNumber; use primitives::v0::BlockNumber;
use sp_runtime::{Perquintill, Perbill, FixedPointNumber, traits::Saturating}; use sp_runtime::{Perquintill, Perbill, FixedPointNumber, traits::Saturating};
use frame_support::{ use frame_support::{
parameter_types, traits::{Currency}, parameter_types, traits::{Currency},
+7 -13
View File
@@ -37,16 +37,13 @@ use frame_support::{
dispatch::IsSubType, dispatch::IsSubType,
weights::{DispatchClass, Weight}, weights::{DispatchClass, Weight},
}; };
use primitives::{ use primitives::v0::{
Balance, Balance, BlockNumber,
BlockNumber,
parachain::{
Id as ParaId, Chain, DutyRoster, AttestedCandidate, CompactStatement as Statement, ParachainDispatchOrigin, Id as ParaId, Chain, DutyRoster, AttestedCandidate, CompactStatement as Statement, ParachainDispatchOrigin,
UpwardMessage, ValidatorId, ActiveParas, CollatorId, Retriable, OmittedValidationData, UpwardMessage, ValidatorId, ActiveParas, CollatorId, Retriable, OmittedValidationData,
CandidateReceipt, GlobalValidationSchedule, AbridgedCandidateReceipt, CandidateReceipt, GlobalValidationSchedule, AbridgedCandidateReceipt,
LocalValidationData, Scheduling, ValidityAttestation, NEW_HEADS_IDENTIFIER, PARACHAIN_KEY_TYPE_ID, LocalValidationData, Scheduling, ValidityAttestation, NEW_HEADS_IDENTIFIER, PARACHAIN_KEY_TYPE_ID,
ValidatorSignature, SigningContext, HeadData, ValidationCode, ValidatorSignature, SigningContext, HeadData, ValidationCode,
},
Remark, DownwardMessage Remark, DownwardMessage
}; };
use frame_support::{ 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. /// 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. /// Origin for the parachains module.
@@ -1681,13 +1678,10 @@ mod tests {
}, },
testing::TestXt, testing::TestXt,
}; };
use primitives::{ use primitives::v0::{
parachain::{
CandidateReceipt, ValidityAttestation, ValidatorId, Info as ParaInfo, CandidateReceipt, ValidityAttestation, ValidatorId, Info as ParaInfo,
Scheduling, CandidateCommitments, Scheduling, CandidateCommitments,
}, BlockNumber, Header,
BlockNumber,
Header,
}; };
use keyring::Sr25519Keyring; use keyring::Sr25519Keyring;
use frame_support::{ use frame_support::{
@@ -1819,7 +1813,7 @@ mod tests {
} }
mod time { mod time {
use primitives::{Moment, BlockNumber}; use primitives::v0::{Moment, BlockNumber};
pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const MILLISECS_PER_BLOCK: Moment = 6000;
pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 1 * HOURS; pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 1 * HOURS;
// These time units are defined in number of blocks. // These time units are defined in number of blocks.
@@ -2246,7 +2240,7 @@ mod tests {
println!("session index {}", i); println!("session index {}", i);
Staking::on_finalize(System::block_number()); Staking::on_finalize(System::block_number());
System::set_block_number((i + 1).into()); 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 // 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 // we need to first get it via `System::finalize` and then set it
+4 -6
View File
@@ -34,7 +34,7 @@ use frame_support::{
weights::{DispatchClass, Weight}, weights::{DispatchClass, Weight},
}; };
use system::{self, ensure_root, ensure_signed}; 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, Id as ParaId, CollatorId, Scheduling, LOWEST_USER_ID, SwapAux, Info as ParaInfo, ActiveParas,
Retriable, ValidationCode, HeadData, Retriable, ValidationCode, HeadData,
}; };
@@ -213,7 +213,7 @@ fn build<T: Trait>(config: &GenesisConfig<T>) {
Parachains::put(&only_ids); Parachains::put(&only_ids);
for (id, code, genesis) in p { 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. // no ingress -- a chain cannot be routed to until it is live.
<parachains::Code>::insert(&id, &code); <parachains::Code>::insert(&id, &code);
<parachains::Heads>::insert(&id, &genesis); <parachains::Heads>::insert(&id, &genesis);
@@ -670,12 +670,10 @@ mod tests {
AccountIdConversion, Extrinsic as ExtrinsicT, AccountIdConversion, Extrinsic as ExtrinsicT,
}, testing::{UintAuthorityId, TestXt}, KeyTypeId, Perbill, curve::PiecewiseLinear, }, testing::{UintAuthorityId, TestXt}, KeyTypeId, Perbill, curve::PiecewiseLinear,
}; };
use primitives::{ use primitives::v0::{
parachain::{
ValidatorId, Info as ParaInfo, Scheduling, LOWEST_USER_ID, AttestedCandidate, ValidatorId, Info as ParaInfo, Scheduling, LOWEST_USER_ID, AttestedCandidate,
CandidateReceipt, HeadData, ValidityAttestation, CompactStatement as Statement, Chain, CandidateReceipt, HeadData, ValidityAttestation, CompactStatement as Statement, Chain,
CollatorPair, CandidateCommitments, CollatorPair, CandidateCommitments,
},
Balance, BlockNumber, Header, Signature, Balance, BlockNumber, Header, Signature,
}; };
use frame_support::{ use frame_support::{
@@ -869,7 +867,7 @@ mod tests {
// This is needed for a custom `AccountId` type which is `u64` in testing here. // This is needed for a custom `AccountId` type which is `u64` in testing here.
pub mod test_keys { pub mod test_keys {
use sp_core::{crypto::KeyTypeId, sr25519}; use sp_core::{crypto::KeyTypeId, sr25519};
use primitives::Signature; use primitives::v0::Signature;
pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"test"); pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"test");
+2 -3
View File
@@ -28,7 +28,7 @@ use frame_support::{
traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get, Randomness}, traits::{Currency, ReservableCurrency, WithdrawReason, ExistenceRequirement, Get, Randomness},
weights::{DispatchClass, Weight}, weights::{DispatchClass, Weight},
}; };
use primitives::parachain::{ use primitives::v0::{
SwapAux, PARACHAIN_INFO, Id as ParaId, ValidationCode, HeadData, SwapAux, PARACHAIN_INFO, Id as ParaId, ValidationCode, HeadData,
}; };
use system::{ensure_signed, ensure_root}; use system::{ensure_signed, ensure_root};
@@ -890,8 +890,7 @@ mod tests {
traits::{OnInitialize, OnFinalize} traits::{OnInitialize, OnFinalize}
}; };
use balances; use balances;
use primitives::{BlockNumber, Header}; use primitives::v0::{BlockNumber, Header, Id as ParaId, Info as ParaInfo, Scheduling};
use primitives::parachain::{Id as ParaId, Info as ParaInfo, Scheduling};
impl_outer_origin! { impl_outer_origin! {
pub enum Origin for Test {} pub enum Origin for Test {}
+3 -3
View File
@@ -16,7 +16,7 @@
/// Money matters. /// Money matters.
pub mod currency { pub mod currency {
use primitives::Balance; use primitives::v0::Balance;
pub const DOTS: Balance = 1_000_000_000_000; pub const DOTS: Balance = 1_000_000_000_000;
pub const DOLLARS: Balance = DOTS / 6; pub const DOLLARS: Balance = DOTS / 6;
@@ -30,7 +30,7 @@ pub mod currency {
/// Time and blocks. /// Time and blocks.
pub mod time { pub mod time {
use primitives::{Moment, BlockNumber}; use primitives::v0::{Moment, BlockNumber};
// Kusama & mainnet // Kusama & mainnet
pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const MILLISECS_PER_BLOCK: Moment = 6000;
// Testnet // Testnet
@@ -55,7 +55,7 @@ pub mod time {
/// Fee-related. /// Fee-related.
pub mod fee { pub mod fee {
pub use sp_runtime::Perbill; pub use sp_runtime::Perbill;
use primitives::Balance; use primitives::v0::Balance;
use runtime_common::ExtrinsicBaseWeight; use runtime_common::ExtrinsicBaseWeight;
use frame_support::weights::{ use frame_support::weights::{
WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients,
+7 -6
View File
@@ -23,9 +23,10 @@
use sp_std::prelude::*; use sp_std::prelude::*;
use sp_core::u32_trait::{_1, _2, _3, _4, _5}; use sp_core::u32_trait::{_1, _2, _3, _4, _5};
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use primitives::{ use primitives::v0::{
self as parachain,
AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, ActiveParas, AbridgedCandidateReceipt, SigningContext,
}; };
use runtime_common::{ use runtime_common::{
attestations, claims, parachains, registrar, slots, SlowAdjustingFeeUpdate, attestations, claims, parachains, registrar, slots, SlowAdjustingFeeUpdate,
@@ -560,7 +561,7 @@ impl grandpa::Trait for Runtime {
type HandleEquivocation = grandpa::EquivocationHandler< type HandleEquivocation = grandpa::EquivocationHandler<
Self::KeyOwnerIdentification, Self::KeyOwnerIdentification,
primitives::fisherman::FishermanAppCrypto, primitives::v0::fisherman::FishermanAppCrypto,
Runtime, Runtime,
Offences, Offences,
>; >;
@@ -596,7 +597,7 @@ parameter_types! {
} }
impl parachains::Trait for Runtime { impl parachains::Trait for Runtime {
type AuthorityId = primitives::fisherman::FishermanAppCrypto; type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto;
type Origin = Origin; type Origin = Origin;
type Call = Call; type Call = Call;
type ParachainCurrency = Balances; type ParachainCurrency = Balances;
@@ -939,7 +940,7 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
construct_runtime! { construct_runtime! {
pub enum Runtime where pub enum Runtime where
Block = Block, Block = Block,
NodeBlock = primitives::Block, NodeBlock = primitives::v0::Block,
UncheckedExtrinsic = UncheckedExtrinsic UncheckedExtrinsic = UncheckedExtrinsic
{ {
// Basic stuff; balances is uncallable initially. // Basic stuff; balances is uncallable initially.
@@ -1147,7 +1148,7 @@ sp_api::impl_runtime_apis! {
fn signing_context() -> SigningContext { fn signing_context() -> SigningContext {
Parachains::signing_context() 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) Parachains::downward_messages(id)
} }
} }
@@ -19,9 +19,7 @@
//! Configuration can change only at session boundaries and is buffered until then. //! Configuration can change only at session boundaries and is buffered until then.
use sp_std::prelude::*; use sp_std::prelude::*;
use primitives::{ use primitives::v1::ValidatorId;
parachain::{ValidatorId},
};
use frame_support::{ use frame_support::{
decl_storage, decl_module, decl_error, decl_storage, decl_module, decl_error,
dispatch::DispatchResult, dispatch::DispatchResult,
+117 -88
View File
@@ -21,12 +21,10 @@
//! to included. //! to included.
use sp_std::prelude::*; use sp_std::prelude::*;
use primitives::{ use primitives::v1::{
parachain::{ ValidatorId, CommittedCandidateReceipt, ValidatorIndex, Id as ParaId,
ValidatorId, AbridgedCandidateReceipt, ValidatorIndex, Id as ParaId,
AvailabilityBitfield as AvailabilityBitfield, SignedAvailabilityBitfields, SigningContext, AvailabilityBitfield as AvailabilityBitfield, SignedAvailabilityBitfields, SigningContext,
BackedCandidate, CoreIndex, GroupIndex, CoreAssignment, BackedCandidate, CoreIndex, GroupIndex, CoreAssignment,
},
}; };
use frame_support::{ use frame_support::{
decl_storage, decl_module, decl_error, ensure, dispatch::DispatchResult, IterableStorageMap, decl_storage, decl_module, decl_error, ensure, dispatch::DispatchResult, IterableStorageMap,
@@ -53,13 +51,15 @@ pub struct AvailabilityBitfieldRecord<N> {
} }
/// A backed candidate pending availability. /// 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)] #[derive(Encode, Decode, PartialEq)]
#[cfg_attr(test, derive(Debug))] #[cfg_attr(test, derive(Debug))]
pub struct CandidatePendingAvailability<H, N> { pub struct CandidatePendingAvailability<H, N> {
/// The availability core this is assigned to. /// The availability core this is assigned to.
core: CoreIndex, core: CoreIndex,
/// The candidate receipt itself. /// The candidate receipt itself.
receipt: AbridgedCandidateReceipt<H>, receipt: CommittedCandidateReceipt<H>,
/// The received availability votes. One bit per validator. /// The received availability votes. One bit per validator.
availability_votes: BitVec<BitOrderLsb0, u8>, availability_votes: BitVec<BitOrderLsb0, u8>,
/// The block number of the relay-parent of the receipt. /// 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]; 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()); last_index = Some(signed_bitfield.validator_index());
} }
@@ -331,11 +334,11 @@ impl<T: Trait> Module<T> {
// list. // list.
'a: 'a:
for candidate in &candidates { 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. // we require that the candidate is in the context of the parent block.
ensure!( ensure!(
candidate.candidate.relay_parent == parent_hash, candidate.descriptor().relay_parent == parent_hash,
Error::<T>::CandidateNotInParentContext, Error::<T>::CandidateNotInParentContext,
); );
@@ -348,17 +351,17 @@ impl<T: Trait> Module<T> {
ensure!(code_upgrade_allowed, Error::<T>::PrematureCodeUpgrade); ensure!(code_upgrade_allowed, Error::<T>::PrematureCodeUpgrade);
ensure!( ensure!(
candidate.candidate.check_signature().is_ok(), candidate.descriptor().check_collator_signature().is_ok(),
Error::<T>::NotCollatorSigned, Error::<T>::NotCollatorSigned,
); );
for (i, assignment) in scheduled[skip..].iter().enumerate() { for (i, assignment) in scheduled[skip..].iter().enumerate() {
check_assignment_in_order(assignment)?; 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() { if let Some(required_collator) = assignment.required_collator() {
ensure!( ensure!(
required_collator == &candidate.candidate.collator, required_collator == &candidate.descriptor().collator,
Error::<T>::WrongCollator, Error::<T>::WrongCollator,
); );
} }
@@ -377,7 +380,7 @@ impl<T: Trait> Module<T> {
// check the signatures in the backing and that it is a majority. // check the signatures in the backing and that it is a majority.
{ {
let maybe_amount_validated let maybe_amount_validated
= primitives::parachain::check_candidate_backing( = primitives::v1::check_candidate_backing(
&candidate, &candidate,
&signing_context, &signing_context,
group_vals.len(), group_vals.len(),
@@ -419,7 +422,7 @@ impl<T: Trait> Module<T> {
// one more sweep for actually writing to storage. // one more sweep for actually writing to storage.
for (candidate, core) in candidates.into_iter().zip(core_indices.iter().cloned()) { 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. // initialize all availability votes to 0.
let availability_votes: BitVec<BitOrderLsb0, u8> let availability_votes: BitVec<BitOrderLsb0, u8>
@@ -438,7 +441,7 @@ impl<T: Trait> Module<T> {
fn enact_candidate( fn enact_candidate(
relay_parent_number: T::BlockNumber, relay_parent_number: T::BlockNumber,
receipt: AbridgedCandidateReceipt<T::Hash>, receipt: CommittedCandidateReceipt<T::Hash>,
) -> Weight { ) -> Weight {
let commitments = receipt.commitments; let commitments = receipt.commitments;
let config = <configuration::Module<T>>::config(); 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); let mut weight = T::DbWeight::get().reads_writes(1, 0);
if let Some(new_code) = commitments.new_validation_code { if let Some(new_code) = commitments.new_validation_code {
weight += <paras::Module<T>>::schedule_code_upgrade( weight += <paras::Module<T>>::schedule_code_upgrade(
receipt.parachain_index, receipt.descriptor.para_id,
new_code, new_code,
relay_parent_number + config.validation_upgrade_delay, relay_parent_number + config.validation_upgrade_delay,
); );
} }
weight + <paras::Module<T>>::note_new_head( weight + <paras::Module<T>>::note_new_head(
receipt.parachain_index, receipt.descriptor.para_id,
receipt.head_data, commitments.head_data,
relay_parent_number, relay_parent_number,
) )
} }
@@ -495,10 +498,11 @@ const fn availability_threshold(n_validators: usize) -> usize {
mod tests { mod tests {
use super::*; use super::*;
use primitives::{BlockNumber, Hash}; use primitives::v1::{BlockNumber, Hash};
use primitives::parachain::{ use primitives::v1::{
SignedAvailabilityBitfield, CompactStatement as Statement, ValidityAttestation, CollatorId, SignedAvailabilityBitfield, CompactStatement as Statement, ValidityAttestation, CollatorId,
CandidateCommitments, SignedStatement, AssignmentKind, CandidateCommitments, SignedStatement, CandidateDescriptor, HeadData, ValidationCode,
AssignmentKind,
}; };
use frame_support::traits::{OnFinalize, OnInitialize}; use frame_support::traits::{OnFinalize, OnInitialize};
use keyring::Sr25519Keyring; use keyring::Sr25519Keyring;
@@ -545,22 +549,22 @@ mod tests {
fn collator_sign_candidate( fn collator_sign_candidate(
collator: Sr25519Keyring, 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( let payload = primitives::v1::collator_signature_payload(
&candidate.relay_parent, &candidate.descriptor.relay_parent,
&candidate.parachain_index, &candidate.descriptor.para_id,
&candidate.pov_block_hash, &candidate.descriptor.pov_hash,
); );
candidate.signature = collator.sign(&payload[..]).into(); candidate.descriptor.signature = collator.sign(&payload[..]).into();
assert!(candidate.check_signature().is_ok()); assert!(candidate.descriptor().check_collator_signature().is_ok());
} }
fn back_candidate( fn back_candidate(
candidate: AbridgedCandidateReceipt, candidate: CommittedCandidateReceipt,
validators: &[Sr25519Keyring], validators: &[Sr25519Keyring],
group: &[ValidatorIndex], group: &[ValidatorIndex],
signing_context: &SigningContext, signing_context: &SigningContext,
@@ -603,7 +607,7 @@ mod tests {
BackingKind::Lacking => false, BackingKind::Lacking => false,
}; };
let successfully_backed = primitives::parachain::check_candidate_backing( let successfully_backed = primitives::v1::check_candidate_backing(
&backed, &backed,
signing_context, signing_context,
group.len(), 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] #[test]
fn collect_pending_cleans_up_pending() { fn collect_pending_cleans_up_pending() {
let chain_a = ParaId::from(1); let chain_a = ParaId::from(1);
@@ -895,11 +926,11 @@ mod tests {
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability { <PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
core: CoreIndex::from(0), core: CoreIndex::from(0),
receipt: AbridgedCandidateReceipt { receipt: TestCandidateBuilder {
parachain_index: chain_a, para_id: chain_a,
head_data: vec![1, 2, 3, 4].into(), head_data: vec![1, 2, 3, 4].into(),
..Default::default() ..Default::default()
}, }.build(),
availability_votes: default_availability_votes(), availability_votes: default_availability_votes(),
relay_parent_number: 0, relay_parent_number: 0,
backed_in_number: 0, backed_in_number: 0,
@@ -907,11 +938,11 @@ mod tests {
<PendingAvailability<Test>>::insert(chain_b, CandidatePendingAvailability { <PendingAvailability<Test>>::insert(chain_b, CandidatePendingAvailability {
core: CoreIndex::from(1), core: CoreIndex::from(1),
receipt: AbridgedCandidateReceipt { receipt: TestCandidateBuilder {
parachain_index: chain_b, para_id: chain_b,
head_data: vec![5, 6, 7, 8].into(), head_data: vec![5, 6, 7, 8].into(),
..Default::default() ..Default::default()
}, }.build(),
availability_votes: default_availability_votes(), availability_votes: default_availability_votes(),
relay_parent_number: 0, relay_parent_number: 0,
backed_in_number: 0, backed_in_number: 0,
@@ -1043,12 +1074,12 @@ mod tests {
// unscheduled candidate. // unscheduled candidate.
{ {
let mut candidate = AbridgedCandidateReceipt { let mut candidate = TestCandidateBuilder {
parachain_index: chain_a, para_id: chain_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
..Default::default() ..Default::default()
}; }.build();
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::One, Sr25519Keyring::One,
&mut candidate, &mut candidate,
@@ -1071,18 +1102,18 @@ mod tests {
// candidates out of order. // candidates out of order.
{ {
let mut candidate_a = AbridgedCandidateReceipt { let mut candidate_a = TestCandidateBuilder {
parachain_index: chain_a, para_id: chain_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
..Default::default() ..Default::default()
}; }.build();
let mut candidate_b = AbridgedCandidateReceipt { let mut candidate_b = TestCandidateBuilder {
parachain_index: chain_b, para_id: chain_b,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([2; 32]), pov_hash: Hash::from([2; 32]),
..Default::default() ..Default::default()
}; }.build();
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::One, Sr25519Keyring::One,
@@ -1119,12 +1150,12 @@ mod tests {
// candidate not backed. // candidate not backed.
{ {
let mut candidate = AbridgedCandidateReceipt { let mut candidate = TestCandidateBuilder {
parachain_index: chain_a, para_id: chain_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
..Default::default() ..Default::default()
}; }.build();
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::One, Sr25519Keyring::One,
&mut candidate, &mut candidate,
@@ -1150,12 +1181,12 @@ mod tests {
let wrong_parent_hash = Hash::from([222; 32]); let wrong_parent_hash = Hash::from([222; 32]);
assert!(System::parent_hash() != wrong_parent_hash); assert!(System::parent_hash() != wrong_parent_hash);
let mut candidate = AbridgedCandidateReceipt { let mut candidate = TestCandidateBuilder {
parachain_index: chain_a, para_id: chain_a,
relay_parent: wrong_parent_hash, relay_parent: wrong_parent_hash,
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
..Default::default() ..Default::default()
}; }.build();
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::One, Sr25519Keyring::One,
&mut candidate, &mut candidate,
@@ -1178,12 +1209,12 @@ mod tests {
// candidate has wrong collator. // candidate has wrong collator.
{ {
let mut candidate = AbridgedCandidateReceipt { let mut candidate = TestCandidateBuilder {
parachain_index: thread_a, para_id: thread_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
..Default::default() ..Default::default()
}; }.build();
assert!(CollatorId::from(Sr25519Keyring::One.public()) != thread_collator); assert!(CollatorId::from(Sr25519Keyring::One.public()) != thread_collator);
collator_sign_candidate( collator_sign_candidate(
@@ -1212,12 +1243,12 @@ mod tests {
// candidate not well-signed by collator. // candidate not well-signed by collator.
{ {
let mut candidate = AbridgedCandidateReceipt { let mut candidate = TestCandidateBuilder {
parachain_index: thread_a, para_id: thread_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
..Default::default() ..Default::default()
}; }.build();
assert_eq!(CollatorId::from(Sr25519Keyring::Two.public()), thread_collator); assert_eq!(CollatorId::from(Sr25519Keyring::Two.public()), thread_collator);
collator_sign_candidate( collator_sign_candidate(
@@ -1225,7 +1256,8 @@ mod tests {
&mut candidate, &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( let backed = back_candidate(
candidate, candidate,
@@ -1244,12 +1276,12 @@ mod tests {
// para occupied - reject. // para occupied - reject.
{ {
let mut candidate = AbridgedCandidateReceipt { let mut candidate = TestCandidateBuilder {
parachain_index: chain_a, para_id: chain_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
..Default::default() ..Default::default()
}; }.build();
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::One, Sr25519Keyring::One,
@@ -1283,16 +1315,13 @@ mod tests {
// interfering code upgrade - reject // interfering code upgrade - reject
{ {
let mut candidate = AbridgedCandidateReceipt { let mut candidate = TestCandidateBuilder {
parachain_index: chain_a, para_id: chain_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
commitments: CandidateCommitments {
new_validation_code: Some(vec![5, 6, 7, 8].into()), new_validation_code: Some(vec![5, 6, 7, 8].into()),
..Default::default() ..Default::default()
}, }.build();
..Default::default()
};
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::One, Sr25519Keyring::One,
@@ -1381,34 +1410,34 @@ mod tests {
group_idx: GroupIndex::from(2), group_idx: GroupIndex::from(2),
}; };
let mut candidate_a = AbridgedCandidateReceipt { let mut candidate_a = TestCandidateBuilder {
parachain_index: chain_a, para_id: chain_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([1; 32]), pov_hash: Hash::from([1; 32]),
..Default::default() ..Default::default()
}; }.build();
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::One, Sr25519Keyring::One,
&mut candidate_a, &mut candidate_a,
); );
let mut candidate_b = AbridgedCandidateReceipt { let mut candidate_b = TestCandidateBuilder {
parachain_index: chain_b, para_id: chain_b,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([2; 32]), pov_hash: Hash::from([2; 32]),
..Default::default() ..Default::default()
}; }.build();
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::One, Sr25519Keyring::One,
&mut candidate_b, &mut candidate_b,
); );
let mut candidate_c = AbridgedCandidateReceipt { let mut candidate_c = TestCandidateBuilder {
parachain_index: thread_a, para_id: thread_a,
relay_parent: System::parent_hash(), relay_parent: System::parent_hash(),
pov_block_hash: Hash::from([3; 32]), pov_hash: Hash::from([3; 32]),
..Default::default() ..Default::default()
}; }.build();
collator_sign_candidate( collator_sign_candidate(
Sr25519Keyring::Two, Sr25519Keyring::Two,
&mut candidate_c, &mut candidate_c,
@@ -22,9 +22,8 @@
//! this module. //! this module.
use sp_std::prelude::*; use sp_std::prelude::*;
use primitives::{ use primitives::v1::{
inclusion_inherent, BackedCandidate, SignedAvailabilityBitfields, INCLUSION_INHERENT_IDENTIFIER,
parachain::{BackedCandidate, SignedAvailabilityBitfields},
}; };
use frame_support::{ use frame_support::{
decl_error, decl_module, decl_storage, ensure, decl_error, decl_module, decl_storage, ensure,
@@ -127,7 +126,7 @@ decl_module! {
impl<T: Trait> ProvideInherent for Module<T> { impl<T: Trait> ProvideInherent for Module<T> {
type Call = Call<T>; type Call = Call<T>;
type Error = MakeFatalError<()>; 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> { fn create_inherent(data: &InherentData) -> Option<Self::Call> {
data.get_data(&Self::INHERENT_IDENTIFIER) data.get_data(&Self::INHERENT_IDENTIFIER)
@@ -21,9 +21,7 @@
use sp_std::prelude::*; use sp_std::prelude::*;
use frame_support::weights::Weight; use frame_support::weights::Weight;
use primitives::{ use primitives::v1::ValidatorId;
parachain::{ValidatorId},
};
use frame_support::{ use frame_support::{
decl_storage, decl_module, decl_error, traits::Randomness, decl_storage, decl_module, decl_error, traits::Randomness,
}; };
+1 -4
View File
@@ -24,10 +24,7 @@ use sp_runtime::{
BlakeTwo256, IdentityLookup, BlakeTwo256, IdentityLookup,
}, },
}; };
use primitives::{ use primitives::v1::{BlockNumber, Header};
BlockNumber,
Header,
};
use frame_support::{ use frame_support::{
impl_outer_origin, impl_outer_dispatch, parameter_types, impl_outer_origin, impl_outer_dispatch, parameter_types,
weights::Weight, traits::Randomness as RandomnessT, weights::Weight, traits::Randomness as RandomnessT,
+3 -3
View File
@@ -26,8 +26,8 @@
use sp_std::prelude::*; use sp_std::prelude::*;
use sp_std::marker::PhantomData; use sp_std::marker::PhantomData;
use sp_runtime::traits::One; use sp_runtime::traits::One;
use primitives::{ use primitives::v1::{
parachain::{Id as ParaId, ValidationCode, HeadData}, Id as ParaId, ValidationCode, HeadData,
}; };
use frame_support::{ use frame_support::{
decl_storage, decl_module, decl_error, decl_storage, decl_module, decl_error,
@@ -541,7 +541,7 @@ impl<T: Trait> Module<T> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use primitives::BlockNumber; use primitives::v1::BlockNumber;
use frame_support::traits::{OnFinalize, OnInitialize}; use frame_support::traits::{OnFinalize, OnInitialize};
use crate::mock::{new_test_ext, Paras, System, GenesisConfig as MockGenesisConfig}; use crate::mock::{new_test_ext, Paras, System, GenesisConfig as MockGenesisConfig};
+2 -4
View File
@@ -37,11 +37,9 @@
use sp_std::prelude::*; use sp_std::prelude::*;
use sp_std::convert::TryInto; use sp_std::convert::TryInto;
use primitives::{ use primitives::v1::{
parachain::{
Id as ParaId, ValidatorIndex, CoreAssignment, CoreOccupied, CoreIndex, AssignmentKind, Id as ParaId, ValidatorIndex, CoreAssignment, CoreOccupied, CoreIndex, AssignmentKind,
GroupIndex, ParathreadClaim, ParathreadEntry, GroupIndex, ParathreadClaim, ParathreadEntry,
},
}; };
use frame_support::{ use frame_support::{
decl_storage, decl_module, decl_error, decl_storage, decl_module, decl_error,
@@ -586,7 +584,7 @@ impl<T: Trait> Module<T> {
mod tests { mod tests {
use super::*; use super::*;
use primitives::{BlockNumber, parachain::{CollatorId, ValidatorId}}; use primitives::v1::{BlockNumber, ValidatorId, CollatorId};
use frame_support::traits::{OnFinalize, OnInitialize}; use frame_support::traits::{OnFinalize, OnInitialize};
use keyring::Sr25519Keyring; use keyring::Sr25519Keyring;
+3 -3
View File
@@ -16,7 +16,7 @@
/// Money matters. /// Money matters.
pub mod currency { pub mod currency {
use primitives::Balance; use primitives::v0::Balance;
pub const DOTS: Balance = 1_000_000_000_000; pub const DOTS: Balance = 1_000_000_000_000;
pub const DOLLARS: Balance = DOTS / 100; // 10_000_000_000 pub const DOLLARS: Balance = DOTS / 100; // 10_000_000_000
@@ -30,7 +30,7 @@ pub mod currency {
/// Time and blocks. /// Time and blocks.
pub mod time { pub mod time {
use primitives::{Moment, BlockNumber}; use primitives::v0::{Moment, BlockNumber};
pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const MILLISECS_PER_BLOCK: Moment = 6000;
pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK;
pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 4 * HOURS; pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 4 * HOURS;
@@ -47,7 +47,7 @@ pub mod time {
/// Fee-related. /// Fee-related.
pub mod fee { pub mod fee {
pub use sp_runtime::Perbill; pub use sp_runtime::Perbill;
use primitives::Balance; use primitives::v0::Balance;
use runtime_common::ExtrinsicBaseWeight; use runtime_common::ExtrinsicBaseWeight;
use frame_support::weights::{ use frame_support::weights::{
WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients,
+7 -6
View File
@@ -31,9 +31,10 @@ use runtime_common::{
use sp_std::prelude::*; use sp_std::prelude::*;
use sp_core::u32_trait::{_1, _2, _3, _4, _5}; use sp_core::u32_trait::{_1, _2, _3, _4, _5};
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use primitives::{ use primitives::v0::{
self as parachain,
AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, ActiveParas, AbridgedCandidateReceipt, SigningContext,
}; };
use sp_runtime::{ use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys, ModuleId, create_runtime_str, generic, impl_opaque_keys, ModuleId,
@@ -629,7 +630,7 @@ impl grandpa::Trait for Runtime {
type HandleEquivocation = grandpa::EquivocationHandler< type HandleEquivocation = grandpa::EquivocationHandler<
Self::KeyOwnerIdentification, Self::KeyOwnerIdentification,
primitives::fisherman::FishermanAppCrypto, primitives::v0::fisherman::FishermanAppCrypto,
Runtime, Runtime,
Offences, Offences,
>; >;
@@ -666,7 +667,7 @@ parameter_types! {
} }
impl parachains::Trait for Runtime { impl parachains::Trait for Runtime {
type AuthorityId = primitives::fisherman::FishermanAppCrypto; type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto;
type Origin = Origin; type Origin = Origin;
type Call = Call; type Call = Call;
type ParachainCurrency = Balances; type ParachainCurrency = Balances;
@@ -943,7 +944,7 @@ impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
construct_runtime! { construct_runtime! {
pub enum Runtime where pub enum Runtime where
Block = Block, Block = Block,
NodeBlock = primitives::Block, NodeBlock = primitives::v0::Block,
UncheckedExtrinsic = UncheckedExtrinsic UncheckedExtrinsic = UncheckedExtrinsic
{ {
// Basic stuff; balances is uncallable initially. // Basic stuff; balances is uncallable initially.
@@ -1147,7 +1148,7 @@ sp_api::impl_runtime_apis! {
fn signing_context() -> SigningContext { fn signing_context() -> SigningContext {
Parachains::signing_context() 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) Parachains::downward_messages(id)
} }
} }
+1 -1
View File
@@ -29,7 +29,7 @@ use frame_support::{
use keyring::AccountKeyring; use keyring::AccountKeyring;
use polkadot_runtime::constants::currency::*; use polkadot_runtime::constants::currency::*;
use polkadot_runtime::{self, Runtime}; use polkadot_runtime::{self, Runtime};
use primitives::AccountId; use primitives::v0::AccountId;
use runtime_common::MaximumBlockWeight; use runtime_common::MaximumBlockWeight;
use democracy::Call as DemocracyCall; use democracy::Call as DemocracyCall;
@@ -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 /// 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. /// should be incremented by one for every block produced.
pub fn needed_extrinsics( pub fn needed_extrinsics(
heads: Vec<polkadot_primitives::parachain::AttestedCandidate>, heads: Vec<polkadot_primitives::v0::AttestedCandidate>,
i: u64, i: u64,
) -> Vec<polkadot_test_runtime::UncheckedExtrinsic> { ) -> Vec<polkadot_test_runtime::UncheckedExtrinsic> {
use polkadot_runtime_common::parachains; use polkadot_runtime_common::parachains;
@@ -16,7 +16,7 @@
/// Money matters. /// Money matters.
pub mod currency { pub mod currency {
use primitives::Balance; use primitives::v0::Balance;
pub const DOTS: Balance = 1_000_000_000_000; pub const DOTS: Balance = 1_000_000_000_000;
pub const DOLLARS: Balance = DOTS; pub const DOLLARS: Balance = DOTS;
@@ -26,7 +26,7 @@ pub mod currency {
/// Time and blocks. /// Time and blocks.
pub mod time { pub mod time {
use primitives::{Moment, BlockNumber}; use primitives::v0::{Moment, BlockNumber};
// Testnet // Testnet
pub const MILLISECS_PER_BLOCK: Moment = 1000; pub const MILLISECS_PER_BLOCK: Moment = 1000;
pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK;
@@ -45,7 +45,7 @@ pub mod time {
/// Fee-related. /// Fee-related.
pub mod fee { pub mod fee {
pub use sp_runtime::Perbill; pub use sp_runtime::Perbill;
use primitives::Balance; use primitives::v0::Balance;
use runtime_common::ExtrinsicBaseWeight; use runtime_common::ExtrinsicBaseWeight;
use frame_support::weights::{ use frame_support::weights::{
WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients,
+6 -5
View File
@@ -22,9 +22,10 @@
use rstd::prelude::*; use rstd::prelude::*;
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use primitives::{ use primitives::v0::{
self as parachain,
AccountId, AccountIndex, Balance, BlockNumber, Hash as HashT, Nonce, Signature, Moment, AccountId, AccountIndex, Balance, BlockNumber, Hash as HashT, Nonce, Signature, Moment,
parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, ValidityError, ActiveParas, AbridgedCandidateReceipt, SigningContext, ValidityError,
}; };
use runtime_common::{ use runtime_common::{
attestations, claims, parachains, registrar, slots, SlowAdjustingFeeUpdate, attestations, claims, parachains, registrar, slots, SlowAdjustingFeeUpdate,
@@ -375,7 +376,7 @@ parameter_types! {
} }
impl parachains::Trait for Runtime { impl parachains::Trait for Runtime {
type AuthorityId = primitives::fisherman::FishermanAppCrypto; type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto;
type Origin = Origin; type Origin = Origin;
type Call = Call; type Call = Call;
type ParachainCurrency = Balances; type ParachainCurrency = Balances;
@@ -521,7 +522,7 @@ impl sudo::Trait for Runtime {
construct_runtime! { construct_runtime! {
pub enum Runtime where pub enum Runtime where
Block = Block, Block = Block,
NodeBlock = primitives::Block, NodeBlock = primitives::v0::Block,
UncheckedExtrinsic = UncheckedExtrinsic UncheckedExtrinsic = UncheckedExtrinsic
{ {
// Basic stuff; balances is uncallable initially. // Basic stuff; balances is uncallable initially.
@@ -702,7 +703,7 @@ sp_api::impl_runtime_apis! {
fn signing_context() -> SigningContext { fn signing_context() -> SigningContext {
Parachains::signing_context() 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) Parachains::downward_messages(id)
} }
} }
+3 -3
View File
@@ -16,7 +16,7 @@
/// Money matters. /// Money matters.
pub mod currency { pub mod currency {
use primitives::Balance; use primitives::v0::Balance;
pub const DOTS: Balance = 1_000_000_000_000; pub const DOTS: Balance = 1_000_000_000_000;
pub const DOLLARS: Balance = DOTS; pub const DOLLARS: Balance = DOTS;
@@ -30,7 +30,7 @@ pub mod currency {
/// Time and blocks. /// Time and blocks.
pub mod time { pub mod time {
use primitives::{Moment, BlockNumber}; use primitives::v0::{Moment, BlockNumber};
pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const MILLISECS_PER_BLOCK: Moment = 6000;
pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK;
pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 1 * HOURS; pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 1 * HOURS;
@@ -47,7 +47,7 @@ pub mod time {
/// Fee-related. /// Fee-related.
pub mod fee { pub mod fee {
pub use sp_runtime::Perbill; pub use sp_runtime::Perbill;
use primitives::Balance; use primitives::v0::Balance;
use runtime_common::ExtrinsicBaseWeight; use runtime_common::ExtrinsicBaseWeight;
use frame_support::weights::{ use frame_support::weights::{
WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients,
+7 -6
View File
@@ -22,9 +22,10 @@
use sp_std::prelude::*; use sp_std::prelude::*;
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use primitives::{ use primitives::v0::{
self as parachain,
AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment,
parachain::{self, ActiveParas, AbridgedCandidateReceipt, SigningContext}, ActiveParas, AbridgedCandidateReceipt, SigningContext,
}; };
use runtime_common::{ use runtime_common::{
attestations, parachains, registrar, SlowAdjustingFeeUpdate, attestations, parachains, registrar, SlowAdjustingFeeUpdate,
@@ -385,7 +386,7 @@ impl grandpa::Trait for Runtime {
type HandleEquivocation = grandpa::EquivocationHandler< type HandleEquivocation = grandpa::EquivocationHandler<
Self::KeyOwnerIdentification, Self::KeyOwnerIdentification,
primitives::fisherman::FishermanAppCrypto, primitives::v0::fisherman::FishermanAppCrypto,
Runtime, Runtime,
Offences, Offences,
>; >;
@@ -421,7 +422,7 @@ parameter_types! {
} }
impl parachains::Trait for Runtime { impl parachains::Trait for Runtime {
type AuthorityId = primitives::fisherman::FishermanAppCrypto; type AuthorityId = primitives::v0::fisherman::FishermanAppCrypto;
type Origin = Origin; type Origin = Origin;
type Call = Call; type Call = Call;
type ParachainCurrency = Balances; type ParachainCurrency = Balances;
@@ -698,7 +699,7 @@ impl proxy::Trait for Runtime {
construct_runtime! { construct_runtime! {
pub enum Runtime where pub enum Runtime where
Block = Block, Block = Block,
NodeBlock = primitives::Block, NodeBlock = primitives::v0::Block,
UncheckedExtrinsic = UncheckedExtrinsic UncheckedExtrinsic = UncheckedExtrinsic
{ {
// Basic stuff; balances is uncallable initially. // Basic stuff; balances is uncallable initially.
@@ -887,7 +888,7 @@ sp_api::impl_runtime_apis! {
fn signing_context() -> SigningContext { fn signing_context() -> SigningContext {
Parachains::signing_context() 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) Parachains::downward_messages(id)
} }
} }
+3 -3
View File
@@ -17,7 +17,7 @@
//! Polkadot chain configurations. //! Polkadot chain configurations.
use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; 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 polkadot_runtime as polkadot;
use kusama_runtime as kusama; use kusama_runtime as kusama;
use westend_runtime as westend; use westend_runtime as westend;
@@ -48,9 +48,9 @@ const DEFAULT_PROTOCOL_ID: &str = "dot";
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Extensions { pub struct Extensions {
/// Block numbers with known hashes. /// 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. /// 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`. /// The `ChainSpec parametrised for polkadot runtime`.
+2 -2
View File
@@ -16,7 +16,7 @@
//! Polkadot-specific GRANDPA integration utilities. //! Polkadot-specific GRANDPA integration utilities.
use polkadot_primitives::Hash; use polkadot_primitives::v0::Hash;
use sp_runtime::traits::{Block as BlockT, NumberFor}; use sp_runtime::traits::{Block as BlockT, NumberFor};
/// A custom GRANDPA voting rule that "pauses" voting (i.e. keeps voting for the /// 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). /// #1500988).
pub(crate) fn kusama_hard_forks() -> Vec<( pub(crate) fn kusama_hard_forks() -> Vec<(
grandpa_primitives::SetId, grandpa_primitives::SetId,
(Hash, polkadot_primitives::BlockNumber), (Hash, polkadot_primitives::v0::BlockNumber),
grandpa_primitives::AuthorityList, grandpa_primitives::AuthorityList,
)> { )> {
use sp_core::crypto::Ss58Codec; use sp_core::crypto::Ss58Codec;
+2 -3
View File
@@ -22,7 +22,7 @@ mod client;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; 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")] #[cfg(feature = "full-node")]
use polkadot_network::{legacy::gossip::Known, protocol as network_protocol}; use polkadot_network::{legacy::gossip::Known, protocol as network_protocol};
use service::{error::Error as ServiceError, ServiceBuilder}; 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_api::{Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend};
pub use sp_runtime::traits::{HashFor, NumberFor}; pub use sp_runtime::traits::{HashFor, NumberFor};
pub use consensus_common::{SelectChain, BlockImport, block_validation::Chain}; pub use consensus_common::{SelectChain, BlockImport, block_validation::Chain};
pub use polkadot_primitives::parachain::{CollatorId, ParachainHost}; pub use polkadot_primitives::v0::{Block, CollatorId, ParachainHost};
pub use polkadot_primitives::Block;
pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256}; pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256};
pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec}; pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec};
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
+1 -1
View File
@@ -28,7 +28,7 @@ use std::collections::hash_map::{HashMap, Entry};
use std::hash::Hash; use std::hash::Hash;
use std::fmt::Debug; use std::fmt::Debug;
use primitives::parachain::{ValidityAttestation as PrimitiveValidityAttestation, ValidatorSignature}; use primitives::v1::{ValidityAttestation as PrimitiveValidityAttestation, ValidatorSignature};
use codec::{Encode, Decode}; use codec::{Encode, Decode};
+46 -34
View File
@@ -16,12 +16,15 @@
pub mod generic; pub mod generic;
pub use generic::Table; pub use generic::{Table, Context};
use primitives::parachain::{ /// Concrete instantiations suitable for v0 primitives.
pub mod v0 {
use crate::generic;
use primitives::v0::{
Hash,
Id, AbridgedCandidateReceipt, CompactStatement as PrimitiveStatement, ValidatorSignature, ValidatorIndex, Id, AbridgedCandidateReceipt, CompactStatement as PrimitiveStatement, ValidatorSignature, ValidatorIndex,
}; };
use primitives::Hash;
/// Statements about candidates on the network. /// Statements about candidates on the network.
pub type Statement = generic::Statement<AbridgedCandidateReceipt, Hash>; pub type Statement = generic::Statement<AbridgedCandidateReceipt, Hash>;
@@ -45,39 +48,47 @@ pub type Misbehavior = generic::Misbehavior<
/// A summary of import of a statement. /// A summary of import of a statement.
pub type Summary = generic::Summary<Hash, Id>; pub type Summary = generic::Summary<Hash, Id>;
/// Context necessary to construct a table. impl<'a> From<&'a Statement> for PrimitiveStatement {
pub trait Context { fn from(s: &'a Statement) -> PrimitiveStatement {
/// Whether a authority is a member of a group. match *s {
/// Members are meant to submit candidates and vote on validity. generic::Statement::Valid(s) => PrimitiveStatement::Valid(s),
fn is_member_of(&self, authority: ValidatorIndex, group: &Id) -> bool; generic::Statement::Invalid(s) => PrimitiveStatement::Invalid(s),
generic::Statement::Candidate(ref s) => PrimitiveStatement::Candidate(s.hash()),
/// 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)
} }
} }
}
}
/// 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 { impl<'a> From<&'a Statement> for PrimitiveStatement {
fn from(s: &'a Statement) -> PrimitiveStatement { fn from(s: &'a Statement) -> PrimitiveStatement {
@@ -88,3 +99,4 @@ impl<'a> From<&'a Statement> for PrimitiveStatement {
} }
} }
} }
}
+2 -2
View File
@@ -28,8 +28,8 @@ use std::{
use sp_blockchain::HeaderBackend; use sp_blockchain::HeaderBackend;
use block_builder::{BlockBuilderApi, BlockBuilderProvider}; use block_builder::{BlockBuilderApi, BlockBuilderProvider};
use consensus::{Proposal, RecordProof}; use consensus::{Proposal, RecordProof};
use polkadot_primitives::{Block, Header}; use polkadot_primitives::v0::{Block, Header};
use polkadot_primitives::parachain::{ use polkadot_primitives::v0::{
ParachainHost, NEW_HEADS_IDENTIFIER, ParachainHost, NEW_HEADS_IDENTIFIER,
}; };
use runtime_primitives::traits::{DigestFor, HashFor}; use runtime_primitives::traits::{DigestFor, HashFor};
+1 -3
View File
@@ -21,11 +21,9 @@
use std::sync::Arc; use std::sync::Arc;
use polkadot_primitives::{ use polkadot_primitives::v0::{
BlakeTwo256, Block, Hash, HashT, 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 polkadot_erasure_coding as erasure;
use sp_api::ProvideRuntimeApi; use sp_api::ProvideRuntimeApi;
+2 -2
View File
@@ -16,7 +16,7 @@
//! Errors that can occur during the validation process. //! Errors that can occur during the validation process.
use polkadot_primitives::{parachain::ValidatorId, Hash}; use polkadot_primitives::v0::{ValidatorId, Hash};
/// Error type for validation /// Error type for validation
#[derive(Debug, derive_more::Display, derive_more::From)] #[derive(Debug, derive_more::Display, derive_more::From)]
@@ -77,7 +77,7 @@ pub enum Error {
CommitmentsMismatch, CommitmentsMismatch,
/// The parachain for which validation work is being done is not active. /// The parachain for which validation work is being done is not active.
#[display(fmt = "Parachain {:?} is not active", _0)] #[display(fmt = "Parachain {:?} is not active", _0)]
InactiveParachain(polkadot_primitives::parachain::Id), InactiveParachain(polkadot_primitives::v0::Id),
/// Block data is too big /// Block data is too big
#[display(fmt = "Block data is too big (maximum allowed size: {}, actual size: {})", size, max_size)] #[display(fmt = "Block data is too big (maximum allowed size: {}, actual size: {})", size, max_size)]
BlockDataTooBig { size: u64, max_size: u64 }, BlockDataTooBig { size: u64, max_size: u64 },
+1 -1
View File
@@ -34,7 +34,7 @@ use std::{
sync::Arc, sync::Arc,
}; };
use codec::Encode; use codec::Encode;
use polkadot_primitives::parachain::{ use polkadot_primitives::v0::{
Id as ParaId, Chain, DutyRoster, AbridgedCandidateReceipt, Id as ParaId, Chain, DutyRoster, AbridgedCandidateReceipt,
CompactStatement as PrimitiveStatement, CompactStatement as PrimitiveStatement,
PoVBlock, ErasureChunk, ValidatorSignature, ValidatorIndex, PoVBlock, ErasureChunk, ValidatorSignature, ValidatorIndex,
+3 -3
View File
@@ -19,12 +19,12 @@
use codec::Encode; use codec::Encode;
use polkadot_erasure_coding as erasure; use polkadot_erasure_coding as erasure;
use polkadot_primitives::parachain::{ use polkadot_primitives::v0::{
CollationInfo, PoVBlock, LocalValidationData, GlobalValidationSchedule, OmittedValidationData, CollationInfo, PoVBlock, LocalValidationData, GlobalValidationSchedule, OmittedValidationData,
AvailableData, FeeSchedule, CandidateCommitments, ErasureChunk, ParachainHost, AvailableData, FeeSchedule, CandidateCommitments, ErasureChunk, ParachainHost,
Id as ParaId, AbridgedCandidateReceipt, ValidationCode, Id as ParaId, AbridgedCandidateReceipt, ValidationCode,
}; };
use polkadot_primitives::{Block, BlockId, Balance, Hash}; use polkadot_primitives::v0::{Block, BlockId, Balance, Hash};
use parachain::{ use parachain::{
wasm_executor::{self, ExecutionMode}, wasm_executor::{self, ExecutionMode},
primitives::{UpwardMessage, ValidationParams}, primitives::{UpwardMessage, ValidationParams},
@@ -125,7 +125,7 @@ impl<'a> ValidatedCandidate<'a> {
omitted_validation, omitted_validation,
}; };
let erasure_chunks = erasure::obtain_chunks( let erasure_chunks = erasure::obtain_chunks_v0(
n_validators, n_validators,
&available_data, &available_data,
)?; )?;
@@ -18,7 +18,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use futures::channel::oneshot; use futures::channel::oneshot;
use polkadot_primitives::Hash; use polkadot_primitives::v0::Hash;
/// Track includability of a set of candidates, /// Track includability of a set of candidates,
pub(super) fn track<I: IntoIterator<Item=(Hash, bool)>>(candidates: I) pub(super) fn track<I: IntoIterator<Item=(Hash, bool)>>(candidates: I)
+36 -21
View File
@@ -21,11 +21,12 @@ use std::collections::hash_map::{HashMap, Entry};
use std::sync::Arc; use std::sync::Arc;
use availability_store::{Store as AvailabilityStore}; use availability_store::{Store as AvailabilityStore};
use table::{self, Table, Context as TableContextTrait}; use table::{v0 as table_v0, Table, Context as TableContextTrait};
use polkadot_primitives::{Block, Hash}; use polkadot_primitives::v0::{
use polkadot_primitives::parachain::{ Block, Hash,
Id as ParaId, AbridgedCandidateReceipt, ValidatorPair, ValidatorId, Id as ParaId, AbridgedCandidateReceipt, ValidatorPair, ValidatorId,
AttestedCandidate, ParachainHost, PoVBlock, ValidatorIndex, SigningContext, AttestedCandidate, ParachainHost, PoVBlock, ValidatorIndex, SigningContext,
ValidatorSignature,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;
@@ -44,7 +45,7 @@ use crate::Error;
mod includable; mod includable;
pub use table::{SignedStatement, Statement}; pub use table_v0::{SignedStatement, Statement};
pub use table::generic::Statement as GenericStatement; pub use table::generic::Statement as GenericStatement;
struct TableContext { struct TableContext {
@@ -54,9 +55,23 @@ struct TableContext {
validators: Vec<ValidatorId>, validators: Vec<ValidatorId>,
} }
impl table::Context for TableContext { impl TableContextTrait for TableContext {
fn is_member_of(&self, authority: ValidatorIndex, group: &ParaId) -> bool { type AuthorityId = ValidatorIndex;
let key = match self.validators.get(authority as usize) { 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, Some(val) => val,
None => return false, 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.local_index().and_then(move |sender|
self.key.as_ref() self.key.as_ref()
.map(|key| crate::sign_table_statement( .map(|key| crate::sign_table_statement(
@@ -93,7 +108,7 @@ impl TableContext {
&self.signing_context, &self.signing_context,
).into() ).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, &mut self,
context: &TableContext, context: &TableContext,
fetch_pov_block: impl Fn(&AbridgedCandidateReceipt) -> Fetch, fetch_pov_block: impl Fn(&AbridgedCandidateReceipt) -> Fetch,
statement: table::SignedStatement, statement: table_v0::SignedStatement,
max_block_data_size: Option<u64>, max_block_data_size: Option<u64>,
) -> Option<ParachainWork< ) -> Option<ParachainWork<
Fetch, Fetch,
@@ -154,7 +169,7 @@ impl SharedTableInner {
self.update_trackers(&summary.candidate, context); self.update_trackers(&summary.candidate, context);
let local_index = context.local_index()?; 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; let digest = &summary.candidate;
// TODO: consider a strategy based on the number of candidate votes as well. // TODO: consider a strategy based on the number of candidate votes as well.
@@ -216,7 +231,7 @@ impl SharedTableInner {
/// Produced after validating a candidate. /// Produced after validating a candidate.
pub struct Validated { pub struct Validated {
/// A statement about the validity of the candidate. /// A statement about the validity of the candidate.
statement: table::Statement, statement: table_v0::Statement,
/// The result of validation. /// The result of validation.
result: Validation, result: Validation,
} }
@@ -461,7 +476,7 @@ impl SharedTable {
pub fn import_remote_statement<Fetch>( pub fn import_remote_statement<Fetch>(
&self, &self,
fetch_pov_block: impl Fn(&AbridgedCandidateReceipt) -> Fetch, fetch_pov_block: impl Fn(&AbridgedCandidateReceipt) -> Fetch,
statement: table::SignedStatement, statement: table_v0::SignedStatement,
) -> Option<ParachainWork< ) -> Option<ParachainWork<
Fetch, Fetch,
>> { >> {
@@ -487,7 +502,7 @@ impl SharedTable {
iterable: I, iterable: I,
) -> U ) -> U
where where
I: IntoIterator<Item=table::SignedStatement>, I: IntoIterator<Item=table_v0::SignedStatement>,
U: ::std::iter::FromIterator<Option<ParachainWork< U: ::std::iter::FromIterator<Option<ParachainWork<
Fetch, Fetch,
>>>, >>>,
@@ -539,7 +554,7 @@ impl SharedTable {
/// Get a set of candidates that can be proposed. /// Get a set of candidates that can be proposed.
pub fn proposed_set(&self) -> Vec<AttestedCandidate> { pub fn proposed_set(&self) -> Vec<AttestedCandidate> {
use table::generic::{ValidityAttestation as GAttestation}; 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 // we transform the types of the attestations gathered from the table
// into the type expected by the runtime. This may do signature // into the type expected by the runtime. This may do signature
@@ -583,7 +598,7 @@ impl SharedTable {
} }
/// Get all witnessed misbehavior. /// 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() self.inner.lock().table.get_misbehavior().clone()
} }
@@ -615,7 +630,7 @@ impl SharedTable {
mod tests { mod tests {
use super::*; use super::*;
use sp_keyring::Sr25519Keyring; use sp_keyring::Sr25519Keyring;
use polkadot_primitives::parachain::{ use polkadot_primitives::v0::{
BlockData, ErasureChunk, AvailableData, BlockData, ErasureChunk, AvailableData,
}; };
use polkadot_erasure_coding::{self as erasure}; use polkadot_erasure_coding::{self as erasure};
@@ -706,7 +721,7 @@ mod tests {
&validity_other_key.into(), &validity_other_key.into(),
&signing_context, &signing_context,
); );
let signed_statement = ::table::generic::SignedStatement { let signed_statement = table::generic::SignedStatement {
statement: candidate_statement, statement: candidate_statement,
signature: signature.into(), signature: signature.into(),
sender: validity_other_index, sender: validity_other_index,
@@ -763,7 +778,7 @@ mod tests {
&validity_other_key.into(), &validity_other_key.into(),
&signing_context, &signing_context,
); );
let signed_statement = ::table::generic::SignedStatement { let signed_statement = table::generic::SignedStatement {
statement: candidate_statement, statement: candidate_statement,
signature: signature.into(), signature: signature.into(),
sender: validity_other_index, sender: validity_other_index,
@@ -860,7 +875,7 @@ mod tests {
omitted_validation: Default::default(), 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( store.note_validator_index_and_n_validators(
&relay_parent, &relay_parent,
@@ -947,7 +962,7 @@ mod tests {
&validity_other_key.into(), &validity_other_key.into(),
&signing_context, &signing_context,
); );
let signed_statement = ::table::generic::SignedStatement { let signed_statement = table::generic::SignedStatement {
statement: candidate_statement, statement: candidate_statement,
signature: signature.into(), signature: signature.into(),
sender: validity_other_index, sender: validity_other_index,
@@ -32,8 +32,8 @@ use crate::pipeline::FullOutput;
use sc_client_api::{BlockchainEvents, BlockBackend}; use sc_client_api::{BlockchainEvents, BlockBackend};
use consensus::SelectChain; use consensus::SelectChain;
use futures::prelude::*; use futures::prelude::*;
use polkadot_primitives::{Block, Hash, BlockId}; use polkadot_primitives::v0::{
use polkadot_primitives::parachain::{ Block, Hash, BlockId,
Chain, ParachainHost, Id as ParaId, ValidatorIndex, ValidatorId, ValidatorPair, Chain, ParachainHost, Id as ParaId, ValidatorIndex, ValidatorId, ValidatorPair,
CollationInfo, SigningContext, CollationInfo, SigningContext,
}; };
@@ -545,7 +545,7 @@ mod tests {
use super::*; use super::*;
use futures::{executor, future::ready, channel::mpsc}; use futures::{executor, future::ready, channel::mpsc};
use availability_store::ErasureNetworking; use availability_store::ErasureNetworking;
use polkadot_primitives::parachain::{ use polkadot_primitives::v0::{
PoVBlock, AbridgedCandidateReceipt, ErasureChunk, ValidatorIndex, PoVBlock, AbridgedCandidateReceipt, ErasureChunk, ValidatorIndex,
CollationInfo, DutyRoster, GlobalValidationSchedule, LocalValidationData, CollationInfo, DutyRoster, GlobalValidationSchedule, LocalValidationData,
Retriable, CollatorId, BlockData, Chain, AvailableData, SigningContext, ValidationCode, Retriable, CollatorId, BlockData, Chain, AvailableData, SigningContext, ValidationCode,
@@ -706,7 +706,7 @@ mod tests {
fn signing_context() -> SigningContext { fn signing_context() -> SigningContext {
Default::default() Default::default()
} }
fn downward_messages(_: ParaId) -> Vec<polkadot_primitives::DownwardMessage> { fn downward_messages(_: ParaId) -> Vec<polkadot_primitives::v0::DownwardMessage> {
Vec::new() Vec::new()
} }
} }