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
+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(),
);