Pass an encoded Roles as the notifications protocols handshakes (#5665)

This commit is contained in:
Pierre Krieger
2020-04-21 10:47:37 +02:00
committed by GitHub
parent 5db336c743
commit f2578bdc3b
5 changed files with 71 additions and 38 deletions
@@ -113,6 +113,8 @@ pub struct GenericProto {
legacy_protocol: RegisteredProtocol,
/// Notification protocols. Entries are only ever added and not removed.
/// Contains, for each protocol, the protocol name and the message to send as part of the
/// initial handshake.
notif_protocols: Vec<(Cow<'static, [u8]>, Vec<u8>)>,
/// Receiver for instructions about who to connect to or disconnect from.
@@ -75,11 +75,12 @@ use std::{borrow::Cow, error, io, str, task::{Context, Poll}};
///
/// See the documentation at the module level for more information.
pub struct NotifsHandlerProto {
/// Prototypes for handlers for inbound substreams.
in_handlers: Vec<NotifsInHandlerProto>,
/// Prototypes for handlers for inbound substreams, and the message we respond with in the
/// handshake.
in_handlers: Vec<(NotifsInHandlerProto, Vec<u8>)>,
/// Prototypes for handlers for outbound substreams.
out_handlers: Vec<NotifsOutHandlerProto>,
/// Prototypes for handlers for outbound substreams, and the initial handshake message we send.
out_handlers: Vec<(NotifsOutHandlerProto, Vec<u8>)>,
/// Prototype for handler for backwards-compatibility.
legacy: LegacyProtoHandlerProto,
@@ -89,11 +90,11 @@ pub struct NotifsHandlerProto {
///
/// See the documentation at the module level for more information.
pub struct NotifsHandler {
/// Handlers for inbound substreams.
in_handlers: Vec<NotifsInHandler>,
/// Handlers for inbound substreams, and the message we respond with in the handshake.
in_handlers: Vec<(NotifsInHandler, Vec<u8>)>,
/// Handlers for outbound substreams.
out_handlers: Vec<NotifsOutHandler>,
/// Handlers for outbound substreams, and the initial handshake message we send.
out_handlers: Vec<(NotifsOutHandler, Vec<u8>)>,
/// Handler for backwards-compatibility.
legacy: LegacyProtoHandler,
@@ -119,7 +120,7 @@ impl IntoProtocolsHandler for NotifsHandlerProto {
fn inbound_protocol(&self) -> SelectUpgrade<UpgradeCollec<NotificationsIn>, RegisteredProtocol> {
let in_handlers = self.in_handlers.iter()
.map(|h| h.inbound_protocol())
.map(|(h, _)| h.inbound_protocol())
.collect::<UpgradeCollec<_>>();
SelectUpgrade::new(in_handlers, self.legacy.inbound_protocol())
@@ -129,11 +130,11 @@ impl IntoProtocolsHandler for NotifsHandlerProto {
NotifsHandler {
in_handlers: self.in_handlers
.into_iter()
.map(|p| p.into_handler(remote_peer_id, connected_point))
.map(|(proto, msg)| (proto.into_handler(remote_peer_id, connected_point), msg))
.collect(),
out_handlers: self.out_handlers
.into_iter()
.map(|p| p.into_handler(remote_peer_id, connected_point))
.map(|(proto, msg)| (proto.into_handler(remote_peer_id, connected_point), msg))
.collect(),
legacy: self.legacy.into_handler(remote_peer_id, connected_point),
enabled: EnabledState::Initial,
@@ -232,28 +233,42 @@ pub enum NotifsHandlerOut {
impl NotifsHandlerProto {
/// Builds a new handler.
///
/// `list` is a list of notification protocols names, and the message to send as part of the
/// handshake. At the moment, the message is always the same whether we open a substream
/// ourselves or respond to handshake from the remote.
///
/// The `queue_size_report` is an optional Prometheus metric that can report the size of the
/// messages queue. If passed, it must have one label for the protocol name.
pub fn new(legacy: RegisteredProtocol, list: impl Into<Vec<(Cow<'static, [u8]>, Vec<u8>)>>, queue_size_report: Option<HistogramVec>) -> Self {
pub fn new(
legacy: RegisteredProtocol,
list: impl Into<Vec<(Cow<'static, [u8]>, Vec<u8>)>>,
queue_size_report: Option<HistogramVec>
) -> Self {
let list = list.into();
let out_handlers = list
.clone()
.into_iter()
.map(|(p, _)| {
.map(|(proto_name, initial_message)| {
let queue_size_report = queue_size_report.as_ref().and_then(|qs| {
if let Ok(utf8) = str::from_utf8(&p) {
if let Ok(utf8) = str::from_utf8(&proto_name) {
Some(qs.with_label_values(&[utf8]))
} else {
log::warn!("Ignoring Prometheus metric because {:?} isn't UTF-8", p);
log::warn!("Ignoring Prometheus metric because {:?} isn't UTF-8", proto_name);
None
}
});
NotifsOutHandlerProto::new(p, queue_size_report)
(NotifsOutHandlerProto::new(proto_name, queue_size_report), initial_message)
}).collect();
let in_handlers = list.clone()
.into_iter()
.map(|(proto_name, msg)| (NotifsInHandlerProto::new(proto_name), msg))
.collect();
NotifsHandlerProto {
in_handlers: list.clone().into_iter().map(|(p, _)| NotifsInHandlerProto::new(p)).collect(),
in_handlers,
out_handlers,
legacy: LegacyProtoHandlerProto::new(legacy),
}
@@ -277,7 +292,7 @@ impl ProtocolsHandler for NotifsHandler {
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol> {
let in_handlers = self.in_handlers.iter()
.map(|h| h.listen_protocol().into_upgrade().1)
.map(|(h, _)| h.listen_protocol().into_upgrade().1)
.collect::<UpgradeCollec<_>>();
let proto = SelectUpgrade::new(in_handlers, self.legacy.listen_protocol().into_upgrade().1);
@@ -290,7 +305,7 @@ impl ProtocolsHandler for NotifsHandler {
) {
match out {
EitherOutput::First((out, num)) =>
self.in_handlers[num].inject_fully_negotiated_inbound(out),
self.in_handlers[num].0.inject_fully_negotiated_inbound(out),
EitherOutput::Second(out) =>
self.legacy.inject_fully_negotiated_inbound(out),
}
@@ -303,7 +318,7 @@ impl ProtocolsHandler for NotifsHandler {
) {
match (out, num) {
(EitherOutput::First(out), Some(num)) =>
self.out_handlers[num].inject_fully_negotiated_outbound(out, ()),
self.out_handlers[num].0.inject_fully_negotiated_outbound(out, ()),
(EitherOutput::Second(out), None) =>
self.legacy.inject_fully_negotiated_outbound(out, ()),
_ => error!("inject_fully_negotiated_outbound called with wrong parameters"),
@@ -318,13 +333,15 @@ impl ProtocolsHandler for NotifsHandler {
}
self.enabled = EnabledState::Enabled;
self.legacy.inject_event(LegacyProtoHandlerIn::Enable);
for handler in &mut self.out_handlers {
for (handler, initial_message) in &mut self.out_handlers {
handler.inject_event(NotifsOutHandlerIn::Enable {
initial_message: vec![]
initial_message: initial_message.clone(),
});
}
for num in self.pending_in.drain(..) {
self.in_handlers[num].inject_event(NotifsInHandlerIn::Accept(vec![]));
let handshake_message = self.in_handlers[num].1.clone();
self.in_handlers[num].0
.inject_event(NotifsInHandlerIn::Accept(handshake_message));
}
},
NotifsHandlerIn::Disable => {
@@ -335,19 +352,19 @@ impl ProtocolsHandler for NotifsHandler {
// The notifications protocols start in the disabled state. If we were in the
// "Initial" state, then we shouldn't disable the notifications protocols again.
if self.enabled != EnabledState::Initial {
for handler in &mut self.out_handlers {
for (handler, _) in &mut self.out_handlers {
handler.inject_event(NotifsOutHandlerIn::Disable);
}
}
self.enabled = EnabledState::Disabled;
for num in self.pending_in.drain(..) {
self.in_handlers[num].inject_event(NotifsInHandlerIn::Refuse);
self.in_handlers[num].0.inject_event(NotifsInHandlerIn::Refuse);
}
},
NotifsHandlerIn::SendLegacy { message } =>
self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { message }),
NotifsHandlerIn::SendNotification { message, encoded_fallback_message, protocol_name } => {
for handler in &mut self.out_handlers {
for (handler, _) in &mut self.out_handlers {
if handler.protocol_name() != &protocol_name[..] {
continue;
}
@@ -372,21 +389,21 @@ impl ProtocolsHandler for NotifsHandler {
) {
match (err, num) {
(ProtocolsHandlerUpgrErr::Timeout, Some(num)) =>
self.out_handlers[num].inject_dial_upgrade_error(
self.out_handlers[num].0.inject_dial_upgrade_error(
(),
ProtocolsHandlerUpgrErr::Timeout
),
(ProtocolsHandlerUpgrErr::Timeout, None) =>
self.legacy.inject_dial_upgrade_error((), ProtocolsHandlerUpgrErr::Timeout),
(ProtocolsHandlerUpgrErr::Timer, Some(num)) =>
self.out_handlers[num].inject_dial_upgrade_error(
self.out_handlers[num].0.inject_dial_upgrade_error(
(),
ProtocolsHandlerUpgrErr::Timer
),
(ProtocolsHandlerUpgrErr::Timer, None) =>
self.legacy.inject_dial_upgrade_error((), ProtocolsHandlerUpgrErr::Timer),
(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), Some(num)) =>
self.out_handlers[num].inject_dial_upgrade_error(
self.out_handlers[num].0.inject_dial_upgrade_error(
(),
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err))
),
@@ -396,7 +413,7 @@ impl ProtocolsHandler for NotifsHandler {
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err))
),
(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(err))), Some(num)) =>
self.out_handlers[num].inject_dial_upgrade_error(
self.out_handlers[num].0.inject_dial_upgrade_error(
(),
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err))
),
@@ -417,7 +434,7 @@ impl ProtocolsHandler for NotifsHandler {
return KeepAlive::Yes;
}
for handler in &self.in_handlers {
for (handler, _) in &self.in_handlers {
let val = handler.connection_keep_alive();
if val.is_yes() {
return KeepAlive::Yes;
@@ -425,7 +442,7 @@ impl ProtocolsHandler for NotifsHandler {
if ret < val { ret = val; }
}
for handler in &self.out_handlers {
for (handler, _) in &self.out_handlers {
let val = handler.connection_keep_alive();
if val.is_yes() {
return KeepAlive::Yes;
@@ -474,7 +491,7 @@ impl ProtocolsHandler for NotifsHandler {
}
}
for (handler_num, handler) in self.in_handlers.iter_mut().enumerate() {
for (handler_num, (handler, handshake_message)) in self.in_handlers.iter_mut().enumerate() {
while let Poll::Ready(ev) = handler.poll(cx) {
match ev {
ProtocolsHandlerEvent::OutboundSubstreamRequest { .. } =>
@@ -484,7 +501,7 @@ impl ProtocolsHandler for NotifsHandler {
match self.enabled {
EnabledState::Initial => self.pending_in.push(handler_num),
EnabledState::Enabled =>
handler.inject_event(NotifsInHandlerIn::Accept(vec![])),
handler.inject_event(NotifsInHandlerIn::Accept(handshake_message.clone())),
EnabledState::Disabled =>
handler.inject_event(NotifsInHandlerIn::Refuse),
},
@@ -504,7 +521,7 @@ impl ProtocolsHandler for NotifsHandler {
}
}
for (handler_num, handler) in self.out_handlers.iter_mut().enumerate() {
for (handler_num, (handler, _)) in self.out_handlers.iter_mut().enumerate() {
while let Poll::Ready(ev) = handler.poll(cx) {
match ev {
ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info: () } =>