Make substrate generic (#169)

* Some initial work on RPC and client

* Rephrase as params

* More work on traitifying substrate.

* Traitify in_mem.rs

* traitify client.rs

* Make new primitives (mainly traits) build again.

* Many (superficial) build fixes throughout.

* Fix remaining build issues up to bft interface.

* Make bft primitives be generic.

* Switch out MisBehaviorReport for generic version.

* Merge Hashing into Header.

* Update runtime for new generics (with Hashing).

* Update demo runtime.

* Make runtime compile.

* Build fixes for runtime

* Remove old modules.

* port substrate-bft to use generic substrate types

* port client

* port substrate-test-runtime

* mostly port test-runtime to get compiling for std

* Ensure `AccountId` has a `Default`.

* Fix type deps.

* finish porting

* initialize test_runtime from genesis correctly

* remove commented code

* maybe unsigned signatures

* runtimes compile

* port over most of network

* serialization for generic types

* fix comment

* remove some unnecessary trait bounds

* network compiles

* tests compile for sync

* fix deserialization

* temporarily remove deserialize derives

* workarounds for serde issues for deriving deserialization

* get demo-runtime compiling on std

* port extrinsic-pool

* primitives reshuffling

* get network compiling again

* remove debugging file

* runtime tests now passing

* port client-db

* start to port over substrate-rpc

* mostly port over PolkadotApi

* test_runtime follows normal conventions

* substrate runtime tests pass

* deal with inherent extrinsics correctly in polkadot-api

* port transaction-pool

* port polkadot-consensus

* port substrate-rpc

* everything compiles

* tests compile

* fix grumbles

* test-runtime uses its own transfer type

* switch to master branch of jsonrpc

* fix network tests and some warnings

* all tests pass locally

* [ci-skip] add another comment about issue

* remove some curlies
This commit is contained in:
Gav Wood
2018-06-06 17:58:45 +02:00
committed by Robert Habermeier
parent 4e844760a3
commit b94cf078af
132 changed files with 4695 additions and 4303 deletions
+1
View File
@@ -25,3 +25,4 @@ substrate-runtime-support = { path = "../../substrate/runtime-support" }
substrate-network = { path = "../../substrate/network" }
substrate-keyring = { path = "../../substrate/keyring" }
substrate-client = { path = "../../substrate/client" }
substrate-runtime-primitives = { path = "../../substrate/runtime/primitives" }
+2 -2
View File
@@ -16,7 +16,7 @@
//! Errors that can occur during the consensus process.
use polkadot_primitives::AccountId;
use primitives::AuthorityId;
error_chain! {
links {
@@ -29,7 +29,7 @@ error_chain! {
description("Duty Roster had invalid length"),
display("Invalid duty roster length: expected {}, got {}", expected, got),
}
NotValidator(id: AccountId) {
NotValidator(id: AuthorityId) {
description("Local account ID not a validator at this block."),
display("Local account ID ({:?}) not a validator at this block.", id),
}
@@ -19,11 +19,9 @@
use super::MAX_TRANSACTIONS_SIZE;
use codec::Slicable;
use polkadot_runtime::Block as PolkadotGenericBlock;
use polkadot_primitives::Timestamp;
use polkadot_runtime::{Block as PolkadotGenericBlock, CheckedBlock};
use polkadot_primitives::{Block, Hash, BlockNumber, Timestamp};
use polkadot_primitives::parachain::Id as ParaId;
use primitives::block::{Block as SubstrateBlock, HeaderHash, Number as BlockNumber};
use transaction_pool::PolkadotBlock;
error_chain! {
links {
@@ -51,7 +49,7 @@ error_chain! {
description("Proposal included unregistered parachain."),
display("Proposal included unregistered parachain {:?}", id),
}
WrongParentHash(expected: HeaderHash, got: HeaderHash) {
WrongParentHash(expected: Hash, got: Hash) {
description("Proposal had wrong parent hash."),
display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got),
}
@@ -72,17 +70,17 @@ error_chain! {
/// Attempt to evaluate a substrate block as a polkadot block, returning error
/// upon any initial validity checks failing.
pub fn evaluate_initial(
proposal: &SubstrateBlock,
proposal: &Block,
now: Timestamp,
parent_hash: &HeaderHash,
parent_hash: &Hash,
parent_number: BlockNumber,
active_parachains: &[ParaId],
) -> Result<PolkadotBlock> {
) -> Result<CheckedBlock> {
const MAX_TIMESTAMP_DRIFT: Timestamp = 60;
let encoded = Slicable::encode(proposal);
let proposal = PolkadotGenericBlock::decode(&mut &encoded[..])
.and_then(|b| PolkadotBlock::from(b).ok())
.and_then(|b| CheckedBlock::new(b).ok())
.ok_or_else(|| ErrorKind::ProposalNotForPolkadot)?;
let transactions_size = proposal.extrinsics.iter().fold(0, |a, tx| {
+38 -35
View File
@@ -35,14 +35,15 @@ extern crate polkadot_api;
extern crate polkadot_collator as collator;
extern crate polkadot_statement_table as table;
extern crate polkadot_parachain as parachain;
extern crate polkadot_primitives;
extern crate polkadot_transaction_pool as transaction_pool;
extern crate polkadot_runtime;
extern crate polkadot_primitives;
extern crate substrate_bft as bft;
extern crate substrate_codec as codec;
extern crate substrate_primitives as primitives;
extern crate substrate_runtime_support as runtime_support;
extern crate substrate_runtime_primitives as runtime_primitives;
extern crate substrate_network;
extern crate exit_future;
@@ -68,10 +69,9 @@ use std::time::{Duration, Instant};
use codec::Slicable;
use table::generic::Statement as GenericStatement;
use runtime_support::Hashable;
use polkadot_api::{PolkadotApi, BlockBuilder};
use polkadot_primitives::{Hash, Timestamp};
use polkadot_primitives::parachain::{Id as ParaId, Chain, DutyRoster, BlockData, Extrinsic, CandidateReceipt};
use primitives::block::{Block as SubstrateBlock, Header as SubstrateHeader, HeaderHash, Id as BlockId, Number as BlockNumber};
use polkadot_api::PolkadotApi;
use polkadot_primitives::{Hash, Block, BlockId, BlockNumber, Header, Timestamp};
use polkadot_primitives::parachain::{Id as ParaId, Chain, DutyRoster, BlockData, Extrinsic as ParachainExtrinsic, CandidateReceipt};
use primitives::AuthorityId;
use transaction_pool::{Ready, TransactionPool};
use tokio_core::reactor::{Handle, Timeout, Interval};
@@ -105,10 +105,10 @@ pub trait TableRouter: Clone {
/// Future that resolves when candidate data is fetched.
type FetchCandidate: IntoFuture<Item=BlockData,Error=Self::Error>;
/// Future that resolves when extrinsic candidate data is fetched.
type FetchExtrinsic: IntoFuture<Item=Extrinsic,Error=Self::Error>;
type FetchExtrinsic: IntoFuture<Item=ParachainExtrinsic,Error=Self::Error>;
/// Note local candidate data, making it available on the network to other validators.
fn local_candidate_data(&self, hash: Hash, block_data: BlockData, extrinsic: Extrinsic);
fn local_candidate_data(&self, hash: Hash, block_data: BlockData, extrinsic: ParachainExtrinsic);
/// Fetch block data for a specific candidate.
fn fetch_block_data(&self, candidate: &CandidateReceipt) -> Self::FetchCandidate;
@@ -236,7 +236,7 @@ pub struct ProposerFactory<C, N, P> {
pub parachain_empty_duration: Duration,
}
impl<C, N, P> bft::ProposerFactory for ProposerFactory<C, N, P>
impl<C, N, P> bft::ProposerFactory<Block> for ProposerFactory<C, N, P>
where
C: PolkadotApi,
N: Network,
@@ -245,14 +245,14 @@ impl<C, N, P> bft::ProposerFactory for ProposerFactory<C, N, P>
type Proposer = Proposer<C, N::TableRouter, P>;
type Error = Error;
fn init(&self, parent_header: &SubstrateHeader, authorities: &[AuthorityId], sign_with: Arc<ed25519::Pair>) -> Result<Self::Proposer, Error> {
fn init(&self, parent_header: &Header, authorities: &[AuthorityId], sign_with: Arc<ed25519::Pair>) -> Result<Self::Proposer, Error> {
use std::time::Duration;
const DELAY_UNTIL: Duration = Duration::from_millis(5000);
let parent_hash = parent_header.blake2_256().into();
let checked_id = self.client.check_id(BlockId::Hash(parent_hash))?;
let checked_id = self.client.check_id(BlockId::hash(parent_hash))?;
let duty_roster = self.client.duty_roster(&checked_id)?;
let random_seed = self.client.random_seed(&checked_id)?;
@@ -312,7 +312,7 @@ pub struct Proposer<C: PolkadotApi, R, P> {
handle: Handle,
local_duty: LocalDuty,
local_key: Arc<ed25519::Pair>,
parent_hash: HeaderHash,
parent_hash: Hash,
parent_id: C::CheckedBlockId,
parent_number: BlockNumber,
random_seed: Hash,
@@ -321,7 +321,7 @@ pub struct Proposer<C: PolkadotApi, R, P> {
transaction_pool: Arc<TransactionPool>,
}
impl<C, R, P> bft::Proposer for Proposer<C, R, P>
impl<C, R, P> bft::Proposer<Block> for Proposer<C, R, P>
where
C: PolkadotApi,
R: TableRouter,
@@ -330,7 +330,7 @@ impl<C, R, P> bft::Proposer for Proposer<C, R, P>
type Error = Error;
type Create = future::Either<
CreateProposal<C, R, P>,
future::FutureResult<SubstrateBlock, Error>,
future::FutureResult<Block, Error>,
>;
type Evaluate = Box<Future<Item=bool, Error=Error>>;
@@ -385,7 +385,7 @@ impl<C, R, P> bft::Proposer for Proposer<C, R, P>
})
}
fn evaluate(&self, proposal: &SubstrateBlock) -> Self::Evaluate {
fn evaluate(&self, unchecked_proposal: &Block) -> Self::Evaluate {
debug!(target: "bft", "evaluating block on top of parent ({}, {:?})", self.parent_number, self.parent_hash);
let active_parachains = match self.client.active_parachains(&self.parent_id) {
@@ -397,7 +397,7 @@ impl<C, R, P> bft::Proposer for Proposer<C, R, P>
// do initial serialization and structural integrity checks.
let maybe_proposal = evaluation::evaluate_initial(
proposal,
unchecked_proposal,
current_timestamp,
&self.parent_hash,
self.parent_number,
@@ -461,7 +461,10 @@ impl<C, R, P> bft::Proposer for Proposer<C, R, P>
// evaluate whether the block is actually valid.
// TODO: is it better to delay this until the delays are finished?
let evaluated = self.client.evaluate_block(&self.parent_id, proposal.into()).map_err(Into::into);
let evaluated = self.client
.evaluate_block(&self.parent_id, unchecked_proposal.clone())
.map_err(Into::into);
let future = future::result(evaluated).and_then(move |good| {
let end_result = future::ok(good);
if good {
@@ -489,13 +492,13 @@ impl<C, R, P> bft::Proposer for Proposer<C, R, P>
proposer
}
fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, bft::Misbehavior)>) {
fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, bft::Misbehavior<Hash>)>) {
use bft::generic::Misbehavior as GenericMisbehavior;
use primitives::bft::{MisbehaviorKind, MisbehaviorReport};
use runtime_primitives::bft::{MisbehaviorKind, MisbehaviorReport};
use runtime_primitives::MaybeUnsigned;
use polkadot_runtime::{Call, Extrinsic, UncheckedExtrinsic, ConsensusCall};
let local_id = self.local_key.public().0;
let local_id = self.local_key.public().0.into();
let mut next_index = {
let readiness_evaluator = Ready::create(self.parent_id.clone(), &*self.client);
let cur_index = self.transaction_pool.cull_and_get_pending(readiness_evaluator, |pending| pending
@@ -536,10 +539,11 @@ impl<C, R, P> bft::Proposer for Proposer<C, R, P>
next_index += 1;
let signature = self.local_key.sign(&extrinsic.encode()).into();
let signature = MaybeUnsigned(self.local_key.sign(&extrinsic.encode()).into());
let uxt = UncheckedExtrinsic { extrinsic, signature };
self.transaction_pool.import_unchecked_extrinsic(uxt).expect("locally signed extrinsic is valid; qed");
self.transaction_pool.import_unchecked_extrinsic(uxt)
.expect("locally signed extrinsic is valid; qed");
}
}
}
@@ -603,7 +607,7 @@ impl ProposalTiming {
/// Future which resolves upon the creation of a proposal.
pub struct CreateProposal<C: PolkadotApi, R, P: Collators> {
parent_hash: HeaderHash,
parent_hash: Hash,
parent_number: BlockNumber,
parent_id: C::CheckedBlockId,
client: Arc<C>,
@@ -620,14 +624,13 @@ impl<C, R, P> CreateProposal<C, R, P>
R: TableRouter,
P: Collators,
{
fn propose_with(&self, candidates: Vec<CandidateReceipt>) -> Result<SubstrateBlock, Error> {
fn propose_with(&self, candidates: Vec<CandidateReceipt>) -> Result<Block, Error> {
use polkadot_api::BlockBuilder;
use runtime_primitives::traits::{Hashing, BlakeTwo256};
// TODO: handle case when current timestamp behind that in state.
let timestamp = current_timestamp();
let mut block_builder = self.client.build_block(
&self.parent_id,
timestamp,
candidates,
)?;
let mut block_builder = self.client.build_block(&self.parent_id, timestamp, candidates)?;
{
let readiness_evaluator = Ready::create(self.parent_id.clone(), &*self.client);
@@ -643,7 +646,7 @@ impl<C, R, P> CreateProposal<C, R, P>
if pending_size + pending.encoded_size() >= MAX_TRANSACTIONS_SIZE { break }
match block_builder.push_extrinsic(pending.as_transaction().clone()) {
match block_builder.push_extrinsic(pending.primitive_extrinsic()) {
Ok(()) => {
pending_size += pending.encoded_size();
}
@@ -658,14 +661,14 @@ impl<C, R, P> CreateProposal<C, R, P>
self.transaction_pool.remove(&unqueue_invalid, false);
}
let polkadot_block = block_builder.bake();
let polkadot_block = block_builder.bake()?;
info!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]",
polkadot_block.header.number,
Hash::from(polkadot_block.header.blake2_256()),
Hash::from(polkadot_block.header.hash()),
polkadot_block.header.parent_hash,
polkadot_block.extrinsics.iter()
.map(|xt| format!("{}", Hash::from(xt.blake2_256())))
.map(|xt| format!("{}", BlakeTwo256::hash_of(xt)))
.collect::<Vec<_>>()
.join(", ")
);
@@ -693,10 +696,10 @@ impl<C, R, P> Future for CreateProposal<C, R, P>
R: TableRouter,
P: Collators,
{
type Item = SubstrateBlock;
type Item = Block;
type Error = Error;
fn poll(&mut self) -> Poll<SubstrateBlock, Error> {
fn poll(&mut self) -> Poll<Block, Error> {
// 1. poll local collation future.
match self.collation.poll() {
Ok(Async::Ready((collation, extrinsic))) => {
+45 -57
View File
@@ -29,10 +29,9 @@ use ed25519;
use futures::prelude::*;
use futures::{future, Canceled};
use polkadot_api::LocalPolkadotApi;
use polkadot_primitives::AccountId;
use polkadot_primitives::{BlockId, Block, Header, Hash, AccountId};
use polkadot_primitives::parachain::{Id as ParaId, BlockData, Extrinsic, CandidateReceipt};
use primitives::{Hash, AuthorityId};
use primitives::block::{Id as BlockId, HeaderHash, Header};
use primitives::AuthorityId;
use runtime_support::Hashable;
use substrate_network as net;
use tokio_core::reactor;
@@ -45,19 +44,19 @@ const TIMER_DELAY_MS: u64 = 5000;
const TIMER_INTERVAL_MS: u64 = 500;
struct BftSink<E> {
network: Arc<net::ConsensusService>,
parent_hash: HeaderHash,
network: Arc<net::ConsensusService<Block>>,
parent_hash: Hash,
_e: ::std::marker::PhantomData<E>,
}
struct Messages {
network_stream: net::BftMessageStream,
network_stream: net::BftMessageStream<Block>,
local_id: AuthorityId,
authorities: Vec<AuthorityId>,
}
impl Stream for Messages {
type Item = bft::Communication;
type Item = bft::Communication<Block>;
type Error = bft::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
@@ -81,10 +80,10 @@ impl Stream for Messages {
}
}
fn process_message(msg: net::LocalizedBftMessage, local_id: &AuthorityId, authorities: &[AuthorityId]) -> Result<Option<bft::Communication>, bft::Error> {
fn process_message(msg: net::LocalizedBftMessage<Block>, local_id: &AuthorityId, authorities: &[AuthorityId]) -> Result<Option<bft::Communication<Block>>, bft::Error> {
Ok(Some(match msg.message {
net::BftMessage::Consensus(c) => bft::generic::Communication::Consensus(match c {
net::SignedConsensusMessage::Propose(proposal) => bft::generic::LocalizedMessage::Propose({
net::generic_message::BftMessage::Consensus(c) => bft::generic::Communication::Consensus(match c {
net::generic_message::SignedConsensusMessage::Propose(proposal) => bft::generic::LocalizedMessage::Propose({
if &proposal.sender == local_id { return Ok(None) }
let proposal = bft::generic::LocalizedProposal {
round_number: proposal.round_number as usize,
@@ -105,7 +104,7 @@ fn process_message(msg: net::LocalizedBftMessage, local_id: &AuthorityId, author
trace!(target: "bft", "importing proposal message for round {} from {}", proposal.round_number, Hash::from(proposal.sender));
proposal
}),
net::SignedConsensusMessage::Vote(vote) => bft::generic::LocalizedMessage::Vote({
net::generic_message::SignedConsensusMessage::Vote(vote) => bft::generic::LocalizedMessage::Vote({
if &vote.sender == local_id { return Ok(None) }
let vote = bft::generic::LocalizedVote {
sender: vote.sender,
@@ -114,21 +113,21 @@ fn process_message(msg: net::LocalizedBftMessage, local_id: &AuthorityId, author
signer: ed25519::Public(vote.sender),
},
vote: match vote.vote {
net::ConsensusVote::Prepare(r, h) => bft::generic::Vote::Prepare(r as usize, h),
net::ConsensusVote::Commit(r, h) => bft::generic::Vote::Commit(r as usize, h),
net::ConsensusVote::AdvanceRound(r) => bft::generic::Vote::AdvanceRound(r as usize),
net::generic_message::ConsensusVote::Prepare(r, h) => bft::generic::Vote::Prepare(r as usize, h),
net::generic_message::ConsensusVote::Commit(r, h) => bft::generic::Vote::Commit(r as usize, h),
net::generic_message::ConsensusVote::AdvanceRound(r) => bft::generic::Vote::AdvanceRound(r as usize),
}
};
bft::check_vote(authorities, &msg.parent_hash, &vote)?;
bft::check_vote::<Block>(authorities, &msg.parent_hash, &vote)?;
trace!(target: "bft", "importing vote {:?} from {}", vote.vote, Hash::from(vote.sender));
vote
}),
}),
net::BftMessage::Auxiliary(a) => {
let justification = bft::UncheckedJustification::from(a);
net::generic_message::BftMessage::Auxiliary(a) => {
let justification = bft::UncheckedJustification::<Hash>::from(a);
// TODO: get proper error
let justification: Result<_, bft::Error> = bft::check_prepare_justification(authorities, msg.parent_hash, justification)
let justification: Result<_, bft::Error> = bft::check_prepare_justification::<Block>(authorities, msg.parent_hash, justification)
.map_err(|_| bft::ErrorKind::InvalidJustification.into());
bft::generic::Communication::Auxiliary(justification?)
},
@@ -136,15 +135,15 @@ fn process_message(msg: net::LocalizedBftMessage, local_id: &AuthorityId, author
}
impl<E> Sink for BftSink<E> {
type SinkItem = bft::Communication;
type SinkItem = bft::Communication<Block>;
// TODO: replace this with the ! type when that's stabilized
type SinkError = E;
fn start_send(&mut self, message: bft::Communication) -> ::futures::StartSend<bft::Communication, E> {
let network_message = net::LocalizedBftMessage {
fn start_send(&mut self, message: bft::Communication<Block>) -> ::futures::StartSend<bft::Communication<Block>, E> {
let network_message = net::generic_message::LocalizedBftMessage {
message: match message {
bft::generic::Communication::Consensus(c) => net::BftMessage::Consensus(match c {
bft::generic::LocalizedMessage::Propose(proposal) => net::SignedConsensusMessage::Propose(net::SignedConsensusProposal {
bft::generic::Communication::Consensus(c) => net::generic_message::BftMessage::Consensus(match c {
bft::generic::LocalizedMessage::Propose(proposal) => net::generic_message::SignedConsensusMessage::Propose(net::generic_message::SignedConsensusProposal {
round_number: proposal.round_number as u32,
proposal: proposal.proposal,
digest: proposal.digest,
@@ -152,17 +151,17 @@ impl<E> Sink for BftSink<E> {
digest_signature: proposal.digest_signature.signature,
full_signature: proposal.full_signature.signature,
}),
bft::generic::LocalizedMessage::Vote(vote) => net::SignedConsensusMessage::Vote(net::SignedConsensusVote {
bft::generic::LocalizedMessage::Vote(vote) => net::generic_message::SignedConsensusMessage::Vote(net::generic_message::SignedConsensusVote {
sender: vote.sender,
signature: vote.signature.signature,
vote: match vote.vote {
bft::generic::Vote::Prepare(r, h) => net::ConsensusVote::Prepare(r as u32, h),
bft::generic::Vote::Commit(r, h) => net::ConsensusVote::Commit(r as u32, h),
bft::generic::Vote::AdvanceRound(r) => net::ConsensusVote::AdvanceRound(r as u32),
bft::generic::Vote::Prepare(r, h) => net::generic_message::ConsensusVote::Prepare(r as u32, h),
bft::generic::Vote::Commit(r, h) => net::generic_message::ConsensusVote::Commit(r as u32, h),
bft::generic::Vote::AdvanceRound(r) => net::generic_message::ConsensusVote::AdvanceRound(r as u32),
}
}),
}),
bft::generic::Communication::Auxiliary(justification) => net::BftMessage::Auxiliary(justification.uncheck().into()),
bft::generic::Communication::Auxiliary(justification) => net::generic_message::BftMessage::Auxiliary(justification.uncheck().into()),
},
parent_hash: self.parent_hash,
};
@@ -175,7 +174,7 @@ impl<E> Sink for BftSink<E> {
}
}
struct Network(Arc<net::ConsensusService>);
struct Network(Arc<net::ConsensusService<Block>>);
impl super::Network for Network {
type TableRouter = Router;
@@ -189,20 +188,20 @@ impl super::Network for Network {
fn start_bft<F, C>(
header: &Header,
handle: reactor::Handle,
client: &bft::Authorities,
network: Arc<net::ConsensusService>,
bft_service: &BftService<F, C>,
client: &bft::Authorities<Block>,
network: Arc<net::ConsensusService<Block>>,
bft_service: &BftService<Block, F, C>,
) where
F: bft::ProposerFactory + 'static,
C: bft::BlockImport + bft::Authorities + 'static,
<F as bft::ProposerFactory>::Error: ::std::fmt::Debug,
<F::Proposer as bft::Proposer>::Error: ::std::fmt::Display + Into<error::Error>,
F: bft::ProposerFactory<Block> + 'static,
C: bft::BlockImport<Block> + bft::Authorities<Block> + 'static,
<F as bft::ProposerFactory<Block>>::Error: ::std::fmt::Debug,
<F::Proposer as bft::Proposer<Block>>::Error: ::std::fmt::Display + Into<error::Error>,
{
let parent_hash = header.blake2_256().into();
let parent_hash = header.hash();
if bft_service.live_agreement().map_or(false, |h| h == parent_hash) {
return;
}
let authorities = match client.authorities(&BlockId::Hash(parent_hash)) {
let authorities = match client.authorities(&BlockId::hash(parent_hash)) {
Ok(authorities) => authorities,
Err(e) => {
debug!("Error reading authorities: {:?}", e);
@@ -235,14 +234,14 @@ impl Service {
pub fn new<A, C>(
client: Arc<C>,
api: Arc<A>,
network: Arc<net::ConsensusService>,
network: Arc<net::ConsensusService<Block>>,
transaction_pool: Arc<TransactionPool>,
parachain_empty_duration: Duration,
key: ed25519::Pair,
) -> Service
where
A: LocalPolkadotApi + Send + Sync + 'static,
C: BlockchainEvents + ChainHead + bft::BlockImport + bft::Authorities + Send + Sync + 'static,
C: BlockchainEvents<Block> + ChainHead<Block> + bft::BlockImport<Block> + bft::Authorities<Block> + Send + Sync + 'static,
{
let (signal, exit) = ::exit_future::signal();
let thread = thread::spawn(move || {
@@ -346,36 +345,25 @@ impl ::collation::Collators for NoCollators {
fn note_bad_collator(&self, _collator: AccountId) { }
}
type FetchCandidateAdapter = future::Map<net::FetchFuture, fn(Vec<u8>) -> BlockData>;
#[derive(Clone)]
struct Router {
network: Arc<net::ConsensusService>,
}
impl Router {
fn fetch_candidate_adapter(data: Vec<u8>) -> BlockData {
BlockData(data)
}
network: Arc<net::ConsensusService<Block>>,
}
impl TableRouter for Router {
type Error = Canceled;
type FetchCandidate = FetchCandidateAdapter;
type FetchCandidate = future::Empty<BlockData, Self::Error>;
type FetchExtrinsic = future::FutureResult<Extrinsic, Self::Error>;
fn local_candidate_data(&self, hash: Hash, block_data: BlockData, _extrinsic: Extrinsic) {
let data = block_data.0;
self.network.set_local_candidate(Some((hash, data)))
fn local_candidate_data(&self, _hash: Hash, _block_data: BlockData, _extrinsic: Extrinsic) {
// TODO
}
fn fetch_block_data(&self, candidate: &CandidateReceipt) -> Self::FetchCandidate {
let hash = candidate.hash();
self.network.fetch_candidate(&hash).map(Self::fetch_candidate_adapter)
fn fetch_block_data(&self, _candidate: &CandidateReceipt) -> Self::FetchCandidate {
future::empty()
}
fn fetch_extrinsic_data(&self, _candidate: &CandidateReceipt) -> Self::FetchExtrinsic {
future::ok(Extrinsic)
}
}
@@ -486,7 +486,7 @@ mod tests {
let candidate = CandidateReceipt {
parachain_index: para_id,
collator: [1; 32],
collator: [1; 32].into(),
head_data: ::polkadot_primitives::parachain::HeadData(vec![1, 2, 3, 4]),
balance_uploads: Vec::new(),
egress_queue_roots: Vec::new(),
@@ -536,7 +536,7 @@ mod tests {
let candidate = CandidateReceipt {
parachain_index: para_id,
collator: [1; 32],
collator: [1; 32].into(),
head_data: ::polkadot_primitives::parachain::HeadData(vec![1, 2, 3, 4]),
balance_uploads: Vec::new(),
egress_queue_roots: Vec::new(),