Make basic collation working

This commit is contained in:
Bastian Köcher
2019-10-18 14:16:32 +02:00
parent d9c6bc408c
commit b5bc9a21a3
12 changed files with 506 additions and 292 deletions
+193 -190
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -7,6 +7,9 @@ edition = "2018"
[dependencies] [dependencies]
# Substrate dependencies # Substrate dependencies
sr-primitives = { package = "sr-primitives", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } sr-primitives = { package = "sr-primitives", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
substrate-primitives = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
substrate-client = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
substrate-service = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
consensus-common = { package = "substrate-consensus-common", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } consensus-common = { package = "substrate-consensus-common", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
inherents = { package = "substrate-inherents", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } inherents = { package = "substrate-inherents", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
cli = { package = "substrate-cli", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } cli = { package = "substrate-cli", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
@@ -15,6 +18,9 @@ cli = { package = "substrate-cli", git = "https://github.com/paritytech/substrat
polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-cumulus-branch" } polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-cumulus-branch" }
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-cumulus-branch" } polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-cumulus-branch" }
# Cumulus dependencies
cumulus-consensus = { path = "../consensus" }
# other deps # other deps
log = "0.4.8" log = "0.4.8"
codec = { package = "parity-scale-codec", version = "1.0.6", features = [ "derive" ] } codec = { package = "parity-scale-codec", version = "1.0.6", features = [ "derive" ] }
+80 -46
View File
@@ -19,12 +19,14 @@
use sr_primitives::traits::Block as BlockT; use sr_primitives::traits::Block as BlockT;
use consensus_common::{Environment, Proposer}; use consensus_common::{Environment, Proposer};
use inherents::InherentDataProviders; use inherents::InherentDataProviders;
use substrate_primitives::Blake2Hasher;
use polkadot_collator::{ use polkadot_collator::{
InvalidHead, ParachainContext, BuildParachainContext, Network as CollatorNetwork, VersionInfo, InvalidHead, ParachainContext, BuildParachainContext, Network as CollatorNetwork, VersionInfo,
TaskExecutor, PolkadotClient,
}; };
use polkadot_primitives::{ use polkadot_primitives::{
Hash, Hash as PHash, Block as PBlock,
parachain::{ parachain::{
self, BlockData, Message, Id as ParaId, OutgoingMessages, Status as ParachainStatus, self, BlockData, Message, Id as ParaId, OutgoingMessages, Status as ParachainStatus,
CollatorPair, CollatorPair,
@@ -33,12 +35,12 @@ use polkadot_primitives::{
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use log::error; use log::{error, trace};
use futures03::TryFutureExt; use futures03::TryFutureExt;
use futures::{Future, future::IntoFuture}; use futures::{Future, future::IntoFuture};
use std::{sync::Arc, marker::PhantomData, time::Duration}; use std::{sync::Arc, marker::PhantomData, time::Duration, fmt::Debug};
use parking_lot::Mutex; use parking_lot::Mutex;
@@ -85,29 +87,30 @@ impl<Block, PF> Clone for Collator<Block, PF> {
impl<Block, PF> ParachainContext for Collator<Block, PF> where impl<Block, PF> ParachainContext for Collator<Block, PF> where
Block: BlockT, Block: BlockT,
PF: Environment<Block> + 'static + Send + Sync, PF: Environment<Block> + 'static + Send,
PF::Error: std::fmt::Debug, PF::Error: Debug,
PF::Proposer: Send + Sync, <PF::Proposer as Proposer<Block>>::Create: Unpin + Send,
<PF::Proposer as Proposer<Block>>::Create: Unpin + Send + Sync,
{ {
type ProduceCandidate = Box< type ProduceCandidate = Box<
dyn Future<Item=(BlockData, parachain::HeadData, OutgoingMessages), Error=InvalidHead> dyn Future<Item=(BlockData, parachain::HeadData, OutgoingMessages), Error=InvalidHead>
+ Send + Sync + Send
>; >;
fn produce_candidate<I: IntoIterator<Item=(ParaId, Message)>>( fn produce_candidate<I: IntoIterator<Item=(ParaId, Message)>>(
&mut self, &mut self,
_relay_chain_parent: Hash, _relay_chain_parent: PHash,
status: ParachainStatus, status: ParachainStatus,
_: I, _: I,
) -> Self::ProduceCandidate { ) -> Self::ProduceCandidate {
trace!(target: "cumulus-collator", "Producing candidate");
let factory = self.proposer_factory.clone(); let factory = self.proposer_factory.clone();
let inherent_providers = self.inherent_data_providers.clone(); let inherent_providers = self.inherent_data_providers.clone();
let res = HeadData::<Block>::decode(&mut &status.head_data.0[..]) let res = HeadData::<Block>::decode(&mut &status.head_data.0[..])
.map_err(|_| InvalidHead) .map_err(|_| InvalidHead)
.into_future() .into_future()
.and_then(move |last_head| .and_then(move |last_head| {
factory.lock() factory.lock()
.init(&last_head.header) .init(&last_head.header)
.map_err(|e| { .map_err(|e| {
@@ -115,17 +118,15 @@ impl<Block, PF> ParachainContext for Collator<Block, PF> where
error!("Could not create proposer: {:?}", e); error!("Could not create proposer: {:?}", e);
InvalidHead InvalidHead
}) })
) .and_then(|mut proposer| {
.and_then(move |proposer| error!("PROPOSING");
inherent_providers.create_inherent_data() let inherent_data = inherent_providers.create_inherent_data()
.map(|id| (proposer, id))
.map_err(|e| { .map_err(|e| {
error!("Failed to create inherent data: {:?}", e); error!("Failed to create inherent data: {:?}", e);
InvalidHead InvalidHead
}) })?;
)
.and_then(|(mut proposer, inherent_data)| { let future = proposer.propose(
proposer.propose(
inherent_data, inherent_data,
Default::default(), Default::default(),
//TODO: Fix this. //TODO: Fix this.
@@ -135,14 +136,23 @@ impl<Block, PF> ParachainContext for Collator<Block, PF> where
error!("Proposing failed: {:?}", e); error!("Proposing failed: {:?}", e);
InvalidHead InvalidHead
}) })
.compat() .compat();
Ok(future)
}) })
})
.flatten()
.map(|b| { .map(|b| {
error!("BUILDING BLOCKDATA");
let block_data = BlockData(b.encode()); let block_data = BlockData(b.encode());
let head_data = HeadData::<Block> { header: b.deconstruct().0 }; let head_data = HeadData::<Block> { header: b.deconstruct().0 };
let messages = OutgoingMessages { outgoing_messages: Vec::new() }; let messages = OutgoingMessages { outgoing_messages: Vec::new() };
(block_data, parachain::HeadData(head_data.encode()), messages) (block_data, parachain::HeadData(head_data.encode()), messages)
})
.then(|r| {
trace!(target: "cumulus-collator", "Produced candidate: {:?}", r);
r
}); });
Box::new(res) Box::new(res)
@@ -150,41 +160,66 @@ impl<Block, PF> ParachainContext for Collator<Block, PF> where
} }
/// Implements `BuildParachainContext` to build a collator instance. /// Implements `BuildParachainContext` to build a collator instance.
struct CollatorBuilder<Block, PF> { struct CollatorBuilder<Block, SP> {
inherent_data_providers: InherentDataProviders, setup_parachain: SP,
proposer_factory: PF, _marker: PhantomData<Block>,
_phantom: PhantomData<Block>,
} }
impl<Block, PF> CollatorBuilder<Block, PF> { impl<Block, SP> CollatorBuilder<Block, SP> {
/// Create a new instance of self. /// Create a new instance of self.
fn new(proposer_factory: PF, inherent_data_providers: InherentDataProviders) -> Self { fn new(setup_parachain: SP) -> Self {
Self { Self {
inherent_data_providers, setup_parachain,
proposer_factory, _marker: PhantomData,
_phantom: Default::default(),
} }
} }
} }
impl<Block, PF> BuildParachainContext for CollatorBuilder<Block, PF> where impl<Block: BlockT, SP: SetupParachain<Block>> BuildParachainContext for CollatorBuilder<Block, SP>
Block: BlockT, where
PF: Environment<Block> + 'static + Send + Sync, <<SP::ProposerFactory as Environment<Block>>::Proposer as Proposer<Block>>::Create: Send + Unpin,
PF::Error: std::fmt::Debug, <SP::ProposerFactory as Environment<Block>>::Error: Debug,
PF::Proposer: Send + Sync,
<PF::Proposer as Proposer<Block>>::Create: Unpin + Send + Sync,
{ {
type ParachainContext = Collator<Block, PF>; type ParachainContext = Collator<Block, SP::ProposerFactory>;
fn build(self, network: Arc<dyn CollatorNetwork>) -> Result<Self::ParachainContext, ()> { fn build<B, E>(
Ok(Collator::new(self.proposer_factory, self.inherent_data_providers, network)) self,
client: Arc<PolkadotClient<B, E>>,
task_executor: TaskExecutor,
network: Arc<dyn CollatorNetwork>,
) -> Result<Self::ParachainContext, ()>
where
B: substrate_client::backend::Backend<PBlock, Blake2Hasher> + 'static,
E: substrate_client::CallExecutor<PBlock, Blake2Hasher> + Clone + Send + Sync + 'static
{
let (proposer_factory, inherent_data_providers) = self.setup_parachain
.setup_parachain(client, task_executor)
.map_err(|e| error!("Error setting up the parachain: {}", e))?;
Ok(Collator::new(proposer_factory, inherent_data_providers, network))
} }
} }
/// Something that can setup a parachain.
pub trait SetupParachain<Block: BlockT>: Send
where
<<Self::ProposerFactory as Environment<Block>>::Proposer as Proposer<Block>>::Create: Send + Unpin,
<Self::ProposerFactory as Environment<Block>>::Error: Debug,
{
/// The proposer factory of the parachain to build blocks.
type ProposerFactory: Environment<Block> + Send + 'static;
/// Setup the parachain.
fn setup_parachain<P: cumulus_consensus::PolkadotClient>(
self,
polkadot_client: P,
task_executor: TaskExecutor,
) -> Result<(Self::ProposerFactory, InherentDataProviders), String>;
}
/// Run a collator with the given proposer factory. /// Run a collator with the given proposer factory.
pub fn run_collator<Block, PF, E, I>( pub fn run_collator<Block, SP, E>(
proposer_factory: PF, setup_parachain: SP,
inherent_data_providers: InherentDataProviders,
para_id: ParaId, para_id: ParaId,
exit: E, exit: E,
key: Arc<CollatorPair>, key: Arc<CollatorPair>,
@@ -192,14 +227,13 @@ pub fn run_collator<Block, PF, E, I>(
) -> Result<(), cli::error::Error> ) -> Result<(), cli::error::Error>
where where
Block: BlockT, Block: BlockT,
PF: Environment<Block> + 'static + Send + Sync, SP: SetupParachain<Block> + Send + 'static,
PF::Error: std::fmt::Debug, <<SP::ProposerFactory as Environment<Block>>::Proposer as Proposer<Block>>::Create: Send + Unpin,
PF::Proposer: Send + Sync, <SP::ProposerFactory as Environment<Block>>::Error: Debug,
<PF::Proposer as Proposer<Block>>::Create: Unpin + Send + Sync,
E: IntoFuture<Item=(), Error=()>, E: IntoFuture<Item=(), Error=()>,
E::Future: Send + Clone + Sync + 'static, E::Future: Send + Clone + Sync + 'static,
{ {
let builder = CollatorBuilder::new(proposer_factory, inherent_data_providers); let builder = CollatorBuilder::new(setup_parachain);
polkadot_collator::run_collator(builder, para_id, exit, key, version) polkadot_collator::run_collator(builder, para_id, exit, key, version)
} }
@@ -273,7 +307,7 @@ mod tests {
unimplemented!("Not required in tests") unimplemented!("Not required in tests")
} }
fn checked_statements(&self, _: Hash) -> fn checked_statements(&self, _: PHash) ->
Box<dyn Stream<Item=SignedStatement, Error=()>> Box<dyn Stream<Item=SignedStatement, Error=()>>
{ {
unimplemented!("Not required in tests") unimplemented!("Not required in tests")
+5 -5
View File
@@ -66,12 +66,12 @@ pub struct HeadUpdate {
/// Helper for the Polkadot client. This is expected to be a lightweight handle /// Helper for the Polkadot client. This is expected to be a lightweight handle
/// like an `Arc`. /// like an `Arc`.
pub trait PolkadotClient: Clone { pub trait PolkadotClient: Clone + 'static {
/// The error type for interacting with the Polkadot client. /// The error type for interacting with the Polkadot client.
type Error: std::fmt::Debug + Send; type Error: std::fmt::Debug + Send;
/// A stream that yields finalized head-data for a certain parachain. /// A stream that yields finalized head-data for a certain parachain.
type Finalized: Stream<Item = Vec<u8>> + Send; type Finalized: Stream<Item = Vec<u8>> + Send + Unpin;
/// Get a stream of finalized heads. /// Get a stream of finalized heads.
fn finalized_heads(&self, para_id: ParaId) -> ClientResult<Self::Finalized>; fn finalized_heads(&self, para_id: ParaId) -> ClientResult<Self::Finalized>;
@@ -85,11 +85,11 @@ pub trait PolkadotClient: Clone {
} }
/// Spawns a future that follows the Polkadot relay chain for the given parachain. /// Spawns a future that follows the Polkadot relay chain for the given parachain.
pub fn follow_polkadot<'a, L: 'a, P: 'a>(para_id: ParaId, local: Arc<L>, polkadot: P) pub fn follow_polkadot<L, P>(para_id: ParaId, local: Arc<L>, polkadot: P)
-> ClientResult<impl Future<Output = ()> + Send + 'a> -> ClientResult<impl Future<Output = ()> + Send + Unpin>
where where
L: LocalClient + Send + Sync, L: LocalClient + Send + Sync,
P: PolkadotClient + Send + Sync, P: PolkadotClient,
{ {
let finalized_heads = polkadot.finalized_heads(para_id)?; let finalized_heads = polkadot.finalized_heads(para_id)?;
+8 -1
View File
@@ -13,6 +13,7 @@ path = 'src/main.rs'
derive_more = '0.15.0' derive_more = '0.15.0'
exit-future = '0.1.4' exit-future = '0.1.4'
futures = '0.1.29' futures = '0.1.29'
futures03 = { package = "futures-preview", version = "0.3.0-alpha.19", features = ["compat"] }
log = '0.4.8' log = '0.4.8'
parking_lot = '0.9.0' parking_lot = '0.9.0'
tokio = '0.1.22' tokio = '0.1.22'
@@ -26,19 +27,25 @@ ctrlc = { version = "3.1.3", features = ["termination"] }
sr-primitives = { git = "https://github.com/paritytech/substrate", default_features = false, branch = "bkchr-cumulus-branch" } sr-primitives = { git = "https://github.com/paritytech/substrate", default_features = false, branch = "bkchr-cumulus-branch" }
sr-io = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } sr-io = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
substrate-cli = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } substrate-cli = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
primitives = { package = "substrate-primitives", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } substrate-primitives = { package = "substrate-primitives", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
substrate-executor = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } substrate-executor = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
substrate-service = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } substrate-service = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
inherents = { package = "substrate-inherents", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } inherents = { package = "substrate-inherents", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
transaction-pool = { package = "substrate-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } transaction-pool = { package = "substrate-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
network = { package = "substrate-network", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } network = { package = "substrate-network", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
substrate-client = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } substrate-client = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
srml-timestamp = { git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
basic-authorship = { package = "substrate-basic-authorship", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" } basic-authorship = { package = "substrate-basic-authorship", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
consensus-common = { package = "substrate-consensus-common", git = "https://github.com/paritytech/substrate", branch = "bkchr-cumulus-branch" }
# Cumulus dependencies # Cumulus dependencies
cumulus-consensus = { path = "../../consensus" } cumulus-consensus = { path = "../../consensus" }
cumulus-collator = { path = "../../collator" } cumulus-collator = { path = "../../collator" }
# Polkadot dependencies
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-cumulus-branch" }
polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "bkchr-cumulus-branch" }
[build-dependencies] [build-dependencies]
vergen = '3.0.4' vergen = '3.0.4'
+16
View File
@@ -1,3 +1,19 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Substrate 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.
// Substrate 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
use std::{env, path::PathBuf}; use std::{env, path::PathBuf};
use vergen::{ConstantsFlags, generate_cargo_keys}; use vergen::{ConstantsFlags, generate_cargo_keys};
+2 -2
View File
@@ -1,5 +1,5 @@
// Copyright 2019 Parity Technologies (UK) Ltd. // Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate. // This file is part of Cumulus.
// Substrate is free software: you can redistribute it and/or modify // Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@@ -12,7 +12,7 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>. // along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource}; use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource};
+16 -2
View File
@@ -1,4 +1,18 @@
//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm. // Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus 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.
// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
@@ -9,7 +23,7 @@
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
use rstd::prelude::*; use rstd::prelude::*;
use primitives::{OpaqueMetadata, crypto::key_types}; use primitives::OpaqueMetadata;
use sr_primitives::{ use sr_primitives::{
ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str, ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str,
impl_opaque_keys, AnySignature impl_opaque_keys, AnySignature
+19 -3
View File
@@ -1,4 +1,20 @@
use primitives::{Pair, Public}; // Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus 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.
// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
use substrate_primitives::{Pair, Public};
use parachain_runtime::{ use parachain_runtime::{
AccountId, BalancesConfig, GenesisConfig, SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, AccountId, BalancesConfig, GenesisConfig, SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY,
}; };
@@ -23,7 +39,7 @@ pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId) {
pub fn get_chain_spec() -> ChainSpec { pub fn get_chain_spec() -> ChainSpec {
ChainSpec::from_genesis( ChainSpec::from_genesis(
"Local Testnet", "Local Testnet",
"local_testnet", "parachain_local_testnet",
|| testnet_genesis( || testnet_genesis(
vec![ vec![
get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Alice"),
@@ -55,7 +71,7 @@ pub fn get_chain_spec() -> ChainSpec {
} }
fn testnet_genesis( fn testnet_genesis(
initial_authorities: Vec<(AccountId, AccountId)>, _initial_authorities: Vec<(AccountId, AccountId)>,
root_key: AccountId, root_key: AccountId,
endowed_accounts: Vec<AccountId>, endowed_accounts: Vec<AccountId>,
_enable_println: bool, _enable_println: bool,
+38 -14
View File
@@ -1,19 +1,35 @@
use crate::{chain_spec, service}; // Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus 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.
// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
use crate::chain_spec;
use parachain_runtime::Block; use parachain_runtime::Block;
pub use substrate_cli::{VersionInfo, IntoExit, error}; pub use substrate_cli::{VersionInfo, IntoExit, error::{self, Result}};
use substrate_cli::{informant, parse_and_prepare, ParseAndPrepare, NoCustom}; use substrate_cli::{parse_and_prepare, ParseAndPrepare, NoCustom};
use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration}; use substrate_service::{Roles as ServiceRoles, Configuration};
use sr_primitives::{traits::{Block as BlockT, Header as HeaderT, Hash as HashT}, BuildStorage}; use sr_primitives::{traits::{Block as BlockT, Header as HeaderT, Hash as HashT}, BuildStorage};
use substrate_client::genesis; use substrate_client::genesis;
use primitives::hexdisplay::HexDisplay; use substrate_primitives::hexdisplay::HexDisplay;
use codec::Encode; use codec::Encode;
use log::info; use log::info;
use std::{path::PathBuf, cell::RefCell}; use std::{path::PathBuf, cell::RefCell, sync::Arc};
use structopt::StructOpt; use structopt::StructOpt;
@@ -44,7 +60,7 @@ pub fn run<I, T, E>(args: I, exit: E, version: VersionInfo) -> error::Result<()>
where where
I: IntoIterator<Item = T>, I: IntoIterator<Item = T>,
T: Into<std::ffi::OsString> + Clone, T: Into<std::ffi::OsString> + Clone,
E: IntoExit, E: IntoExit + Send + 'static,
{ {
type Config<T> = Configuration<(), T>; type Config<T> = Configuration<(), T>;
match parse_and_prepare::<SubCommands, NoCustom, _>( match parse_and_prepare::<SubCommands, NoCustom, _>(
@@ -53,18 +69,26 @@ pub fn run<I, T, E>(args: I, exit: E, version: VersionInfo) -> error::Result<()>
args, args,
) { ) {
ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit,
|exit, _cli_args, _custom_args, config: Config<_>| { |exit, _cli_args, _custom_args, mut config: Config<_>| {
info!("{}", version.name); info!("{}", version.name);
info!(" version {}", config.full_version()); info!(" version {}", config.full_version());
info!(" by {}, 2019", version.author); info!(" by {}, 2019", version.author);
info!("Chain specification: {}", config.chain_spec.name()); info!("Chain specification: {}", config.chain_spec.name());
info!("Node name: {}", config.name); info!("Node name: {}", config.name);
info!("Roles: {:?}", config.roles); info!("Roles: {:?}", config.roles);
panic!(); info!("Parachain id: {:?}", crate::PARA_ID);
// match config.roles {
// ServiceRoles::LIGHT => unimplemented!("Light client not supported!"), // TODO
// _ => unimplemented!(), let key = Arc::new(substrate_primitives::Pair::from_seed(&[10; 32]));
// }.map_err(|e| format!("{:?}", e))
// TODO
config.network.listen_addresses = Vec::new();
config.chain_spec = chain_spec::get_chain_spec();
match config.roles {
ServiceRoles::LIGHT => unimplemented!("Light client not supported!"),
_ => crate::service::run_collator(config, exit, key, version.clone()),
}.map_err(|e| format!("{:?}", e))
}), }),
ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec), ParseAndPrepare::BuildSpec(cmd) => cmd.run(load_spec),
ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>| ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>|
@@ -82,7 +106,7 @@ pub fn run<I, T, E>(args: I, exit: E, version: VersionInfo) -> error::Result<()>
Ok(()) Ok(())
} }
fn load_spec(id: &str) -> Result<Option<chain_spec::ChainSpec>, String> { fn load_spec(_: &str) -> std::result::Result<Option<chain_spec::ChainSpec>, String> {
Ok(Some(chain_spec::get_chain_spec())) Ok(Some(chain_spec::get_chain_spec()))
} }
+22 -1
View File
@@ -1,8 +1,26 @@
//! Substrate Node Template CLI library. // Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus 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.
// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
//! Cumulus test parachain collator
#![warn(missing_docs)] #![warn(missing_docs)]
#![warn(unused_extern_crates)] #![warn(unused_extern_crates)]
use polkadot_primitives::parachain::Id as ParaId;
mod chain_spec; mod chain_spec;
#[macro_use] #[macro_use]
mod service; mod service;
@@ -10,6 +28,9 @@ mod cli;
pub use substrate_cli::{VersionInfo, IntoExit, error}; pub use substrate_cli::{VersionInfo, IntoExit, error};
/// The parachain id of this parachain.
pub const PARA_ID: ParaId = ParaId::new(100);
fn main() -> Result<(), cli::error::Error> { fn main() -> Result<(), cli::error::Error> {
let version = VersionInfo { let version = VersionInfo {
name: "Cumulus Test Parachain Collator", name: "Cumulus Test Parachain Collator",
+90 -17
View File
@@ -1,15 +1,34 @@
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service. // Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus 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.
// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use substrate_client::LongestChain; use parachain_runtime::{self, GenesisConfig, opaque::Block};
use futures::prelude::*;
use parachain_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi};
use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder};
use transaction_pool::{self, txpool::{Pool as TransactionPool}};
use inherents::InherentDataProviders; use inherents::InherentDataProviders;
use substrate_service::{AbstractService, Configuration};
use network::construct_simple_protocol; use network::construct_simple_protocol;
use substrate_executor::native_executor_instance; use substrate_executor::native_executor_instance;
use futures::prelude::*;
use futures03::FutureExt;
use log::error;
pub use substrate_executor::NativeExecutor; pub use substrate_executor::NativeExecutor;
// Our native executor instance. // Our native executor instance.
@@ -55,19 +74,73 @@ macro_rules! new_full_start {
}} }}
} }
/// Builds a new service for a full client. /// Run the collator with the given `config`.
pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisConfig>) pub fn run_collator<C: Send + Default + 'static, E: crate::cli::IntoExit + Send + 'static>(
-> Result<impl AbstractService, ServiceError> config: Configuration<C, GenesisConfig>,
{ exit: E,
let is_authority = config.roles.is_authority(); key: Arc<polkadot_primitives::parachain::CollatorPair>,
let name = config.name.clone(); version: crate::cli::VersionInfo,
let disable_grandpa = config.disable_grandpa; ) -> crate::cli::Result<()> {
let force_authoring = config.force_authoring;
let (builder, inherent_data_providers) = new_full_start!(config); let (builder, inherent_data_providers) = new_full_start!(config);
inherent_data_providers.register_provider(srml_timestamp::InherentDataProvider).unwrap();
let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))?.build()?; let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))?.build()?;
let proposer_factory = basic_authorship::ProposerFactory {
client: service.client(),
transaction_pool: service.transaction_pool(),
};
Ok(service) let on_exit = service.on_exit();
let setup_parachain = SetupParachain { service, inherent_data_providers, proposer_factory, exit };
cumulus_collator::run_collator(setup_parachain, crate::PARA_ID, on_exit, key, version)
} }
struct SetupParachain<S, PF, E> {
service: S,
proposer_factory: PF,
exit: E,
inherent_data_providers: InherentDataProviders,
}
impl<S, PF, E> cumulus_collator::SetupParachain<Block> for SetupParachain<S, PF, E>
where
S: AbstractService,
E: Send + crate::cli::IntoExit,
PF: consensus_common::Environment<Block> + Send + 'static,
<PF::Proposer as consensus_common::Proposer<Block>>::Create: Send + Unpin,
PF::Error: std::fmt::Debug,
{
type ProposerFactory = PF;
fn setup_parachain<P: cumulus_consensus::PolkadotClient>(
self,
polkadot_client: P,
task_executor: polkadot_collator::TaskExecutor,
) -> Result<(Self::ProposerFactory, InherentDataProviders), String> {
let client = self.service.client();
let follow = match cumulus_consensus::follow_polkadot(crate::PARA_ID, client, polkadot_client) {
Ok(follow) => follow,
Err(e) => {
return Err(format!("Could not start following polkadot: {:?}", e));
}
};
task_executor.execute(
Box::new(
self.service
.map_err(|e| error!("Parachain service error: {:?}", e))
.select(futures03::compat::Compat::new(follow.map(|_| Ok::<(), ()>(()))))
.map(|_| ())
.map_err(|_| ())
.select(self.exit.into_exit())
.map(|_| ())
.map_err(|_| ())
),
).map_err(|_| "Could not spawn parachain server!")?;
Ok((self.proposer_factory, self.inherent_data_providers))
}
}