Switch GrandPa to std futures (replaces #3909) (#4612)

* Switch GrandPa to new futures

* Work on making tests work

* until_imported tests working again

* Work on switching tests to stable futures

* Modifications

* Re-add test as #[ignore]

* Don't ignore

* Add manual unpins

* Remove Header import

* Return concrete Sink type

* Switch to crates.io finality-grandpa version

* Remove use statement that slipped in

* Fix some nitpicks

* Remove unpin from i

* Fixed typo

* Move futures01 to dev-deps

* Fix nitpicks

* Update client/finality-grandpa/src/communication/mod.rs

Co-Authored-By: André Silva <andre.beat@gmail.com>

* nitpicking

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: André Silva <andre.beat@gmail.com>
This commit is contained in:
Ashley
2020-01-24 13:34:42 +01:00
committed by GitHub
parent 14e95f3398
commit c2c429877e
16 changed files with 468 additions and 513 deletions
+179 -191
View File
@@ -25,7 +25,6 @@ use sc_network_test::{
use sc_network::config::{ProtocolConfig, Roles, BoxFinalityProofRequestBuilder};
use parking_lot::Mutex;
use futures_timer::Delay;
use futures03::TryStreamExt as _;
use tokio::runtime::current_thread;
use sp_keyring::Ed25519Keyring;
use sc_client::LongestChain;
@@ -48,6 +47,8 @@ use sp_runtime::generic::{BlockId, DigestItem};
use sp_core::{H256, NativeOrEncoded, ExecutionContext, crypto::Public};
use sp_finality_grandpa::{GRANDPA_ENGINE_ID, AuthorityList, GrandpaApi};
use sp_state_machine::{InMemoryBackend, prove_read, read_proof_check};
use futures01::Async;
use futures::compat::Future01CompatExt;
use authorities::AuthoritySet;
use finality_proof::{
@@ -196,7 +197,7 @@ impl TestNetFactory for GrandpaTestNet {
#[derive(Clone)]
struct Exit;
impl futures03::Future for Exit {
impl futures::Future for Exit {
type Output = ();
fn poll(self: Pin<&mut Self>, _: &mut task::Context) -> task::Poll<()> {
@@ -371,17 +372,28 @@ fn create_keystore(authority: Ed25519Keyring) -> (KeyStorePtr, tempfile::TempDir
(keystore, keystore_path)
}
fn block_until_complete(future: impl Future + Unpin, net: &Arc<Mutex<GrandpaTestNet>>, runtime: &mut current_thread::Runtime) {
let drive_to_completion = futures01::future::poll_fn(|| {
net.lock().poll(); Ok::<Async<()>, ()>(Async::NotReady)
});
runtime.block_on(
future::select(future, drive_to_completion.compat())
.map(|_| Ok::<(), ()>(()))
.compat()
).unwrap();
}
// run the voters to completion. provide a closure to be invoked after
// the voters are spawned but before blocking on them.
fn run_to_completion_with<F>(
runtime: &mut current_thread::Runtime,
threads_pool: &futures03::executor::ThreadPool,
threads_pool: &futures::executor::ThreadPool,
blocks: u64,
net: Arc<Mutex<GrandpaTestNet>>,
peers: &[Ed25519Keyring],
with: F,
) -> u64 where
F: FnOnce(current_thread::Handle) -> Option<Box<dyn Future<Item=(), Error=()>>>
F: FnOnce(current_thread::Handle) -> Option<Pin<Box<dyn Future<Output = ()>>>>
{
use parking_lot::RwLock;
@@ -411,17 +423,16 @@ fn run_to_completion_with<F>(
};
wait_for.push(
Box::new(
Box::pin(
client.finality_notification_stream()
.map(|v| Ok::<_, ()>(v)).compat()
.take_while(move |n| {
let mut highest_finalized = highest_finalized.write();
if *n.header.number() > *highest_finalized {
*highest_finalized = *n.header.number();
}
Ok(n.header.number() < &blocks)
future::ready(n.header.number() < &blocks)
})
.collect()
.collect::<Vec<_>>()
.map(|_| ())
)
);
@@ -449,24 +460,20 @@ fn run_to_completion_with<F>(
assert_send(&voter);
runtime.spawn(voter);
runtime.spawn(voter.unit_error().compat());
}
// wait for all finalized on each.
let wait_for = ::futures::future::join_all(wait_for)
.map(|_| ())
.map_err(|_| ());
let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) });
let _ = runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap();
let wait_for = ::futures::future::join_all(wait_for);
block_until_complete(wait_for, &net, runtime);
let highest_finalized = *highest_finalized.read();
highest_finalized
}
fn run_to_completion(
runtime: &mut current_thread::Runtime,
threads_pool: &futures03::executor::ThreadPool,
threads_pool: &futures::executor::ThreadPool,
blocks: u64,
net: Arc<Mutex<GrandpaTestNet>>,
peers: &[Ed25519Keyring]
@@ -496,7 +503,7 @@ fn add_forced_change(
fn finalize_3_voters_no_observers() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let voters = make_ids(peers);
@@ -522,7 +529,7 @@ fn finalize_3_voters_no_observers() {
#[test]
fn finalize_3_voters_1_full_observer() {
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let voters = make_ids(peers);
@@ -555,9 +562,8 @@ fn finalize_3_voters_1_full_observer() {
};
finality_notifications.push(
client.finality_notification_stream()
.map(|v| Ok::<_, ()>(v)).compat()
.take_while(|n| Ok(n.header.number() < &20))
.for_each(move |_| Ok(()))
.take_while(|n| future::ready(n.header.number() < &20))
.for_each(move |_| future::ready(()))
);
let keystore = if let Some(local_key) = local_key {
@@ -590,16 +596,14 @@ fn finalize_3_voters_1_full_observer() {
}
for voter in voters {
runtime.spawn(voter);
runtime.spawn(voter.unit_error().compat());
}
// wait for all finalized on each.
let wait_for = futures::future::join_all(finality_notifications)
.map(|_| ())
.map_err(|_| ());
.map(|_| ());
let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) });
let _ = runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap();
block_until_complete(wait_for, &net, &mut runtime);
}
#[test]
@@ -631,7 +635,7 @@ fn transition_3_voters_twice_1_full_observer() {
let net = Arc::new(Mutex::new(GrandpaTestNet::new(api, 8)));
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
net.lock().peer(0).push_blocks(1, false);
net.lock().block_until_sync(&mut runtime);
@@ -654,8 +658,7 @@ fn transition_3_voters_twice_1_full_observer() {
// wait for blocks to be finalized before generating new ones
let block_production = client.finality_notification_stream()
.map(|v| Ok::<_, ()>(v)).compat()
.take_while(|n| Ok(n.header.number() < &30))
.take_while(|n| future::ready(n.header.number() < &30))
.for_each(move |n| {
match n.header.number() {
1 => {
@@ -692,10 +695,10 @@ fn transition_3_voters_twice_1_full_observer() {
_ => {},
}
Ok(())
future::ready(())
});
runtime.spawn(block_production);
runtime.spawn(block_production.unit_error().compat());
}
let mut finality_notifications = Vec::new();
@@ -725,9 +728,8 @@ fn transition_3_voters_twice_1_full_observer() {
finality_notifications.push(
client.finality_notification_stream()
.map(|v| Ok::<_, ()>(v)).compat()
.take_while(|n| Ok(n.header.number() < &30))
.for_each(move |_| Ok(()))
.take_while(|n| future::ready(n.header.number() < &30))
.for_each(move |_| future::ready(()))
.map(move |()| {
let full_client = client.as_full().expect("only full clients are used in test");
let set: AuthoritySet<Hash, BlockNumber> = crate::aux_schema::load_authorities(&*full_client).unwrap();
@@ -756,22 +758,19 @@ fn transition_3_voters_twice_1_full_observer() {
};
let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network");
runtime.spawn(voter);
runtime.spawn(voter.unit_error().compat());
}
// wait for all finalized on each.
let wait_for = ::futures::future::join_all(finality_notifications)
.map(|_| ())
.map_err(|_| ());
let wait_for = ::futures::future::join_all(finality_notifications);
let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) });
let _ = runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap();
block_until_complete(wait_for, &net, &mut runtime);
}
#[test]
fn justification_is_emitted_when_consensus_data_changes() {
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3);
@@ -790,7 +789,7 @@ fn justification_is_emitted_when_consensus_data_changes() {
#[test]
fn justification_is_generated_periodically() {
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let voters = make_ids(peers);
@@ -830,7 +829,7 @@ fn consensus_changes_works() {
#[test]
fn sync_justifications_on_change_blocks() {
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let peers_b = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob];
let voters = make_ids(peers_b);
@@ -871,21 +870,21 @@ fn sync_justifications_on_change_blocks() {
}
// the last peer should get the justification by syncing from other peers
runtime.block_on(futures::future::poll_fn(move || -> std::result::Result<_, ()> {
futures::executor::block_on(futures::future::poll_fn(move |_| {
if net.lock().peer(3).client().justification(&BlockId::Number(21)).unwrap().is_none() {
net.lock().poll();
Ok(Async::NotReady)
Poll::Pending
} else {
Ok(Async::Ready(()))
Poll::Ready(())
}
})).unwrap()
}))
}
#[test]
fn finalizes_multiple_pending_changes_in_order() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let peers_b = &[Ed25519Keyring::Dave, Ed25519Keyring::Eve, Ed25519Keyring::Ferdie];
@@ -946,7 +945,7 @@ fn finalizes_multiple_pending_changes_in_order() {
fn force_change_to_new_set() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
// two of these guys are offline.
let genesis_authorities = &[
Ed25519Keyring::Alice,
@@ -1123,11 +1122,11 @@ fn voter_persists_its_votes() {
use std::iter::FromIterator;
use std::sync::atomic::{AtomicUsize, Ordering};
use futures::future;
use futures::sync::mpsc;
use futures::channel::mpsc;
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
// we have two authorities but we'll only be running the voter for alice
// we are going to be listening for the prevotes it casts
@@ -1161,56 +1160,56 @@ fn voter_persists_its_votes() {
keystore_paths.push(keystore_path);
struct ResettableVoter {
voter: Box<dyn Future<Item = (), Error = ()> + Send>,
voter: Pin<Box<dyn Future<Output = ()> + Send + Unpin>>,
voter_rx: mpsc::UnboundedReceiver<()>,
net: Arc<Mutex<GrandpaTestNet>>,
client: PeersClient,
keystore: KeyStorePtr,
threads_pool: futures03::executor::ThreadPool,
threads_pool: futures::executor::ThreadPool,
}
impl Future for ResettableVoter {
type Item = ();
type Error = ();
type Output = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match self.voter.poll() {
Ok(Async::Ready(())) | Err(_) => panic!("error in the voter"),
Ok(Async::NotReady) => {},
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let this = Pin::into_inner(self);
if let Poll::Ready(()) = Pin::new(&mut this.voter).poll(cx) {
panic!("error in the voter");
}
match self.voter_rx.poll() {
Err(_) | Ok(Async::Ready(None)) => return Ok(Async::Ready(())),
Ok(Async::NotReady) => {}
Ok(Async::Ready(Some(()))) => {
match Pin::new(&mut this.voter_rx).poll_next(cx) {
Poll::Pending => return Poll::Pending,
Poll::Ready(None) => return Poll::Ready(()),
Poll::Ready(Some(())) => {
let (_block_import, _, _, _, link) =
self.net.lock()
this.net.lock()
.make_block_import::<
TransactionFor<substrate_test_runtime_client::Backend, Block>
>(self.client.clone());
>(this.client.clone());
let link = link.lock().take().unwrap();
let grandpa_params = GrandpaParams {
config: Config {
gossip_duration: TEST_GOSSIP_DURATION,
justification_period: 32,
keystore: Some(self.keystore.clone()),
keystore: Some(this.keystore.clone()),
name: Some(format!("peer#{}", 0)),
is_authority: true,
observer_enabled: true,
},
link,
network: self.net.lock().peers[0].network_service().clone(),
network: this.net.lock().peers[0].network_service().clone(),
inherent_data_providers: InherentDataProviders::new(),
on_exit: Exit,
telemetry_on_connect: None,
voting_rule: VotingRulesBuilder::default().build(),
executor: self.threads_pool.clone(),
executor: this.threads_pool.clone(),
};
let voter = run_grandpa_voter(grandpa_params)
.expect("all in order with client and network")
.then(move |r| {
.map(move |r| {
// we need to keep the block_import alive since it owns the
// sender for the voter commands channel, if that gets dropped
// then the voter will stop
@@ -1218,30 +1217,30 @@ fn voter_persists_its_votes() {
r
});
self.voter = Box::new(voter);
this.voter = Box::pin(voter);
// notify current task in order to poll the voter
futures::task::current().notify();
cx.waker().wake_by_ref();
}
};
Ok(Async::NotReady)
Poll::Pending
}
}
// we create a "dummy" voter by setting it to `empty` and triggering the `tx`.
// we create a "dummy" voter by setting it to `pending` and triggering the `tx`.
// this way, the `ResettableVoter` will reset its `voter` field to a value ASAP.
voter_tx.unbounded_send(()).unwrap();
runtime.spawn(ResettableVoter {
voter: Box::new(futures::future::empty()),
voter: Box::pin(futures::future::pending()),
voter_rx,
net: net.clone(),
client: client.clone(),
keystore,
threads_pool: threads_pool.clone(),
});
}.unit_error().compat());
}
let (exit_tx, exit_rx) = futures::sync::oneshot::channel::<()>();
let (exit_tx, exit_rx) = futures::channel::oneshot::channel::<()>();
// create the communication layer for bob, but don't start any
// voter. instead we'll listen for the prevote that alice casts
@@ -1284,122 +1283,107 @@ fn voter_persists_its_votes() {
HasVoted::No,
);
let round_rx = futures03::compat::Compat::new(round_rx.map(|item| Ok::<_, Error>(item)));
let round_tx = futures03::compat::CompatSink::new(round_tx);
let round_tx = Arc::new(Mutex::new(round_tx));
let exit_tx = Arc::new(Mutex::new(Some(exit_tx)));
let net = net.clone();
let state = AtomicUsize::new(0);
let state = Arc::new(AtomicUsize::new(0));
runtime.spawn(round_rx.for_each(move |signed| {
if state.compare_and_swap(0, 1, Ordering::SeqCst) == 0 {
// the first message we receive should be a prevote from alice.
let prevote = match signed.message {
finality_grandpa::Message::Prevote(prevote) => prevote,
_ => panic!("voter should prevote."),
};
let net2 = net.clone();
let net = net.clone();
let voter_tx = voter_tx.clone();
let round_tx = round_tx.clone();
let state = state.clone();
let exit_tx = exit_tx.clone();
// its chain has 20 blocks and the voter targets 3/4 of the
// unfinalized chain, so the vote should be for block 15
assert!(prevote.target_number == 15);
async move {
if state.compare_and_swap(0, 1, Ordering::SeqCst) == 0 {
// the first message we receive should be a prevote from alice.
let prevote = match signed.message {
finality_grandpa::Message::Prevote(prevote) => prevote,
_ => panic!("voter should prevote."),
};
// we push 20 more blocks to alice's chain
net.lock().peer(0).push_blocks(20, false);
// its chain has 20 blocks and the voter targets 3/4 of the
// unfinalized chain, so the vote should be for block 15
assert!(prevote.target_number == 15);
let net2 = net.clone();
let net = net.clone();
let voter_tx = voter_tx.clone();
let round_tx = round_tx.clone();
// we push 20 more blocks to alice's chain
net.lock().peer(0).push_blocks(20, false);
let interval = futures03::stream::unfold(Delay::new(Duration::from_millis(200)), |delay|
Box::pin(async move {
delay.await;
Some(((), Delay::new(Duration::from_millis(200))))
})).map(Ok::<_, ()>).compat();
let interval = futures::stream::unfold(Delay::new(Duration::from_millis(200)), |delay|
Box::pin(async move {
delay.await;
Some(((), Delay::new(Duration::from_millis(200))))
})
);
future::Either::A(interval
.take_while(move |_| {
Ok(net2.lock().peer(1).client().info().best_number != 40)
})
.for_each(|_| Ok(()))
.and_then(move |_| {
let block_30_hash =
net.lock().peer(0).client().as_full().unwrap().hash(30).unwrap().unwrap();
interval
.take_while(move |_| {
future::ready(net2.lock().peer(1).client().info().best_number != 40)
})
.for_each(|_| future::ready(()))
.await;
// we restart alice's voter
voter_tx.unbounded_send(()).unwrap();
let block_30_hash =
net.lock().peer(0).client().as_full().unwrap().hash(30).unwrap().unwrap();
// and we push our own prevote for block 30
let prevote = finality_grandpa::Prevote {
target_number: 30,
target_hash: block_30_hash,
};
// we restart alice's voter
voter_tx.unbounded_send(()).unwrap();
// One should either be calling `Sink::send` or `Sink::start_send` followed
// by `Sink::poll_complete` to make sure items are being flushed. Given that
// we send in a loop including a delay until items are received, this can be
// ignored for the sake of reduced complexity.
if !round_tx.lock()
.start_send(finality_grandpa::Message::Prevote(prevote))
.unwrap()
.is_ready() {
panic!("expected sink to be ready to write to.");
}
// and we push our own prevote for block 30
let prevote = finality_grandpa::Prevote {
target_number: 30,
target_hash: block_30_hash,
};
Ok(())
}).map_err(|_| panic!()))
// One should either be calling `Sink::send` or `Sink::start_send` followed
// by `Sink::poll_complete` to make sure items are being flushed. Given that
// we send in a loop including a delay until items are received, this can be
// ignored for the sake of reduced complexity.
Pin::new(&mut *round_tx.lock()).start_send(finality_grandpa::Message::Prevote(prevote)).unwrap();
} else if state.compare_and_swap(1, 2, Ordering::SeqCst) == 1 {
// the next message we receive should be our own prevote
let prevote = match signed.message {
finality_grandpa::Message::Prevote(prevote) => prevote,
_ => panic!("We should receive our own prevote."),
};
} else if state.compare_and_swap(1, 2, Ordering::SeqCst) == 1 {
// the next message we receive should be our own prevote
let prevote = match signed.message {
finality_grandpa::Message::Prevote(prevote) => prevote,
_ => panic!("We should receive our own prevote."),
};
// targeting block 30
assert!(prevote.target_number == 30);
// targeting block 30
assert!(prevote.target_number == 30);
// after alice restarts it should send its previous prevote
// therefore we won't ever receive it again since it will be a
// known message on the gossip layer
// after alice restarts it should send its previous prevote
// therefore we won't ever receive it again since it will be a
// known message on the gossip layer
} else if state.compare_and_swap(2, 3, Ordering::SeqCst) == 2 {
// we then receive a precommit from alice for block 15
// even though we casted a prevote for block 30
let precommit = match signed.message {
finality_grandpa::Message::Precommit(precommit) => precommit,
_ => panic!("voter should precommit."),
};
future::Either::B(future::ok(()))
assert!(precommit.target_number == 15);
} else if state.compare_and_swap(2, 3, Ordering::SeqCst) == 2 {
// we then receive a precommit from alice for block 15
// even though we casted a prevote for block 30
let precommit = match signed.message {
finality_grandpa::Message::Precommit(precommit) => precommit,
_ => panic!("voter should precommit."),
};
assert!(precommit.target_number == 15);
// signal exit
exit_tx.clone().lock().take().unwrap().send(()).unwrap();
future::Either::B(future::ok(()))
} else {
panic!()
// signal exit
exit_tx.clone().lock().take().unwrap().send(()).unwrap();
} else {
panic!()
}
}
}).map_err(|_| ()));
}).map(Ok).boxed().compat());
}
let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) });
let exit = exit_rx.into_future().map(|_| ()).map_err(|_| ());
runtime.block_on(drive_to_completion.select(exit).map(|_| ()).map_err(|_| ())).unwrap();
block_until_complete(exit_rx.into_future(), &net, &mut runtime);
}
#[test]
fn finalize_3_voters_1_light_observer() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let authorities = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let voters = make_ids(authorities);
@@ -1416,9 +1400,8 @@ fn finalize_3_voters_1_light_observer() {
let link = net.lock().peer(3).data.lock().take().expect("link initialized on startup; qed");
let finality_notifications = net.lock().peer(3).client().finality_notification_stream()
.map(|v| Ok::<_, ()>(v)).compat()
.take_while(|n| Ok(n.header.number() < &20))
.collect();
.take_while(|n| future::ready(n.header.number() < &20))
.collect::<Vec<_>>();
run_to_completion_with(&mut runtime, &threads_pool, 20, net.clone(), authorities, |executor| {
executor.spawn(
@@ -1435,10 +1418,10 @@ fn finalize_3_voters_1_light_observer() {
net.lock().peers[3].network_service().clone(),
Exit,
threads_pool.clone(),
).unwrap()
).unwrap().unit_error().compat()
).unwrap();
Some(Box::new(finality_notifications.map(|_| ())))
Some(Box::pin(finality_notifications.map(|_| ())))
});
}
@@ -1446,7 +1429,7 @@ fn finalize_3_voters_1_light_observer() {
fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() {
let _ = ::env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers = &[Ed25519Keyring::Alice];
let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1);
@@ -1460,14 +1443,15 @@ fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() {
net.lock().block_until_sync(&mut runtime);
// check that the block#1 is finalized on light client
runtime.block_on(futures::future::poll_fn(move || -> std::result::Result<_, ()> {
let mut runtime = current_thread::Runtime::new().unwrap();
let _ = runtime.block_on(futures::future::poll_fn(move |_| {
if net.lock().peer(1).client().info().finalized_number == 1 {
Ok(Async::Ready(()))
Poll::Ready(())
} else {
net.lock().poll();
Ok(Async::NotReady)
Poll::Pending
}
})).unwrap()
}).unit_error().compat());
}
#[test]
@@ -1477,7 +1461,7 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ
let _ = ::env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
// two of these guys are offline.
let genesis_authorities = if FORCE_CHANGE {
@@ -1542,7 +1526,7 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ
fn voter_catches_up_to_latest_round_when_behind() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob];
let voters = make_ids(peers);
@@ -1554,7 +1538,7 @@ fn voter_catches_up_to_latest_round_when_behind() {
let net = Arc::new(Mutex::new(net));
let mut finality_notifications = Vec::new();
let voter = |keystore, peer_id, link, net: Arc<Mutex<GrandpaTestNet>>| -> Box<dyn Future<Item=(), Error=()> + Send> {
let voter = |keystore, peer_id, link, net: Arc<Mutex<GrandpaTestNet>>| -> Pin<Box<dyn Future<Output = ()> + Send>> {
let grandpa_params = GrandpaParams {
config: Config {
gossip_duration: TEST_GOSSIP_DURATION,
@@ -1573,7 +1557,7 @@ fn voter_catches_up_to_latest_round_when_behind() {
executor: threads_pool.clone(),
};
Box::new(run_grandpa_voter(grandpa_params).expect("all in order with client and network"))
Box::pin(run_grandpa_voter(grandpa_params).expect("all in order with client and network"))
};
let mut keystore_paths = Vec::new();
@@ -1591,9 +1575,8 @@ fn voter_catches_up_to_latest_round_when_behind() {
finality_notifications.push(
client.finality_notification_stream()
.map(|v| Ok::<_, ()>(v)).compat()
.take_while(|n| Ok(n.header.number() < &50))
.for_each(move |_| Ok(()))
.take_while(|n| future::ready(n.header.number() < &50))
.for_each(move |_| future::ready(()))
);
let (keystore, keystore_path) = create_keystore(*key);
@@ -1601,14 +1584,13 @@ fn voter_catches_up_to_latest_round_when_behind() {
let voter = voter(Some(keystore), peer_id, link, net.clone());
runtime.spawn(voter);
runtime.spawn(voter.unit_error().compat());
}
// wait for them to finalize block 50. since they'll vote on 3/4 of the
// unfinalized chain it will take at least 4 rounds to do it.
let wait_for_finality = ::futures::future::join_all(finality_notifications)
.map(|_| ())
.map_err(|_| ());
.map(|_| ());
// spawn a new voter, it should be behind by at least 4 rounds and should be
// able to catch up to the latest round
@@ -1616,7 +1598,7 @@ fn voter_catches_up_to_latest_round_when_behind() {
let net = net.clone();
let runtime = runtime.handle();
wait_for_finality.and_then(move |_| {
wait_for_finality.then(move |_| {
let peer_id = 2;
let link = {
let net = net.lock();
@@ -1628,20 +1610,20 @@ fn voter_catches_up_to_latest_round_when_behind() {
let voter = voter(None, peer_id, link, net);
runtime.spawn(voter).unwrap();
runtime.spawn(voter.unit_error().compat()).unwrap();
let start_time = std::time::Instant::now();
let timeout = Duration::from_secs(5 * 60);
let wait_for_catch_up = futures::future::poll_fn(move || {
let wait_for_catch_up = futures::future::poll_fn(move |_| {
// The voter will start at round 1 and since everyone else is
// already at a later round the only way to get to round 4 (or
// later) is by issuing a catch up request.
if set_state.read().last_completed_round().number >= 4 {
Ok(Async::Ready(()))
Poll::Ready(())
} else if start_time.elapsed() > timeout {
panic!("Timed out while waiting for catch up to happen")
} else {
Ok(Async::NotReady)
Poll::Pending
}
});
@@ -1649,8 +1631,14 @@ fn voter_catches_up_to_latest_round_when_behind() {
})
};
let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) });
let _ = runtime.block_on(test.select(drive_to_completion).map_err(|_| ())).unwrap();
let drive_to_completion = futures01::future::poll_fn(|| {
net.lock().poll(); Ok::<Async<()>, ()>(Async::NotReady)
});
runtime.block_on(
future::select(test, drive_to_completion.compat())
.map(|_| Ok::<(), ()>(()))
.compat()
).unwrap();
}
#[test]
@@ -1658,7 +1646,7 @@ fn grandpa_environment_respects_voting_rules() {
use finality_grandpa::Chain;
use sc_network_test::TestClient;
let threads_pool = futures03::executor::ThreadPool::new().unwrap();
let threads_pool = futures::executor::ThreadPool::new().unwrap();
let peers = &[Ed25519Keyring::Alice];
let voters = make_ids(peers);