// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//! Periodic rebroadcast of neighbor packets.
use futures::{future::FutureExt as _, prelude::*, ready, stream::Stream};
use futures_timer::Delay;
use log::debug;
use std::{
pin::Pin,
task::{Context, Poll},
time::Duration,
};
use pezsc_network_types::PeerId;
use pezsc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
use pezsp_runtime::traits::{Block as BlockT, NumberFor};
use super::gossip::{GossipMessage, NeighborPacket};
use crate::LOG_TARGET;
/// A sender used to send neighbor packets to a background job.
#[derive(Clone)]
pub(super) struct NeighborPacketSender(
TracingUnboundedSender<(Vec, NeighborPacket>)>,
);
impl NeighborPacketSender {
/// Send a neighbor packet for the background worker to gossip to peers.
pub fn send(
&self,
who: Vec,
neighbor_packet: NeighborPacket>,
) {
if let Err(err) = self.0.unbounded_send((who, neighbor_packet)) {
debug!(target: LOG_TARGET, "Failed to send neighbor packet: {:?}", err);
}
}
}
/// NeighborPacketWorker is listening on a channel for new neighbor packets being produced by
/// components within `finality-grandpa` and forwards those packets to the underlying
/// `NetworkEngine` through the `NetworkBridge` that it is being polled by (see `Stream`
/// implementation). Periodically it sends out the last packet in cases where no new ones arrive.
pub(super) struct NeighborPacketWorker {
last: Option<(Vec, NeighborPacket>)>,
rebroadcast_period: Duration,
delay: Delay,
rx: TracingUnboundedReceiver<(Vec, NeighborPacket>)>,
}
impl Unpin for NeighborPacketWorker {}
impl NeighborPacketWorker {
pub(super) fn new(rebroadcast_period: Duration) -> (Self, NeighborPacketSender) {
let (tx, rx) = tracing_unbounded::<(Vec, NeighborPacket>)>(
"mpsc_grandpa_neighbor_packet_worker",
100_000,
);
let delay = Delay::new(rebroadcast_period);
(
NeighborPacketWorker { last: None, rebroadcast_period, delay, rx },
NeighborPacketSender(tx),
)
}
}
impl Stream for NeighborPacketWorker {
type Item = (Vec, GossipMessage);
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll