mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 22:07:58 +00:00
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:
committed by
Arkadiy Paronyan
parent
cbe13c459b
commit
6c41d0b3ec
@@ -17,9 +17,9 @@
|
||||
use futures::{prelude::*, sync::mpsc};
|
||||
use network_libp2p::PeerId;
|
||||
use primitives::storage::StorageKey;
|
||||
use runtime_primitives::{generic::BlockId, ConsensusEngineId};
|
||||
use consensus::{import_queue::IncomingBlock, import_queue::Origin, BlockOrigin};
|
||||
use runtime_primitives::{generic::BlockId, ConsensusEngineId, Justification};
|
||||
use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT, NumberFor, Zero};
|
||||
use consensus::import_queue::ImportQueue;
|
||||
use crate::message::{self, BlockRequest as BlockRequestMessage, Message};
|
||||
use crate::message::generic::{Message as GenericMessage, ConsensusMessage};
|
||||
use crate::consensus_gossip::{ConsensusGossip, MessageRecipient as GossipMessageRecipient};
|
||||
@@ -32,7 +32,6 @@ use parking_lot::RwLock;
|
||||
use rustc_hex::ToHex;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::{cmp, num::NonZeroUsize, time};
|
||||
use log::{trace, debug, warn, error};
|
||||
use crate::chain::Client;
|
||||
@@ -276,10 +275,6 @@ pub enum ProtocolMsg<B: BlockT, S: NetworkSpecialization<B>> {
|
||||
ExecuteWithGossip(Box<GossipTask<B> + Send + 'static>),
|
||||
/// Incoming gossip consensus message.
|
||||
GossipConsensusMessage(B::Hash, ConsensusEngineId, Vec<u8>, GossipMessageRecipient),
|
||||
/// Tell protocol to abort sync (does not stop protocol).
|
||||
/// Only used in tests.
|
||||
#[cfg(any(test, feature = "test-helpers"))]
|
||||
Abort,
|
||||
/// Tell protocol to perform regular maintenance.
|
||||
#[cfg(any(test, feature = "test-helpers"))]
|
||||
Tick,
|
||||
@@ -291,20 +286,17 @@ pub enum ProtocolMsg<B: BlockT, S: NetworkSpecialization<B>> {
|
||||
impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
/// Create a new instance.
|
||||
pub fn new(
|
||||
is_offline: Arc<AtomicBool>,
|
||||
is_major_syncing: Arc<AtomicBool>,
|
||||
connected_peers: Arc<RwLock<HashMap<PeerId, ConnectedPeer<B>>>>,
|
||||
network_chan: NetworkChan<B>,
|
||||
config: ProtocolConfig,
|
||||
chain: Arc<Client<B>>,
|
||||
import_queue: Box<ImportQueue<B>>,
|
||||
on_demand: Option<Arc<OnDemandService<B>>>,
|
||||
transaction_pool: Arc<TransactionPool<H, B>>,
|
||||
specialization: S,
|
||||
) -> error::Result<(Protocol<B, S, H>, mpsc::UnboundedSender<ProtocolMsg<B, S>>)> {
|
||||
let (protocol_sender, port) = mpsc::unbounded();
|
||||
let info = chain.info()?;
|
||||
let sync = ChainSync::new(is_offline, is_major_syncing, config.roles, &info, import_queue);
|
||||
let sync = ChainSync::new(config.roles, &info);
|
||||
let protocol = Protocol {
|
||||
network_chan,
|
||||
port,
|
||||
@@ -341,6 +333,14 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
.count(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_major_syncing(&self) -> bool {
|
||||
self.sync.status().is_major_syncing()
|
||||
}
|
||||
|
||||
pub fn is_offline(&self) -> bool {
|
||||
self.sync.status().is_offline()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Future for Protocol<B, S, H> {
|
||||
@@ -358,10 +358,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Future for Protocol<B,
|
||||
|
||||
loop {
|
||||
match self.port.poll() {
|
||||
Ok(Async::Ready(None)) | Err(_) => {
|
||||
self.stop();
|
||||
return Ok(Async::Ready(()))
|
||||
}
|
||||
Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(())),
|
||||
Ok(Async::Ready(Some(msg))) => if !self.handle_client_msg(msg) {
|
||||
return Ok(Async::Ready(()))
|
||||
}
|
||||
@@ -415,8 +412,6 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
#[cfg(any(test, feature = "test-helpers"))]
|
||||
ProtocolMsg::Tick => self.tick(),
|
||||
#[cfg(any(test, feature = "test-helpers"))]
|
||||
ProtocolMsg::Abort => self.abort(),
|
||||
#[cfg(any(test, feature = "test-helpers"))]
|
||||
ProtocolMsg::Synchronize => {
|
||||
trace!(target: "sync", "handle_client_msg: received Synchronize msg");
|
||||
self.network_chan.send(NetworkMsg::Synchronized)
|
||||
@@ -457,14 +452,15 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_custom_message(&mut self, who: PeerId, message: Message<B>) {
|
||||
pub fn on_custom_message(&mut self, who: PeerId, message: Message<B>) -> CustomMessageOutcome<B> {
|
||||
match message {
|
||||
GenericMessage::Status(s) => self.on_status_message(who, s),
|
||||
GenericMessage::BlockRequest(r) => self.on_block_request(who, r),
|
||||
GenericMessage::BlockResponse(r) => {
|
||||
if let Some(request) = self.handle_response(who.clone(), &r) {
|
||||
self.on_block_response(who.clone(), request, r);
|
||||
let outcome = self.on_block_response(who.clone(), request, r);
|
||||
self.update_peer_info(&who);
|
||||
return outcome
|
||||
}
|
||||
},
|
||||
GenericMessage::BlockAnnounce(announce) => {
|
||||
@@ -495,6 +491,8 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
&mut Some(other),
|
||||
),
|
||||
}
|
||||
|
||||
CustomMessageOutcome::None
|
||||
}
|
||||
|
||||
fn send_message(&mut self, who: PeerId, message: Message<B>) {
|
||||
@@ -643,7 +641,7 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
peer: PeerId,
|
||||
request: message::BlockRequest<B>,
|
||||
response: message::BlockResponse<B>,
|
||||
) {
|
||||
) -> CustomMessageOutcome<B> {
|
||||
let blocks_range = match (
|
||||
response.blocks.first().and_then(|b| b.header.as_ref().map(|h| h.number())),
|
||||
response.blocks.last().and_then(|b| b.header.as_ref().map(|h| h.number())),
|
||||
@@ -658,14 +656,26 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
// TODO [andre]: move this logic to the import queue so that
|
||||
// justifications are imported asynchronously (#1482)
|
||||
if request.fields == message::BlockAttributes::JUSTIFICATION {
|
||||
self.sync.on_block_justification_data(
|
||||
let outcome = self.sync.on_block_justification_data(
|
||||
&mut ProtocolContext::new(&mut self.context_data, &self.network_chan),
|
||||
peer,
|
||||
request,
|
||||
response,
|
||||
);
|
||||
|
||||
if let Some((origin, hash, nb, just)) = outcome {
|
||||
CustomMessageOutcome::JustificationImport(origin, hash, nb, just)
|
||||
} else {
|
||||
CustomMessageOutcome::None
|
||||
}
|
||||
|
||||
} else {
|
||||
self.sync.on_block_data(&mut ProtocolContext::new(&mut self.context_data, &self.network_chan), peer, request, response);
|
||||
let outcome = self.sync.on_block_data(&mut ProtocolContext::new(&mut self.context_data, &self.network_chan), peer, request, response);
|
||||
if let Some((origin, blocks)) = outcome {
|
||||
CustomMessageOutcome::BlockImport(origin, blocks)
|
||||
} else {
|
||||
CustomMessageOutcome::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -891,22 +901,6 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
}
|
||||
}
|
||||
|
||||
fn abort(&mut self) {
|
||||
self.sync.clear();
|
||||
self.specialization.on_abort();
|
||||
self.context_data.peers.clear();
|
||||
self.handshaking_peers.clear();
|
||||
self.consensus_gossip.abort();
|
||||
}
|
||||
|
||||
fn stop(&mut self) {
|
||||
// stop processing import requests first (without holding a sync lock)
|
||||
self.sync.stop();
|
||||
|
||||
// and then clear all the sync data
|
||||
self.abort();
|
||||
}
|
||||
|
||||
fn on_block_announce(&mut self, who: PeerId, announce: message::BlockAnnounce<B::Header>) {
|
||||
let header = announce.header;
|
||||
let hash = header.hash();
|
||||
@@ -1107,6 +1101,14 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Outcome of an incoming custom message.
|
||||
#[derive(Debug)]
|
||||
pub enum CustomMessageOutcome<B: BlockT> {
|
||||
BlockImport(BlockOrigin, Vec<IncomingBlock<B>>),
|
||||
JustificationImport(Origin, B::Hash, NumberFor<B>, Justification),
|
||||
None,
|
||||
}
|
||||
|
||||
fn send_message<B: BlockT, H: ExHashT>(
|
||||
peers: &mut HashMap<PeerId, Peer<B, H>>,
|
||||
network_chan: &NetworkChan<B>,
|
||||
|
||||
Reference in New Issue
Block a user