Collator for the "adder" (formerly basic-add) parachain and various small fixes (#438)

* update basic_add wasm

* wasm feature and collator feature

* move test parachains around a little

* fix wasm build for basic_add

* move basic_add to adder, introduce README

* minimal basic_add collator

* ensure collator messages are sent in the right order

* more logging

* route consensus statements to all peers

* minor bugfixes for parachains

* genesis builder accounts for parachain heads

* fix parachains tests

* targets for txpool

* tweak runtime + collator

* fix version in adder-collator

* consistency for overflowing

* adjust comment

* fix stable test run

* remove dummy registration test

* final grumbles
This commit is contained in:
Robert Habermeier
2018-08-01 17:04:04 +02:00
committed by GitHub
parent f5aa4f6f79
commit f4cd995558
27 changed files with 569 additions and 333 deletions
+24 -44
View File
@@ -25,7 +25,7 @@
use polkadot_api::{PolkadotApi, LocalPolkadotApi};
use polkadot_consensus::{SharedTable, TableRouter, SignedStatement, GenericStatement, StatementProducer};
use polkadot_primitives::{Hash, BlockId, SessionKey};
use polkadot_primitives::parachain::{BlockData, Extrinsic, CandidateReceipt, Id as ParaId};
use polkadot_primitives::parachain::{BlockData, Extrinsic, CandidateReceipt};
use futures::prelude::*;
use tokio::runtime::TaskExecutor;
@@ -89,14 +89,16 @@ impl<P: PolkadotApi> Clone for Router<P> {
impl<P: LocalPolkadotApi + Send + Sync + 'static> Router<P> {
/// Import a statement whose signature has been checked already.
pub(crate) fn import_statement(&self, statement: SignedStatement) {
trace!(target: "p_net", "importing consensus statement {:?}", statement.statement);
// defer any statements for which we haven't imported the candidate yet
let (c_hash, parachain_index) = {
let c_hash = {
let candidate_data = match statement.statement {
GenericStatement::Candidate(ref c) => Some((c.hash(), c.parachain_index)),
GenericStatement::Candidate(ref c) => Some(c.hash()),
GenericStatement::Valid(ref hash)
| GenericStatement::Invalid(ref hash)
| GenericStatement::Available(ref hash)
=> self.table.with_candidate(hash, |c| c.map(|c| (*hash, c.parachain_index))),
=> self.table.with_candidate(hash, |c| c.map(|_| *hash)),
};
match candidate_data {
Some(x) => x,
@@ -115,6 +117,7 @@ impl<P: LocalPolkadotApi + Send + Sync + 'static> Router<P> {
};
// prepend the candidate statement.
debug!(target: "consensus", "Importing statements about candidate {:?}", c_hash);
statements.insert(0, statement);
let producers: Vec<_> = self.table.import_remote_statements(
self,
@@ -122,17 +125,16 @@ impl<P: LocalPolkadotApi + Send + Sync + 'static> Router<P> {
);
// dispatch future work as necessary.
for (producer, statement) in producers.into_iter().zip(statements) {
let producer = match producer {
Some(p) => p,
None => continue, // statement redundant
};
self.knowledge.lock().note_statement(statement.sender, &statement.statement);
self.dispatch_work(c_hash, producer, parachain_index);
if let Some(producer) = producer {
trace!(target: "consensus", "driving statement work to completion");
self.dispatch_work(c_hash, producer);
}
}
}
fn dispatch_work<D, E>(&self, candidate_hash: Hash, producer: StatementProducer<D, E>, parachain: ParaId) where
fn dispatch_work<D, E>(&self, candidate_hash: Hash, producer: StatementProducer<D, E>) where
D: Future<Item=BlockData,Error=()> + Send + 'static,
E: Future<Item=Extrinsic,Error=()> + Send + 'static,
{
@@ -160,13 +162,13 @@ impl<P: LocalPolkadotApi + Send + Sync + 'static> Router<P> {
// propagate the statements
if let Some(validity) = produced.validity {
let signed = table.sign_and_import(validity.clone());
route_statement(&*network, &*table, parachain, parent_hash, signed);
let signed = table.sign_and_import(validity.clone()).0;
network.with_spec(|spec, ctx| spec.gossip_statement(ctx, parent_hash, signed));
}
if let Some(availability) = produced.availability {
let signed = table.sign_and_import(availability);
route_statement(&*network, &*table, parachain, parent_hash, signed);
let signed = table.sign_and_import(availability).0;
network.with_spec(|spec, ctx| spec.gossip_statement(ctx, parent_hash, signed));
}
});
@@ -182,11 +184,15 @@ impl<P: LocalPolkadotApi + Send> TableRouter for Router<P> {
fn local_candidate(&self, receipt: CandidateReceipt, block_data: BlockData, extrinsic: Extrinsic) {
// give to network to make available.
let hash = receipt.hash();
let para_id = receipt.parachain_index;
let signed = self.table.sign_and_import(GenericStatement::Candidate(receipt));
let (candidate, availability) = self.table.sign_and_import(GenericStatement::Candidate(receipt));
self.knowledge.lock().note_candidate(hash, Some(block_data), Some(extrinsic));
route_statement(&*self.network, &*self.table, para_id, self.parent_hash, signed);
self.network.with_spec(|spec, ctx| {
spec.gossip_statement(ctx, self.parent_hash, candidate);
if let Some(availability) = availability {
spec.gossip_statement(ctx, self.parent_hash, availability);
}
});
}
fn fetch_block_data(&self, candidate: &CandidateReceipt) -> BlockDataReceiver {
@@ -217,32 +223,6 @@ impl Future for BlockDataReceiver {
}
}
// get statement to relevant validators.
fn route_statement(network: &NetworkService, table: &SharedTable, para_id: ParaId, parent_hash: Hash, statement: SignedStatement) {
let broadcast = |i: &mut Iterator<Item=&SessionKey>| {
let local_key = table.session_key();
network.with_spec(|spec, ctx| {
for val in i.filter(|&x| x != &local_key) {
spec.send_statement(ctx, *val, parent_hash, statement.clone());
}
});
};
let g_info = table
.group_info()
.get(&para_id)
.expect("statements only produced about groups which exist");
match statement.statement {
GenericStatement::Candidate(_) =>
broadcast(&mut g_info.validity_guarantors.iter().chain(g_info.availability_guarantors.iter())),
GenericStatement::Valid(_) | GenericStatement::Invalid(_) =>
broadcast(&mut g_info.validity_guarantors.iter()),
GenericStatement::Available(_) =>
broadcast(&mut g_info.availability_guarantors.iter()),
}
}
// A unique trace for valid statements issued by a validator.
#[derive(Hash, PartialEq, Eq, Clone, Debug)]
enum StatementTrace {