mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 10:27:59 +00:00
Add a back-pressure-friendly alternative to NetworkService::write_notifications 🎉 (#6692)
* Add NetworkService::send_notifications * Doc * Doc * API adjustment * Address concerns * Make it compile * Start implementation * Progress in the implementation * Change implementation strategy again * More work before weekend * Finish changes * Minor doc fix * Revert some minor changes * Apply suggestions from code review * GroupError -> NotifsHandlerError * Apply suggestions from code review Co-authored-by: Roman Borschel <romanb@users.noreply.github.com> * state_transition_waker -> close_waker * Apply suggestions from code review Co-authored-by: Roman Borschel <romanb@users.noreply.github.com> * Finish renames in service.rs * More renames * More review suggestsions applied * More review addressing * Final change * 512 -> 2048 Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
This commit is contained in:
@@ -47,8 +47,8 @@ use sp_runtime::traits::{
|
||||
};
|
||||
use sp_arithmetic::traits::SaturatedConversion;
|
||||
use message::{BlockAnnounce, Message};
|
||||
use message::generic::{Message as GenericMessage, ConsensusMessage, Roles};
|
||||
use prometheus_endpoint::{Registry, Gauge, Counter, GaugeVec, HistogramVec, PrometheusError, Opts, register, U64};
|
||||
use message::generic::{Message as GenericMessage, Roles};
|
||||
use prometheus_endpoint::{Registry, Gauge, Counter, GaugeVec, PrometheusError, Opts, register, U64};
|
||||
use sync::{ChainSync, SyncState};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque, hash_map::Entry};
|
||||
@@ -67,7 +67,7 @@ pub mod message;
|
||||
pub mod event;
|
||||
pub mod sync;
|
||||
|
||||
pub use generic_proto::LegacyConnectionKillError;
|
||||
pub use generic_proto::{NotificationsSink, Ready, NotifsHandlerError, LegacyConnectionKillError};
|
||||
|
||||
const REQUEST_TIMEOUT_SEC: u64 = 40;
|
||||
/// Interval at which we perform time based maintenance
|
||||
@@ -388,7 +388,6 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
|
||||
block_announce_validator: Box<dyn BlockAnnounceValidator<B> + Send>,
|
||||
metrics_registry: Option<&Registry>,
|
||||
boot_node_ids: Arc<HashSet<PeerId>>,
|
||||
queue_size_report: Option<HistogramVec>,
|
||||
) -> error::Result<(Protocol<B, H>, sc_peerset::PeersetHandle)> {
|
||||
let info = chain.info();
|
||||
let sync = ChainSync::new(
|
||||
@@ -417,7 +416,6 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
|
||||
versions,
|
||||
build_status_message(&config, &chain),
|
||||
peerset,
|
||||
queue_size_report,
|
||||
);
|
||||
|
||||
let mut legacy_equiv_by_name = HashMap::new();
|
||||
@@ -948,7 +946,12 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
|
||||
}
|
||||
|
||||
/// Called on receipt of a status message via the legacy protocol on the first connection between two peers.
|
||||
pub fn on_peer_connected(&mut self, who: PeerId, status: message::Status<B>) -> CustomMessageOutcome<B> {
|
||||
pub fn on_peer_connected(
|
||||
&mut self,
|
||||
who: PeerId,
|
||||
status: message::Status<B>,
|
||||
notifications_sink: NotificationsSink,
|
||||
) -> CustomMessageOutcome<B> {
|
||||
trace!(target: "sync", "New peer {} {:?}", who, status);
|
||||
let _protocol_version = {
|
||||
if self.context_data.peers.contains_key(&who) {
|
||||
@@ -1060,32 +1063,7 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
|
||||
remote: who,
|
||||
protocols: self.protocol_name_by_engine.keys().cloned().collect(),
|
||||
roles: info.roles,
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a notification to the given peer we're connected to.
|
||||
///
|
||||
/// Doesn't do anything if we don't have a notifications substream for that protocol with that
|
||||
/// peer.
|
||||
pub fn write_notification(
|
||||
&mut self,
|
||||
target: PeerId,
|
||||
engine_id: ConsensusEngineId,
|
||||
message: impl Into<Vec<u8>>,
|
||||
) {
|
||||
if let Some(protocol_name) = self.protocol_name_by_engine.get(&engine_id) {
|
||||
let message = message.into();
|
||||
let fallback = GenericMessage::<(), (), (), ()>::Consensus(ConsensusMessage {
|
||||
engine_id,
|
||||
data: message.clone(),
|
||||
}).encode();
|
||||
self.behaviour.write_notification(&target, protocol_name.clone(), message, fallback);
|
||||
} else {
|
||||
error!(
|
||||
target: "sub-libp2p",
|
||||
"Sending a notification with a protocol that wasn't registered: {:?}",
|
||||
engine_id
|
||||
);
|
||||
notifications_sink,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1099,7 +1077,7 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
|
||||
engine_id: ConsensusEngineId,
|
||||
protocol_name: impl Into<Cow<'static, [u8]>>,
|
||||
handshake_message: Vec<u8>,
|
||||
) -> impl ExactSizeIterator<Item = (&'a PeerId, Roles)> + 'a {
|
||||
) -> impl Iterator<Item = (&'a PeerId, Roles, &'a NotificationsSink)> + 'a {
|
||||
let protocol_name = protocol_name.into();
|
||||
if self.protocol_name_by_engine.insert(engine_id, protocol_name.clone()).is_some() {
|
||||
error!(target: "sub-libp2p", "Notifications protocol already registered: {:?}", protocol_name);
|
||||
@@ -1108,8 +1086,15 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
|
||||
self.legacy_equiv_by_name.insert(protocol_name, Fallback::Consensus(engine_id));
|
||||
}
|
||||
|
||||
self.context_data.peers.iter()
|
||||
.map(|(peer_id, peer)| (peer_id, peer.info.roles))
|
||||
let behaviour = &self.behaviour;
|
||||
self.context_data.peers.iter().filter_map(move |(peer_id, peer)| {
|
||||
if let Some(notifications_sink) = behaviour.notifications_sink(peer_id) {
|
||||
Some((peer_id, peer.info.roles, notifications_sink))
|
||||
} else {
|
||||
log::error!("State mismatch: no notifications sink for opened peer {:?}", peer_id);
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Called when peer sends us new transactions
|
||||
@@ -1863,7 +1848,18 @@ pub enum CustomMessageOutcome<B: BlockT> {
|
||||
JustificationImport(Origin, B::Hash, NumberFor<B>, Justification),
|
||||
FinalityProofImport(Origin, B::Hash, NumberFor<B>, Vec<u8>),
|
||||
/// Notification protocols have been opened with a remote.
|
||||
NotificationStreamOpened { remote: PeerId, protocols: Vec<ConsensusEngineId>, roles: Roles },
|
||||
NotificationStreamOpened {
|
||||
remote: PeerId,
|
||||
protocols: Vec<ConsensusEngineId>,
|
||||
roles: Roles,
|
||||
notifications_sink: NotificationsSink
|
||||
},
|
||||
/// The [`NotificationsSink`] of some notification protocols need an update.
|
||||
NotificationStreamReplaced {
|
||||
remote: PeerId,
|
||||
protocols: Vec<ConsensusEngineId>,
|
||||
notifications_sink: NotificationsSink,
|
||||
},
|
||||
/// Notification protocols have been closed with a remote.
|
||||
NotificationStreamClosed { remote: PeerId, protocols: Vec<ConsensusEngineId> },
|
||||
/// Messages have been received on one or more notifications protocols.
|
||||
@@ -2028,9 +2024,10 @@ impl<B: BlockT, H: ExHashT> NetworkBehaviour for Protocol<B, H> {
|
||||
};
|
||||
|
||||
let outcome = match event {
|
||||
GenericProtoOut::CustomProtocolOpen { peer_id, received_handshake, .. } => {
|
||||
GenericProtoOut::CustomProtocolOpen { peer_id, received_handshake, notifications_sink, .. } => {
|
||||
match <Message<B> as Decode>::decode(&mut &received_handshake[..]) {
|
||||
Ok(GenericMessage::Status(handshake)) => self.on_peer_connected(peer_id, handshake),
|
||||
Ok(GenericMessage::Status(handshake)) =>
|
||||
self.on_peer_connected(peer_id, handshake, notifications_sink),
|
||||
Ok(msg) => {
|
||||
debug!(
|
||||
target: "sync",
|
||||
@@ -2054,6 +2051,13 @@ impl<B: BlockT, H: ExHashT> NetworkBehaviour for Protocol<B, H> {
|
||||
}
|
||||
}
|
||||
}
|
||||
GenericProtoOut::CustomProtocolReplaced { peer_id, notifications_sink, .. } => {
|
||||
CustomMessageOutcome::NotificationStreamReplaced {
|
||||
remote: peer_id,
|
||||
protocols: self.protocol_name_by_engine.keys().cloned().collect(),
|
||||
notifications_sink,
|
||||
}
|
||||
},
|
||||
GenericProtoOut::CustomProtocolClosed { peer_id, .. } => {
|
||||
self.on_peer_disconnected(peer_id)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user