Remove blocking sync -> import-queue operations (#1818)

* remove blocking sync -> import-queue operations

add specialization to testnet

remove add peer default impl on TestNetFactory

* remove empty brackets from dummy specialization

* nits

* make mut_peers take an fn once

* add SpecializationFactory trait in test

* remove add_peer imple in grandpa, fix typo

* use cmp::max for best importing number comparison

* remove import of non-existent create_peer

* add sender to start message
This commit is contained in:
Gregory Terzian
2019-02-28 19:11:18 +08:00
committed by Bastian Köcher
parent 04fed82940
commit 8a72abffdd
7 changed files with 190 additions and 187 deletions
+111 -35
View File
@@ -93,7 +93,8 @@ pub struct NoopLink { }
impl<B: BlockT> Link<B> for NoopLink { }
/// The test specialization.
pub struct DummySpecialization { }
#[derive(Clone)]
pub struct DummySpecialization;
impl NetworkSpecialization<Block> for DummySpecialization {
fn status(&self) -> Vec<u8> {
@@ -117,23 +118,92 @@ impl NetworkSpecialization<Block> for DummySpecialization {
pub type PeersClient = client::Client<test_client::Backend, test_client::Executor, Block, test_client::runtime::RuntimeApi>;
pub struct Peer<D> {
#[derive(Clone)]
/// A Link that can wait for a block to have been imported.
pub struct TestLink<S: NetworkSpecialization<Block> + Clone> {
import_done: Arc<AtomicBool>,
hash: Arc<Mutex<Hash>>,
link: NetworkLink<Block, S>,
}
impl<S: NetworkSpecialization<Block> + Clone> TestLink<S> {
fn new(
protocol_sender: Sender<ProtocolMsg<Block, S>>,
network_sender: NetworkChan<Block>
) -> TestLink<S> {
TestLink {
import_done: Arc::new(AtomicBool::new(false)),
hash: Arc::new(Mutex::new(Default::default())),
link: NetworkLink {
protocol_sender,
network_sender,
}
}
}
/// Set the hash which will be awaited for import.
fn with_hash(&self, hash: Hash) {
self.import_done.store(false, Ordering::SeqCst);
*self.hash.lock() = hash;
}
/// Simulate a synchronous import.
fn wait_for_import(&self) {
while !self.import_done.load(Ordering::SeqCst) {
thread::sleep(Duration::from_millis(20));
}
}
}
impl<S: NetworkSpecialization<Block> + Clone> Link<Block> for TestLink<S> {
fn block_imported(&self, hash: &Hash, number: NumberFor<Block>) {
if hash == &*self.hash.lock() {
self.import_done.store(true, Ordering::SeqCst);
}
self.link.block_imported(hash, number);
}
fn blocks_processed(&self, processed_blocks: Vec<Hash>, has_error: bool) {
self.link.blocks_processed(processed_blocks, has_error);
}
fn justification_imported(&self, who: NodeIndex, hash: &Hash, number:NumberFor<Block>, success: bool) {
self.link.justification_imported(who, hash, number, success);
}
fn request_justification(&self, hash: &Hash, number: NumberFor<Block>) {
self.link.request_justification(hash, number);
}
fn useless_peer(&self, who: NodeIndex, reason: &str) {
self.link.useless_peer(who, reason);
}
fn note_useless_and_restart_sync(&self, who: NodeIndex, reason: &str) {
self.link.note_useless_and_restart_sync(who, reason);
}
fn restart(&self) {
self.link.restart();
}
}
pub struct Peer<D, S: NetworkSpecialization<Block> + Clone> {
pub is_offline: Arc<AtomicBool>,
pub is_major_syncing: Arc<AtomicBool>,
pub peers: Arc<RwLock<HashMap<NodeIndex, ConnectedPeer<Block>>>>,
client: Arc<PeersClient>,
network_to_protocol_sender: Sender<FromNetworkMsg<Block>>,
pub protocol_sender: Sender<ProtocolMsg<Block, DummySpecialization>>,
network_port: Mutex<NetworkPort<Block>>,
pub protocol_sender: Sender<ProtocolMsg<Block, S>>,
network_link: TestLink<S>,
network_port: Arc<Mutex<NetworkPort<Block>>>,
pub import_queue: Box<ImportQueue<Block>>,
network_sender: NetworkChan<Block>,
pub data: D,
best_hash: Mutex<Option<H256>>,
finalized_hash: Mutex<Option<H256>>,
}
impl<D> Peer<D> {
impl<D, S: NetworkSpecialization<Block> + Clone> Peer<D, S> {
fn new(
is_offline: Arc<AtomicBool>,
is_major_syncing: Arc<AtomicBool>,
@@ -141,12 +211,14 @@ impl<D> Peer<D> {
client: Arc<PeersClient>,
import_queue: Box<ImportQueue<Block>>,
network_to_protocol_sender: Sender<FromNetworkMsg<Block>>,
protocol_sender: Sender<ProtocolMsg<Block, DummySpecialization>>,
protocol_sender: Sender<ProtocolMsg<Block, S>>,
network_sender: NetworkChan<Block>,
network_port: NetworkPort<Block>,
data: D,
) -> Self {
let network_port = Mutex::new(network_port);
let network_port = Arc::new(Mutex::new(network_port));
let network_link = TestLink::new(protocol_sender.clone(), network_sender.clone());
import_queue.start(Box::new(network_link.clone())).expect("Test ImportQueue always starts");
Peer {
is_offline,
is_major_syncing,
@@ -155,7 +227,7 @@ impl<D> Peer<D> {
network_to_protocol_sender,
protocol_sender,
import_queue,
network_sender,
network_link,
network_port,
data,
best_hash: Mutex::new(None),
@@ -171,12 +243,6 @@ impl<D> Peer<D> {
.header(&BlockId::Hash(info.chain.best_hash))
.unwrap()
.unwrap();
let network_link = NetworkLink {
protocol_sender: self.protocol_sender.clone(),
network_sender: self.network_sender.clone(),
};
self.import_queue.start(Box::new(network_link)).expect("Test ImportQueue always starts");
let _ = self
.protocol_sender
.send(ProtocolMsg::BlockImported(info.chain.best_hash, header));
@@ -237,8 +303,7 @@ impl<D> Peer<D> {
/// Whether this peer is done syncing (has no messages to send).
fn is_done(&self) -> bool {
self.import_queue.status().importing_count == 0 &&
self.network_port.lock().receiver().is_empty()
self.network_port.lock().receiver().is_empty()
}
/// Execute a "sync step". This is called for each peer after it sends a packet.
@@ -362,7 +427,7 @@ impl<D> Peer<D> {
);
let header = block.header.clone();
at = hash;
self.network_link.with_hash(hash);
self.import_queue.import_blocks(
origin,
vec![IncomingBlock {
@@ -373,10 +438,8 @@ impl<D> Peer<D> {
justification: None,
}],
);
// Simulate a synchronous import.
while self.import_queue.status().importing_count > 0 {
thread::sleep(Duration::from_millis(20));
}
// Simulate a sync import.
self.network_link.wait_for_import();
}
at
}
@@ -436,7 +499,18 @@ impl TransactionPool<Hash, Block> for EmptyTransactionPool {
fn on_broadcasted(&self, _: HashMap<Hash, Vec<String>>) {}
}
pub trait SpecializationFactory {
fn create() -> Self;
}
impl SpecializationFactory for DummySpecialization {
fn create() -> DummySpecialization {
DummySpecialization
}
}
pub trait TestNetFactory: Sized {
type Specialization: NetworkSpecialization<Block> + Clone + SpecializationFactory;
type Verifier: 'static + Verifier<Block>;
type PeerData: Default;
@@ -445,9 +519,9 @@ pub trait TestNetFactory: Sized {
fn make_verifier(&self, client: Arc<PeersClient>, config: &ProtocolConfig) -> Arc<Self::Verifier>;
/// Get reference to peer.
fn peer(&self, i: usize) -> &Peer<Self::PeerData>;
fn peers(&self) -> &Vec<Arc<Peer<Self::PeerData>>>;
fn mut_peers<F: Fn(&mut Vec<Arc<Peer<Self::PeerData>>>)>(&mut self, closure: F);
fn peer(&self, i: usize) -> &Peer<Self::PeerData, Self::Specialization>;
fn peers(&self) -> &Vec<Arc<Peer<Self::PeerData, Self::Specialization>>>;
fn mut_peers<F: FnOnce(&mut Vec<Arc<Peer<Self::PeerData, Self::Specialization>>>)>(&mut self, closure: F);
fn started(&self) -> bool;
fn set_started(&mut self, now: bool);
@@ -483,9 +557,9 @@ pub trait TestNetFactory: Sized {
let (network_sender, network_port) = network_channel(ProtocolId::default());
let import_queue = Box::new(BasicQueue::new(verifier, block_import, justification_import));
let specialization = DummySpecialization {};
let is_offline = Arc::new(AtomicBool::new(true));
let is_major_syncing = Arc::new(AtomicBool::new(false));
let specialization = self::SpecializationFactory::create();
let peers: Arc<RwLock<HashMap<NodeIndex, ConnectedPeer<Block>>>> = Arc::new(Default::default());
let (protocol_sender, network_to_protocol_sender) = Protocol::new(
is_offline.clone(),
@@ -514,7 +588,7 @@ pub trait TestNetFactory: Sized {
));
self.mut_peers(|peers| {
peers.push(peer.clone())
peers.push(peer)
});
}
@@ -666,11 +740,12 @@ pub trait TestNetFactory: Sized {
}
pub struct TestNet {
peers: Vec<Arc<Peer<()>>>,
peers: Vec<Arc<Peer<(), DummySpecialization>>>,
started: bool,
}
impl TestNetFactory for TestNet {
type Specialization = DummySpecialization;
type Verifier = PassThroughVerifier;
type PeerData = ();
@@ -688,15 +763,15 @@ impl TestNetFactory for TestNet {
Arc::new(PassThroughVerifier(false))
}
fn peer(&self, i: usize) -> &Peer<()> {
fn peer(&self, i: usize) -> &Peer<(), Self::Specialization> {
&self.peers[i]
}
fn peers(&self) -> &Vec<Arc<Peer<()>>> {
fn peers(&self) -> &Vec<Arc<Peer<(), Self::Specialization>>> {
&self.peers
}
fn mut_peers<F: Fn(&mut Vec<Arc<Peer<()>>>)>(&mut self, closure: F) {
fn mut_peers<F: FnOnce(&mut Vec<Arc<Peer<(), Self::Specialization>>>)>(&mut self, closure: F) {
closure(&mut self.peers);
}
@@ -728,6 +803,7 @@ impl JustificationImport<Block> for ForceFinalized {
pub struct JustificationTestNet(TestNet);
impl TestNetFactory for JustificationTestNet {
type Specialization = DummySpecialization;
type Verifier = PassThroughVerifier;
type PeerData = ();
@@ -741,15 +817,15 @@ impl TestNetFactory for JustificationTestNet {
self.0.make_verifier(client, config)
}
fn peer(&self, i: usize) -> &Peer<Self::PeerData> {
fn peer(&self, i: usize) -> &Peer<Self::PeerData, Self::Specialization> {
self.0.peer(i)
}
fn peers(&self) -> &Vec<Arc<Peer<Self::PeerData>>> {
fn peers(&self) -> &Vec<Arc<Peer<Self::PeerData, Self::Specialization>>> {
self.0.peers()
}
fn mut_peers<F: Fn(&mut Vec<Arc<Peer<Self::PeerData>>>)>(&mut self, closure: F ) {
fn mut_peers<F: FnOnce(&mut Vec<Arc<Peer<Self::PeerData, Self::Specialization>>>)>(&mut self, closure: F ) {
self.0.mut_peers(closure)
}