mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 10:01:17 +00:00
Remove more instances of futures01 (#4633)
* Start removing last few instances of futures01 * Use to_poll on wasm * Revert "Use to_poll on wasm" This reverts commit 1c61728f10d520df5f9b28c415a0db68e478b9c7. * Fix fg test * Upgrade network test futures * Update offchain hyper version * Update service test * bump tokio to 0.2.10 * Removed some unneeded tokios * fixes * fix run_until_all_full * Make service test debuggable * Update client/offchain/src/api/http.rs Co-Authored-By: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com> * Add service_test to test-int output * nitpicking * Finally fix test * Give up and revert client/serviec/test * Revert gitlab ci too Co-authored-by: Demi Obenour <demi@parity.io>
This commit is contained in:
@@ -13,8 +13,7 @@ repository = "https://github.com/paritytech/substrate/"
|
||||
sc-network = { version = "0.8.0-alpha.2", path = "../" }
|
||||
log = "0.4.8"
|
||||
parking_lot = "0.10.0"
|
||||
futures = "0.1.29"
|
||||
futures03 = { package = "futures", version = "0.3.1", features = ["compat"] }
|
||||
futures = "0.3.1"
|
||||
futures-timer = "3.0.1"
|
||||
rand = "0.7.2"
|
||||
libp2p = { version = "0.16.1", default-features = false, features = ["libp2p-websocket"] }
|
||||
@@ -30,4 +29,3 @@ env_logger = "0.7.0"
|
||||
substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" }
|
||||
substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" }
|
||||
tempfile = "3.1.0"
|
||||
tokio = "0.1.22"
|
||||
|
||||
@@ -21,7 +21,7 @@ mod block_import;
|
||||
#[cfg(test)]
|
||||
mod sync;
|
||||
|
||||
use std::{collections::HashMap, pin::Pin, sync::Arc, marker::PhantomData};
|
||||
use std::{collections::HashMap, pin::Pin, sync::Arc, marker::PhantomData, task::{Poll, Context as FutureContext}};
|
||||
|
||||
use libp2p::build_multiaddr;
|
||||
use log::trace;
|
||||
@@ -46,7 +46,6 @@ use sp_consensus::block_import::{BlockImport, ImportResult};
|
||||
use sp_consensus::Error as ConsensusError;
|
||||
use sp_consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport};
|
||||
use futures::prelude::*;
|
||||
use futures03::{Future as _, FutureExt as _, TryFutureExt as _, StreamExt as _, TryStreamExt as _};
|
||||
use sc_network::{NetworkWorker, NetworkStateInfo, NetworkService, ReportHandle, config::ProtocolId};
|
||||
use sc_network::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder};
|
||||
use libp2p::PeerId;
|
||||
@@ -187,8 +186,8 @@ pub struct Peer<D> {
|
||||
select_chain: Option<LongestChain<substrate_test_runtime_client::Backend, Block>>,
|
||||
backend: Option<Arc<substrate_test_runtime_client::Backend>>,
|
||||
network: NetworkWorker<Block, <Block as BlockT>::Hash>,
|
||||
imported_blocks_stream: Box<dyn Stream<Item = BlockImportNotification<Block>, Error = ()> + Send>,
|
||||
finality_notification_stream: Box<dyn Stream<Item = FinalityNotification<Block>, Error = ()> + Send>,
|
||||
imported_blocks_stream: Pin<Box<dyn Stream<Item = BlockImportNotification<Block>> + Send>>,
|
||||
finality_notification_stream: Pin<Box<dyn Stream<Item = FinalityNotification<Block>> + Send>>,
|
||||
}
|
||||
|
||||
impl<D> Peer<D> {
|
||||
@@ -649,10 +648,8 @@ pub trait TestNetFactory: Sized {
|
||||
peer.network.add_known_address(network.service().local_peer_id(), listen_addr.clone());
|
||||
}
|
||||
|
||||
let imported_blocks_stream = Box::new(client.import_notification_stream()
|
||||
.map(|v| Ok::<_, ()>(v)).compat().fuse());
|
||||
let finality_notification_stream = Box::new(client.finality_notification_stream()
|
||||
.map(|v| Ok::<_, ()>(v)).compat().fuse());
|
||||
let imported_blocks_stream = Box::pin(client.import_notification_stream().fuse());
|
||||
let finality_notification_stream = Box::pin(client.finality_notification_stream().fuse());
|
||||
|
||||
peers.push(Peer {
|
||||
data,
|
||||
@@ -724,10 +721,8 @@ pub trait TestNetFactory: Sized {
|
||||
peer.network.add_known_address(network.service().local_peer_id(), listen_addr.clone());
|
||||
}
|
||||
|
||||
let imported_blocks_stream = Box::new(client.import_notification_stream()
|
||||
.map(|v| Ok::<_, ()>(v)).compat().fuse());
|
||||
let finality_notification_stream = Box::new(client.finality_notification_stream()
|
||||
.map(|v| Ok::<_, ()>(v)).compat().fuse());
|
||||
let imported_blocks_stream = Box::pin(client.import_notification_stream().fuse());
|
||||
let finality_notification_stream = Box::pin(client.finality_notification_stream().fuse());
|
||||
|
||||
peers.push(Peer {
|
||||
data,
|
||||
@@ -746,70 +741,70 @@ pub trait TestNetFactory: Sized {
|
||||
/// Polls the testnet until all nodes are in sync.
|
||||
///
|
||||
/// Must be executed in a task context.
|
||||
fn poll_until_sync(&mut self) -> Async<()> {
|
||||
self.poll();
|
||||
fn poll_until_sync(&mut self, cx: &mut FutureContext) -> Poll<()> {
|
||||
self.poll(cx);
|
||||
|
||||
// Return `NotReady` if there's a mismatch in the highest block number.
|
||||
let mut highest = None;
|
||||
for peer in self.peers().iter() {
|
||||
if peer.is_major_syncing() || peer.network.num_queued_blocks() != 0 {
|
||||
return Async::NotReady
|
||||
return Poll::Pending
|
||||
}
|
||||
if peer.network.num_sync_requests() != 0 {
|
||||
return Async::NotReady
|
||||
return Poll::Pending
|
||||
}
|
||||
match (highest, peer.client.info().best_hash) {
|
||||
(None, b) => highest = Some(b),
|
||||
(Some(ref a), ref b) if a == b => {},
|
||||
(Some(_), _) => return Async::NotReady,
|
||||
(Some(_), _) => return Poll::Pending
|
||||
}
|
||||
}
|
||||
Async::Ready(())
|
||||
Poll::Ready(())
|
||||
}
|
||||
|
||||
/// Polls the testnet until theres' no activiy of any kind.
|
||||
///
|
||||
/// Must be executed in a task context.
|
||||
fn poll_until_idle(&mut self) -> Async<()> {
|
||||
self.poll();
|
||||
fn poll_until_idle(&mut self, cx: &mut FutureContext) -> Poll<()> {
|
||||
self.poll(cx);
|
||||
|
||||
for peer in self.peers().iter() {
|
||||
if peer.is_major_syncing() || peer.network.num_queued_blocks() != 0 {
|
||||
return Async::NotReady
|
||||
return Poll::Pending
|
||||
}
|
||||
if peer.network.num_sync_requests() != 0 {
|
||||
return Async::NotReady
|
||||
return Poll::Pending
|
||||
}
|
||||
}
|
||||
Async::Ready(())
|
||||
Poll::Ready(())
|
||||
}
|
||||
|
||||
/// Blocks the current thread until we are sync'ed.
|
||||
///
|
||||
/// Calls `poll_until_sync` repeatedly with the runtime passed as parameter.
|
||||
fn block_until_sync(&mut self, runtime: &mut tokio::runtime::current_thread::Runtime) {
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| Ok(self.poll_until_sync()))).unwrap();
|
||||
/// Calls `poll_until_sync` repeatedly.
|
||||
fn block_until_sync(&mut self) {
|
||||
futures::executor::block_on(futures::future::poll_fn::<(), _>(|cx| self.poll_until_sync(cx)));
|
||||
}
|
||||
|
||||
/// Blocks the current thread until there are no pending packets.
|
||||
///
|
||||
/// Calls `poll_until_idle` repeatedly with the runtime passed as parameter.
|
||||
fn block_until_idle(&mut self, runtime: &mut tokio::runtime::current_thread::Runtime) {
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| Ok(self.poll_until_idle()))).unwrap();
|
||||
fn block_until_idle(&mut self) {
|
||||
futures::executor::block_on(futures::future::poll_fn::<(), _>(|cx| self.poll_until_idle(cx)));
|
||||
}
|
||||
|
||||
/// Polls the testnet. Processes all the pending actions and returns `NotReady`.
|
||||
fn poll(&mut self) {
|
||||
fn poll(&mut self, cx: &mut FutureContext) {
|
||||
self.mut_peers(|peers| {
|
||||
for peer in peers {
|
||||
trace!(target: "sync", "-- Polling {}", peer.id());
|
||||
futures03::future::poll_fn(|cx| Pin::new(&mut peer.network).poll(cx))
|
||||
.map(|item| Ok::<_, ()>(item))
|
||||
.compat().poll().unwrap();
|
||||
if let Poll::Ready(res) = Pin::new(&mut peer.network).poll(cx) {
|
||||
res.unwrap();
|
||||
}
|
||||
trace!(target: "sync", "-- Polling complete {}", peer.id());
|
||||
|
||||
// We poll `imported_blocks_stream`.
|
||||
while let Ok(Async::Ready(Some(notification))) = peer.imported_blocks_stream.poll() {
|
||||
while let Poll::Ready(Some(notification)) = peer.imported_blocks_stream.as_mut().poll_next(cx) {
|
||||
peer.network.on_block_imported(
|
||||
notification.header,
|
||||
Vec::new(),
|
||||
@@ -819,7 +814,7 @@ pub trait TestNetFactory: Sized {
|
||||
|
||||
// We poll `finality_notification_stream`, but we only take the last event.
|
||||
let mut last = None;
|
||||
while let Ok(Async::Ready(Some(item))) = peer.finality_notification_stream.poll() {
|
||||
while let Poll::Ready(Some(item)) = peer.finality_notification_stream.as_mut().poll_next(cx) {
|
||||
last = Some(item);
|
||||
}
|
||||
if let Some(notification) = last {
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
|
||||
use sc_network::config::Roles;
|
||||
use sp_consensus::BlockOrigin;
|
||||
use futures03::TryFutureExt as _;
|
||||
use std::time::Duration;
|
||||
use tokio::runtime::current_thread;
|
||||
use futures::executor::block_on;
|
||||
use super::*;
|
||||
|
||||
fn test_ancestor_search_when_common_is(n: usize) {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
|
||||
net.peer(0).push_blocks(n, false);
|
||||
@@ -34,7 +32,7 @@ fn test_ancestor_search_when_common_is(n: usize) {
|
||||
net.peer(1).push_blocks(100, false);
|
||||
net.peer(2).push_blocks(100, false);
|
||||
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
let peer1 = &net.peers()[1];
|
||||
assert!(net.peers()[0].blockchain_canon_equals(peer1));
|
||||
}
|
||||
@@ -42,24 +40,22 @@ fn test_ancestor_search_when_common_is(n: usize) {
|
||||
#[test]
|
||||
fn sync_peers_works() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
for peer in 0..3 {
|
||||
if net.peer(peer).num_peers() != 2 {
|
||||
return Ok(Async::NotReady)
|
||||
return Poll::Pending
|
||||
}
|
||||
}
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
Poll::Ready(())
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_cycle_from_offline_to_syncing_to_offline() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
for peer in 0..3 {
|
||||
// Offline, and not major syncing.
|
||||
@@ -71,51 +67,50 @@ fn sync_cycle_from_offline_to_syncing_to_offline() {
|
||||
net.peer(2).push_blocks(100, false);
|
||||
|
||||
// Block until all nodes are online and nodes 0 and 1 and major syncing.
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
for peer in 0..3 {
|
||||
// Online
|
||||
if net.peer(peer).is_offline() {
|
||||
return Ok(Async::NotReady)
|
||||
return Poll::Pending
|
||||
}
|
||||
if peer < 2 {
|
||||
// Major syncing.
|
||||
if net.peer(peer).blocks_count() < 100 && !net.peer(peer).is_major_syncing() {
|
||||
return Ok(Async::NotReady)
|
||||
return Poll::Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
Poll::Ready(())
|
||||
}));
|
||||
|
||||
// Block until all nodes are done syncing.
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
for peer in 0..3 {
|
||||
if net.peer(peer).is_major_syncing() {
|
||||
return Ok(Async::NotReady)
|
||||
return Poll::Pending
|
||||
}
|
||||
}
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
Poll::Ready(())
|
||||
}));
|
||||
|
||||
// Now drop nodes 1 and 2, and check that node 0 is offline.
|
||||
net.peers.remove(2);
|
||||
net.peers.remove(1);
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if !net.peer(0).is_offline() {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
} else {
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
}
|
||||
})).unwrap();
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn syncing_node_not_major_syncing_when_disconnected() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
|
||||
// Generate blocks.
|
||||
@@ -125,36 +120,35 @@ fn syncing_node_not_major_syncing_when_disconnected() {
|
||||
assert!(!net.peer(1).is_major_syncing());
|
||||
|
||||
// Check that we switch to major syncing.
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if !net.peer(1).is_major_syncing() {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
} else {
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
}
|
||||
})).unwrap();
|
||||
}));
|
||||
|
||||
// Destroy two nodes, and check that we switch to non-major syncing.
|
||||
net.peers.remove(2);
|
||||
net.peers.remove(0);
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(0).is_major_syncing() {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
} else {
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
}
|
||||
})).unwrap();
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_from_two_peers_works() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
net.peer(1).push_blocks(100, false);
|
||||
net.peer(2).push_blocks(100, false);
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
let peer1 = &net.peers()[1];
|
||||
assert!(net.peers()[0].blockchain_canon_equals(peer1));
|
||||
assert!(!net.peer(0).is_major_syncing());
|
||||
@@ -163,12 +157,11 @@ fn sync_from_two_peers_works() {
|
||||
#[test]
|
||||
fn sync_from_two_peers_with_ancestry_search_works() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
net.peer(0).push_blocks(10, true);
|
||||
net.peer(1).push_blocks(100, false);
|
||||
net.peer(2).push_blocks(100, false);
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
let peer1 = &net.peers()[1];
|
||||
assert!(net.peers()[0].blockchain_canon_equals(peer1));
|
||||
}
|
||||
@@ -176,14 +169,13 @@ fn sync_from_two_peers_with_ancestry_search_works() {
|
||||
#[test]
|
||||
fn ancestry_search_works_when_backoff_is_one() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
|
||||
net.peer(0).push_blocks(1, false);
|
||||
net.peer(1).push_blocks(2, false);
|
||||
net.peer(2).push_blocks(2, false);
|
||||
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
let peer1 = &net.peers()[1];
|
||||
assert!(net.peers()[0].blockchain_canon_equals(peer1));
|
||||
}
|
||||
@@ -191,14 +183,13 @@ fn ancestry_search_works_when_backoff_is_one() {
|
||||
#[test]
|
||||
fn ancestry_search_works_when_ancestor_is_genesis() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
|
||||
net.peer(0).push_blocks(13, true);
|
||||
net.peer(1).push_blocks(100, false);
|
||||
net.peer(2).push_blocks(100, false);
|
||||
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
let peer1 = &net.peers()[1];
|
||||
assert!(net.peers()[0].blockchain_canon_equals(peer1));
|
||||
}
|
||||
@@ -221,10 +212,9 @@ fn ancestry_search_works_when_common_is_hundred() {
|
||||
#[test]
|
||||
fn sync_long_chain_works() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(2);
|
||||
net.peer(1).push_blocks(500, false);
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
let peer1 = &net.peers()[1];
|
||||
assert!(net.peers()[0].blockchain_canon_equals(peer1));
|
||||
}
|
||||
@@ -232,18 +222,17 @@ fn sync_long_chain_works() {
|
||||
#[test]
|
||||
fn sync_no_common_longer_chain_fails() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
net.peer(0).push_blocks(20, true);
|
||||
net.peer(1).push_blocks(20, false);
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(0).is_major_syncing() {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
} else {
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
}
|
||||
})).unwrap();
|
||||
}));
|
||||
let peer1 = &net.peers()[1];
|
||||
assert!(!net.peers()[0].blockchain_canon_equals(peer1));
|
||||
}
|
||||
@@ -251,10 +240,9 @@ fn sync_no_common_longer_chain_fails() {
|
||||
#[test]
|
||||
fn sync_justifications() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = JustificationTestNet::new(3);
|
||||
net.peer(0).push_blocks(20, false);
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
|
||||
// there's currently no justification for block #10
|
||||
assert_eq!(net.peer(0).client().justification(&BlockId::Number(10)).unwrap(), None);
|
||||
@@ -274,26 +262,25 @@ fn sync_justifications() {
|
||||
net.peer(1).request_justification(&h2.hash().into(), 15);
|
||||
net.peer(1).request_justification(&h3.hash().into(), 20);
|
||||
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
|
||||
for height in (10..21).step_by(5) {
|
||||
if net.peer(0).client().justification(&BlockId::Number(height)).unwrap() != Some(Vec::new()) {
|
||||
return Ok(Async::NotReady);
|
||||
return Poll::Pending;
|
||||
}
|
||||
if net.peer(1).client().justification(&BlockId::Number(height)).unwrap() != Some(Vec::new()) {
|
||||
return Ok(Async::NotReady);
|
||||
return Poll::Pending;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
Poll::Ready(())
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_justifications_across_forks() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = JustificationTestNet::new(3);
|
||||
// we push 5 blocks
|
||||
net.peer(0).push_blocks(5, false);
|
||||
@@ -303,30 +290,29 @@ fn sync_justifications_across_forks() {
|
||||
|
||||
// peer 1 will only see the longer fork. but we'll request justifications
|
||||
// for both and finalize the small fork instead.
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
|
||||
net.peer(0).client().finalize_block(BlockId::Hash(f1_best), Some(Vec::new()), true).unwrap();
|
||||
|
||||
net.peer(1).request_justification(&f1_best, 10);
|
||||
net.peer(1).request_justification(&f2_best, 11);
|
||||
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
|
||||
if net.peer(0).client().justification(&BlockId::Number(10)).unwrap() == Some(Vec::new()) &&
|
||||
net.peer(1).client().justification(&BlockId::Number(10)).unwrap() == Some(Vec::new())
|
||||
{
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
}
|
||||
})).unwrap();
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_after_fork_works() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
net.peer(0).push_blocks(30, false);
|
||||
net.peer(1).push_blocks(30, false);
|
||||
@@ -340,7 +326,7 @@ fn sync_after_fork_works() {
|
||||
net.peer(2).push_blocks(1, false);
|
||||
|
||||
// peer 1 has the best chain
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
let peer1 = &net.peers()[1];
|
||||
assert!(net.peers()[0].blockchain_canon_equals(peer1));
|
||||
(net.peers()[1].blockchain_canon_equals(peer1));
|
||||
@@ -350,7 +336,6 @@ fn sync_after_fork_works() {
|
||||
#[test]
|
||||
fn syncs_all_forks() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(4);
|
||||
net.peer(0).push_blocks(2, false);
|
||||
net.peer(1).push_blocks(2, false);
|
||||
@@ -358,7 +343,7 @@ fn syncs_all_forks() {
|
||||
net.peer(0).push_blocks(2, true);
|
||||
net.peer(1).push_blocks(4, false);
|
||||
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
// Check that all peers have all of the blocks.
|
||||
assert_eq!(9, net.peer(0).blocks_count());
|
||||
assert_eq!(9, net.peer(1).blocks_count());
|
||||
@@ -367,12 +352,11 @@ fn syncs_all_forks() {
|
||||
#[test]
|
||||
fn own_blocks_are_announced() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
net.block_until_sync(&mut runtime); // connect'em
|
||||
net.block_until_sync(); // connect'em
|
||||
net.peer(0).generate_blocks(1, BlockOrigin::Own, |builder| builder.build().unwrap().block);
|
||||
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
|
||||
assert_eq!(net.peer(0).client.info().best_number, 1);
|
||||
assert_eq!(net.peer(1).client.info().best_number, 1);
|
||||
@@ -384,7 +368,6 @@ fn own_blocks_are_announced() {
|
||||
#[test]
|
||||
fn blocks_are_not_announced_by_light_nodes() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(0);
|
||||
|
||||
// full peer0 is connected to light peer
|
||||
@@ -397,7 +380,7 @@ fn blocks_are_not_announced_by_light_nodes() {
|
||||
// Sync between 0 and 1.
|
||||
net.peer(0).push_blocks(1, false);
|
||||
assert_eq!(net.peer(0).client.info().best_number, 1);
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
assert_eq!(net.peer(1).client.info().best_number, 1);
|
||||
|
||||
// Add another node and remove node 0.
|
||||
@@ -405,18 +388,17 @@ fn blocks_are_not_announced_by_light_nodes() {
|
||||
net.peers.remove(0);
|
||||
|
||||
// Poll for a few seconds and make sure 1 and 2 (now 0 and 1) don't sync together.
|
||||
let mut delay = futures_timer::Delay::new(Duration::from_secs(5)).unit_error().compat();
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| {
|
||||
net.poll();
|
||||
delay.poll().map_err(|_| ())
|
||||
})).unwrap();
|
||||
let mut delay = futures_timer::Delay::new(Duration::from_secs(5));
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
Pin::new(&mut delay).poll(cx)
|
||||
}));
|
||||
assert_eq!(net.peer(1).client.info().best_number, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_sync_small_non_best_forks() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(2);
|
||||
net.peer(0).push_blocks(30, false);
|
||||
net.peer(1).push_blocks(30, false);
|
||||
@@ -435,14 +417,14 @@ fn can_sync_small_non_best_forks() {
|
||||
assert!(net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none());
|
||||
|
||||
// poll until the two nodes connect, otherwise announcing the block will not work
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(0).num_peers() == 0 {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
} else {
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
}
|
||||
})).unwrap();
|
||||
}));
|
||||
|
||||
// synchronization: 0 synced to longer chain and 1 didn't sync to small chain.
|
||||
|
||||
@@ -455,32 +437,31 @@ fn can_sync_small_non_best_forks() {
|
||||
|
||||
// after announcing, peer 1 downloads the block.
|
||||
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
|
||||
assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some());
|
||||
if net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none() {
|
||||
return Ok(Async::NotReady)
|
||||
return Poll::Pending
|
||||
}
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
net.block_until_sync(&mut runtime);
|
||||
Poll::Ready(())
|
||||
}));
|
||||
net.block_until_sync();
|
||||
|
||||
let another_fork = net.peer(0).push_blocks_at(BlockId::Number(35), 2, true);
|
||||
net.peer(0).announce_block(another_fork, Vec::new());
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(1).client().header(&BlockId::Hash(another_fork)).unwrap().is_none() {
|
||||
return Ok(Async::NotReady)
|
||||
return Poll::Pending
|
||||
}
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
Poll::Ready(())
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_not_sync_from_light_peer() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
|
||||
// given the network with 1 full nodes (#0) and 1 light node (#1)
|
||||
let mut net = TestNet::new(1);
|
||||
@@ -490,7 +471,7 @@ fn can_not_sync_from_light_peer() {
|
||||
net.peer(0).push_blocks(1, false);
|
||||
|
||||
// and let the light client sync from this node
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
|
||||
// ensure #0 && #1 have the same best block
|
||||
let full0_info = net.peer(0).client.info();
|
||||
@@ -504,29 +485,28 @@ fn can_not_sync_from_light_peer() {
|
||||
net.peers.remove(0);
|
||||
|
||||
// ensure that the #2 (now #1) fails to sync block #1 even after 5 seconds
|
||||
let mut test_finished = futures_timer::Delay::new(Duration::from_secs(5)).unit_error().compat();
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
test_finished.poll().map_err(|_| ())
|
||||
})).unwrap();
|
||||
let mut test_finished = futures_timer::Delay::new(Duration::from_secs(5));
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
Pin::new(&mut test_finished).poll(cx)
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn light_peer_imports_header_from_announce() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
|
||||
fn import_with_announce(net: &mut TestNet, runtime: &mut current_thread::Runtime, hash: H256) {
|
||||
fn import_with_announce(net: &mut TestNet, hash: H256) {
|
||||
net.peer(0).announce_block(hash, Vec::new());
|
||||
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(1).client().header(&BlockId::Hash(hash)).unwrap().is_some() {
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
}
|
||||
})).unwrap();
|
||||
}));
|
||||
}
|
||||
|
||||
// given the network with 1 full nodes (#0) and 1 light node (#1)
|
||||
@@ -534,21 +514,20 @@ fn light_peer_imports_header_from_announce() {
|
||||
net.add_light_peer(&Default::default());
|
||||
|
||||
// let them connect to each other
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
|
||||
// check that NEW block is imported from announce message
|
||||
let new_hash = net.peer(0).push_blocks(1, false);
|
||||
import_with_announce(&mut net, &mut runtime, new_hash);
|
||||
import_with_announce(&mut net, new_hash);
|
||||
|
||||
// check that KNOWN STALE block is imported from announce message
|
||||
let known_stale_hash = net.peer(0).push_blocks_at(BlockId::Number(0), 1, true);
|
||||
import_with_announce(&mut net, &mut runtime, known_stale_hash);
|
||||
import_with_announce(&mut net, known_stale_hash);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_sync_explicit_forks() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(2);
|
||||
net.peer(0).push_blocks(30, false);
|
||||
net.peer(1).push_blocks(30, false);
|
||||
@@ -568,14 +547,14 @@ fn can_sync_explicit_forks() {
|
||||
assert!(net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none());
|
||||
|
||||
// poll until the two nodes connect, otherwise announcing the block will not work
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(0).num_peers() == 0 || net.peer(1).num_peers() == 0 {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
} else {
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
}
|
||||
})).unwrap();
|
||||
}));
|
||||
|
||||
// synchronization: 0 synced to longer chain and 1 didn't sync to small chain.
|
||||
|
||||
@@ -589,21 +568,20 @@ fn can_sync_explicit_forks() {
|
||||
net.peer(1).set_sync_fork_request(vec![first_peer_id], small_hash, small_number);
|
||||
|
||||
// peer 1 downloads the block.
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
|
||||
assert!(net.peer(0).client().header(&BlockId::Hash(small_hash)).unwrap().is_some());
|
||||
if net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none() {
|
||||
return Ok(Async::NotReady)
|
||||
return Poll::Pending
|
||||
}
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
Poll::Ready(())
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn syncs_header_only_forks() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(0);
|
||||
let config = ProtocolConfig::default();
|
||||
net.add_full_peer_with_states(&config, None);
|
||||
@@ -616,7 +594,7 @@ fn syncs_header_only_forks() {
|
||||
let small_number = net.peer(0).client().info().best_number;
|
||||
net.peer(1).push_blocks(4, false);
|
||||
|
||||
net.block_until_sync(&mut runtime);
|
||||
net.block_until_sync();
|
||||
// Peer 1 will sync the small fork even though common block state is missing
|
||||
assert_eq!(9, net.peer(0).blocks_count());
|
||||
assert_eq!(9, net.peer(1).blocks_count());
|
||||
@@ -624,19 +602,18 @@ fn syncs_header_only_forks() {
|
||||
// Request explicit header-only sync request for the ancient fork.
|
||||
let first_peer_id = net.peer(0).id();
|
||||
net.peer(1).set_sync_fork_request(vec![first_peer_id], small_hash, small_number);
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(1).client().header(&BlockId::Hash(small_hash)).unwrap().is_none() {
|
||||
return Ok(Async::NotReady)
|
||||
return Poll::Pending
|
||||
}
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
Poll::Ready(())
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_not_sync_announced_old_best_block() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(3);
|
||||
|
||||
let old_hash = net.peer(0).push_blocks(1, false);
|
||||
@@ -645,19 +622,19 @@ fn does_not_sync_announced_old_best_block() {
|
||||
net.peer(1).push_blocks(20, true);
|
||||
|
||||
net.peer(0).announce_block(old_hash, Vec::new());
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
// poll once to import announcement
|
||||
net.poll();
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
net.poll(cx);
|
||||
Poll::Ready(())
|
||||
}));
|
||||
assert!(!net.peer(1).is_major_syncing());
|
||||
|
||||
net.peer(0).announce_block(old_hash_with_parent, Vec::new());
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
// poll once to import announcement
|
||||
net.poll();
|
||||
Ok(Async::Ready(()))
|
||||
})).unwrap();
|
||||
net.poll(cx);
|
||||
Poll::Ready(())
|
||||
}));
|
||||
assert!(!net.peer(1).is_major_syncing());
|
||||
}
|
||||
|
||||
@@ -665,19 +642,18 @@ fn does_not_sync_announced_old_best_block() {
|
||||
fn full_sync_requires_block_body() {
|
||||
// Check that we don't sync headers-only in full mode.
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
let mut net = TestNet::new(2);
|
||||
|
||||
net.peer(0).push_headers(1);
|
||||
// Wait for nodes to connect
|
||||
runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> {
|
||||
net.poll();
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(0).num_peers() == 0 || net.peer(1).num_peers() == 0 {
|
||||
Ok(Async::NotReady)
|
||||
Poll::Pending
|
||||
} else {
|
||||
Ok(Async::Ready(()))
|
||||
Poll::Ready(())
|
||||
}
|
||||
})).unwrap();
|
||||
net.block_until_idle(&mut runtime);
|
||||
}));
|
||||
net.block_until_idle();
|
||||
assert_eq!(net.peer(1).client.info().best_number, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user