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