mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 10:01:17 +00:00
Rewrite the BasiQueue using channels (#1327)
* use channels to implement basic import queue * async justification import * better conditional for is_done in tests * reword the test for presence of link * fix conditional * trace instead of panic when no link present * reword expectations when sending to importers * fix * debug justification import error * update expectations * use NumberFor * nits * add general description * move error handling into closure
This commit is contained in:
committed by
Gav Wood
parent
797de27d2b
commit
72bb8ef4c5
@@ -15,7 +15,6 @@
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
use log::{trace, debug};
|
||||
use crate::protocol::Context;
|
||||
@@ -30,6 +29,7 @@ use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberF
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use crate::message::{self, generic::Message as GenericMessage};
|
||||
use crate::config::Roles;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
// Maximum blocks to request in a single packet.
|
||||
const MAX_BLOCKS_TO_REQUEST: usize = 128;
|
||||
@@ -197,14 +197,25 @@ impl<B: BlockT> PendingJustifications<B> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Process the import of a justification.
|
||||
/// Queues a retry in case the import failed.
|
||||
fn justification_import_result(&mut self, hash: B::Hash, number: NumberFor<B>, success: bool) {
|
||||
let request = (hash, number);
|
||||
if success {
|
||||
self.justifications.remove(&request);
|
||||
self.previous_requests.remove(&request);
|
||||
return;
|
||||
}
|
||||
self.pending_requests.push_front(request);
|
||||
}
|
||||
|
||||
/// Processes the response for the request previously sent to the given
|
||||
/// peer. Queues a retry in case the import fails or the given justification
|
||||
/// peer. Queues a retry in case the given justification
|
||||
/// was `None`.
|
||||
fn on_response(
|
||||
&mut self,
|
||||
who: NodeIndex,
|
||||
justification: Option<Justification>,
|
||||
protocol: &mut Context<B>,
|
||||
import_queue: &ImportQueue<B>,
|
||||
) {
|
||||
// we assume that the request maps to the given response, this is
|
||||
@@ -212,23 +223,13 @@ impl<B: BlockT> PendingJustifications<B> {
|
||||
// messages to chain sync.
|
||||
if let Some(request) = self.peer_requests.remove(&who) {
|
||||
if let Some(justification) = justification {
|
||||
if import_queue.import_justification(request.0, request.1, justification) {
|
||||
self.justifications.remove(&request);
|
||||
self.previous_requests.remove(&request);
|
||||
return;
|
||||
} else {
|
||||
protocol.report_peer(
|
||||
who,
|
||||
Severity::Bad(format!("Invalid justification provided for #{}", request.0)),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.previous_requests
|
||||
.entry(request)
|
||||
.or_insert(Vec::new())
|
||||
.push((who, Instant::now()));
|
||||
import_queue.import_justification(who.clone(), request.0, request.1, justification);
|
||||
return
|
||||
}
|
||||
|
||||
self.previous_requests
|
||||
.entry(request)
|
||||
.or_insert(Vec::new())
|
||||
.push((who, Instant::now()));
|
||||
self.pending_requests.push_front(request);
|
||||
}
|
||||
}
|
||||
@@ -251,8 +252,9 @@ pub struct ChainSync<B: BlockT> {
|
||||
best_queued_number: NumberFor<B>,
|
||||
best_queued_hash: B::Hash,
|
||||
required_block_attributes: message::BlockAttributes,
|
||||
import_queue: Arc<ImportQueue<B>>,
|
||||
justifications: PendingJustifications<B>,
|
||||
import_queue: Box<ImportQueue<B>>,
|
||||
is_stopping: AtomicBool,
|
||||
}
|
||||
|
||||
/// Reported sync state.
|
||||
@@ -293,7 +295,7 @@ impl<B: BlockT> Status<B> {
|
||||
|
||||
impl<B: BlockT> ChainSync<B> {
|
||||
/// Create a new instance.
|
||||
pub(crate) fn new(role: Roles, info: &ClientInfo<B>, import_queue: Arc<ImportQueue<B>>) -> Self {
|
||||
pub(crate) fn new(role: Roles, info: &ClientInfo<B>, import_queue: Box<ImportQueue<B>>) -> Self {
|
||||
let mut required_block_attributes = message::BlockAttributes::HEADER | message::BlockAttributes::JUSTIFICATION;
|
||||
if role.intersects(Roles::FULL | Roles::AUTHORITY) {
|
||||
required_block_attributes |= message::BlockAttributes::BODY;
|
||||
@@ -308,6 +310,7 @@ impl<B: BlockT> ChainSync<B> {
|
||||
justifications: PendingJustifications::new(),
|
||||
required_block_attributes,
|
||||
import_queue,
|
||||
is_stopping: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +319,7 @@ impl<B: BlockT> ChainSync<B> {
|
||||
}
|
||||
|
||||
/// Returns import queue reference.
|
||||
pub(crate) fn import_queue(&self) -> Arc<ImportQueue<B>> {
|
||||
pub(crate) fn import_queue(&self) -> Box<ImportQueue<B>> {
|
||||
self.import_queue.clone()
|
||||
}
|
||||
|
||||
@@ -536,7 +539,6 @@ impl<B: BlockT> ChainSync<B> {
|
||||
self.justifications.on_response(
|
||||
who,
|
||||
response.justification,
|
||||
protocol,
|
||||
&*self.import_queue,
|
||||
);
|
||||
},
|
||||
@@ -558,6 +560,9 @@ impl<B: BlockT> ChainSync<B> {
|
||||
|
||||
/// Maintain the sync process (download new blocks, fetch justifications).
|
||||
pub fn maintain_sync(&mut self, protocol: &mut Context<B>) {
|
||||
if self.is_stopping.load(Ordering::SeqCst) {
|
||||
return
|
||||
}
|
||||
let peers: Vec<NodeIndex> = self.peers.keys().map(|p| *p).collect();
|
||||
for peer in peers {
|
||||
self.download_new(protocol, peer);
|
||||
@@ -578,6 +583,15 @@ impl<B: BlockT> ChainSync<B> {
|
||||
self.justifications.dispatch(&mut self.peers, protocol);
|
||||
}
|
||||
|
||||
pub fn justification_import_result(&mut self, hash: B::Hash, number: NumberFor<B>, success: bool) {
|
||||
self.justifications.justification_import_result(hash, number, success);
|
||||
}
|
||||
|
||||
pub fn stop(&self) {
|
||||
self.is_stopping.store(true, Ordering::SeqCst);
|
||||
self.import_queue.stop();
|
||||
}
|
||||
|
||||
/// Notify about successful import of the given block.
|
||||
pub fn block_imported(&mut self, hash: &B::Hash, number: NumberFor<B>) {
|
||||
trace!(target: "sync", "Block imported successfully {} ({})", number, hash);
|
||||
|
||||
Reference in New Issue
Block a user