Unverified Commit 61b0b774 authored by Bastian Köcher's avatar Bastian Köcher Committed by GitHub
Browse files

Introduce `BuildParachainContext` trait (#302)

* Introduce `BuildParachainContext` trait

* Change the structure and hide the actual network implementation behind a
trait

* Add functions to collator `Network` trait
parent fa1fea18
Pipeline #41609 passed with stages
in 22 minutes and 42 seconds
...@@ -2308,6 +2308,7 @@ dependencies = [ ...@@ -2308,6 +2308,7 @@ dependencies = [
"substrate-consensus-aura 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-consensus-aura 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
"substrate-consensus-common 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-consensus-common 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
"substrate-keyring 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-keyring 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
"substrate-network 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
"substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)", "substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-master)",
"tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
......
...@@ -10,6 +10,7 @@ futures = "0.1.17" ...@@ -10,6 +10,7 @@ futures = "0.1.17"
client = { package = "substrate-client", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } client = { package = "substrate-client", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
parity-codec = "3.0" parity-codec = "3.0"
primitives = { package = "substrate-primitives", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } primitives = { package = "substrate-primitives", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
substrate-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
consensus_common = { package = "substrate-consensus-common", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } consensus_common = { package = "substrate-consensus-common", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
aura = { package = "substrate-consensus-aura", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } aura = { package = "substrate-consensus-aura", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
polkadot-runtime = { path = "../runtime", version = "0.1" } polkadot-runtime = { path = "../runtime", version = "0.1" }
......
...@@ -53,14 +53,18 @@ use futures::{future, Stream, Future, IntoFuture}; ...@@ -53,14 +53,18 @@ use futures::{future, Stream, Future, IntoFuture};
use log::{info, warn}; use log::{info, warn};
use client::BlockchainEvents; use client::BlockchainEvents;
use primitives::{ed25519, Pair}; use primitives::{ed25519, Pair};
use polkadot_primitives::{BlockId, SessionKey, Hash, Block}; use polkadot_primitives::{
use polkadot_primitives::parachain::{ BlockId, SessionKey, Hash, Block,
self, BlockData, DutyRoster, HeadData, ConsolidatedIngress, Message, Id as ParaId, Extrinsic, parachain::{
PoVBlock, Status as ParachainStatus, self, BlockData, DutyRoster, HeadData, ConsolidatedIngress, Message, Id as ParaId, Extrinsic,
PoVBlock, Status as ParachainStatus,
}
};
use polkadot_cli::{
Worker, IntoExit, ProvideRuntimeApi, TaskExecutor, PolkadotService, CustomConfiguration,
ParachainHost,
}; };
use polkadot_cli::{PolkadotService, CustomConfiguration, ParachainHost}; use polkadot_network::validation::{SessionParams, ValidationNetwork};
use polkadot_cli::{Worker, IntoExit, ProvideRuntimeApi, TaskExecutor};
use polkadot_network::validation::{ValidationNetwork, SessionParams};
use polkadot_network::NetworkService; use polkadot_network::NetworkService;
use tokio::timer::Timeout; use tokio::timer::Timeout;
use consensus_common::SelectChain; use consensus_common::SelectChain;
...@@ -68,9 +72,41 @@ use aura::AuraApi; ...@@ -68,9 +72,41 @@ use aura::AuraApi;
pub use polkadot_cli::VersionInfo; pub use polkadot_cli::VersionInfo;
pub use polkadot_network::validation::Incoming; pub use polkadot_network::validation::Incoming;
pub use polkadot_validation::SignedStatement;
pub use polkadot_primitives::parachain::CollatorId;
pub use substrate_network::PeerId;
const COLLATION_TIMEOUT: Duration = Duration::from_secs(30); const COLLATION_TIMEOUT: Duration = Duration::from_secs(30);
/// An abstraction over the `Network` with useful functions for a `Collator`.
pub trait Network {
/// Convert the given `CollatorId` to a `PeerId`.
fn collator_id_to_peer_id(&self, collator_id: CollatorId) ->
Box<dyn Future<Item=Option<PeerId>, Error=()> + Send>;
/// Create a `Stream` of checked statements for the given `relay_parent`.
///
/// The returned stream will not terminate, so it is required to make sure that the stream is
/// dropped when it is not required anymore. Otherwise, it will stick around in memory
/// infinitely.
fn checked_statements(&self, relay_parent: Hash) -> Box<dyn Stream<Item=SignedStatement, Error=()>>;
}
impl<P, E> Network for ValidationNetwork<P, E, NetworkService, TaskExecutor> where
P: 'static,
E: 'static,
{
fn collator_id_to_peer_id(&self, collator_id: CollatorId) ->
Box<dyn Future<Item=Option<PeerId>, Error=()> + Send>
{
Box::new(Self::collator_id_to_peer_id(self, collator_id))
}
fn checked_statements(&self, relay_parent: Hash) -> Box<dyn Stream<Item=SignedStatement, Error=()>> {
Box::new(Self::checked_statements(self, relay_parent))
}
}
/// Error to return when the head data was invalid. /// Error to return when the head data was invalid.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct InvalidHead; pub struct InvalidHead;
...@@ -93,6 +129,15 @@ impl<R: fmt::Display> fmt::Display for Error<R> { ...@@ -93,6 +129,15 @@ impl<R: fmt::Display> fmt::Display for Error<R> {
} }
} }
/// Something that can build a `ParachainContext`.
pub trait BuildParachainContext {
/// The parachain context produced by the `build` function.
type ParachainContext: self::ParachainContext;
/// Build the `ParachainContext`.
fn build(self, network: Arc<dyn Network>) -> Result<Self::ParachainContext, ()>;
}
/// Parachain context needed for collation. /// Parachain context needed for collation.
/// ///
/// This can be implemented through an externally attached service or a stub. /// This can be implemented through an externally attached service or a stub.
...@@ -114,7 +159,7 @@ pub trait ParachainContext: Clone { ...@@ -114,7 +159,7 @@ pub trait ParachainContext: Clone {
/// This encapsulates a network and local database which may store /// This encapsulates a network and local database which may store
/// some of the input. /// some of the input.
pub trait RelayChainContext { pub trait RelayChainContext {
type Error: ::std::fmt::Debug; type Error: std::fmt::Debug;
/// Future that resolves to the un-routed egress queues of a parachain. /// Future that resolves to the un-routed egress queues of a parachain.
/// The first item is the oldest. /// The first item is the oldest.
...@@ -182,7 +227,7 @@ pub fn collate<'a, R, P>( ...@@ -182,7 +227,7 @@ pub fn collate<'a, R, P>(
/// Polkadot-api context. /// Polkadot-api context.
struct ApiContext<P, E> { struct ApiContext<P, E> {
network: ValidationNetwork<P, E, NetworkService, TaskExecutor>, network: Arc<ValidationNetwork<P, E, NetworkService, TaskExecutor>>,
parent_hash: Hash, parent_hash: Hash,
authorities: Vec<SessionKey>, authorities: Vec<SessionKey>,
} }
...@@ -210,14 +255,13 @@ impl<P: 'static, E: 'static> RelayChainContext for ApiContext<P, E> where ...@@ -210,14 +255,13 @@ impl<P: 'static, E: 'static> RelayChainContext for ApiContext<P, E> where
} }
struct CollationNode<P, E> { struct CollationNode<P, E> {
parachain_context: P, build_parachain_context: P,
exit: E, exit: E,
para_id: ParaId, para_id: ParaId,
key: Arc<ed25519::Pair>, key: Arc<ed25519::Pair>,
} }
impl<P, E> IntoExit for CollationNode<P, E> where impl<P, E> IntoExit for CollationNode<P, E> where
P: ParachainContext + Send + 'static,
E: Future<Item=(),Error=()> + Send + 'static E: Future<Item=(),Error=()> + Send + 'static
{ {
type Exit = E; type Exit = E;
...@@ -227,11 +271,12 @@ impl<P, E> IntoExit for CollationNode<P, E> where ...@@ -227,11 +271,12 @@ impl<P, E> IntoExit for CollationNode<P, E> where
} }
impl<P, E> Worker for CollationNode<P, E> where impl<P, E> Worker for CollationNode<P, E> where
P: ParachainContext + Send + 'static, P: BuildParachainContext + Send + 'static,
E: Future<Item=(),Error=()> + Clone + Send + Sync + 'static, P::ParachainContext: Send + 'static,
<P::ProduceCandidate as IntoFuture>::Future: Send + 'static, <<P::ParachainContext as ParachainContext>::ProduceCandidate as IntoFuture>::Future: Send + 'static,
E: Future<Item=(), Error=()> + Clone + Send + Sync + 'static,
{ {
type Work = Box<dyn Future<Item=(),Error=()> + Send>; type Work = Box<dyn Future<Item=(), Error=()> + Send>;
fn configuration(&self) -> CustomConfiguration { fn configuration(&self) -> CustomConfiguration {
let mut config = CustomConfiguration::default(); let mut config = CustomConfiguration::default();
...@@ -242,10 +287,10 @@ impl<P, E> Worker for CollationNode<P, E> where ...@@ -242,10 +287,10 @@ impl<P, E> Worker for CollationNode<P, E> where
config config
} }
fn work<S>(self, service: &S, task_executor: TaskExecutor) -> Self::Work fn work<S>(self, service: &S, task_executor: TaskExecutor) -> Self::Work where
where S: PolkadotService, S: PolkadotService,
{ {
let CollationNode { parachain_context, exit, para_id, key } = self; let CollationNode { build_parachain_context, exit, para_id, key } = self;
let client = service.client(); let client = service.client();
let network = service.network(); let network = service.network();
let known_oracle = client.clone(); let known_oracle = client.clone();
...@@ -278,14 +323,15 @@ impl<P, E> Worker for CollationNode<P, E> where ...@@ -278,14 +323,15 @@ impl<P, E> Worker for CollationNode<P, E> where
}, },
); );
let validation_network = ValidationNetwork::new( let validation_network = Arc::new(ValidationNetwork::new(
network.clone(), network.clone(),
exit.clone(), exit.clone(),
message_validator, message_validator,
client.clone(), client.clone(),
task_executor, task_executor,
); ));
let parachain_context = build_parachain_context.build(validation_network.clone()).unwrap();
let inner_exit = exit.clone(); let inner_exit = exit.clone();
let work = client.import_notification_stream() let work = client.import_notification_stream()
.for_each(move |notification| { .for_each(move |notification| {
...@@ -376,27 +422,28 @@ fn compute_targets(para_id: ParaId, session_keys: &[SessionKey], roster: DutyRos ...@@ -376,27 +422,28 @@ fn compute_targets(para_id: ParaId, session_keys: &[SessionKey], roster: DutyRos
.collect() .collect()
} }
/// Run a collator node with the given `RelayChainContext` and `ParachainContext` and /// Run a collator node with the given `RelayChainContext` and `ParachainContext`
/// arguments to the underlying polkadot node. /// build by the given `BuildParachainContext` and arguments to the underlying polkadot node.
/// ///
/// Provide a future which resolves when the node should exit. /// Provide a future which resolves when the node should exit.
/// This function blocks until done. /// This function blocks until done.
pub fn run_collator<P, E, I, ArgT>( pub fn run_collator<P, E, I, ArgT>(
parachain_context: P, build_parachain_context: P,
para_id: ParaId, para_id: ParaId,
exit: E, exit: E,
key: Arc<ed25519::Pair>, key: Arc<ed25519::Pair>,
args: I, args: I,
version: VersionInfo, version: VersionInfo,
) -> polkadot_cli::error::Result<()> where ) -> polkadot_cli::error::Result<()> where
P: ParachainContext + Send + 'static, P: BuildParachainContext + Send + 'static,
<P::ProduceCandidate as IntoFuture>::Future: Send + 'static, P::ParachainContext: Send + 'static,
<<P::ParachainContext as ParachainContext>::ProduceCandidate as IntoFuture>::Future: Send + 'static,
E: IntoFuture<Item=(),Error=()>, E: IntoFuture<Item=(),Error=()>,
E::Future: Send + Clone + Sync + 'static, E::Future: Send + Clone + Sync + 'static,
I: IntoIterator<Item=ArgT>, I: IntoIterator<Item=ArgT>,
ArgT: Into<std::ffi::OsString> + Clone, ArgT: Into<std::ffi::OsString> + Clone,
{ {
let node_logic = CollationNode { parachain_context, exit: exit.into_future(), para_id, key }; let node_logic = CollationNode { build_parachain_context, exit: exit.into_future(), para_id, key };
polkadot_cli::run(args, node_logic, version) polkadot_cli::run(args, node_logic, version)
} }
......
...@@ -288,7 +288,9 @@ impl<P, E, N, T> ValidationNetwork<P, E, N, T> where ...@@ -288,7 +288,9 @@ impl<P, E, N, T> ValidationNetwork<P, E, N, T> where
rx rx
} }
}
impl<P, E, N, T> ValidationNetwork<P, E, N, T> where N: NetworkService {
/// Convert the given `CollatorId` to a `PeerId`. /// Convert the given `CollatorId` to a `PeerId`.
pub fn collator_id_to_peer_id(&self, collator_id: CollatorId) -> pub fn collator_id_to_peer_id(&self, collator_id: CollatorId) ->
impl Future<Item=Option<PeerId>, Error=()> + Send impl Future<Item=Option<PeerId>, Error=()> + Send
......
...@@ -23,17 +23,20 @@ use std::sync::Arc; ...@@ -23,17 +23,20 @@ use std::sync::Arc;
use adder::{HeadData as AdderHead, BlockData as AdderBody}; use adder::{HeadData as AdderHead, BlockData as AdderBody};
use substrate_primitives::Pair; use substrate_primitives::Pair;
use parachain::codec::{Encode, Decode}; use parachain::codec::{Encode, Decode};
use primitives::Hash; use primitives::{
use primitives::parachain::{ Hash,
HeadData, BlockData, Id as ParaId, Message, Extrinsic, Status as ParachainStatus, parachain::{HeadData, BlockData, Id as ParaId, Message, Extrinsic, Status as ParachainStatus},
}; };
use collator::{InvalidHead, ParachainContext, VersionInfo}; use collator::{InvalidHead, ParachainContext, VersionInfo, Network, BuildParachainContext};
use parking_lot::Mutex; use parking_lot::Mutex;
const GENESIS: AdderHead = AdderHead { const GENESIS: AdderHead = AdderHead {
number: 0, number: 0,
parent_hash: [0; 32], parent_hash: [0; 32],
post_state: [1, 27, 77, 3, 221, 140, 1, 241, 4, 145, 67, 207, 156, 76, 129, 126, 75, 22, 127, 29, 27, 131, 229, 198, 240, 241, 13, 137, 186, 30, 123, 206], post_state: [
1, 27, 77, 3, 221, 140, 1, 241, 4, 145, 67, 207, 156, 76, 129, 126, 75,
22, 127, 29, 27, 131, 229, 198, 240, 241, 13, 137, 186, 30, 123, 206
],
}; };
const GENESIS_BODY: AdderBody = AdderBody { const GENESIS_BODY: AdderBody = AdderBody {
...@@ -93,6 +96,14 @@ impl ParachainContext for AdderContext { ...@@ -93,6 +96,14 @@ impl ParachainContext for AdderContext {
} }
} }
impl BuildParachainContext for AdderContext {
type ParachainContext = Self;
fn build(self, _: Arc<dyn Network>) -> Result<Self::ParachainContext, ()> {
Ok(self)
}
}
fn main() { fn main() {
let key = Arc::new(Pair::from_seed(&[1; 32])); let key = Arc::new(Pair::from_seed(&[1; 32]));
let id: ParaId = 100.into(); let id: ParaId = 100.into();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment