mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-21 05:11:02 +00:00
Update futures and tokio for browser light client (#673)
* Make availability-store compile for WASM * Use --manifest-path instead * Make validation work on wasm! * Switch to Spawn trait * Migrate validation to std futures * Migrate network to std futures * Final changes to validation * Tidy up network * Tidy up validation * Switch branch * Migrate service * Get polkadot to compile via wasm! * Add browser-demo * Add initial browser file * Add browser-demo * Tidy * Temp switch back to substrate/master * tidy * Fix wasm build * Re-add release flag * Switch to polkadot-master * Revert cli tokio version to avoid libp2p panic * Update tokio version * Fix availability store tests * Fix validation tests * Remove futures01 from availability-store * Fix network tests * Small changes * Fix collator * Fix typo * Revert removal of tokio_executor that causes tokio version mismatch panic * Fix adder test parachain * Revert "Revert removal of tokio_executor that causes tokio version mismatch panic" This reverts commit cfeb50c01d8df5e209483406a711e64761b44ae9. * Update availability-store/src/worker.rs Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com> * Update network/src/lib.rs Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com> * Update network/src/lib.rs Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com> * Box pin changes * Asyncify network functions * Clean up browser validation worker error * Fix av store test * Nits * Fix validation test * Switch favicon * Fix validation test again * Revert "Asyncify network functions" This reverts commit f20ae6548dc482cb1e75bc80641cfe55c6131a53. * Add async blocks back in
This commit is contained in:
@@ -20,7 +20,7 @@ use codec::{Encode, Decode};
|
||||
use polkadot_primitives::Hash;
|
||||
use polkadot_primitives::parachain::{CollatorId, Id as ParaId, Collation};
|
||||
use sc_network::PeerId;
|
||||
use futures::sync::oneshot;
|
||||
use futures::channel::oneshot;
|
||||
|
||||
use std::collections::hash_map::{HashMap, Entry};
|
||||
use std::time::{Duration, Instant};
|
||||
@@ -230,7 +230,7 @@ mod tests {
|
||||
use polkadot_primitives::parachain::{
|
||||
CandidateReceipt, BlockData, PoVBlock, HeadData, ConsolidatedIngress,
|
||||
};
|
||||
use futures::Future;
|
||||
use futures::executor::block_on;
|
||||
|
||||
fn make_pov(block_data: Vec<u8>) -> PoVBlock {
|
||||
PoVBlock {
|
||||
@@ -293,8 +293,8 @@ mod tests {
|
||||
pov: make_pov(vec![4, 5, 6]),
|
||||
});
|
||||
|
||||
rx1.wait().unwrap();
|
||||
rx2.wait().unwrap();
|
||||
block_on(rx1).unwrap();
|
||||
block_on(rx2).unwrap();
|
||||
assert_eq!(pool.collators.get(&primary).map(|ids| &ids.1).unwrap(), &peer_id);
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ mod tests {
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
pool.await_collation(relay_parent, para_id, tx);
|
||||
rx.wait().unwrap();
|
||||
block_on(rx).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+24
-29
@@ -26,10 +26,9 @@ pub mod validation;
|
||||
pub mod gossip;
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use futures::sync::oneshot;
|
||||
use futures::future::Either;
|
||||
use futures::channel::{oneshot, mpsc};
|
||||
use futures::prelude::*;
|
||||
use futures03::{channel::mpsc, compat::{Compat, Stream01CompatExt}, FutureExt, StreamExt, TryFutureExt};
|
||||
use futures::future::Either;
|
||||
use polkadot_primitives::{Block, Hash, Header};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, CollatorId, CandidateReceipt, Collation, PoVBlock,
|
||||
@@ -48,6 +47,8 @@ use self::local_collations::LocalCollations;
|
||||
use log::{trace, debug, warn};
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context as PollContext, Poll};
|
||||
|
||||
use crate::gossip::{POLKADOT_ENGINE_ID, GossipMessage, ErasureChunkMessage};
|
||||
|
||||
@@ -112,23 +113,18 @@ impl<T> av_store::ProvideGossipMessages for AvailabilityNetworkShim<T>
|
||||
where T: NetworkService
|
||||
{
|
||||
fn gossip_messages_for(&self, topic: Hash)
|
||||
-> Box<dyn futures03::Stream<Item = (Hash, Hash, ErasureChunk)> + Unpin + Send>
|
||||
-> Pin<Box<dyn Stream<Item = (Hash, Hash, ErasureChunk)> + Send>>
|
||||
{
|
||||
Box::new(self.0.gossip_messages_for(topic)
|
||||
.compat()
|
||||
.filter_map(|msg| async move {
|
||||
self.0.gossip_messages_for(topic)
|
||||
.filter_map(|(msg, _)| async move {
|
||||
match msg {
|
||||
Ok(msg) => match msg.0 {
|
||||
GossipMessage::ErasureChunk(chunk) => {
|
||||
Some((chunk.relay_parent, chunk.candidate_hash, chunk.chunk))
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
GossipMessage::ErasureChunk(chunk) => {
|
||||
Some((chunk.relay_parent, chunk.candidate_hash, chunk.chunk))
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.boxed()
|
||||
)
|
||||
}
|
||||
|
||||
fn gossip_erasure_chunk(
|
||||
@@ -170,7 +166,7 @@ impl NetworkService for PolkadotNetworkService {
|
||||
Err(_) => mpsc::unbounded().1, // return empty channel.
|
||||
};
|
||||
|
||||
GossipMessageStream::new(Box::new(Compat::new(topic_stream.map(Ok))))
|
||||
GossipMessageStream::new(topic_stream.boxed())
|
||||
}
|
||||
|
||||
fn gossip_message(&self, topic: Hash, message: GossipMessage) {
|
||||
@@ -213,12 +209,12 @@ impl GossipService for consensus_gossip::ConsensusGossip<Block> {
|
||||
|
||||
/// A stream of gossip messages and an optional sender for a topic.
|
||||
pub struct GossipMessageStream {
|
||||
topic_stream: Box<dyn Stream<Item = TopicNotification, Error = ()> + Send>,
|
||||
topic_stream: Pin<Box<dyn Stream<Item = TopicNotification> + Send>>,
|
||||
}
|
||||
|
||||
impl GossipMessageStream {
|
||||
/// Create a new instance with the given topic stream.
|
||||
pub fn new(topic_stream: Box<dyn Stream<Item = TopicNotification, Error = ()> + Send>) -> Self {
|
||||
pub fn new(topic_stream: Pin<Box<dyn Stream<Item = TopicNotification> + Send>>) -> Self {
|
||||
Self {
|
||||
topic_stream,
|
||||
}
|
||||
@@ -227,18 +223,20 @@ impl GossipMessageStream {
|
||||
|
||||
impl Stream for GossipMessageStream {
|
||||
type Item = (GossipMessage, Option<PeerId>);
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut PollContext) -> Poll<Option<Self::Item>> {
|
||||
let this = Pin::into_inner(self);
|
||||
|
||||
loop {
|
||||
let msg = match futures::try_ready!(self.topic_stream.poll()) {
|
||||
Some(msg) => msg,
|
||||
None => return Ok(Async::Ready(None)),
|
||||
let msg = match Pin::new(&mut this.topic_stream).poll_next(cx) {
|
||||
Poll::Ready(Some(msg)) => msg,
|
||||
Poll::Ready(None) => return Poll::Ready(None),
|
||||
Poll::Pending => return Poll::Pending,
|
||||
};
|
||||
|
||||
debug!(target: "validation", "Processing statement for live validation leaf-work");
|
||||
if let Ok(gmsg) = GossipMessage::decode(&mut &msg.message[..]) {
|
||||
return Ok(Async::Ready(Some((gmsg, msg.sender))))
|
||||
return Poll::Ready(Some((gmsg, msg.sender)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -835,7 +833,7 @@ impl PolkadotProtocol {
|
||||
targets: HashSet<ValidatorId>,
|
||||
collation: Collation,
|
||||
outgoing_targeted: OutgoingMessages,
|
||||
) -> impl futures::future::Future<Item = (), Error=()> {
|
||||
) -> impl Future<Output = ()> {
|
||||
debug!(target: "p_net", "Importing local collation on relay parent {:?} and parachain {:?}",
|
||||
relay_parent, collation.info.parachain_index);
|
||||
|
||||
@@ -843,7 +841,7 @@ impl PolkadotProtocol {
|
||||
Some(ref availability_store) => {
|
||||
let availability_store_cloned = availability_store.clone();
|
||||
let collation_cloned = collation.clone();
|
||||
Either::A((async move {
|
||||
Either::Left((async move {
|
||||
let _ = availability_store_cloned.make_available(av_store::Data {
|
||||
relay_parent,
|
||||
parachain_id: collation_cloned.info.parachain_index,
|
||||
@@ -852,13 +850,10 @@ impl PolkadotProtocol {
|
||||
}).await;
|
||||
}
|
||||
)
|
||||
.unit_error()
|
||||
.boxed()
|
||||
.compat()
|
||||
.then(|_| Ok(()))
|
||||
)
|
||||
}
|
||||
None => Either::B(futures::future::ok::<(), ()>(())),
|
||||
None => Either::Right(futures::future::ready(())),
|
||||
};
|
||||
|
||||
for (primary, cloned_collation) in self.local_collations.add_collation(relay_parent, targets, collation.clone()) {
|
||||
|
||||
@@ -34,7 +34,7 @@ use polkadot_primitives::parachain::{
|
||||
use crate::gossip::{RegisteredMessageValidator, GossipMessage, GossipStatement, ErasureChunkMessage};
|
||||
|
||||
use futures::prelude::*;
|
||||
use futures03::{future::FutureExt, TryFutureExt};
|
||||
use futures::{task::SpawnExt, future::{ready, select}};
|
||||
use parking_lot::Mutex;
|
||||
use log::{debug, trace};
|
||||
|
||||
@@ -59,14 +59,14 @@ pub(crate) fn attestation_topic(parent_hash: Hash) -> Hash {
|
||||
/// dropped when it is not required anymore. Otherwise, it will stick around in memory
|
||||
/// infinitely.
|
||||
pub(crate) fn checked_statements<N: NetworkService>(network: &N, topic: Hash) ->
|
||||
impl Stream<Item=SignedStatement, Error=()> {
|
||||
impl Stream<Item=SignedStatement> {
|
||||
// spin up a task in the background that processes all incoming statements
|
||||
// validation has been done already by the gossip validator.
|
||||
// this will block internally until the gossip messages stream is obtained.
|
||||
network.gossip_messages_for(topic)
|
||||
.filter_map(|msg| match msg.0 {
|
||||
GossipMessage::Statement(s) => Some(s.signed_statement),
|
||||
_ => None
|
||||
GossipMessage::Statement(s) => ready(Some(s.signed_statement)),
|
||||
_ => ready(None)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ impl<P, E, N: NetworkService, T> Router<P, E, N, T> {
|
||||
/// 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.
|
||||
pub(crate) fn checked_statements(&self) -> impl Stream<Item=SignedStatement, Error=()> {
|
||||
pub(crate) fn checked_statements(&self) -> impl Stream<Item=SignedStatement> {
|
||||
checked_statements(&**self.network(), self.attestation_topic)
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ impl<P: ProvideRuntimeApi + Send + Sync + 'static, E, N, T> Router<P, E, N, T> w
|
||||
P::Api: ParachainHost<Block, Error = sp_blockchain::Error>,
|
||||
N: NetworkService,
|
||||
T: Clone + Executor + Send + 'static,
|
||||
E: futures03::Future<Output=()> + Clone + Send + Unpin + 'static,
|
||||
E: Future<Output=()> + Clone + Send + Unpin + 'static,
|
||||
{
|
||||
/// Import a statement whose signature has been checked already.
|
||||
pub(crate) fn import_statement(&self, statement: SignedStatement) {
|
||||
@@ -174,50 +174,54 @@ impl<P: ProvideRuntimeApi + Send + Sync + 'static, E, N, T> Router<P, E, N, T> w
|
||||
|
||||
if let Some(work) = producer.map(|p| self.create_work(c_hash, p)) {
|
||||
trace!(target: "validation", "driving statement work to completion");
|
||||
let exit = self.fetcher.exit().clone().unit_error().compat();
|
||||
let work = work.select2(exit).then(|_| Ok(()));
|
||||
self.fetcher.executor().spawn(work);
|
||||
|
||||
let work = select(work.boxed(), self.fetcher.exit().clone())
|
||||
.map(drop);
|
||||
let _ = self.fetcher.executor().spawn(work);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_work<D>(&self, candidate_hash: Hash, producer: ParachainWork<D>)
|
||||
-> impl Future<Item=(),Error=()> + Send + 'static
|
||||
-> impl Future<Output=()> + Send + 'static
|
||||
where
|
||||
D: Future<Item=PoVBlock,Error=io::Error> + Send + 'static,
|
||||
D: Future<Output=Result<PoVBlock,io::Error>> + Send + Unpin + 'static,
|
||||
{
|
||||
let table = self.table.clone();
|
||||
let network = self.network().clone();
|
||||
let knowledge = self.fetcher.knowledge().clone();
|
||||
let attestation_topic = self.attestation_topic;
|
||||
let parent_hash = self.parent_hash();
|
||||
let api = self.fetcher.api().clone();
|
||||
|
||||
producer.prime(self.fetcher.api().clone())
|
||||
.validate()
|
||||
.boxed()
|
||||
.compat()
|
||||
.map(move |validated| {
|
||||
// store the data before broadcasting statements, so other peers can fetch.
|
||||
knowledge.lock().note_candidate(
|
||||
async move {
|
||||
match producer.prime(api).validate().await {
|
||||
Ok(validated) => {
|
||||
// store the data before broadcasting statements, so other peers can fetch.
|
||||
knowledge.lock().note_candidate(
|
||||
candidate_hash,
|
||||
Some(validated.0.pov_block().clone()),
|
||||
validated.0.outgoing_messages().cloned(),
|
||||
);
|
||||
);
|
||||
|
||||
// propagate the statement.
|
||||
// consider something more targeted than gossip in the future.
|
||||
let statement = GossipStatement::new(
|
||||
// propagate the statement.
|
||||
// consider something more targeted than gossip in the future.
|
||||
let statement = GossipStatement::new(
|
||||
parent_hash,
|
||||
match table.import_validated(validated.0) {
|
||||
None => return,
|
||||
Some(s) => s,
|
||||
None => return,
|
||||
Some(s) => s,
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
network.gossip_message(attestation_topic, statement.into());
|
||||
})
|
||||
.map_err(|e| debug!(target: "p_net", "Failed to produce statements: {:?}", e))
|
||||
network.gossip_message(attestation_topic, statement.into());
|
||||
},
|
||||
Err(err) => {
|
||||
debug!(target: "p_net", "Failed to produce statements: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +229,7 @@ impl<P: ProvideRuntimeApi + Send, E, N, T> TableRouter for Router<P, E, N, T> wh
|
||||
P::Api: ParachainHost<Block>,
|
||||
N: NetworkService,
|
||||
T: Clone + Executor + Send + 'static,
|
||||
E: futures03::Future<Output=()> + Clone + Send + Unpin + 'static,
|
||||
E: Future<Output=()> + Clone + Send + 'static,
|
||||
{
|
||||
type Error = io::Error;
|
||||
type FetchValidationProof = validation::PoVReceiver;
|
||||
|
||||
@@ -33,7 +33,7 @@ use sc_network::{
|
||||
specialization::NetworkSpecialization,
|
||||
};
|
||||
|
||||
use futures::Future;
|
||||
use futures::executor::block_on;
|
||||
|
||||
mod validation;
|
||||
|
||||
@@ -245,7 +245,7 @@ fn fetches_from_those_with_knowledge() {
|
||||
let pov_block = make_pov(block_data.0);
|
||||
on_message(&mut protocol, &mut ctx, peer_b, Message::PovBlock(2, Some(pov_block.clone())));
|
||||
drop(protocol);
|
||||
assert_eq!(recv.wait().unwrap(), pov_block);
|
||||
assert_eq!(block_on(recv).unwrap(), pov_block);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,22 +39,23 @@ use sp_runtime::traits::{ApiRef, {Block as BlockT}, ProvideRuntimeApi};
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use futures::{prelude::*, sync::mpsc};
|
||||
use std::pin::Pin;
|
||||
use std::task::{Poll, Context};
|
||||
use futures::{prelude::*, channel::mpsc};
|
||||
use codec::Encode;
|
||||
|
||||
use super::{TestContext, TestChainContext};
|
||||
|
||||
type TaskExecutor = Arc<dyn futures::future::Executor<Box<dyn Future<Item = (), Error = ()> + Send>> + Send + Sync>;
|
||||
type TaskExecutor = Arc<dyn futures::task::Spawn + Send + Sync>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct NeverExit;
|
||||
|
||||
impl Future for NeverExit {
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
type Output = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<(), ()> {
|
||||
Ok(Async::NotReady)
|
||||
fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,27 +94,28 @@ impl GossipRouter {
|
||||
}
|
||||
|
||||
impl Future for GossipRouter {
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
type Output = ();
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
let this = Pin::into_inner(self);
|
||||
|
||||
fn poll(&mut self) -> Poll<(), ()> {
|
||||
loop {
|
||||
match self.incoming_messages.poll().unwrap() {
|
||||
Async::Ready(Some((topic, message))) => self.add_message(topic, message),
|
||||
Async::Ready(None) => panic!("ended early."),
|
||||
Async::NotReady => break,
|
||||
match Pin::new(&mut this.incoming_messages).poll_next(cx) {
|
||||
Poll::Ready(Some((topic, message))) => this.add_message(topic, message),
|
||||
Poll::Ready(None) => panic!("ended early."),
|
||||
Poll::Pending => break,
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match self.incoming_streams.poll().unwrap() {
|
||||
Async::Ready(Some((topic, sender))) => self.add_outgoing(topic, sender),
|
||||
Async::Ready(None) => panic!("ended early."),
|
||||
Async::NotReady => break,
|
||||
match Pin::new(&mut this.incoming_streams).poll_next(cx) {
|
||||
Poll::Ready(Some((topic, sender))) => this.add_outgoing(topic, sender),
|
||||
Poll::Ready(None) => panic!("ended early."),
|
||||
Poll::Pending => break,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +150,7 @@ impl NetworkService for TestNetwork {
|
||||
fn gossip_messages_for(&self, topic: Hash) -> GossipMessageStream {
|
||||
let (tx, rx) = mpsc::unbounded();
|
||||
let _ = self.gossip.send_listener.unbounded_send((topic, tx));
|
||||
GossipMessageStream::new(Box::new(rx))
|
||||
GossipMessageStream::new(rx.boxed())
|
||||
}
|
||||
|
||||
fn gossip_message(&self, topic: Hash, message: GossipMessage) {
|
||||
@@ -417,8 +419,8 @@ impl av_store::ProvideGossipMessages for DummyGossipMessages {
|
||||
fn gossip_messages_for(
|
||||
&self,
|
||||
_topic: Hash
|
||||
) -> Box<dyn futures03::Stream<Item = (Hash, Hash, ErasureChunk)> + Send + Unpin> {
|
||||
Box::new(futures03::stream::empty())
|
||||
) -> Pin<Box<dyn futures::Stream<Item = (Hash, Hash, ErasureChunk)> + Send>> {
|
||||
stream::empty().boxed()
|
||||
}
|
||||
|
||||
fn gossip_erasure_chunk(
|
||||
|
||||
@@ -31,17 +31,19 @@ use polkadot_primitives::parachain::{
|
||||
};
|
||||
|
||||
use futures::prelude::*;
|
||||
use futures::future::{self, Executor as FutureExecutor};
|
||||
use futures::sync::oneshot::{self, Receiver};
|
||||
use futures03::{FutureExt as _, TryFutureExt as _};
|
||||
use futures::task::SpawnExt;
|
||||
pub use futures::task::Spawn as Executor;
|
||||
use futures::channel::oneshot::{self, Receiver};
|
||||
use futures::future::{ready, select};
|
||||
|
||||
use std::collections::hash_map::{HashMap, Entry};
|
||||
use std::io;
|
||||
use std::sync::Arc;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Poll, Context};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use parking_lot::Mutex;
|
||||
use log::warn;
|
||||
|
||||
use crate::router::Router;
|
||||
use crate::gossip::{RegisteredMessageValidator, MessageValidationData};
|
||||
@@ -50,33 +52,6 @@ use super::NetworkService;
|
||||
|
||||
pub use polkadot_validation::Incoming;
|
||||
|
||||
/// An executor suitable for dispatching async consensus tasks.
|
||||
pub trait Executor {
|
||||
fn spawn<F: Future<Item=(),Error=()> + Send + 'static>(&self, f: F);
|
||||
}
|
||||
|
||||
/// A wrapped futures::future::Executor.
|
||||
#[derive(Clone)]
|
||||
pub struct WrappedExecutor<T>(pub T);
|
||||
|
||||
impl<T> Executor for WrappedExecutor<T>
|
||||
where T: FutureExecutor<Box<dyn Future<Item=(),Error=()> + Send + 'static>>
|
||||
{
|
||||
fn spawn<F: Future<Item=(),Error=()> + Send + 'static>(&self, f: F) {
|
||||
if let Err(e) = self.0.execute(Box::new(f)) {
|
||||
warn!(target: "validation", "could not spawn consensus task: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Executor for Arc<
|
||||
dyn futures::future::Executor<Box<dyn Future<Item = (), Error = ()> + Send>> + Send + Sync
|
||||
> {
|
||||
fn spawn<F: Future<Item=(),Error=()> + Send + 'static>(&self, f: F) {
|
||||
let _ = FutureExecutor::execute(&**self, Box::new(f));
|
||||
}
|
||||
}
|
||||
|
||||
/// Params to instantiate validation work on a block-DAG leaf.
|
||||
pub struct LeafWorkParams {
|
||||
/// The local session key.
|
||||
@@ -124,7 +99,7 @@ impl<P, E: Clone, N, T: Clone> Clone for ValidationNetwork<P, E, N, T> {
|
||||
impl<P, E, N, T> ValidationNetwork<P, E, N, T> where
|
||||
P: ProvideRuntimeApi + Send + Sync + 'static,
|
||||
P::Api: ParachainHost<Block>,
|
||||
E: Clone + futures03::Future<Output=()> + Send + Sync + 'static,
|
||||
E: Clone + Future<Output=()> + Send + Sync + 'static,
|
||||
N: NetworkService,
|
||||
T: Clone + Executor + Send + Sync + 'static,
|
||||
{
|
||||
@@ -184,13 +159,17 @@ impl<P, E, N, T> ValidationNetwork<P, E, N, T> where
|
||||
impl<P, E, N, T> ValidationNetwork<P, E, N, T> where N: NetworkService {
|
||||
/// Convert the given `CollatorId` to a `PeerId`.
|
||||
pub fn collator_id_to_peer_id(&self, collator_id: CollatorId) ->
|
||||
impl Future<Item=Option<PeerId>, Error=()> + Send
|
||||
impl Future<Output=Option<PeerId>> + Send
|
||||
{
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.network.with_spec(move |spec, _| {
|
||||
let _ = send.send(spec.collator_id_to_peer_id(&collator_id).cloned());
|
||||
});
|
||||
recv.map_err(|_| ())
|
||||
let network = self.network.clone();
|
||||
|
||||
async move {
|
||||
let (send, recv) = oneshot::channel();
|
||||
network.with_spec(move |spec, _| {
|
||||
let _ = send.send(spec.collator_id_to_peer_id(&collator_id).cloned());
|
||||
});
|
||||
recv.await.ok().and_then(|opt| opt)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a `Stream` of checked statements for the given `relay_parent`.
|
||||
@@ -198,7 +177,7 @@ impl<P, E, N, T> ValidationNetwork<P, E, N, T> where N: NetworkService {
|
||||
/// 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.
|
||||
pub fn checked_statements(&self, relay_parent: Hash) -> impl Stream<Item=SignedStatement, Error=()> {
|
||||
pub fn checked_statements(&self, relay_parent: Hash) -> impl Stream<Item=SignedStatement> {
|
||||
crate::router::checked_statements(&*self.network, crate::router::attestation_topic(relay_parent))
|
||||
}
|
||||
}
|
||||
@@ -207,13 +186,13 @@ impl<P, E, N, T> ValidationNetwork<P, E, N, T> where N: NetworkService {
|
||||
impl<P, E, N, T> ParachainNetwork for ValidationNetwork<P, E, N, T> where
|
||||
P: ProvideRuntimeApi + Send + Sync + 'static,
|
||||
P::Api: ParachainHost<Block, Error = sp_blockchain::Error>,
|
||||
E: Clone + futures03::Future<Output=()> + Send + Sync + Unpin + 'static,
|
||||
E: Clone + Future<Output=()> + Send + Sync + Unpin + 'static,
|
||||
N: NetworkService,
|
||||
T: Clone + Executor + Send + Sync + 'static,
|
||||
{
|
||||
type Error = String;
|
||||
type TableRouter = Router<P, E, N, T>;
|
||||
type BuildTableRouter = Box<dyn Future<Item=Self::TableRouter, Error=String> + Send>;
|
||||
type BuildTableRouter = Box<dyn Future<Output=Result<Self::TableRouter, String>> + Send + Unpin>;
|
||||
|
||||
fn communication_for(
|
||||
&self,
|
||||
@@ -234,7 +213,7 @@ impl<P, E, N, T> ParachainNetwork for ValidationNetwork<P, E, N, T> where
|
||||
let executor = self.executor.clone();
|
||||
let work = build_fetcher
|
||||
.map_err(|e| format!("{:?}", e))
|
||||
.map(move |fetcher| {
|
||||
.map_ok(move |fetcher| {
|
||||
let table_router = Router::new(
|
||||
table,
|
||||
fetcher,
|
||||
@@ -243,12 +222,14 @@ impl<P, E, N, T> ParachainNetwork for ValidationNetwork<P, E, N, T> where
|
||||
|
||||
let table_router_clone = table_router.clone();
|
||||
let work = table_router.checked_statements()
|
||||
.for_each(move |msg| { table_router_clone.import_statement(msg); Ok(()) })
|
||||
.select(exit.clone().unit_error().compat())
|
||||
.map(|_| ())
|
||||
.map_err(|_| ());
|
||||
.for_each(move |msg| {
|
||||
table_router_clone.import_statement(msg);
|
||||
ready(())
|
||||
});
|
||||
|
||||
executor.spawn(work);
|
||||
let work = select(work, exit).map(drop);
|
||||
|
||||
let _ = executor.spawn(work);
|
||||
|
||||
table_router
|
||||
});
|
||||
@@ -263,27 +244,26 @@ pub struct NetworkDown;
|
||||
|
||||
/// A future that resolves when a collation is received.
|
||||
pub struct AwaitingCollation {
|
||||
outer: futures::sync::oneshot::Receiver<::futures::sync::oneshot::Receiver<Collation>>,
|
||||
inner: Option<::futures::sync::oneshot::Receiver<Collation>>
|
||||
outer: oneshot::Receiver<oneshot::Receiver<Collation>>,
|
||||
inner: Option<oneshot::Receiver<Collation>>
|
||||
}
|
||||
|
||||
impl Future for AwaitingCollation {
|
||||
type Item = Collation;
|
||||
type Error = NetworkDown;
|
||||
type Output = Result<Collation, NetworkDown>;
|
||||
|
||||
fn poll(&mut self) -> Poll<Collation, NetworkDown> {
|
||||
if let Some(ref mut inner) = self.inner {
|
||||
return inner
|
||||
.poll()
|
||||
.map_err(|_| NetworkDown)
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
let this = Pin::into_inner(self);
|
||||
|
||||
if let Some(ref mut inner) = this.inner {
|
||||
return Pin::new(inner).poll(cx).map_err(|_| NetworkDown)
|
||||
}
|
||||
match self.outer.poll() {
|
||||
Ok(futures::Async::Ready(inner)) => {
|
||||
self.inner = Some(inner);
|
||||
self.poll()
|
||||
match Pin::new(&mut this.outer).poll(cx) {
|
||||
Poll::Ready(Ok(inner)) => {
|
||||
this.inner = Some(inner);
|
||||
Pin::new(this).poll(cx)
|
||||
},
|
||||
Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady),
|
||||
Err(_) => Err(NetworkDown)
|
||||
Poll::Ready(Err(_)) => Poll::Ready(Err(NetworkDown)),
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,7 +277,7 @@ impl<P, E: Clone, N, T: Clone> Collators for ValidationNetwork<P, E, N, T> where
|
||||
type Collation = AwaitingCollation;
|
||||
|
||||
fn collate(&self, parachain: ParaId, relay_parent: Hash) -> Self::Collation {
|
||||
let (tx, rx) = ::futures::sync::oneshot::channel();
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.network.with_spec(move |spec, _| {
|
||||
let collation = spec.await_collation(relay_parent, parachain);
|
||||
let _ = tx.send(collation);
|
||||
@@ -375,17 +355,16 @@ pub struct IncomingReceiver {
|
||||
}
|
||||
|
||||
impl Future for IncomingReceiver {
|
||||
type Item = Incoming;
|
||||
type Error = io::Error;
|
||||
type Output = Result<Incoming, io::Error>;
|
||||
|
||||
fn poll(&mut self) -> Poll<Incoming, io::Error> {
|
||||
match self.inner.poll() {
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Ok(Async::Ready(i)) => Ok(Async::Ready(Incoming::clone(&*i))),
|
||||
Err(_) => Err(io::Error::new(
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
match Pin::new(&mut Pin::into_inner(self).inner).poll(cx) {
|
||||
Poll::Ready(Ok(i)) => Poll::Ready(Ok(Incoming::clone(&i))),
|
||||
Poll::Ready(Err(_)) => Poll::Ready(Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"Sending end of channel hung up",
|
||||
)),
|
||||
))),
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -592,24 +571,25 @@ pub struct PoVReceiver {
|
||||
}
|
||||
|
||||
impl Future for PoVReceiver {
|
||||
type Item = PoVBlock;
|
||||
type Error = io::Error;
|
||||
type Output = Result<PoVBlock, io::Error>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
let this = Pin::into_inner(self);
|
||||
|
||||
fn poll(&mut self) -> Poll<PoVBlock, io::Error> {
|
||||
let map_err = |_| io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"Sending end of channel hung up",
|
||||
);
|
||||
|
||||
if let Some(ref mut inner) = self.inner {
|
||||
return inner.poll().map_err(map_err);
|
||||
if let Some(ref mut inner) = this.inner {
|
||||
return Pin::new(inner).poll(cx).map_err(map_err);
|
||||
}
|
||||
match self.outer.poll().map_err(map_err)? {
|
||||
Async::Ready(inner) => {
|
||||
self.inner = Some(inner);
|
||||
self.poll()
|
||||
match Pin::new(&mut this.outer).poll(cx).map_err(map_err)? {
|
||||
Poll::Ready(inner) => {
|
||||
this.inner = Some(inner);
|
||||
Pin::new(this).poll(cx)
|
||||
}
|
||||
Async::NotReady => Ok(Async::NotReady),
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -675,7 +655,7 @@ impl<P: ProvideRuntimeApi + Send, E, N, T> LeafWorkDataFetcher<P, E, N, T> where
|
||||
P::Api: ParachainHost<Block>,
|
||||
N: NetworkService,
|
||||
T: Clone + Executor + Send + 'static,
|
||||
E: futures03::Future<Output=()> + Clone + Send + 'static,
|
||||
E: Future<Output=()> + Clone + Send + 'static,
|
||||
{
|
||||
/// Fetch PoV block for the given candidate receipt.
|
||||
pub fn fetch_pov_block(&self, candidate: &CandidateReceipt) -> PoVReceiver {
|
||||
@@ -697,7 +677,7 @@ impl<P: ProvideRuntimeApi + Send, E, N, T> LeafWorkDataFetcher<P, E, N, T> where
|
||||
);
|
||||
|
||||
let candidate = candidate.clone();
|
||||
let (tx, rx) = ::futures::sync::oneshot::channel();
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.network.with_spec(move |spec, ctx| {
|
||||
if let Ok(Some(canon_roots)) = canon_roots {
|
||||
let inner_rx = spec.fetch_pov_block(ctx, &candidate, parent_hash, canon_roots);
|
||||
|
||||
Reference in New Issue
Block a user