Isolate the code of ChainSync and turn it into a state machine (#2497)

* Move the is_offline and is_major_syncing logic to service.rs

* Move the ImportQueue to service.rs

* Remove stop() and abort()

* Add some more documentation to sync.rs
This commit is contained in:
Pierre Krieger
2019-05-12 19:23:45 +02:00
committed by Arkadiy Paronyan
parent cbe13c459b
commit 6c41d0b3ec
5 changed files with 164 additions and 170 deletions
+30 -21
View File
@@ -23,7 +23,7 @@ mod sync;
use std::collections::{HashMap, HashSet, VecDeque};
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::{AtomicBool, Ordering};
use log::trace;
use client;
@@ -40,7 +40,7 @@ use crate::message::Message;
use network_libp2p::PeerId;
use parking_lot::{Mutex, RwLock};
use primitives::{H256, sr25519::Public as AuthorityId};
use crate::protocol::{ConnectedPeer, Context, Protocol, ProtocolMsg};
use crate::protocol::{ConnectedPeer, Context, Protocol, ProtocolMsg, CustomMessageOutcome};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{AuthorityIdFor, Block as BlockT, Digest, DigestItem, Header, NumberFor};
use runtime_primitives::{Justification, ConsensusEngineId};
@@ -427,11 +427,6 @@ impl<D, S: NetworkSpecialization<Block>> Peer<D, S> {
*finalized_hash = Some(info.chain.finalized_hash);
}
/// Restart sync for a peer.
fn restart_sync(&self) {
self.net_proto_channel.send_from_client(ProtocolMsg::Abort);
}
/// Push a message into the gossip network and relay to peers.
/// `TestNet::sync_step` needs to be called to ensure it's propagated.
pub fn gossip_message(
@@ -654,30 +649,46 @@ pub trait TestNetFactory: Sized {
let (network_to_protocol_sender, mut network_to_protocol_rx) = mpsc::unbounded();
let (mut protocol, protocol_sender) = Protocol::new(
is_offline.clone(),
is_major_syncing.clone(),
peers.clone(),
network_sender.clone(),
config.clone(),
client.clone(),
import_queue.clone(),
None,
tx_pool,
specialization,
).unwrap();
let is_offline2 = is_offline.clone();
let is_major_syncing2 = is_major_syncing.clone();
let import_queue2 = import_queue.clone();
std::thread::spawn(move || {
tokio::runtime::current_thread::run(futures::future::poll_fn(move || {
while let Async::Ready(msg) = network_to_protocol_rx.poll().unwrap() {
match msg {
Some(FromNetworkMsg::PeerConnected(peer_id, debug_msg)) =>
protocol.on_peer_connected(peer_id, debug_msg),
Some(FromNetworkMsg::PeerDisconnected(peer_id, debug_msg)) =>
protocol.on_peer_disconnected(peer_id, debug_msg),
let outcome = match msg {
Some(FromNetworkMsg::PeerConnected(peer_id, debug_msg)) => {
protocol.on_peer_connected(peer_id, debug_msg);
CustomMessageOutcome::None
},
Some(FromNetworkMsg::PeerDisconnected(peer_id, debug_msg)) => {
protocol.on_peer_disconnected(peer_id, debug_msg);
CustomMessageOutcome::None
},
Some(FromNetworkMsg::CustomMessage(peer_id, message)) =>
protocol.on_custom_message(peer_id, message),
Some(FromNetworkMsg::Synchronize) => protocol.synchronize(),
Some(FromNetworkMsg::Synchronize) => {
protocol.synchronize();
CustomMessageOutcome::None
},
None => return Ok(Async::Ready(()))
};
match outcome {
CustomMessageOutcome::BlockImport(origin, blocks) =>
import_queue2.import_blocks(origin, blocks),
CustomMessageOutcome::JustificationImport(origin, hash, nb, justification) =>
import_queue2.import_justification(origin, hash, nb, justification),
CustomMessageOutcome::None => {}
}
}
@@ -685,6 +696,9 @@ pub trait TestNetFactory: Sized {
return Ok(Async::Ready(()))
}
is_offline2.store(protocol.is_offline(), Ordering::Relaxed);
is_major_syncing2.store(protocol.is_major_syncing(), Ordering::Relaxed);
Ok(Async::NotReady)
}));
});
@@ -803,11 +817,6 @@ pub trait TestNetFactory: Sized {
self.peers().iter().for_each(|peer| peer.send_finality_notifications())
}
/// Restart sync for a peer.
fn restart_peer(&mut self, i: usize) {
self.peers()[i].restart_sync();
}
/// Perform synchronization until complete, if provided the
/// given nodes set are excluded from sync.
fn sync_with(&mut self, disconnect: bool, disconnected: Option<HashSet<usize>>) {
+2 -4
View File
@@ -33,7 +33,6 @@ fn test_ancestor_search_when_common_is(n: usize) {
net.peer(1).push_blocks(100, false);
net.peer(2).push_blocks(100, false);
net.restart_peer(0);
net.sync();
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
@@ -96,6 +95,7 @@ fn sync_cycle_from_offline_to_syncing_to_offline() {
net.peer(peer).on_disconnect(net.peer(other));
}
}
net.sync();
assert!(net.peer(peer).is_offline());
assert!(!net.peer(peer).is_major_syncing());
}
@@ -119,6 +119,7 @@ fn syncing_node_not_major_syncing_when_disconnected() {
net.peer(1).on_disconnect(net.peer(2));
// Peer 1 is not major-syncing.
net.sync();
assert!(!net.peer(1).is_major_syncing());
}
@@ -141,7 +142,6 @@ fn sync_from_two_peers_with_ancestry_search_works() {
net.peer(0).push_blocks(10, true);
net.peer(1).push_blocks(100, false);
net.peer(2).push_blocks(100, false);
net.restart_peer(0);
net.sync();
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
@@ -156,7 +156,6 @@ fn ancestry_search_works_when_backoff_is_one() {
net.peer(1).push_blocks(2, false);
net.peer(2).push_blocks(2, false);
net.restart_peer(0);
net.sync();
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
@@ -171,7 +170,6 @@ fn ancestry_search_works_when_ancestor_is_genesis() {
net.peer(1).push_blocks(100, false);
net.peer(2).push_blocks(100, false);
net.restart_peer(0);
net.sync();
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));