mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-18 04:21:22 +00:00
swarm/behaviour: Replace inject_*
with on_event
(#3011)
This commit is contained in:
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
- Update to `libp2p-request-response` `v0.23.0`.
|
- Update to `libp2p-request-response` `v0.23.0`.
|
||||||
|
|
||||||
|
- Replace `Behaviour`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
|
|
||||||
# 0.8.0
|
# 0.8.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.37.0`.
|
- Update to `libp2p-core` `v0.37.0`.
|
||||||
|
@ -29,15 +29,19 @@ pub use as_server::{InboundProbeError, InboundProbeEvent};
|
|||||||
use futures_timer::Delay;
|
use futures_timer::Delay;
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
connection::ConnectionId, multiaddr::Protocol, transport::ListenerId, ConnectedPoint, Endpoint,
|
connection::ConnectionId, multiaddr::Protocol, ConnectedPoint, Endpoint, Multiaddr, PeerId,
|
||||||
Multiaddr, PeerId,
|
|
||||||
};
|
};
|
||||||
use libp2p_request_response::{
|
use libp2p_request_response::{
|
||||||
handler::RequestResponseHandlerEvent, ProtocolSupport, RequestId, RequestResponse,
|
ProtocolSupport, RequestId, RequestResponse, RequestResponseConfig, RequestResponseEvent,
|
||||||
RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel,
|
RequestResponseMessage, ResponseChannel,
|
||||||
};
|
};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
|
behaviour::{
|
||||||
|
AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr,
|
||||||
|
ExpiredListenAddr, FromSwarm,
|
||||||
|
},
|
||||||
|
ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction,
|
||||||
|
PollParameters,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, VecDeque},
|
collections::{HashMap, VecDeque},
|
||||||
@ -298,28 +302,17 @@ impl Behaviour {
|
|||||||
ongoing_inbound: &mut self.ongoing_inbound,
|
ongoing_inbound: &mut self.ongoing_inbound,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkBehaviour for Behaviour {
|
fn on_connection_established(
|
||||||
type ConnectionHandler = <RequestResponse<AutoNatCodec> as NetworkBehaviour>::ConnectionHandler;
|
|
||||||
type OutEvent = Event;
|
|
||||||
|
|
||||||
fn inject_connection_established(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
peer: &PeerId,
|
ConnectionEstablished {
|
||||||
conn: &ConnectionId,
|
peer_id: peer,
|
||||||
endpoint: &ConnectedPoint,
|
connection_id: conn,
|
||||||
failed_addresses: Option<&Vec<Multiaddr>>,
|
|
||||||
other_established: usize,
|
|
||||||
) {
|
|
||||||
self.inner.inject_connection_established(
|
|
||||||
peer,
|
|
||||||
conn,
|
|
||||||
endpoint,
|
endpoint,
|
||||||
failed_addresses,
|
..
|
||||||
other_established,
|
}: ConnectionEstablished,
|
||||||
);
|
) {
|
||||||
let connections = self.connected.entry(*peer).or_default();
|
let connections = self.connected.entry(peer).or_default();
|
||||||
let addr = endpoint.get_remote_address();
|
let addr = endpoint.get_remote_address();
|
||||||
let observed_addr =
|
let observed_addr =
|
||||||
if !endpoint.is_relayed() && (!self.config.only_global_ips || addr.is_global_ip()) {
|
if !endpoint.is_relayed() && (!self.config.only_global_ips || addr.is_global_ip()) {
|
||||||
@ -327,14 +320,14 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
connections.insert(*conn, observed_addr);
|
connections.insert(conn, observed_addr);
|
||||||
|
|
||||||
match endpoint {
|
match endpoint {
|
||||||
ConnectedPoint::Dialer {
|
ConnectedPoint::Dialer {
|
||||||
address,
|
address,
|
||||||
role_override: Endpoint::Dialer,
|
role_override: Endpoint::Dialer,
|
||||||
} => {
|
} => {
|
||||||
if let Some(event) = self.as_server().on_outbound_connection(peer, address) {
|
if let Some(event) = self.as_server().on_outbound_connection(&peer, address) {
|
||||||
self.pending_out_events
|
self.pending_out_events
|
||||||
.push_back(Event::InboundProbe(event));
|
.push_back(Event::InboundProbe(event));
|
||||||
}
|
}
|
||||||
@ -351,50 +344,69 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_closed(
|
fn on_connection_closed(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer: &PeerId,
|
ConnectionClosed {
|
||||||
conn: &ConnectionId,
|
peer_id,
|
||||||
endpoint: &ConnectedPoint,
|
connection_id,
|
||||||
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
endpoint,
|
||||||
remaining_established: usize,
|
handler,
|
||||||
|
remaining_established,
|
||||||
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
) {
|
) {
|
||||||
self.inner
|
self.inner
|
||||||
.inject_connection_closed(peer, conn, endpoint, handler, remaining_established);
|
.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
handler,
|
||||||
|
remaining_established,
|
||||||
|
}));
|
||||||
|
|
||||||
if remaining_established == 0 {
|
if remaining_established == 0 {
|
||||||
self.connected.remove(peer);
|
self.connected.remove(&peer_id);
|
||||||
} else {
|
} else {
|
||||||
let connections = self.connected.get_mut(peer).expect("Peer is connected.");
|
let connections = self
|
||||||
connections.remove(conn);
|
.connected
|
||||||
|
.get_mut(&peer_id)
|
||||||
|
.expect("Peer is connected.");
|
||||||
|
connections.remove(&connection_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_dial_failure(
|
fn on_dial_failure(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer: Option<PeerId>,
|
DialFailure {
|
||||||
handler: Self::ConnectionHandler,
|
peer_id,
|
||||||
error: &DialError,
|
handler,
|
||||||
|
error,
|
||||||
|
}: DialFailure<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
) {
|
) {
|
||||||
self.inner.inject_dial_failure(peer, handler, error);
|
self.inner
|
||||||
if let Some(event) = self.as_server().on_outbound_dial_error(peer, error) {
|
.on_swarm_event(FromSwarm::DialFailure(DialFailure {
|
||||||
|
peer_id,
|
||||||
|
handler,
|
||||||
|
error,
|
||||||
|
}));
|
||||||
|
if let Some(event) = self.as_server().on_outbound_dial_error(peer_id, error) {
|
||||||
self.pending_out_events
|
self.pending_out_events
|
||||||
.push_back(Event::InboundProbe(event));
|
.push_back(Event::InboundProbe(event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_address_change(
|
fn on_address_change(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer: &PeerId,
|
AddressChange {
|
||||||
conn: &ConnectionId,
|
peer_id: peer,
|
||||||
old: &ConnectedPoint,
|
connection_id: conn,
|
||||||
new: &ConnectedPoint,
|
old,
|
||||||
|
new,
|
||||||
|
}: AddressChange,
|
||||||
) {
|
) {
|
||||||
self.inner.inject_address_change(peer, conn, old, new);
|
|
||||||
|
|
||||||
if old.is_relayed() && new.is_relayed() {
|
if old.is_relayed() && new.is_relayed() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let connections = self.connected.get_mut(peer).expect("Peer is connected.");
|
let connections = self.connected.get_mut(&peer).expect("Peer is connected.");
|
||||||
let addr = new.get_remote_address();
|
let addr = new.get_remote_address();
|
||||||
let observed_addr =
|
let observed_addr =
|
||||||
if !new.is_relayed() && (!self.config.only_global_ips || addr.is_global_ip()) {
|
if !new.is_relayed() && (!self.config.only_global_ips || addr.is_global_ip()) {
|
||||||
@ -402,28 +414,13 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
connections.insert(*conn, observed_addr);
|
connections.insert(conn, observed_addr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
|
impl NetworkBehaviour for Behaviour {
|
||||||
self.inner.inject_new_listen_addr(id, addr);
|
type ConnectionHandler = <RequestResponse<AutoNatCodec> as NetworkBehaviour>::ConnectionHandler;
|
||||||
self.as_client().on_new_address();
|
type OutEvent = Event;
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
|
|
||||||
self.inner.inject_expired_listen_addr(id, addr);
|
|
||||||
self.as_client().on_expired_address(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
|
|
||||||
self.inner.inject_new_external_addr(addr);
|
|
||||||
self.as_client().on_new_address();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
|
|
||||||
self.inner.inject_expired_external_addr(addr);
|
|
||||||
self.as_client().on_expired_address(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll(&mut self, cx: &mut Context<'_>, params: &mut impl PollParameters) -> Poll<Action> {
|
fn poll(&mut self, cx: &mut Context<'_>, params: &mut impl PollParameters) -> Poll<Action> {
|
||||||
loop {
|
loop {
|
||||||
@ -478,35 +475,65 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
self.inner.addresses_of_peer(peer)
|
self.inner.addresses_of_peer(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(connection_established) => {
|
||||||
|
self.inner
|
||||||
|
.on_swarm_event(FromSwarm::ConnectionEstablished(connection_established));
|
||||||
|
self.on_connection_established(connection_established)
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
|
self.on_connection_closed(connection_closed)
|
||||||
|
}
|
||||||
|
FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure),
|
||||||
|
FromSwarm::AddressChange(address_change) => {
|
||||||
|
self.inner
|
||||||
|
.on_swarm_event(FromSwarm::AddressChange(address_change));
|
||||||
|
self.on_address_change(address_change)
|
||||||
|
}
|
||||||
|
listen_addr @ FromSwarm::NewListenAddr(_) => {
|
||||||
|
self.inner.on_swarm_event(listen_addr);
|
||||||
|
self.as_client().on_new_address();
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredListenAddr(ExpiredListenAddr { listener_id, addr }) => {
|
||||||
|
self.inner
|
||||||
|
.on_swarm_event(FromSwarm::ExpiredListenAddr(ExpiredListenAddr {
|
||||||
|
listener_id,
|
||||||
|
addr,
|
||||||
|
}));
|
||||||
|
self.as_client().on_expired_address(addr);
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) => {
|
||||||
|
self.inner
|
||||||
|
.on_swarm_event(FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }));
|
||||||
|
self.as_client().on_expired_address(addr);
|
||||||
|
}
|
||||||
|
external_addr @ FromSwarm::NewExternalAddr(_) => {
|
||||||
|
self.inner.on_swarm_event(external_addr);
|
||||||
|
self.as_client().on_new_address();
|
||||||
|
}
|
||||||
|
listen_failure @ FromSwarm::ListenFailure(_) => {
|
||||||
|
self.inner.on_swarm_event(listen_failure)
|
||||||
|
}
|
||||||
|
new_listener @ FromSwarm::NewListener(_) => self.inner.on_swarm_event(new_listener),
|
||||||
|
listener_error @ FromSwarm::ListenerError(_) => {
|
||||||
|
self.inner.on_swarm_event(listener_error)
|
||||||
|
}
|
||||||
|
listener_closed @ FromSwarm::ListenerClosed(_) => {
|
||||||
|
self.inner.on_swarm_event(listener_closed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
conn: ConnectionId,
|
connection_id: ConnectionId,
|
||||||
event: RequestResponseHandlerEvent<AutoNatCodec>,
|
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
|
||||||
) {
|
ConnectionHandler>::OutEvent,
|
||||||
self.inner.inject_event(peer_id, conn, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listen_failure(
|
|
||||||
&mut self,
|
|
||||||
local_addr: &Multiaddr,
|
|
||||||
send_back_addr: &Multiaddr,
|
|
||||||
handler: Self::ConnectionHandler,
|
|
||||||
) {
|
) {
|
||||||
self.inner
|
self.inner
|
||||||
.inject_listen_failure(local_addr, send_back_addr, handler)
|
.on_connection_handler_event(peer_id, connection_id, event)
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listener(&mut self, id: ListenerId) {
|
|
||||||
self.inner.inject_new_listener(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) {
|
|
||||||
self.inner.inject_listener_error(id, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) {
|
|
||||||
self.inner.inject_listener_closed(id, reason)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `Behaviour`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
|
|
||||||
# 0.7.0
|
# 0.7.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.37.0`.
|
- Update to `libp2p-core` `v0.37.0`.
|
||||||
|
@ -26,10 +26,11 @@ use either::Either;
|
|||||||
use libp2p_core::connection::{ConnectedPoint, ConnectionId};
|
use libp2p_core::connection::{ConnectedPoint, ConnectionId};
|
||||||
use libp2p_core::multiaddr::Protocol;
|
use libp2p_core::multiaddr::Protocol;
|
||||||
use libp2p_core::{Multiaddr, PeerId};
|
use libp2p_core::{Multiaddr, PeerId};
|
||||||
|
use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm};
|
||||||
use libp2p_swarm::dial_opts::{self, DialOpts};
|
use libp2p_swarm::dial_opts::{self, DialOpts};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
ConnectionHandler, ConnectionHandlerUpgrErr, DialError, IntoConnectionHandler,
|
ConnectionHandler, ConnectionHandlerUpgrErr, IntoConnectionHandler, NetworkBehaviour,
|
||||||
NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
|
NetworkBehaviourAction, NotifyHandler, PollParameters,
|
||||||
};
|
};
|
||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@ -81,30 +82,18 @@ impl Behaviour {
|
|||||||
direct_connections: Default::default(),
|
direct_connections: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkBehaviour for Behaviour {
|
fn on_connection_established(
|
||||||
type ConnectionHandler = handler::Prototype;
|
|
||||||
type OutEvent = Event;
|
|
||||||
|
|
||||||
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
|
||||||
handler::Prototype::UnknownConnection
|
|
||||||
}
|
|
||||||
|
|
||||||
fn addresses_of_peer(&mut self, _peer_id: &PeerId) -> Vec<Multiaddr> {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_established(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: &PeerId,
|
ConnectionEstablished {
|
||||||
connection_id: &ConnectionId,
|
peer_id,
|
||||||
connected_point: &ConnectedPoint,
|
connection_id,
|
||||||
_failed_addresses: Option<&Vec<Multiaddr>>,
|
endpoint: connected_point,
|
||||||
_other_established: usize,
|
..
|
||||||
|
}: ConnectionEstablished,
|
||||||
) {
|
) {
|
||||||
if connected_point.is_relayed() {
|
if connected_point.is_relayed() {
|
||||||
if connected_point.is_listener() && !self.direct_connections.contains_key(peer_id) {
|
if connected_point.is_listener() && !self.direct_connections.contains_key(&peer_id) {
|
||||||
// TODO: Try dialing the remote peer directly. Specification:
|
// TODO: Try dialing the remote peer directly. Specification:
|
||||||
//
|
//
|
||||||
// > The protocol starts with the completion of a relay connection from A to B. Upon
|
// > The protocol starts with the completion of a relay connection from A to B. Upon
|
||||||
@ -116,13 +105,13 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
// https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol
|
// https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol
|
||||||
self.queued_actions.extend([
|
self.queued_actions.extend([
|
||||||
ActionBuilder::Connect {
|
ActionBuilder::Connect {
|
||||||
peer_id: *peer_id,
|
peer_id,
|
||||||
attempt: 1,
|
attempt: 1,
|
||||||
handler: NotifyHandler::One(*connection_id),
|
handler: NotifyHandler::One(connection_id),
|
||||||
},
|
},
|
||||||
NetworkBehaviourAction::GenerateEvent(
|
NetworkBehaviourAction::GenerateEvent(
|
||||||
Event::InitiatedDirectConnectionUpgrade {
|
Event::InitiatedDirectConnectionUpgrade {
|
||||||
remote_peer_id: *peer_id,
|
remote_peer_id: peer_id,
|
||||||
local_relayed_addr: match connected_point {
|
local_relayed_addr: match connected_point {
|
||||||
ConnectedPoint::Listener { local_addr, .. } => local_addr.clone(),
|
ConnectedPoint::Listener { local_addr, .. } => local_addr.clone(),
|
||||||
ConnectedPoint::Dialer { .. } => unreachable!("Due to outer if."),
|
ConnectedPoint::Dialer { .. } => unreachable!("Due to outer if."),
|
||||||
@ -134,17 +123,17 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.direct_connections
|
self.direct_connections
|
||||||
.entry(*peer_id)
|
.entry(peer_id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(*connection_id);
|
.insert(connection_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_dial_failure(
|
fn on_dial_failure(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: Option<PeerId>,
|
DialFailure {
|
||||||
handler: Self::ConnectionHandler,
|
peer_id, handler, ..
|
||||||
_error: &DialError,
|
}: DialFailure<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
) {
|
) {
|
||||||
if let handler::Prototype::DirectConnection {
|
if let handler::Prototype::DirectConnection {
|
||||||
relayed_connection_id,
|
relayed_connection_id,
|
||||||
@ -178,34 +167,45 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_closed(
|
fn on_connection_closed(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: &PeerId,
|
ConnectionClosed {
|
||||||
connection_id: &ConnectionId,
|
peer_id,
|
||||||
connected_point: &ConnectedPoint,
|
connection_id,
|
||||||
_handler: <<Self as NetworkBehaviour>::ConnectionHandler as IntoConnectionHandler>::Handler,
|
endpoint: connected_point,
|
||||||
_remaining_established: usize,
|
..
|
||||||
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
) {
|
) {
|
||||||
if !connected_point.is_relayed() {
|
if !connected_point.is_relayed() {
|
||||||
let connections = self
|
let connections = self
|
||||||
.direct_connections
|
.direct_connections
|
||||||
.get_mut(peer_id)
|
.get_mut(&peer_id)
|
||||||
.expect("Peer of direct connection to be tracked.");
|
.expect("Peer of direct connection to be tracked.");
|
||||||
connections
|
connections
|
||||||
.remove(connection_id)
|
.remove(&connection_id)
|
||||||
.then(|| ())
|
.then(|| ())
|
||||||
.expect("Direct connection to be tracked.");
|
.expect("Direct connection to be tracked.");
|
||||||
if connections.is_empty() {
|
if connections.is_empty() {
|
||||||
self.direct_connections.remove(peer_id);
|
self.direct_connections.remove(&peer_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn inject_event(
|
impl NetworkBehaviour for Behaviour {
|
||||||
|
type ConnectionHandler = handler::Prototype;
|
||||||
|
type OutEvent = Event;
|
||||||
|
|
||||||
|
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
||||||
|
handler::Prototype::UnknownConnection
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event_source: PeerId,
|
event_source: PeerId,
|
||||||
connection: ConnectionId,
|
connection: ConnectionId,
|
||||||
handler_event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
handler_event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
|
||||||
|
ConnectionHandler>::OutEvent,
|
||||||
) {
|
) {
|
||||||
match handler_event {
|
match handler_event {
|
||||||
Either::Left(handler::relayed::Event::InboundConnectRequest {
|
Either::Left(handler::relayed::Event::InboundConnectRequest {
|
||||||
@ -316,6 +316,27 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
|
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(connection_established) => {
|
||||||
|
self.on_connection_established(connection_established)
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
|
self.on_connection_closed(connection_closed)
|
||||||
|
}
|
||||||
|
FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure),
|
||||||
|
FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [`NetworkBehaviourAction`], either complete, or still requiring data from [`PollParameters`]
|
/// A [`NetworkBehaviourAction`], either complete, or still requiring data from [`PollParameters`]
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `Floodsub`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
|
|
||||||
# 0.40.0
|
# 0.40.0
|
||||||
|
|
||||||
- Bump rand to 0.8 and quickcheck to 1. See [PR 2857].
|
- Bump rand to 0.8 and quickcheck to 1. See [PR 2857].
|
||||||
|
@ -27,11 +27,12 @@ use crate::FloodsubConfig;
|
|||||||
use cuckoofilter::{CuckooError, CuckooFilter};
|
use cuckoofilter::{CuckooError, CuckooFilter};
|
||||||
use fnv::FnvHashSet;
|
use fnv::FnvHashSet;
|
||||||
use libp2p_core::{connection::ConnectionId, PeerId};
|
use libp2p_core::{connection::ConnectionId, PeerId};
|
||||||
use libp2p_core::{ConnectedPoint, Multiaddr};
|
use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler,
|
dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler,
|
||||||
PollParameters,
|
PollParameters,
|
||||||
};
|
};
|
||||||
|
use libp2p_swarm::{ConnectionHandler, IntoConnectionHandler};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::collections::hash_map::{DefaultHasher, HashMap};
|
use std::collections::hash_map::{DefaultHasher, HashMap};
|
||||||
@ -276,23 +277,14 @@ impl Floodsub {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkBehaviour for Floodsub {
|
fn on_connection_established(
|
||||||
type ConnectionHandler = OneShotHandler<FloodsubProtocol, FloodsubRpc, InnerMessage>;
|
|
||||||
type OutEvent = FloodsubEvent;
|
|
||||||
|
|
||||||
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
|
||||||
Default::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_established(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
id: &PeerId,
|
ConnectionEstablished {
|
||||||
_: &ConnectionId,
|
peer_id,
|
||||||
_: &ConnectedPoint,
|
other_established,
|
||||||
_: Option<&Vec<Multiaddr>>,
|
..
|
||||||
other_established: usize,
|
}: ConnectionEstablished,
|
||||||
) {
|
) {
|
||||||
if other_established > 0 {
|
if other_established > 0 {
|
||||||
// We only care about the first time a peer connects.
|
// We only care about the first time a peer connects.
|
||||||
@ -300,11 +292,11 @@ impl NetworkBehaviour for Floodsub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We need to send our subscriptions to the newly-connected node.
|
// We need to send our subscriptions to the newly-connected node.
|
||||||
if self.target_peers.contains(id) {
|
if self.target_peers.contains(&peer_id) {
|
||||||
for topic in self.subscribed_topics.iter().cloned() {
|
for topic in self.subscribed_topics.iter().cloned() {
|
||||||
self.events
|
self.events
|
||||||
.push_back(NetworkBehaviourAction::NotifyHandler {
|
.push_back(NetworkBehaviourAction::NotifyHandler {
|
||||||
peer_id: *id,
|
peer_id,
|
||||||
handler: NotifyHandler::Any,
|
handler: NotifyHandler::Any,
|
||||||
event: FloodsubRpc {
|
event: FloodsubRpc {
|
||||||
messages: Vec::new(),
|
messages: Vec::new(),
|
||||||
@ -317,41 +309,51 @@ impl NetworkBehaviour for Floodsub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.connected_peers.insert(*id, SmallVec::new());
|
self.connected_peers.insert(peer_id, SmallVec::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_closed(
|
fn on_connection_closed(
|
||||||
&mut self,
|
&mut self,
|
||||||
id: &PeerId,
|
ConnectionClosed {
|
||||||
_: &ConnectionId,
|
peer_id,
|
||||||
_: &ConnectedPoint,
|
remaining_established,
|
||||||
_: Self::ConnectionHandler,
|
..
|
||||||
remaining_established: usize,
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
) {
|
) {
|
||||||
if remaining_established > 0 {
|
if remaining_established > 0 {
|
||||||
// we only care about peer disconnections
|
// we only care about peer disconnections
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let was_in = self.connected_peers.remove(id);
|
let was_in = self.connected_peers.remove(&peer_id);
|
||||||
debug_assert!(was_in.is_some());
|
debug_assert!(was_in.is_some());
|
||||||
|
|
||||||
// We can be disconnected by the remote in case of inactivity for example, so we always
|
// We can be disconnected by the remote in case of inactivity for example, so we always
|
||||||
// try to reconnect.
|
// try to reconnect.
|
||||||
if self.target_peers.contains(id) {
|
if self.target_peers.contains(&peer_id) {
|
||||||
let handler = self.new_handler();
|
let handler = self.new_handler();
|
||||||
self.events.push_back(NetworkBehaviourAction::Dial {
|
self.events.push_back(NetworkBehaviourAction::Dial {
|
||||||
opts: DialOpts::peer_id(*id).build(),
|
opts: DialOpts::peer_id(peer_id).build(),
|
||||||
handler,
|
handler,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn inject_event(
|
impl NetworkBehaviour for Floodsub {
|
||||||
|
type ConnectionHandler = OneShotHandler<FloodsubProtocol, FloodsubRpc, InnerMessage>;
|
||||||
|
type OutEvent = FloodsubEvent;
|
||||||
|
|
||||||
|
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
propagation_source: PeerId,
|
propagation_source: PeerId,
|
||||||
_connection: ConnectionId,
|
_connection_id: ConnectionId,
|
||||||
event: InnerMessage,
|
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
|
||||||
|
ConnectionHandler>::OutEvent,
|
||||||
) {
|
) {
|
||||||
// We ignore successful sends or timeouts.
|
// We ignore successful sends or timeouts.
|
||||||
let event = match event {
|
let event = match event {
|
||||||
@ -477,6 +479,27 @@ impl NetworkBehaviour for Floodsub {
|
|||||||
|
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(connection_established) => {
|
||||||
|
self.on_connection_established(connection_established)
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
|
self.on_connection_closed(connection_closed)
|
||||||
|
}
|
||||||
|
FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transmission between the `OneShotHandler` and the `FloodsubHandler`.
|
/// Transmission between the `OneShotHandler` and the `FloodsubHandler`.
|
||||||
|
@ -8,7 +8,11 @@
|
|||||||
|
|
||||||
- Refactoring GossipsubCodec to use common protobuf Codec. See [PR 3070].
|
- Refactoring GossipsubCodec to use common protobuf Codec. See [PR 3070].
|
||||||
|
|
||||||
|
- Replace `Gossipsub`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
[PR 3070]: https://github.com/libp2p/rust-libp2p/pull/3070
|
[PR 3070]: https://github.com/libp2p/rust-libp2p/pull/3070
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
|
|
||||||
# 0.42.0
|
# 0.42.0
|
||||||
|
|
||||||
|
@ -38,10 +38,12 @@ use rand::{seq::SliceRandom, thread_rng};
|
|||||||
|
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
connection::ConnectionId, identity::Keypair, multiaddr::Protocol::Ip4,
|
connection::ConnectionId, identity::Keypair, multiaddr::Protocol::Ip4,
|
||||||
multiaddr::Protocol::Ip6, ConnectedPoint, Multiaddr, PeerId,
|
multiaddr::Protocol::Ip6, Multiaddr, PeerId,
|
||||||
};
|
};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
dial_opts::DialOpts, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction,
|
behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm},
|
||||||
|
dial_opts::DialOpts,
|
||||||
|
ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction,
|
||||||
NotifyHandler, PollParameters,
|
NotifyHandler, PollParameters,
|
||||||
};
|
};
|
||||||
use wasm_timer::Instant;
|
use wasm_timer::Instant;
|
||||||
@ -3028,6 +3030,261 @@ where
|
|||||||
|
|
||||||
Ok(rpc_list)
|
Ok(rpc_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_connection_established(
|
||||||
|
&mut self,
|
||||||
|
ConnectionEstablished {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
other_established,
|
||||||
|
..
|
||||||
|
}: ConnectionEstablished,
|
||||||
|
) {
|
||||||
|
// Diverging from the go implementation we only want to consider a peer as outbound peer
|
||||||
|
// if its first connection is outbound.
|
||||||
|
|
||||||
|
if endpoint.is_dialer() && other_established == 0 && !self.px_peers.contains(&peer_id) {
|
||||||
|
// The first connection is outbound and it is not a peer from peer exchange => mark
|
||||||
|
// it as outbound peer
|
||||||
|
self.outbound_peers.insert(peer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the IP to the peer scoring system
|
||||||
|
if let Some((peer_score, ..)) = &mut self.peer_score {
|
||||||
|
if let Some(ip) = get_ip_addr(endpoint.get_remote_address()) {
|
||||||
|
peer_score.add_ip(&peer_id, ip);
|
||||||
|
} else {
|
||||||
|
trace!(
|
||||||
|
"Couldn't extract ip from endpoint of peer {} with endpoint {:?}",
|
||||||
|
peer_id,
|
||||||
|
endpoint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// By default we assume a peer is only a floodsub peer.
|
||||||
|
//
|
||||||
|
// The protocol negotiation occurs once a message is sent/received. Once this happens we
|
||||||
|
// update the type of peer that this is in order to determine which kind of routing should
|
||||||
|
// occur.
|
||||||
|
self.connected_peers
|
||||||
|
.entry(peer_id)
|
||||||
|
.or_insert(PeerConnections {
|
||||||
|
kind: PeerKind::Floodsub,
|
||||||
|
connections: vec![],
|
||||||
|
})
|
||||||
|
.connections
|
||||||
|
.push(connection_id);
|
||||||
|
|
||||||
|
if other_established == 0 {
|
||||||
|
// Ignore connections from blacklisted peers.
|
||||||
|
if self.blacklisted_peers.contains(&peer_id) {
|
||||||
|
debug!("Ignoring connection from blacklisted peer: {}", peer_id);
|
||||||
|
} else {
|
||||||
|
debug!("New peer connected: {}", peer_id);
|
||||||
|
// We need to send our subscriptions to the newly-connected node.
|
||||||
|
let mut subscriptions = vec![];
|
||||||
|
for topic_hash in self.mesh.keys() {
|
||||||
|
subscriptions.push(GossipsubSubscription {
|
||||||
|
topic_hash: topic_hash.clone(),
|
||||||
|
action: GossipsubSubscriptionAction::Subscribe,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if !subscriptions.is_empty() {
|
||||||
|
// send our subscriptions to the peer
|
||||||
|
if self
|
||||||
|
.send_message(
|
||||||
|
peer_id,
|
||||||
|
GossipsubRpc {
|
||||||
|
messages: Vec::new(),
|
||||||
|
subscriptions,
|
||||||
|
control_msgs: Vec::new(),
|
||||||
|
}
|
||||||
|
.into_protobuf(),
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
error!("Failed to send subscriptions, message too large");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert an empty set of the topics of this peer until known.
|
||||||
|
self.peer_topics.insert(peer_id, Default::default());
|
||||||
|
|
||||||
|
if let Some((peer_score, ..)) = &mut self.peer_score {
|
||||||
|
peer_score.add_peer(peer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_closed(
|
||||||
|
&mut self,
|
||||||
|
ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
remaining_established,
|
||||||
|
..
|
||||||
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
|
) {
|
||||||
|
// Remove IP from peer scoring system
|
||||||
|
if let Some((peer_score, ..)) = &mut self.peer_score {
|
||||||
|
if let Some(ip) = get_ip_addr(endpoint.get_remote_address()) {
|
||||||
|
peer_score.remove_ip(&peer_id, &ip);
|
||||||
|
} else {
|
||||||
|
trace!(
|
||||||
|
"Couldn't extract ip from endpoint of peer {} with endpoint {:?}",
|
||||||
|
peer_id,
|
||||||
|
endpoint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if remaining_established != 0 {
|
||||||
|
// Remove the connection from the list
|
||||||
|
if let Some(connections) = self.connected_peers.get_mut(&peer_id) {
|
||||||
|
let index = connections
|
||||||
|
.connections
|
||||||
|
.iter()
|
||||||
|
.position(|v| v == &connection_id)
|
||||||
|
.expect("Previously established connection to peer must be present");
|
||||||
|
connections.connections.remove(index);
|
||||||
|
|
||||||
|
// If there are more connections and this peer is in a mesh, inform the first connection
|
||||||
|
// handler.
|
||||||
|
if !connections.connections.is_empty() {
|
||||||
|
if let Some(topics) = self.peer_topics.get(&peer_id) {
|
||||||
|
for topic in topics {
|
||||||
|
if let Some(mesh_peers) = self.mesh.get(topic) {
|
||||||
|
if mesh_peers.contains(&peer_id) {
|
||||||
|
self.events
|
||||||
|
.push_back(NetworkBehaviourAction::NotifyHandler {
|
||||||
|
peer_id,
|
||||||
|
event: Arc::new(GossipsubHandlerIn::JoinedMesh),
|
||||||
|
handler: NotifyHandler::One(connections.connections[0]),
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// remove from mesh, topic_peers, peer_topic and the fanout
|
||||||
|
debug!("Peer disconnected: {}", peer_id);
|
||||||
|
{
|
||||||
|
let topics = match self.peer_topics.get(&peer_id) {
|
||||||
|
Some(topics) => topics,
|
||||||
|
None => {
|
||||||
|
debug_assert!(
|
||||||
|
self.blacklisted_peers.contains(&peer_id),
|
||||||
|
"Disconnected node not in connected list"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// remove peer from all mappings
|
||||||
|
for topic in topics {
|
||||||
|
// check the mesh for the topic
|
||||||
|
if let Some(mesh_peers) = self.mesh.get_mut(topic) {
|
||||||
|
// check if the peer is in the mesh and remove it
|
||||||
|
if mesh_peers.remove(&peer_id) {
|
||||||
|
if let Some(m) = self.metrics.as_mut() {
|
||||||
|
m.peers_removed(topic, Churn::Dc, 1);
|
||||||
|
m.set_mesh_peers(topic, mesh_peers.len());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from topic_peers
|
||||||
|
if let Some(peer_list) = self.topic_peers.get_mut(topic) {
|
||||||
|
if !peer_list.remove(&peer_id) {
|
||||||
|
// debugging purposes
|
||||||
|
warn!(
|
||||||
|
"Disconnected node: {} not in topic_peers peer list",
|
||||||
|
peer_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(m) = self.metrics.as_mut() {
|
||||||
|
m.set_topic_peers(topic, peer_list.len())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"Disconnected node: {} with topic: {:?} not in topic_peers",
|
||||||
|
&peer_id, &topic
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from fanout
|
||||||
|
self.fanout
|
||||||
|
.get_mut(topic)
|
||||||
|
.map(|peers| peers.remove(&peer_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forget px and outbound status for this peer
|
||||||
|
self.px_peers.remove(&peer_id);
|
||||||
|
self.outbound_peers.remove(&peer_id);
|
||||||
|
|
||||||
|
// Remove peer from peer_topics and connected_peers
|
||||||
|
// NOTE: It is possible the peer has already been removed from all mappings if it does not
|
||||||
|
// support the protocol.
|
||||||
|
self.peer_topics.remove(&peer_id);
|
||||||
|
|
||||||
|
// If metrics are enabled, register the disconnection of a peer based on its protocol.
|
||||||
|
if let Some(metrics) = self.metrics.as_mut() {
|
||||||
|
let peer_kind = &self
|
||||||
|
.connected_peers
|
||||||
|
.get(&peer_id)
|
||||||
|
.expect("Connected peer must be registered")
|
||||||
|
.kind;
|
||||||
|
metrics.peer_protocol_disconnected(peer_kind.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.connected_peers.remove(&peer_id);
|
||||||
|
|
||||||
|
if let Some((peer_score, ..)) = &mut self.peer_score {
|
||||||
|
peer_score.remove_peer(&peer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_address_change(
|
||||||
|
&mut self,
|
||||||
|
AddressChange {
|
||||||
|
peer_id,
|
||||||
|
old: endpoint_old,
|
||||||
|
new: endpoint_new,
|
||||||
|
..
|
||||||
|
}: AddressChange,
|
||||||
|
) {
|
||||||
|
// Exchange IP in peer scoring system
|
||||||
|
if let Some((peer_score, ..)) = &mut self.peer_score {
|
||||||
|
if let Some(ip) = get_ip_addr(endpoint_old.get_remote_address()) {
|
||||||
|
peer_score.remove_ip(&peer_id, &ip);
|
||||||
|
} else {
|
||||||
|
trace!(
|
||||||
|
"Couldn't extract ip from endpoint of peer {} with endpoint {:?}",
|
||||||
|
&peer_id,
|
||||||
|
endpoint_old
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if let Some(ip) = get_ip_addr(endpoint_new.get_remote_address()) {
|
||||||
|
peer_score.add_ip(&peer_id, ip);
|
||||||
|
} else {
|
||||||
|
trace!(
|
||||||
|
"Couldn't extract ip from endpoint of peer {} with endpoint {:?}",
|
||||||
|
peer_id,
|
||||||
|
endpoint_new
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ip_addr(addr: &Multiaddr) -> Option<IpAddr> {
|
fn get_ip_addr(addr: &Multiaddr) -> Option<IpAddr> {
|
||||||
@ -3058,260 +3315,12 @@ where
|
|||||||
GossipsubHandler::new(protocol_config, self.config.idle_timeout())
|
GossipsubHandler::new(protocol_config, self.config.idle_timeout())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_established(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
connection_id: &ConnectionId,
|
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
_: Option<&Vec<Multiaddr>>,
|
|
||||||
other_established: usize,
|
|
||||||
) {
|
|
||||||
// Diverging from the go implementation we only want to consider a peer as outbound peer
|
|
||||||
// if its first connection is outbound.
|
|
||||||
|
|
||||||
if endpoint.is_dialer() && other_established == 0 && !self.px_peers.contains(peer_id) {
|
|
||||||
// The first connection is outbound and it is not a peer from peer exchange => mark
|
|
||||||
// it as outbound peer
|
|
||||||
self.outbound_peers.insert(*peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the IP to the peer scoring system
|
|
||||||
if let Some((peer_score, ..)) = &mut self.peer_score {
|
|
||||||
if let Some(ip) = get_ip_addr(endpoint.get_remote_address()) {
|
|
||||||
peer_score.add_ip(peer_id, ip);
|
|
||||||
} else {
|
|
||||||
trace!(
|
|
||||||
"Couldn't extract ip from endpoint of peer {} with endpoint {:?}",
|
|
||||||
peer_id,
|
|
||||||
endpoint
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// By default we assume a peer is only a floodsub peer.
|
|
||||||
//
|
|
||||||
// The protocol negotiation occurs once a message is sent/received. Once this happens we
|
|
||||||
// update the type of peer that this is in order to determine which kind of routing should
|
|
||||||
// occur.
|
|
||||||
self.connected_peers
|
|
||||||
.entry(*peer_id)
|
|
||||||
.or_insert(PeerConnections {
|
|
||||||
kind: PeerKind::Floodsub,
|
|
||||||
connections: vec![],
|
|
||||||
})
|
|
||||||
.connections
|
|
||||||
.push(*connection_id);
|
|
||||||
|
|
||||||
if other_established == 0 {
|
|
||||||
// Ignore connections from blacklisted peers.
|
|
||||||
if self.blacklisted_peers.contains(peer_id) {
|
|
||||||
debug!("Ignoring connection from blacklisted peer: {}", peer_id);
|
|
||||||
} else {
|
|
||||||
debug!("New peer connected: {}", peer_id);
|
|
||||||
// We need to send our subscriptions to the newly-connected node.
|
|
||||||
let mut subscriptions = vec![];
|
|
||||||
for topic_hash in self.mesh.keys() {
|
|
||||||
subscriptions.push(GossipsubSubscription {
|
|
||||||
topic_hash: topic_hash.clone(),
|
|
||||||
action: GossipsubSubscriptionAction::Subscribe,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if !subscriptions.is_empty() {
|
|
||||||
// send our subscriptions to the peer
|
|
||||||
if self
|
|
||||||
.send_message(
|
|
||||||
*peer_id,
|
|
||||||
GossipsubRpc {
|
|
||||||
messages: Vec::new(),
|
|
||||||
subscriptions,
|
|
||||||
control_msgs: Vec::new(),
|
|
||||||
}
|
|
||||||
.into_protobuf(),
|
|
||||||
)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
error!("Failed to send subscriptions, message too large");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert an empty set of the topics of this peer until known.
|
|
||||||
self.peer_topics.insert(*peer_id, Default::default());
|
|
||||||
|
|
||||||
if let Some((peer_score, ..)) = &mut self.peer_score {
|
|
||||||
peer_score.add_peer(*peer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_closed(
|
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
connection_id: &ConnectionId,
|
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
_: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
|
||||||
remaining_established: usize,
|
|
||||||
) {
|
|
||||||
// Remove IP from peer scoring system
|
|
||||||
if let Some((peer_score, ..)) = &mut self.peer_score {
|
|
||||||
if let Some(ip) = get_ip_addr(endpoint.get_remote_address()) {
|
|
||||||
peer_score.remove_ip(peer_id, &ip);
|
|
||||||
} else {
|
|
||||||
trace!(
|
|
||||||
"Couldn't extract ip from endpoint of peer {} with endpoint {:?}",
|
|
||||||
peer_id,
|
|
||||||
endpoint
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if remaining_established != 0 {
|
|
||||||
// Remove the connection from the list
|
|
||||||
if let Some(connections) = self.connected_peers.get_mut(peer_id) {
|
|
||||||
let index = connections
|
|
||||||
.connections
|
|
||||||
.iter()
|
|
||||||
.position(|v| v == connection_id)
|
|
||||||
.expect("Previously established connection to peer must be present");
|
|
||||||
connections.connections.remove(index);
|
|
||||||
|
|
||||||
// If there are more connections and this peer is in a mesh, inform the first connection
|
|
||||||
// handler.
|
|
||||||
if !connections.connections.is_empty() {
|
|
||||||
if let Some(topics) = self.peer_topics.get(peer_id) {
|
|
||||||
for topic in topics {
|
|
||||||
if let Some(mesh_peers) = self.mesh.get(topic) {
|
|
||||||
if mesh_peers.contains(peer_id) {
|
|
||||||
self.events
|
|
||||||
.push_back(NetworkBehaviourAction::NotifyHandler {
|
|
||||||
peer_id: *peer_id,
|
|
||||||
event: Arc::new(GossipsubHandlerIn::JoinedMesh),
|
|
||||||
handler: NotifyHandler::One(connections.connections[0]),
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// remove from mesh, topic_peers, peer_topic and the fanout
|
|
||||||
debug!("Peer disconnected: {}", peer_id);
|
|
||||||
{
|
|
||||||
let topics = match self.peer_topics.get(peer_id) {
|
|
||||||
Some(topics) => topics,
|
|
||||||
None => {
|
|
||||||
debug_assert!(
|
|
||||||
self.blacklisted_peers.contains(peer_id),
|
|
||||||
"Disconnected node not in connected list"
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// remove peer from all mappings
|
|
||||||
for topic in topics {
|
|
||||||
// check the mesh for the topic
|
|
||||||
if let Some(mesh_peers) = self.mesh.get_mut(topic) {
|
|
||||||
// check if the peer is in the mesh and remove it
|
|
||||||
if mesh_peers.remove(peer_id) {
|
|
||||||
if let Some(m) = self.metrics.as_mut() {
|
|
||||||
m.peers_removed(topic, Churn::Dc, 1);
|
|
||||||
m.set_mesh_peers(topic, mesh_peers.len());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove from topic_peers
|
|
||||||
if let Some(peer_list) = self.topic_peers.get_mut(topic) {
|
|
||||||
if !peer_list.remove(peer_id) {
|
|
||||||
// debugging purposes
|
|
||||||
warn!(
|
|
||||||
"Disconnected node: {} not in topic_peers peer list",
|
|
||||||
peer_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some(m) = self.metrics.as_mut() {
|
|
||||||
m.set_topic_peers(topic, peer_list.len())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!(
|
|
||||||
"Disconnected node: {} with topic: {:?} not in topic_peers",
|
|
||||||
&peer_id, &topic
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove from fanout
|
|
||||||
self.fanout
|
|
||||||
.get_mut(topic)
|
|
||||||
.map(|peers| peers.remove(peer_id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forget px and outbound status for this peer
|
|
||||||
self.px_peers.remove(peer_id);
|
|
||||||
self.outbound_peers.remove(peer_id);
|
|
||||||
|
|
||||||
// Remove peer from peer_topics and connected_peers
|
|
||||||
// NOTE: It is possible the peer has already been removed from all mappings if it does not
|
|
||||||
// support the protocol.
|
|
||||||
self.peer_topics.remove(peer_id);
|
|
||||||
|
|
||||||
// If metrics are enabled, register the disconnection of a peer based on its protocol.
|
|
||||||
if let Some(metrics) = self.metrics.as_mut() {
|
|
||||||
let peer_kind = &self
|
|
||||||
.connected_peers
|
|
||||||
.get(peer_id)
|
|
||||||
.expect("Connected peer must be registered")
|
|
||||||
.kind;
|
|
||||||
metrics.peer_protocol_disconnected(peer_kind.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.connected_peers.remove(peer_id);
|
|
||||||
|
|
||||||
if let Some((peer_score, ..)) = &mut self.peer_score {
|
|
||||||
peer_score.remove_peer(peer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_address_change(
|
|
||||||
&mut self,
|
|
||||||
peer: &PeerId,
|
|
||||||
_: &ConnectionId,
|
|
||||||
endpoint_old: &ConnectedPoint,
|
|
||||||
endpoint_new: &ConnectedPoint,
|
|
||||||
) {
|
|
||||||
// Exchange IP in peer scoring system
|
|
||||||
if let Some((peer_score, ..)) = &mut self.peer_score {
|
|
||||||
if let Some(ip) = get_ip_addr(endpoint_old.get_remote_address()) {
|
|
||||||
peer_score.remove_ip(peer, &ip);
|
|
||||||
} else {
|
|
||||||
trace!(
|
|
||||||
"Couldn't extract ip from endpoint of peer {} with endpoint {:?}",
|
|
||||||
peer,
|
|
||||||
endpoint_old
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if let Some(ip) = get_ip_addr(endpoint_new.get_remote_address()) {
|
|
||||||
peer_score.add_ip(peer, ip);
|
|
||||||
} else {
|
|
||||||
trace!(
|
|
||||||
"Couldn't extract ip from endpoint of peer {} with endpoint {:?}",
|
|
||||||
peer,
|
|
||||||
endpoint_new
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_event(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
propagation_source: PeerId,
|
propagation_source: PeerId,
|
||||||
_: ConnectionId,
|
_connection_id: ConnectionId,
|
||||||
handler_event: HandlerEvent,
|
handler_event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
|
||||||
|
ConnectionHandler>::OutEvent,
|
||||||
) {
|
) {
|
||||||
match handler_event {
|
match handler_event {
|
||||||
HandlerEvent::PeerKind(kind) => {
|
HandlerEvent::PeerKind(kind) => {
|
||||||
@ -3333,7 +3342,8 @@ where
|
|||||||
));
|
));
|
||||||
} else if let Some(conn) = self.connected_peers.get_mut(&propagation_source) {
|
} else if let Some(conn) = self.connected_peers.get_mut(&propagation_source) {
|
||||||
// Only change the value if the old value is Floodsub (the default set in
|
// Only change the value if the old value is Floodsub (the default set in
|
||||||
// inject_connection_established). All other PeerKind changes are ignored.
|
// `NetworkBehaviour::on_event` with FromSwarm::ConnectionEstablished).
|
||||||
|
// All other PeerKind changes are ignored.
|
||||||
debug!(
|
debug!(
|
||||||
"New peer type found: {} for peer: {}",
|
"New peer type found: {} for peer: {}",
|
||||||
kind, propagation_source
|
kind, propagation_source
|
||||||
@ -3458,6 +3468,27 @@ where
|
|||||||
|
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(connection_established) => {
|
||||||
|
self.on_connection_established(connection_established)
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
|
self.on_connection_closed(connection_closed)
|
||||||
|
}
|
||||||
|
FromSwarm::AddressChange(address_change) => self.on_address_change(address_change),
|
||||||
|
FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called when peers are added to any mesh. It checks if the peer existed
|
/// This is called when peers are added to any mesh. It checks if the peer existed
|
||||||
|
@ -31,7 +31,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use async_std::net::Ipv4Addr;
|
use async_std::net::Ipv4Addr;
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
use libp2p_core::Endpoint;
|
use libp2p_core::{ConnectedPoint, Endpoint};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
@ -181,25 +181,27 @@ where
|
|||||||
F: TopicSubscriptionFilter + Clone + Default + Send + 'static,
|
F: TopicSubscriptionFilter + Clone + Default + Send + 'static,
|
||||||
{
|
{
|
||||||
let peer = PeerId::random();
|
let peer = PeerId::random();
|
||||||
gs.inject_connection_established(
|
let endpoint = if outbound {
|
||||||
&peer,
|
ConnectedPoint::Dialer {
|
||||||
&ConnectionId::new(0),
|
address,
|
||||||
&if outbound {
|
role_override: Endpoint::Dialer,
|
||||||
ConnectedPoint::Dialer {
|
}
|
||||||
address,
|
} else {
|
||||||
role_override: Endpoint::Dialer,
|
ConnectedPoint::Listener {
|
||||||
}
|
local_addr: Multiaddr::empty(),
|
||||||
} else {
|
send_back_addr: address,
|
||||||
ConnectedPoint::Listener {
|
}
|
||||||
local_addr: Multiaddr::empty(),
|
};
|
||||||
send_back_addr: address,
|
|
||||||
}
|
gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
},
|
peer_id: peer,
|
||||||
None,
|
connection_id: ConnectionId::new(0),
|
||||||
0, // first connection
|
endpoint: &endpoint,
|
||||||
);
|
failed_addresses: &[],
|
||||||
|
other_established: 0, // first connection
|
||||||
|
}));
|
||||||
if let Some(kind) = kind {
|
if let Some(kind) = kind {
|
||||||
gs.inject_event(peer, ConnectionId::new(1), HandlerEvent::PeerKind(kind));
|
gs.on_connection_handler_event(peer, ConnectionId::new(1), HandlerEvent::PeerKind(kind));
|
||||||
}
|
}
|
||||||
if explicit {
|
if explicit {
|
||||||
gs.add_explicit_peer(&peer);
|
gs.add_explicit_peer(&peer);
|
||||||
@ -232,16 +234,16 @@ where
|
|||||||
}; // this is not relevant
|
}; // this is not relevant
|
||||||
// peer_connections.connections should never be empty.
|
// peer_connections.connections should never be empty.
|
||||||
let mut active_connections = peer_connections.connections.len();
|
let mut active_connections = peer_connections.connections.len();
|
||||||
for conn_id in peer_connections.connections.clone() {
|
for connection_id in peer_connections.connections.clone() {
|
||||||
let handler = gs.new_handler();
|
let handler = gs.new_handler();
|
||||||
active_connections = active_connections.checked_sub(1).unwrap();
|
active_connections = active_connections.checked_sub(1).unwrap();
|
||||||
gs.inject_connection_closed(
|
gs.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
peer_id,
|
peer_id: *peer_id,
|
||||||
&conn_id,
|
connection_id,
|
||||||
&fake_endpoint,
|
endpoint: &fake_endpoint,
|
||||||
handler,
|
handler,
|
||||||
active_connections,
|
remaining_established: active_connections,
|
||||||
);
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,16 +547,16 @@ fn test_join() {
|
|||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
let random_peer = PeerId::random();
|
let random_peer = PeerId::random();
|
||||||
// inform the behaviour of a new peer
|
// inform the behaviour of a new peer
|
||||||
gs.inject_connection_established(
|
gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
&random_peer,
|
peer_id: random_peer,
|
||||||
&ConnectionId::new(1),
|
connection_id: ConnectionId::new(1),
|
||||||
&ConnectedPoint::Dialer {
|
endpoint: &ConnectedPoint::Dialer {
|
||||||
address: "/ip4/127.0.0.1".parse::<Multiaddr>().unwrap(),
|
address: "/ip4/127.0.0.1".parse::<Multiaddr>().unwrap(),
|
||||||
role_override: Endpoint::Dialer,
|
role_override: Endpoint::Dialer,
|
||||||
},
|
},
|
||||||
None,
|
failed_addresses: &[],
|
||||||
0,
|
other_established: 0,
|
||||||
);
|
}));
|
||||||
|
|
||||||
// add the new peer to the fanout
|
// add the new peer to the fanout
|
||||||
let fanout_peers = gs.fanout.get_mut(&topic_hashes[1]).unwrap();
|
let fanout_peers = gs.fanout.get_mut(&topic_hashes[1]).unwrap();
|
||||||
@ -2349,12 +2351,6 @@ fn test_add_outbound_peers_if_min_is_not_satisfied() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO add a test that ensures that new outbound connections are recognized as such.
|
|
||||||
// This is at the moment done in behaviour with relying on the fact that the call to
|
|
||||||
// `inject_connection_established` for the first connection is done before `inject_connected`
|
|
||||||
// gets called. For all further connections `inject_connection_established` should get called
|
|
||||||
// after `inject_connected`.
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_prune_negative_scored_peers() {
|
fn test_prune_negative_scored_peers() {
|
||||||
let config = GossipsubConfig::default();
|
let config = GossipsubConfig::default();
|
||||||
@ -2983,7 +2979,7 @@ fn test_ignore_rpc_from_peers_below_graylist_threshold() {
|
|||||||
gs.events.clear();
|
gs.events.clear();
|
||||||
|
|
||||||
//receive from p1
|
//receive from p1
|
||||||
gs.inject_event(
|
gs.on_connection_handler_event(
|
||||||
p1,
|
p1,
|
||||||
ConnectionId::new(0),
|
ConnectionId::new(0),
|
||||||
HandlerEvent::Message {
|
HandlerEvent::Message {
|
||||||
@ -3009,7 +3005,7 @@ fn test_ignore_rpc_from_peers_below_graylist_threshold() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//receive from p2
|
//receive from p2
|
||||||
gs.inject_event(
|
gs.on_connection_handler_event(
|
||||||
p2,
|
p2,
|
||||||
ConnectionId::new(0),
|
ConnectionId::new(0),
|
||||||
HandlerEvent::Message {
|
HandlerEvent::Message {
|
||||||
@ -3621,7 +3617,7 @@ fn test_scoring_p4_invalid_signature() {
|
|||||||
//peer 0 delivers message with invalid signature
|
//peer 0 delivers message with invalid signature
|
||||||
let m = random_message(&mut seq, &topics);
|
let m = random_message(&mut seq, &topics);
|
||||||
|
|
||||||
gs.inject_event(
|
gs.on_connection_handler_event(
|
||||||
peers[0],
|
peers[0],
|
||||||
ConnectionId::new(0),
|
ConnectionId::new(0),
|
||||||
HandlerEvent::Message {
|
HandlerEvent::Message {
|
||||||
@ -4105,16 +4101,16 @@ fn test_scoring_p6() {
|
|||||||
|
|
||||||
//add additional connection for 3 others with addr
|
//add additional connection for 3 others with addr
|
||||||
for id in others.iter().take(3) {
|
for id in others.iter().take(3) {
|
||||||
gs.inject_connection_established(
|
gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
id,
|
peer_id: *id,
|
||||||
&ConnectionId::new(0),
|
connection_id: ConnectionId::new(0),
|
||||||
&ConnectedPoint::Dialer {
|
endpoint: &ConnectedPoint::Dialer {
|
||||||
address: addr.clone(),
|
address: addr.clone(),
|
||||||
role_override: Endpoint::Dialer,
|
role_override: Endpoint::Dialer,
|
||||||
},
|
},
|
||||||
None,
|
failed_addresses: &[],
|
||||||
0,
|
other_established: 0,
|
||||||
);
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
//penalties apply squared
|
//penalties apply squared
|
||||||
@ -4126,16 +4122,16 @@ fn test_scoring_p6() {
|
|||||||
|
|
||||||
//add additional connection for 3 of the peers to addr2
|
//add additional connection for 3 of the peers to addr2
|
||||||
for peer in peers.iter().take(3) {
|
for peer in peers.iter().take(3) {
|
||||||
gs.inject_connection_established(
|
gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
peer,
|
peer_id: *peer,
|
||||||
&ConnectionId::new(0),
|
connection_id: ConnectionId::new(0),
|
||||||
&ConnectedPoint::Dialer {
|
endpoint: &ConnectedPoint::Dialer {
|
||||||
address: addr2.clone(),
|
address: addr2.clone(),
|
||||||
role_override: Endpoint::Dialer,
|
role_override: Endpoint::Dialer,
|
||||||
},
|
},
|
||||||
None,
|
failed_addresses: &[],
|
||||||
1,
|
other_established: 1,
|
||||||
);
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
//double penalties for the first three of each
|
//double penalties for the first three of each
|
||||||
@ -4156,16 +4152,16 @@ fn test_scoring_p6() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
//two times same ip doesn't count twice
|
//two times same ip doesn't count twice
|
||||||
gs.inject_connection_established(
|
gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
&peers[0],
|
peer_id: peers[0],
|
||||||
&ConnectionId::new(0),
|
connection_id: ConnectionId::new(0),
|
||||||
&ConnectedPoint::Dialer {
|
endpoint: &ConnectedPoint::Dialer {
|
||||||
address: addr,
|
address: addr,
|
||||||
role_override: Endpoint::Dialer,
|
role_override: Endpoint::Dialer,
|
||||||
},
|
},
|
||||||
None,
|
failed_addresses: &[],
|
||||||
2,
|
other_established: 2,
|
||||||
);
|
}));
|
||||||
|
|
||||||
//nothing changed
|
//nothing changed
|
||||||
//double penalties for the first three of each
|
//double penalties for the first three of each
|
||||||
@ -5203,7 +5199,7 @@ fn test_subscribe_and_graft_with_negative_score() {
|
|||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
for message in messages_to_p1 {
|
for message in messages_to_p1 {
|
||||||
gs1.inject_event(
|
gs1.on_connection_handler_event(
|
||||||
p2,
|
p2,
|
||||||
connection_id,
|
connection_id,
|
||||||
HandlerEvent::Message {
|
HandlerEvent::Message {
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `Behaviour`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
[PR 2995]: https://github.com/libp2p/rust-libp2p/pull/2995
|
[PR 2995]: https://github.com/libp2p/rust-libp2p/pull/2995
|
||||||
|
|
||||||
# 0.40.0
|
# 0.40.0
|
||||||
|
@ -22,9 +22,9 @@ use crate::handler::{self, Proto, Push};
|
|||||||
use crate::protocol::{Info, ReplySubstream, UpgradeError};
|
use crate::protocol::{Info, ReplySubstream, UpgradeError};
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
connection::ConnectionId, multiaddr::Protocol, transport::ListenerId, ConnectedPoint,
|
connection::ConnectionId, multiaddr::Protocol, ConnectedPoint, Multiaddr, PeerId, PublicKey,
|
||||||
Multiaddr, PeerId, PublicKey,
|
|
||||||
};
|
};
|
||||||
|
use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError,
|
dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError,
|
||||||
IntoConnectionHandler, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction,
|
IntoConnectionHandler, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction,
|
||||||
@ -206,6 +206,33 @@ impl Behaviour {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_connection_established(
|
||||||
|
&mut self,
|
||||||
|
ConnectionEstablished {
|
||||||
|
peer_id,
|
||||||
|
connection_id: conn,
|
||||||
|
endpoint,
|
||||||
|
failed_addresses,
|
||||||
|
..
|
||||||
|
}: ConnectionEstablished,
|
||||||
|
) {
|
||||||
|
let addr = match endpoint {
|
||||||
|
ConnectedPoint::Dialer { address, .. } => address.clone(),
|
||||||
|
ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.connected
|
||||||
|
.entry(peer_id)
|
||||||
|
.or_default()
|
||||||
|
.insert(conn, addr);
|
||||||
|
|
||||||
|
if let Some(entry) = self.discovered_peers.get_mut(&peer_id) {
|
||||||
|
for addr in failed_addresses {
|
||||||
|
entry.remove(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkBehaviour for Behaviour {
|
impl NetworkBehaviour for Behaviour {
|
||||||
@ -216,84 +243,7 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
Proto::new(self.config.initial_delay, self.config.interval)
|
Proto::new(self.config.initial_delay, self.config.interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_established(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
conn: &ConnectionId,
|
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
failed_addresses: Option<&Vec<Multiaddr>>,
|
|
||||||
_other_established: usize,
|
|
||||||
) {
|
|
||||||
let addr = match endpoint {
|
|
||||||
ConnectedPoint::Dialer { address, .. } => address.clone(),
|
|
||||||
ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.connected
|
|
||||||
.entry(*peer_id)
|
|
||||||
.or_default()
|
|
||||||
.insert(*conn, addr);
|
|
||||||
|
|
||||||
if let Some(entry) = self.discovered_peers.get_mut(peer_id) {
|
|
||||||
for addr in failed_addresses
|
|
||||||
.into_iter()
|
|
||||||
.flat_map(|addresses| addresses.iter())
|
|
||||||
{
|
|
||||||
entry.remove(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_closed(
|
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
conn: &ConnectionId,
|
|
||||||
_: &ConnectedPoint,
|
|
||||||
_: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
|
||||||
remaining_established: usize,
|
|
||||||
) {
|
|
||||||
if remaining_established == 0 {
|
|
||||||
self.connected.remove(peer_id);
|
|
||||||
self.pending_push.remove(peer_id);
|
|
||||||
} else if let Some(addrs) = self.connected.get_mut(peer_id) {
|
|
||||||
addrs.remove(conn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_dial_failure(
|
|
||||||
&mut self,
|
|
||||||
peer_id: Option<PeerId>,
|
|
||||||
_: Self::ConnectionHandler,
|
|
||||||
error: &DialError,
|
|
||||||
) {
|
|
||||||
if let Some(peer_id) = peer_id {
|
|
||||||
if !self.connected.contains_key(&peer_id) {
|
|
||||||
self.pending_push.remove(&peer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(entry) = peer_id.and_then(|id| self.discovered_peers.get_mut(&id)) {
|
|
||||||
if let DialError::Transport(errors) = error {
|
|
||||||
for (addr, _error) in errors {
|
|
||||||
entry.remove(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {
|
|
||||||
if self.config.push_listen_addr_updates {
|
|
||||||
self.pending_push.extend(self.connected.keys());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {
|
|
||||||
if self.config.push_listen_addr_updates {
|
|
||||||
self.pending_push.extend(self.connected.keys());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_event(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
connection: ConnectionId,
|
connection: ConnectionId,
|
||||||
@ -333,8 +283,9 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
.get(&peer_id)
|
.get(&peer_id)
|
||||||
.and_then(|addrs| addrs.get(&connection))
|
.and_then(|addrs| addrs.get(&connection))
|
||||||
.expect(
|
.expect(
|
||||||
"`inject_event` is only called with an established connection \
|
"`on_connection_handler_event` is only called \
|
||||||
and `inject_connection_established` ensures there is an entry; qed",
|
with an established connection and calling `NetworkBehaviour::on_event` \
|
||||||
|
with `FromSwarm::ConnectionEstablished ensures there is an entry; qed",
|
||||||
);
|
);
|
||||||
self.pending_replies.push_back(Reply::Queued {
|
self.pending_replies.push_back(Reply::Queued {
|
||||||
peer: peer_id,
|
peer: peer_id,
|
||||||
@ -452,6 +403,59 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec<Multiaddr> {
|
fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec<Multiaddr> {
|
||||||
self.discovered_peers.get(peer)
|
self.discovered_peers.get(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(connection_established) => {
|
||||||
|
self.on_connection_established(connection_established)
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
remaining_established,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
if remaining_established == 0 {
|
||||||
|
self.connected.remove(&peer_id);
|
||||||
|
self.pending_push.remove(&peer_id);
|
||||||
|
} else if let Some(addrs) = self.connected.get_mut(&peer_id) {
|
||||||
|
addrs.remove(&connection_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FromSwarm::DialFailure(DialFailure { peer_id, error, .. }) => {
|
||||||
|
if let Some(peer_id) = peer_id {
|
||||||
|
if !self.connected.contains_key(&peer_id) {
|
||||||
|
self.pending_push.remove(&peer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(entry) = peer_id.and_then(|id| self.discovered_peers.get_mut(&id)) {
|
||||||
|
if let DialError::Transport(errors) = error {
|
||||||
|
for (addr, _error) in errors {
|
||||||
|
entry.remove(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FromSwarm::NewListenAddr(_) => {
|
||||||
|
if self.config.push_listen_addr_updates {
|
||||||
|
self.pending_push.extend(self.connected.keys());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredListenAddr(_) => {
|
||||||
|
if self.config.push_listen_addr_updates {
|
||||||
|
self.pending_push.extend(self.connected.keys());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Event emitted by the `Identify` behaviour.
|
/// Event emitted by the `Identify` behaviour.
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `Kademlia`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
|
|
||||||
# 0.41.0
|
# 0.41.0
|
||||||
|
|
||||||
- Remove deprecated `set_protocol_name()` from `KademliaConfig` & `KademliaProtocolConfig`.
|
- Remove deprecated `set_protocol_name()` from `KademliaConfig` & `KademliaProtocolConfig`.
|
||||||
|
@ -39,8 +39,10 @@ use crate::record::{
|
|||||||
use crate::K_VALUE;
|
use crate::K_VALUE;
|
||||||
use fnv::{FnvHashMap, FnvHashSet};
|
use fnv::{FnvHashMap, FnvHashSet};
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use libp2p_core::{
|
use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId};
|
||||||
connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId,
|
use libp2p_swarm::behaviour::{
|
||||||
|
AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredListenAddr,
|
||||||
|
FromSwarm, NewExternalAddr, NewListenAddr,
|
||||||
};
|
};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
dial_opts::{self, DialOpts},
|
dial_opts::{self, DialOpts},
|
||||||
@ -1771,6 +1773,166 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_connection_established(
|
||||||
|
&mut self,
|
||||||
|
ConnectionEstablished {
|
||||||
|
peer_id,
|
||||||
|
failed_addresses,
|
||||||
|
other_established,
|
||||||
|
..
|
||||||
|
}: ConnectionEstablished,
|
||||||
|
) {
|
||||||
|
for addr in failed_addresses {
|
||||||
|
self.address_failed(peer_id, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When a connection is established, we don't know yet whether the
|
||||||
|
// remote supports the configured protocol name. Only once a connection
|
||||||
|
// handler reports [`KademliaHandlerEvent::ProtocolConfirmed`] do we
|
||||||
|
// update the local routing table.
|
||||||
|
|
||||||
|
// Peer's first connection.
|
||||||
|
if other_established == 0 {
|
||||||
|
// Queue events for sending pending RPCs to the connected peer.
|
||||||
|
// There can be only one pending RPC for a particular peer and query per definition.
|
||||||
|
for (peer_id, event) in self.queries.iter_mut().filter_map(|q| {
|
||||||
|
q.inner
|
||||||
|
.pending_rpcs
|
||||||
|
.iter()
|
||||||
|
.position(|(p, _)| p == &peer_id)
|
||||||
|
.map(|p| q.inner.pending_rpcs.remove(p))
|
||||||
|
}) {
|
||||||
|
self.queued_events
|
||||||
|
.push_back(NetworkBehaviourAction::NotifyHandler {
|
||||||
|
peer_id,
|
||||||
|
event,
|
||||||
|
handler: NotifyHandler::Any,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.connected_peers.insert(peer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_address_change(
|
||||||
|
&mut self,
|
||||||
|
AddressChange {
|
||||||
|
peer_id: peer,
|
||||||
|
old,
|
||||||
|
new,
|
||||||
|
..
|
||||||
|
}: AddressChange,
|
||||||
|
) {
|
||||||
|
let (old, new) = (old.get_remote_address(), new.get_remote_address());
|
||||||
|
|
||||||
|
// Update routing table.
|
||||||
|
if let Some(addrs) = self.kbuckets.entry(&kbucket::Key::from(peer)).value() {
|
||||||
|
if addrs.replace(old, new) {
|
||||||
|
debug!(
|
||||||
|
"Address '{}' replaced with '{}' for peer '{}'.",
|
||||||
|
old, new, peer
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
debug!(
|
||||||
|
"Address '{}' not replaced with '{}' for peer '{}' as old address wasn't \
|
||||||
|
present.",
|
||||||
|
old, new, peer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debug!(
|
||||||
|
"Address '{}' not replaced with '{}' for peer '{}' as peer is not present in the \
|
||||||
|
routing table.",
|
||||||
|
old, new, peer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update query address cache.
|
||||||
|
//
|
||||||
|
// Given two connected nodes: local node A and remote node B. Say node B
|
||||||
|
// is not in node A's routing table. Additionally node B is part of the
|
||||||
|
// `QueryInner::addresses` list of an ongoing query on node A. Say Node
|
||||||
|
// B triggers an address change and then disconnects. Later on the
|
||||||
|
// earlier mentioned query on node A would like to connect to node B.
|
||||||
|
// Without replacing the address in the `QueryInner::addresses` set node
|
||||||
|
// A would attempt to dial the old and not the new address.
|
||||||
|
//
|
||||||
|
// While upholding correctness, iterating through all discovered
|
||||||
|
// addresses of a peer in all currently ongoing queries might have a
|
||||||
|
// large performance impact. If so, the code below might be worth
|
||||||
|
// revisiting.
|
||||||
|
for query in self.queries.iter_mut() {
|
||||||
|
if let Some(addrs) = query.inner.addresses.get_mut(&peer) {
|
||||||
|
for addr in addrs.iter_mut() {
|
||||||
|
if addr == old {
|
||||||
|
*addr = new.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_dial_failure(
|
||||||
|
&mut self,
|
||||||
|
DialFailure { peer_id, error, .. }: DialFailure<
|
||||||
|
<Self as NetworkBehaviour>::ConnectionHandler,
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
let peer_id = match peer_id {
|
||||||
|
Some(id) => id,
|
||||||
|
// Not interested in dial failures to unknown peers.
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
match error {
|
||||||
|
DialError::Banned
|
||||||
|
| DialError::ConnectionLimit(_)
|
||||||
|
| DialError::LocalPeerId
|
||||||
|
| DialError::InvalidPeerId { .. }
|
||||||
|
| DialError::WrongPeerId { .. }
|
||||||
|
| DialError::Aborted
|
||||||
|
| DialError::ConnectionIo(_)
|
||||||
|
| DialError::Transport(_)
|
||||||
|
| DialError::NoAddresses => {
|
||||||
|
if let DialError::Transport(addresses) = error {
|
||||||
|
for (addr, _) in addresses {
|
||||||
|
self.address_failed(peer_id, addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for query in self.queries.iter_mut() {
|
||||||
|
query.on_failure(&peer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DialError::DialPeerConditionFalse(
|
||||||
|
dial_opts::PeerCondition::Disconnected | dial_opts::PeerCondition::NotDialing,
|
||||||
|
) => {
|
||||||
|
// We might (still) be connected, or about to be connected, thus do not report the
|
||||||
|
// failure to the queries.
|
||||||
|
}
|
||||||
|
DialError::DialPeerConditionFalse(dial_opts::PeerCondition::Always) => {
|
||||||
|
unreachable!("DialPeerCondition::Always can not trigger DialPeerConditionFalse.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_closed(
|
||||||
|
&mut self,
|
||||||
|
ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
remaining_established,
|
||||||
|
..
|
||||||
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
|
) {
|
||||||
|
if remaining_established == 0 {
|
||||||
|
for query in self.queries.iter_mut() {
|
||||||
|
query.on_failure(&peer_id);
|
||||||
|
}
|
||||||
|
self.connection_updated(peer_id, None, NodeStatus::Disconnected);
|
||||||
|
self.connected_peers.remove(&peer_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exponentially decrease the given duration (base 2).
|
/// Exponentially decrease the given duration (base 2).
|
||||||
@ -1817,164 +1979,7 @@ where
|
|||||||
peer_addrs
|
peer_addrs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_established(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
_: &ConnectionId,
|
|
||||||
_: &ConnectedPoint,
|
|
||||||
errors: Option<&Vec<Multiaddr>>,
|
|
||||||
other_established: usize,
|
|
||||||
) {
|
|
||||||
for addr in errors.map(|a| a.iter()).into_iter().flatten() {
|
|
||||||
self.address_failed(*peer_id, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When a connection is established, we don't know yet whether the
|
|
||||||
// remote supports the configured protocol name. Only once a connection
|
|
||||||
// handler reports [`KademliaHandlerEvent::ProtocolConfirmed`] do we
|
|
||||||
// update the local routing table.
|
|
||||||
|
|
||||||
// Peer's first connection.
|
|
||||||
if other_established == 0 {
|
|
||||||
// Queue events for sending pending RPCs to the connected peer.
|
|
||||||
// There can be only one pending RPC for a particular peer and query per definition.
|
|
||||||
for (peer_id, event) in self.queries.iter_mut().filter_map(|q| {
|
|
||||||
q.inner
|
|
||||||
.pending_rpcs
|
|
||||||
.iter()
|
|
||||||
.position(|(p, _)| p == peer_id)
|
|
||||||
.map(|p| q.inner.pending_rpcs.remove(p))
|
|
||||||
}) {
|
|
||||||
self.queued_events
|
|
||||||
.push_back(NetworkBehaviourAction::NotifyHandler {
|
|
||||||
peer_id,
|
|
||||||
event,
|
|
||||||
handler: NotifyHandler::Any,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.connected_peers.insert(*peer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_address_change(
|
|
||||||
&mut self,
|
|
||||||
peer: &PeerId,
|
|
||||||
_: &ConnectionId,
|
|
||||||
old: &ConnectedPoint,
|
|
||||||
new: &ConnectedPoint,
|
|
||||||
) {
|
|
||||||
let (old, new) = (old.get_remote_address(), new.get_remote_address());
|
|
||||||
|
|
||||||
// Update routing table.
|
|
||||||
if let Some(addrs) = self.kbuckets.entry(&kbucket::Key::from(*peer)).value() {
|
|
||||||
if addrs.replace(old, new) {
|
|
||||||
debug!(
|
|
||||||
"Address '{}' replaced with '{}' for peer '{}'.",
|
|
||||||
old, new, peer
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
debug!(
|
|
||||||
"Address '{}' not replaced with '{}' for peer '{}' as old address wasn't \
|
|
||||||
present.",
|
|
||||||
old, new, peer,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
debug!(
|
|
||||||
"Address '{}' not replaced with '{}' for peer '{}' as peer is not present in the \
|
|
||||||
routing table.",
|
|
||||||
old, new, peer,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update query address cache.
|
|
||||||
//
|
|
||||||
// Given two connected nodes: local node A and remote node B. Say node B
|
|
||||||
// is not in node A's routing table. Additionally node B is part of the
|
|
||||||
// `QueryInner::addresses` list of an ongoing query on node A. Say Node
|
|
||||||
// B triggers an address change and then disconnects. Later on the
|
|
||||||
// earlier mentioned query on node A would like to connect to node B.
|
|
||||||
// Without replacing the address in the `QueryInner::addresses` set node
|
|
||||||
// A would attempt to dial the old and not the new address.
|
|
||||||
//
|
|
||||||
// While upholding correctness, iterating through all discovered
|
|
||||||
// addresses of a peer in all currently ongoing queries might have a
|
|
||||||
// large performance impact. If so, the code below might be worth
|
|
||||||
// revisiting.
|
|
||||||
for query in self.queries.iter_mut() {
|
|
||||||
if let Some(addrs) = query.inner.addresses.get_mut(peer) {
|
|
||||||
for addr in addrs.iter_mut() {
|
|
||||||
if addr == old {
|
|
||||||
*addr = new.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_dial_failure(
|
|
||||||
&mut self,
|
|
||||||
peer_id: Option<PeerId>,
|
|
||||||
_: Self::ConnectionHandler,
|
|
||||||
error: &DialError,
|
|
||||||
) {
|
|
||||||
let peer_id = match peer_id {
|
|
||||||
Some(id) => id,
|
|
||||||
// Not interested in dial failures to unknown peers.
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
match error {
|
|
||||||
DialError::Banned
|
|
||||||
| DialError::ConnectionLimit(_)
|
|
||||||
| DialError::LocalPeerId
|
|
||||||
| DialError::InvalidPeerId { .. }
|
|
||||||
| DialError::WrongPeerId { .. }
|
|
||||||
| DialError::Aborted
|
|
||||||
| DialError::ConnectionIo(_)
|
|
||||||
| DialError::Transport(_)
|
|
||||||
| DialError::NoAddresses => {
|
|
||||||
if let DialError::Transport(addresses) = error {
|
|
||||||
for (addr, _) in addresses {
|
|
||||||
self.address_failed(peer_id, addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for query in self.queries.iter_mut() {
|
|
||||||
query.on_failure(&peer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DialError::DialPeerConditionFalse(
|
|
||||||
dial_opts::PeerCondition::Disconnected | dial_opts::PeerCondition::NotDialing,
|
|
||||||
) => {
|
|
||||||
// We might (still) be connected, or about to be connected, thus do not report the
|
|
||||||
// failure to the queries.
|
|
||||||
}
|
|
||||||
DialError::DialPeerConditionFalse(dial_opts::PeerCondition::Always) => {
|
|
||||||
unreachable!("DialPeerCondition::Always can not trigger DialPeerConditionFalse.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_closed(
|
|
||||||
&mut self,
|
|
||||||
id: &PeerId,
|
|
||||||
_: &ConnectionId,
|
|
||||||
_: &ConnectedPoint,
|
|
||||||
_: <Self::ConnectionHandler as libp2p_swarm::IntoConnectionHandler>::Handler,
|
|
||||||
remaining_established: usize,
|
|
||||||
) {
|
|
||||||
if remaining_established == 0 {
|
|
||||||
for query in self.queries.iter_mut() {
|
|
||||||
query.on_failure(id);
|
|
||||||
}
|
|
||||||
self.connection_updated(*id, None, NodeStatus::Disconnected);
|
|
||||||
self.connected_peers.remove(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_event(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
source: PeerId,
|
source: PeerId,
|
||||||
connection: ConnectionId,
|
connection: ConnectionId,
|
||||||
@ -2225,20 +2230,6 @@ where
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_new_listen_addr(&mut self, _id: ListenerId, addr: &Multiaddr) {
|
|
||||||
self.local_addrs.insert(addr.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_listen_addr(&mut self, _id: ListenerId, addr: &Multiaddr) {
|
|
||||||
self.local_addrs.remove(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
|
|
||||||
if self.local_addrs.len() < MAX_LOCAL_EXTERNAL_ADDRS {
|
|
||||||
self.local_addrs.insert(addr.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll(
|
fn poll(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
@ -2360,6 +2351,35 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(connection_established) => {
|
||||||
|
self.on_connection_established(connection_established)
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
|
self.on_connection_closed(connection_closed)
|
||||||
|
}
|
||||||
|
FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure),
|
||||||
|
FromSwarm::AddressChange(address_change) => self.on_address_change(address_change),
|
||||||
|
FromSwarm::ExpiredListenAddr(ExpiredListenAddr { addr, .. }) => {
|
||||||
|
self.local_addrs.remove(addr);
|
||||||
|
}
|
||||||
|
FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => {
|
||||||
|
if self.local_addrs.len() < MAX_LOCAL_EXTERNAL_ADDRS {
|
||||||
|
self.local_addrs.insert(addr.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => {
|
||||||
|
self.local_addrs.insert(addr.clone());
|
||||||
|
}
|
||||||
|
FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A quorum w.r.t. the configured replication factor specifies the minimum
|
/// A quorum w.r.t. the configured replication factor specifies the minimum
|
||||||
|
@ -1277,7 +1277,7 @@ fn manual_bucket_inserts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn network_behaviour_inject_address_change() {
|
fn network_behaviour_on_address_change() {
|
||||||
let local_peer_id = PeerId::random();
|
let local_peer_id = PeerId::random();
|
||||||
|
|
||||||
let remote_peer_id = PeerId::random();
|
let remote_peer_id = PeerId::random();
|
||||||
@ -1293,7 +1293,13 @@ fn network_behaviour_inject_address_change() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Mimick a connection being established.
|
// Mimick a connection being established.
|
||||||
kademlia.inject_connection_established(&remote_peer_id, &connection_id, &endpoint, None, 0);
|
kademlia.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
|
peer_id: remote_peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint: &endpoint,
|
||||||
|
failed_addresses: &[],
|
||||||
|
other_established: 0,
|
||||||
|
}));
|
||||||
|
|
||||||
// At this point the remote is not yet known to support the
|
// At this point the remote is not yet known to support the
|
||||||
// configured protocol name, so the peer is not yet in the
|
// configured protocol name, so the peer is not yet in the
|
||||||
@ -1302,7 +1308,7 @@ fn network_behaviour_inject_address_change() {
|
|||||||
|
|
||||||
// Mimick the connection handler confirming the protocol for
|
// Mimick the connection handler confirming the protocol for
|
||||||
// the test connection, so that the peer is added to the routing table.
|
// the test connection, so that the peer is added to the routing table.
|
||||||
kademlia.inject_event(
|
kademlia.on_connection_handler_event(
|
||||||
remote_peer_id,
|
remote_peer_id,
|
||||||
connection_id,
|
connection_id,
|
||||||
KademliaHandlerEvent::ProtocolConfirmed { endpoint },
|
KademliaHandlerEvent::ProtocolConfirmed { endpoint },
|
||||||
@ -1313,18 +1319,18 @@ fn network_behaviour_inject_address_change() {
|
|||||||
kademlia.addresses_of_peer(&remote_peer_id),
|
kademlia.addresses_of_peer(&remote_peer_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
kademlia.inject_address_change(
|
kademlia.on_swarm_event(FromSwarm::AddressChange(AddressChange {
|
||||||
&remote_peer_id,
|
peer_id: remote_peer_id,
|
||||||
&connection_id,
|
connection_id,
|
||||||
&ConnectedPoint::Dialer {
|
old: &ConnectedPoint::Dialer {
|
||||||
address: old_address,
|
address: old_address,
|
||||||
role_override: Endpoint::Dialer,
|
role_override: Endpoint::Dialer,
|
||||||
},
|
},
|
||||||
&ConnectedPoint::Dialer {
|
new: &ConnectedPoint::Dialer {
|
||||||
address: new_address.clone(),
|
address: new_address.clone(),
|
||||||
role_override: Endpoint::Dialer,
|
role_override: Endpoint::Dialer,
|
||||||
},
|
},
|
||||||
);
|
}));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec![new_address],
|
vec![new_address],
|
||||||
|
@ -4,8 +4,12 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `GenMdns`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
- Use `trust-dns-proto` to parse DNS messages. See [PR 3102].
|
- Use `trust-dns-proto` to parse DNS messages. See [PR 3102].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
[PR 3102]: https://github.com/libp2p/rust-libp2p/pull/3102
|
[PR 3102]: https://github.com/libp2p/rust-libp2p/pull/3102
|
||||||
|
|
||||||
# 0.41.0
|
# 0.41.0
|
||||||
|
@ -27,8 +27,8 @@ use crate::behaviour::{socket::AsyncSocket, timer::Builder};
|
|||||||
use crate::MdnsConfig;
|
use crate::MdnsConfig;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use if_watch::{IfEvent, IfWatcher};
|
use if_watch::{IfEvent, IfWatcher};
|
||||||
use libp2p_core::transport::ListenerId;
|
|
||||||
use libp2p_core::{Multiaddr, PeerId};
|
use libp2p_core::{Multiaddr, PeerId};
|
||||||
|
use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
|
dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
|
||||||
};
|
};
|
||||||
@ -133,7 +133,7 @@ where
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: PeerId,
|
_: PeerId,
|
||||||
_: libp2p_core::connection::ConnectionId,
|
_: libp2p_core::connection::ConnectionId,
|
||||||
@ -142,23 +142,33 @@ where
|
|||||||
void::unreachable(ev)
|
void::unreachable(ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
log::trace!("waking interface state because listening address changed");
|
match event {
|
||||||
for iface in self.iface_states.values_mut() {
|
FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
iface.fire_timer();
|
peer_id,
|
||||||
}
|
remaining_established,
|
||||||
}
|
..
|
||||||
|
}) => {
|
||||||
fn inject_connection_closed(
|
if remaining_established == 0 {
|
||||||
&mut self,
|
self.expire_node(&peer_id);
|
||||||
peer: &PeerId,
|
}
|
||||||
_: &libp2p_core::connection::ConnectionId,
|
}
|
||||||
_: &libp2p_core::ConnectedPoint,
|
FromSwarm::NewListener(_) => {
|
||||||
_: Self::ConnectionHandler,
|
log::trace!("waking interface state because listening address changed");
|
||||||
remaining_established: usize,
|
for iface in self.iface_states.values_mut() {
|
||||||
) {
|
iface.fire_timer();
|
||||||
if remaining_established == 0 {
|
}
|
||||||
self.expire_node(peer);
|
}
|
||||||
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `Behaviour`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
|
|
||||||
# 0.40.0
|
# 0.40.0
|
||||||
|
|
||||||
- Bump rand to 0.8 and quickcheck to 1. See [PR 2857].
|
- Bump rand to 0.8 and quickcheck to 1. See [PR 2857].
|
||||||
|
@ -48,7 +48,9 @@ mod protocol;
|
|||||||
use handler::Handler;
|
use handler::Handler;
|
||||||
pub use handler::{Config, Failure, Success};
|
pub use handler::{Config, Failure, Success};
|
||||||
use libp2p_core::{connection::ConnectionId, PeerId};
|
use libp2p_core::{connection::ConnectionId, PeerId};
|
||||||
use libp2p_swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
use libp2p_swarm::{
|
||||||
|
behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
|
||||||
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
@ -121,7 +123,7 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
Handler::new(self.config.clone())
|
Handler::new(self.config.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(&mut self, peer: PeerId, _: ConnectionId, result: Result) {
|
fn on_connection_handler_event(&mut self, peer: PeerId, _: ConnectionId, result: Result) {
|
||||||
self.events.push_front(Event { peer, result })
|
self.events.push_front(Event { peer, result })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,4 +146,24 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(
|
||||||
|
&mut self,
|
||||||
|
event: libp2p_swarm::behaviour::FromSwarm<Self::ConnectionHandler>,
|
||||||
|
) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::ConnectionClosed(_)
|
||||||
|
| FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `Client` and `Relay`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
|
|
||||||
# 0.13.0
|
# 0.13.0
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.37.0`.
|
- Update to `libp2p-core` `v0.37.0`.
|
||||||
|
@ -32,10 +32,10 @@ use futures::future::{BoxFuture, FutureExt};
|
|||||||
use futures::io::{AsyncRead, AsyncWrite};
|
use futures::io::{AsyncRead, AsyncWrite};
|
||||||
use futures::ready;
|
use futures::ready;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use libp2p_core::connection::{ConnectedPoint, ConnectionId};
|
use libp2p_core::connection::ConnectionId;
|
||||||
use libp2p_core::{Multiaddr, PeerId};
|
use libp2p_core::PeerId;
|
||||||
|
use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm};
|
||||||
use libp2p_swarm::dial_opts::DialOpts;
|
use libp2p_swarm::dial_opts::DialOpts;
|
||||||
use libp2p_swarm::dummy;
|
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
ConnectionHandlerUpgrErr, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction,
|
ConnectionHandlerUpgrErr, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction,
|
||||||
NotifyHandler, PollParameters,
|
NotifyHandler, PollParameters,
|
||||||
@ -113,47 +113,23 @@ impl Client {
|
|||||||
};
|
};
|
||||||
(transport, behaviour)
|
(transport, behaviour)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkBehaviour for Client {
|
fn on_connection_closed(
|
||||||
type ConnectionHandler = handler::Prototype;
|
|
||||||
type OutEvent = Event;
|
|
||||||
|
|
||||||
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
|
||||||
handler::Prototype::new(self.local_peer_id, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_established(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: &PeerId,
|
ConnectionClosed {
|
||||||
connection_id: &ConnectionId,
|
peer_id,
|
||||||
endpoint: &ConnectedPoint,
|
connection_id,
|
||||||
_failed_addresses: Option<&Vec<Multiaddr>>,
|
endpoint,
|
||||||
_other_established: usize,
|
..
|
||||||
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
) {
|
) {
|
||||||
if !endpoint.is_relayed() {
|
if !endpoint.is_relayed() {
|
||||||
self.directly_connected_peers
|
match self.directly_connected_peers.entry(peer_id) {
|
||||||
.entry(*peer_id)
|
|
||||||
.or_default()
|
|
||||||
.push(*connection_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_closed(
|
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
connection_id: &ConnectionId,
|
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
_handler: Either<handler::Handler, dummy::ConnectionHandler>,
|
|
||||||
_remaining_established: usize,
|
|
||||||
) {
|
|
||||||
if !endpoint.is_relayed() {
|
|
||||||
match self.directly_connected_peers.entry(*peer_id) {
|
|
||||||
hash_map::Entry::Occupied(mut connections) => {
|
hash_map::Entry::Occupied(mut connections) => {
|
||||||
let position = connections
|
let position = connections
|
||||||
.get()
|
.get()
|
||||||
.iter()
|
.iter()
|
||||||
.position(|c| c == connection_id)
|
.position(|c| c == &connection_id)
|
||||||
.expect("Connection to be known.");
|
.expect("Connection to be known.");
|
||||||
connections.get_mut().remove(position);
|
connections.get_mut().remove(position);
|
||||||
|
|
||||||
@ -167,8 +143,48 @@ impl NetworkBehaviour for Client {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn inject_event(
|
impl NetworkBehaviour for Client {
|
||||||
|
type ConnectionHandler = handler::Prototype;
|
||||||
|
type OutEvent = Event;
|
||||||
|
|
||||||
|
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
||||||
|
handler::Prototype::new(self.local_peer_id, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
if !endpoint.is_relayed() {
|
||||||
|
self.directly_connected_peers
|
||||||
|
.entry(peer_id)
|
||||||
|
.or_default()
|
||||||
|
.push(connection_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
|
self.on_connection_closed(connection_closed)
|
||||||
|
}
|
||||||
|
FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event_source: PeerId,
|
event_source: PeerId,
|
||||||
_connection: ConnectionId,
|
_connection: ConnectionId,
|
||||||
|
@ -27,11 +27,12 @@ use crate::v2::message_proto;
|
|||||||
use crate::v2::protocol::inbound_hop;
|
use crate::v2::protocol::inbound_hop;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use libp2p_core::connection::{ConnectedPoint, ConnectionId};
|
use libp2p_core::connection::ConnectionId;
|
||||||
use libp2p_core::multiaddr::Protocol;
|
use libp2p_core::multiaddr::Protocol;
|
||||||
use libp2p_core::PeerId;
|
use libp2p_core::PeerId;
|
||||||
|
use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
dummy, ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler,
|
ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler,
|
||||||
PollParameters,
|
PollParameters,
|
||||||
};
|
};
|
||||||
use std::collections::{hash_map, HashMap, HashSet, VecDeque};
|
use std::collections::{hash_map, HashMap, HashSet, VecDeque};
|
||||||
@ -212,6 +213,39 @@ impl Relay {
|
|||||||
queued_actions: Default::default(),
|
queued_actions: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_connection_closed(
|
||||||
|
&mut self,
|
||||||
|
ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
..
|
||||||
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
|
) {
|
||||||
|
if let hash_map::Entry::Occupied(mut peer) = self.reservations.entry(peer_id) {
|
||||||
|
peer.get_mut().remove(&connection_id);
|
||||||
|
if peer.get().is_empty() {
|
||||||
|
peer.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for circuit in self
|
||||||
|
.circuits
|
||||||
|
.remove_by_connection(peer_id, connection_id)
|
||||||
|
.iter()
|
||||||
|
// Only emit [`CircuitClosed`] for accepted requests.
|
||||||
|
.filter(|c| matches!(c.status, CircuitStatus::Accepted))
|
||||||
|
{
|
||||||
|
self.queued_actions.push_back(
|
||||||
|
NetworkBehaviourAction::GenerateEvent(Event::CircuitClosed {
|
||||||
|
src_peer_id: circuit.src_peer_id,
|
||||||
|
dst_peer_id: circuit.dst_peer_id,
|
||||||
|
error: Some(std::io::ErrorKind::ConnectionAborted.into()),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkBehaviour for Relay {
|
impl NetworkBehaviour for Relay {
|
||||||
@ -228,40 +262,26 @@ impl NetworkBehaviour for Relay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_closed(
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
&mut self,
|
match event {
|
||||||
peer: &PeerId,
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
connection: &ConnectionId,
|
self.on_connection_closed(connection_closed)
|
||||||
_: &ConnectedPoint,
|
|
||||||
_handler: Either<handler::Handler, dummy::ConnectionHandler>,
|
|
||||||
_remaining_established: usize,
|
|
||||||
) {
|
|
||||||
if let hash_map::Entry::Occupied(mut peer) = self.reservations.entry(*peer) {
|
|
||||||
peer.get_mut().remove(connection);
|
|
||||||
if peer.get().is_empty() {
|
|
||||||
peer.remove();
|
|
||||||
}
|
}
|
||||||
}
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
for circuit in self
|
| FromSwarm::AddressChange(_)
|
||||||
.circuits
|
| FromSwarm::ListenFailure(_)
|
||||||
.remove_by_connection(*peer, *connection)
|
| FromSwarm::NewListener(_)
|
||||||
.iter()
|
| FromSwarm::NewListenAddr(_)
|
||||||
// Only emit [`CircuitClosed`] for accepted requests.
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
.filter(|c| matches!(c.status, CircuitStatus::Accepted))
|
| FromSwarm::ListenerError(_)
|
||||||
{
|
| FromSwarm::ListenerClosed(_)
|
||||||
self.queued_actions.push_back(
|
| FromSwarm::NewExternalAddr(_)
|
||||||
NetworkBehaviourAction::GenerateEvent(Event::CircuitClosed {
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
src_peer_id: circuit.src_peer_id,
|
|
||||||
dst_peer_id: circuit.dst_peer_id,
|
|
||||||
error: Some(std::io::ErrorKind::ConnectionAborted.into()),
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event_source: PeerId,
|
event_source: PeerId,
|
||||||
connection: ConnectionId,
|
connection: ConnectionId,
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
# 0.11.0 [unreleased]
|
# 0.11.0 [unreleased]
|
||||||
|
|
||||||
- De- and encode protobuf messages using `prost-codec`. See [PR 3058].
|
- De- and encode protobuf messages using `prost-codec`. See [PR 3058].
|
||||||
|
|
||||||
- Update to `libp2p-core` `v0.38.0`.
|
- Update to `libp2p-core` `v0.38.0`.
|
||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `Client` and `Server`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
[PR 3058]: https://github.com/libp2p/rust-libp2p/pull/3058
|
[PR 3058]: https://github.com/libp2p/rust-libp2p/pull/3058
|
||||||
|
|
||||||
# 0.10.0
|
# 0.10.0
|
||||||
|
@ -32,6 +32,7 @@ use libp2p_core::connection::ConnectionId;
|
|||||||
use libp2p_core::identity::error::SigningError;
|
use libp2p_core::identity::error::SigningError;
|
||||||
use libp2p_core::identity::Keypair;
|
use libp2p_core::identity::Keypair;
|
||||||
use libp2p_core::{Multiaddr, PeerId, PeerRecord};
|
use libp2p_core::{Multiaddr, PeerId, PeerRecord};
|
||||||
|
use libp2p_swarm::behaviour::FromSwarm;
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
|
CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
|
||||||
};
|
};
|
||||||
@ -183,7 +184,7 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
connection_id: ConnectionId,
|
connection_id: ConnectionId,
|
||||||
@ -265,6 +266,23 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
|
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::ConnectionClosed(_)
|
||||||
|
| FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_outbound_event(
|
fn handle_outbound_event(
|
||||||
|
@ -29,6 +29,7 @@ use futures::stream::FuturesUnordered;
|
|||||||
use futures::{FutureExt, StreamExt};
|
use futures::{FutureExt, StreamExt};
|
||||||
use libp2p_core::connection::ConnectionId;
|
use libp2p_core::connection::ConnectionId;
|
||||||
use libp2p_core::PeerId;
|
use libp2p_core::PeerId;
|
||||||
|
use libp2p_swarm::behaviour::FromSwarm;
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
|
CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
|
||||||
};
|
};
|
||||||
@ -118,7 +119,7 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
SubstreamConnectionHandler::new_inbound_only(initial_keep_alive)
|
SubstreamConnectionHandler::new_inbound_only(initial_keep_alive)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
connection: ConnectionId,
|
connection: ConnectionId,
|
||||||
@ -160,6 +161,23 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
|
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::ConnectionClosed(_)
|
||||||
|
| FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_inbound_event(
|
fn handle_inbound_event(
|
||||||
|
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
- Update to `libp2p-swarm` `v0.41.0`.
|
- Update to `libp2p-swarm` `v0.41.0`.
|
||||||
|
|
||||||
|
- Replace `RequestResponse`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
|
|
||||||
# 0.22.0
|
# 0.22.0
|
||||||
|
|
||||||
- Bump rand to 0.8 and quickcheck to 1. See [PR 2857].
|
- Bump rand to 0.8 and quickcheck to 1. See [PR 2857].
|
||||||
|
@ -68,8 +68,9 @@ use futures::channel::oneshot;
|
|||||||
use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEvent};
|
use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEvent};
|
||||||
use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId};
|
use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId};
|
||||||
use libp2p_swarm::{
|
use libp2p_swarm::{
|
||||||
dial_opts::DialOpts, DialError, IntoConnectionHandler, NetworkBehaviour,
|
behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm},
|
||||||
NetworkBehaviourAction, NotifyHandler, PollParameters,
|
dial_opts::DialOpts,
|
||||||
|
IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{
|
use std::{
|
||||||
@ -560,6 +561,134 @@ where
|
|||||||
.get_mut(peer)
|
.get_mut(peer)
|
||||||
.and_then(|connections| connections.iter_mut().find(|c| c.id == connection))
|
.and_then(|connections| connections.iter_mut().find(|c| c.id == connection))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_address_change(
|
||||||
|
&mut self,
|
||||||
|
AddressChange {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
new,
|
||||||
|
..
|
||||||
|
}: AddressChange,
|
||||||
|
) {
|
||||||
|
let new_address = match new {
|
||||||
|
ConnectedPoint::Dialer { address, .. } => Some(address.clone()),
|
||||||
|
ConnectedPoint::Listener { .. } => None,
|
||||||
|
};
|
||||||
|
let connections = self
|
||||||
|
.connected
|
||||||
|
.get_mut(&peer_id)
|
||||||
|
.expect("Address change can only happen on an established connection.");
|
||||||
|
|
||||||
|
let connection = connections
|
||||||
|
.iter_mut()
|
||||||
|
.find(|c| c.id == connection_id)
|
||||||
|
.expect("Address change can only happen on an established connection.");
|
||||||
|
connection.address = new_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_established(
|
||||||
|
&mut self,
|
||||||
|
ConnectionEstablished {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
other_established,
|
||||||
|
..
|
||||||
|
}: ConnectionEstablished,
|
||||||
|
) {
|
||||||
|
let address = match endpoint {
|
||||||
|
ConnectedPoint::Dialer { address, .. } => Some(address.clone()),
|
||||||
|
ConnectedPoint::Listener { .. } => None,
|
||||||
|
};
|
||||||
|
self.connected
|
||||||
|
.entry(peer_id)
|
||||||
|
.or_default()
|
||||||
|
.push(Connection::new(connection_id, address));
|
||||||
|
|
||||||
|
if other_established == 0 {
|
||||||
|
if let Some(pending) = self.pending_outbound_requests.remove(&peer_id) {
|
||||||
|
for request in pending {
|
||||||
|
let request = self.try_send_request(&peer_id, request);
|
||||||
|
assert!(request.is_none());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_closed(
|
||||||
|
&mut self,
|
||||||
|
ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
remaining_established,
|
||||||
|
..
|
||||||
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
|
) {
|
||||||
|
let connections = self
|
||||||
|
.connected
|
||||||
|
.get_mut(&peer_id)
|
||||||
|
.expect("Expected some established connection to peer before closing.");
|
||||||
|
|
||||||
|
let connection = connections
|
||||||
|
.iter()
|
||||||
|
.position(|c| c.id == connection_id)
|
||||||
|
.map(|p: usize| connections.remove(p))
|
||||||
|
.expect("Expected connection to be established before closing.");
|
||||||
|
|
||||||
|
debug_assert_eq!(connections.is_empty(), remaining_established == 0);
|
||||||
|
if connections.is_empty() {
|
||||||
|
self.connected.remove(&peer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for request_id in connection.pending_outbound_responses {
|
||||||
|
self.pending_events
|
||||||
|
.push_back(NetworkBehaviourAction::GenerateEvent(
|
||||||
|
RequestResponseEvent::InboundFailure {
|
||||||
|
peer: peer_id,
|
||||||
|
request_id,
|
||||||
|
error: InboundFailure::ConnectionClosed,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
for request_id in connection.pending_inbound_responses {
|
||||||
|
self.pending_events
|
||||||
|
.push_back(NetworkBehaviourAction::GenerateEvent(
|
||||||
|
RequestResponseEvent::OutboundFailure {
|
||||||
|
peer: peer_id,
|
||||||
|
request_id,
|
||||||
|
error: OutboundFailure::ConnectionClosed,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_dial_failure(
|
||||||
|
&mut self,
|
||||||
|
DialFailure { peer_id, .. }: DialFailure<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
|
) {
|
||||||
|
if let Some(peer) = peer_id {
|
||||||
|
// If there are pending outgoing requests when a dial failure occurs,
|
||||||
|
// it is implied that we are not connected to the peer, since pending
|
||||||
|
// outgoing requests are drained when a connection is established and
|
||||||
|
// only created when a peer is not connected when a request is made.
|
||||||
|
// Thus these requests must be considered failed, even if there is
|
||||||
|
// another, concurrent dialing attempt ongoing.
|
||||||
|
if let Some(pending) = self.pending_outbound_requests.remove(&peer) {
|
||||||
|
for request in pending {
|
||||||
|
self.pending_events
|
||||||
|
.push_back(NetworkBehaviourAction::GenerateEvent(
|
||||||
|
RequestResponseEvent::OutboundFailure {
|
||||||
|
peer,
|
||||||
|
request_id: request.request_id,
|
||||||
|
error: OutboundFailure::DialFailure,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TCodec> NetworkBehaviour for RequestResponse<TCodec>
|
impl<TCodec> NetworkBehaviour for RequestResponse<TCodec>
|
||||||
@ -590,136 +719,33 @@ where
|
|||||||
addresses
|
addresses
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_address_change(
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
&mut self,
|
match event {
|
||||||
peer: &PeerId,
|
FromSwarm::ConnectionEstablished(connection_established) => {
|
||||||
conn: &ConnectionId,
|
self.on_connection_established(connection_established)
|
||||||
_old: &ConnectedPoint,
|
|
||||||
new: &ConnectedPoint,
|
|
||||||
) {
|
|
||||||
let new_address = match new {
|
|
||||||
ConnectedPoint::Dialer { address, .. } => Some(address.clone()),
|
|
||||||
ConnectedPoint::Listener { .. } => None,
|
|
||||||
};
|
|
||||||
let connections = self
|
|
||||||
.connected
|
|
||||||
.get_mut(peer)
|
|
||||||
.expect("Address change can only happen on an established connection.");
|
|
||||||
|
|
||||||
let connection = connections
|
|
||||||
.iter_mut()
|
|
||||||
.find(|c| &c.id == conn)
|
|
||||||
.expect("Address change can only happen on an established connection.");
|
|
||||||
connection.address = new_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_established(
|
|
||||||
&mut self,
|
|
||||||
peer: &PeerId,
|
|
||||||
conn: &ConnectionId,
|
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
_errors: Option<&Vec<Multiaddr>>,
|
|
||||||
other_established: usize,
|
|
||||||
) {
|
|
||||||
let address = match endpoint {
|
|
||||||
ConnectedPoint::Dialer { address, .. } => Some(address.clone()),
|
|
||||||
ConnectedPoint::Listener { .. } => None,
|
|
||||||
};
|
|
||||||
self.connected
|
|
||||||
.entry(*peer)
|
|
||||||
.or_default()
|
|
||||||
.push(Connection::new(*conn, address));
|
|
||||||
|
|
||||||
if other_established == 0 {
|
|
||||||
if let Some(pending) = self.pending_outbound_requests.remove(peer) {
|
|
||||||
for request in pending {
|
|
||||||
let request = self.try_send_request(peer, request);
|
|
||||||
assert!(request.is_none());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
}
|
self.on_connection_closed(connection_closed)
|
||||||
|
|
||||||
fn inject_connection_closed(
|
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
conn: &ConnectionId,
|
|
||||||
_: &ConnectedPoint,
|
|
||||||
_: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
|
||||||
remaining_established: usize,
|
|
||||||
) {
|
|
||||||
let connections = self
|
|
||||||
.connected
|
|
||||||
.get_mut(peer_id)
|
|
||||||
.expect("Expected some established connection to peer before closing.");
|
|
||||||
|
|
||||||
let connection = connections
|
|
||||||
.iter()
|
|
||||||
.position(|c| &c.id == conn)
|
|
||||||
.map(|p: usize| connections.remove(p))
|
|
||||||
.expect("Expected connection to be established before closing.");
|
|
||||||
|
|
||||||
debug_assert_eq!(connections.is_empty(), remaining_established == 0);
|
|
||||||
if connections.is_empty() {
|
|
||||||
self.connected.remove(peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
for request_id in connection.pending_outbound_responses {
|
|
||||||
self.pending_events
|
|
||||||
.push_back(NetworkBehaviourAction::GenerateEvent(
|
|
||||||
RequestResponseEvent::InboundFailure {
|
|
||||||
peer: *peer_id,
|
|
||||||
request_id,
|
|
||||||
error: InboundFailure::ConnectionClosed,
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
for request_id in connection.pending_inbound_responses {
|
|
||||||
self.pending_events
|
|
||||||
.push_back(NetworkBehaviourAction::GenerateEvent(
|
|
||||||
RequestResponseEvent::OutboundFailure {
|
|
||||||
peer: *peer_id,
|
|
||||||
request_id,
|
|
||||||
error: OutboundFailure::ConnectionClosed,
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_dial_failure(
|
|
||||||
&mut self,
|
|
||||||
peer: Option<PeerId>,
|
|
||||||
_: Self::ConnectionHandler,
|
|
||||||
_: &DialError,
|
|
||||||
) {
|
|
||||||
if let Some(peer) = peer {
|
|
||||||
// If there are pending outgoing requests when a dial failure occurs,
|
|
||||||
// it is implied that we are not connected to the peer, since pending
|
|
||||||
// outgoing requests are drained when a connection is established and
|
|
||||||
// only created when a peer is not connected when a request is made.
|
|
||||||
// Thus these requests must be considered failed, even if there is
|
|
||||||
// another, concurrent dialing attempt ongoing.
|
|
||||||
if let Some(pending) = self.pending_outbound_requests.remove(&peer) {
|
|
||||||
for request in pending {
|
|
||||||
self.pending_events
|
|
||||||
.push_back(NetworkBehaviourAction::GenerateEvent(
|
|
||||||
RequestResponseEvent::OutboundFailure {
|
|
||||||
peer,
|
|
||||||
request_id: request.request_id,
|
|
||||||
error: OutboundFailure::DialFailure,
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
FromSwarm::AddressChange(address_change) => self.on_address_change(address_change),
|
||||||
|
FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure),
|
||||||
|
FromSwarm::ListenFailure(_) => {}
|
||||||
|
FromSwarm::NewListener(_) => {}
|
||||||
|
FromSwarm::NewListenAddr(_) => {}
|
||||||
|
FromSwarm::ExpiredListenAddr(_) => {}
|
||||||
|
FromSwarm::ListenerError(_) => {}
|
||||||
|
FromSwarm::ListenerClosed(_) => {}
|
||||||
|
FromSwarm::NewExternalAddr(_) => {}
|
||||||
|
FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer: PeerId,
|
peer: PeerId,
|
||||||
connection: ConnectionId,
|
connection: ConnectionId,
|
||||||
event: RequestResponseHandlerEvent<TCodec>,
|
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
|
||||||
|
libp2p_swarm::ConnectionHandler>::OutEvent,
|
||||||
) {
|
) {
|
||||||
match event {
|
match event {
|
||||||
RequestResponseHandlerEvent::Response {
|
RequestResponseHandlerEvent::Response {
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
# 0.30.2 [unreleased]
|
# 0.30.2 - [unreleased]
|
||||||
|
|
||||||
|
- Replace `NetworkBehaviour` Derive macro deprecated `inject_*` method implementations
|
||||||
|
with the new `on_swarm_event` and `on_connection_handler_event`.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
- Add `prelude` configuration option.
|
- Add `prelude` configuration option.
|
||||||
The derive-macro generates code that needs to refer to various symbols. See [PR 3055].
|
The derive-macro generates code that needs to refer to various symbols. See [PR 3055].
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
|
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
|
||||||
|
|
||||||
# 0.30.1
|
# 0.30.1
|
||||||
|
@ -48,7 +48,6 @@ fn build(ast: &DeriveInput) -> TokenStream {
|
|||||||
fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||||
let name = &ast.ident;
|
let name = &ast.ident;
|
||||||
let (_, ty_generics, where_clause) = ast.generics.split_for_impl();
|
let (_, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||||
|
|
||||||
let prelude_path = parse_attribute_value_by_key::<syn::Path>(ast, "prelude")
|
let prelude_path = parse_attribute_value_by_key::<syn::Path>(ast, "prelude")
|
||||||
.unwrap_or_else(|| syn::parse_quote! { ::libp2p::swarm::derive_prelude });
|
.unwrap_or_else(|| syn::parse_quote! { ::libp2p::swarm::derive_prelude });
|
||||||
|
|
||||||
@ -61,11 +60,20 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
let into_proto_select_ident = quote! { #prelude_path::IntoConnectionHandlerSelect };
|
let into_proto_select_ident = quote! { #prelude_path::IntoConnectionHandlerSelect };
|
||||||
let peer_id = quote! { #prelude_path::PeerId };
|
let peer_id = quote! { #prelude_path::PeerId };
|
||||||
let connection_id = quote! { #prelude_path::ConnectionId };
|
let connection_id = quote! { #prelude_path::ConnectionId };
|
||||||
let dial_errors = quote! {Option<&Vec<#prelude_path::Multiaddr>> };
|
|
||||||
let connected_point = quote! { #prelude_path::ConnectedPoint };
|
|
||||||
let listener_id = quote! { #prelude_path::ListenerId };
|
|
||||||
let dial_error = quote! { #prelude_path::DialError };
|
|
||||||
let poll_parameters = quote! { #prelude_path::PollParameters };
|
let poll_parameters = quote! { #prelude_path::PollParameters };
|
||||||
|
let from_swarm = quote! { #prelude_path::FromSwarm };
|
||||||
|
let connection_established = quote! { #prelude_path::ConnectionEstablished };
|
||||||
|
let address_change = quote! { #prelude_path::AddressChange };
|
||||||
|
let connection_closed = quote! { #prelude_path::ConnectionClosed };
|
||||||
|
let dial_failure = quote! { #prelude_path::DialFailure };
|
||||||
|
let listen_failure = quote! { #prelude_path::ListenFailure };
|
||||||
|
let new_listener = quote! { #prelude_path::NewListener };
|
||||||
|
let new_listen_addr = quote! { #prelude_path::NewListenAddr };
|
||||||
|
let expired_listen_addr = quote! { #prelude_path::ExpiredListenAddr };
|
||||||
|
let new_external_addr = quote! { #prelude_path::NewExternalAddr };
|
||||||
|
let expired_external_addr = quote! { #prelude_path::ExpiredExternalAddr };
|
||||||
|
let listener_error = quote! { #prelude_path::ListenerError };
|
||||||
|
let listener_closed = quote! { #prelude_path::ListenerClosed };
|
||||||
|
|
||||||
// Build the generics.
|
// Build the generics.
|
||||||
let impl_generics = {
|
let impl_generics = {
|
||||||
@ -171,35 +179,50 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_connection_established()`.
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
let inject_connection_established_stmts = {
|
// for the `FromSwarm::ConnectionEstablished` variant.
|
||||||
data_struct.fields.iter().enumerate().map(move |(field_n, field)| {
|
let on_connection_established_stmts = {
|
||||||
match field.ident {
|
data_struct
|
||||||
Some(ref i) => quote!{ self.#i.inject_connection_established(peer_id, connection_id, endpoint, errors, other_established); },
|
.fields
|
||||||
None => quote!{ self.#field_n.inject_connection_established(peer_id, connection_id, endpoint, errors, other_established); },
|
.iter()
|
||||||
}
|
.enumerate()
|
||||||
})
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_connection_established(&peer_id, &connection_id, endpoint, Some(&failed_addresses.into()), other_established);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_connection_established(&peer_id, &connection_id, endpoint, Some(&failed_addresses.into()), other_established);},
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_address_change()`.
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
let inject_address_change_stmts = {
|
// for the `FromSwarm::AddressChange variant`.
|
||||||
data_struct.fields.iter().enumerate().map(move |(field_n, field)| {
|
let on_address_change_stmts = {
|
||||||
match field.ident {
|
data_struct
|
||||||
Some(ref i) => quote!{ self.#i.inject_address_change(peer_id, connection_id, old, new); },
|
.fields
|
||||||
None => quote!{ self.#field_n.inject_address_change(peer_id, connection_id, old, new); },
|
.iter()
|
||||||
}
|
.enumerate()
|
||||||
})
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_address_change(&peer_id, &connection_id, old, new);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_address_change(&peer_id, &connection_id, old, new);},
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_connection_closed()`.
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
let inject_connection_closed_stmts = {
|
// for the `FromSwarm::ConnectionClosed` variant.
|
||||||
|
let on_connection_closed_stmts = {
|
||||||
data_struct.fields
|
data_struct.fields
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
// The outmost handler belongs to the last behaviour.
|
// The outmost handler belongs to the last behaviour.
|
||||||
.rev()
|
.rev()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(move |(enum_n, (field_n, field))| {
|
.map(|(enum_n, (field_n, field))| {
|
||||||
let handler = if field_n == 0 {
|
let handler = if field_n == 0 {
|
||||||
// Given that the iterator is reversed, this is the innermost handler only.
|
// Given that the iterator is reversed, this is the innermost handler only.
|
||||||
quote! { let handler = handlers }
|
quote! { let handler = handlers }
|
||||||
@ -209,8 +232,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let inject = match field.ident {
|
let inject = match field.ident {
|
||||||
Some(ref i) => quote!{ self.#i.inject_connection_closed(peer_id, connection_id, endpoint, handler, remaining_established) },
|
Some(ref i) => quote! {
|
||||||
None => quote!{ self.#enum_n.inject_connection_closed(peer_id, connection_id, endpoint, handler, remaining_established) },
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_connection_closed(&peer_id, &connection_id, endpoint, handler, remaining_established);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#enum_n.inject_connection_closed(&peer_id, &connection_id, endpoint, handler, remaining_established);},
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
@ -220,8 +247,9 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_dial_failure()`.
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
let inject_dial_failure_stmts = {
|
// for the `FromSwarm::DialFailure` variant.
|
||||||
|
let on_dial_failure_stmts = {
|
||||||
data_struct
|
data_struct
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
@ -229,7 +257,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
// The outmost handler belongs to the last behaviour.
|
// The outmost handler belongs to the last behaviour.
|
||||||
.rev()
|
.rev()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(move |(enum_n, (field_n, field))| {
|
.map(|(enum_n, (field_n, field))| {
|
||||||
let handler = if field_n == 0 {
|
let handler = if field_n == 0 {
|
||||||
// Given that the iterator is reversed, this is the innermost handler only.
|
// Given that the iterator is reversed, this is the innermost handler only.
|
||||||
quote! { let handler = handlers }
|
quote! { let handler = handlers }
|
||||||
@ -240,12 +268,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let inject = match field.ident {
|
let inject = match field.ident {
|
||||||
Some(ref i) => {
|
Some(ref i) => quote! {
|
||||||
quote! { self.#i.inject_dial_failure(peer_id, handler, error) }
|
#[allow(deprecated)]
|
||||||
}
|
self.#i.inject_dial_failure(peer_id, handler, error);},
|
||||||
None => {
|
None => quote! {
|
||||||
quote! { self.#enum_n.inject_dial_failure(peer_id, handler, error) }
|
#[allow(deprecated)]
|
||||||
}
|
self.#enum_n.inject_dial_failure(peer_id, handler, error);},
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
@ -255,138 +283,186 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_listen_failure()`.
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
let inject_listen_failure_stmts = {
|
// for the `FromSwarm::ListenFailure` variant.
|
||||||
data_struct.fields
|
let on_listen_failure_stmts =
|
||||||
.iter()
|
{
|
||||||
.enumerate()
|
data_struct.fields.iter().enumerate().rev().enumerate().map(
|
||||||
.rev()
|
|(enum_n, (field_n, field))| {
|
||||||
.enumerate()
|
let handler = if field_n == 0 {
|
||||||
.map(move |(enum_n, (field_n, field))| {
|
quote! { let handler = handlers }
|
||||||
let handler = if field_n == 0 {
|
} else {
|
||||||
quote! { let handler = handlers }
|
quote! {
|
||||||
} else {
|
let (handlers, handler) = handlers.into_inner()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let inject = match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_listen_failure(local_addr, send_back_addr, handler);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#enum_n.inject_listen_failure(local_addr, send_back_addr, handler);},
|
||||||
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
let (handlers, handler) = handlers.into_inner()
|
#handler;
|
||||||
|
#inject;
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
)
|
||||||
let inject = match field.ident {
|
|
||||||
Some(ref i) => quote! { self.#i.inject_listen_failure(local_addr, send_back_addr, handler) },
|
|
||||||
None => quote! { self.#enum_n.inject_listen_failure(local_addr, send_back_addr, handler) },
|
|
||||||
};
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#handler;
|
|
||||||
#inject;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_new_listener()`.
|
|
||||||
let inject_new_listener_stmts = {
|
|
||||||
data_struct
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(move |(field_n, field)| match field.ident {
|
|
||||||
Some(ref i) => quote! { self.#i.inject_new_listener(id); },
|
|
||||||
None => quote! { self.#field_n.inject_new_listener(id); },
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_new_listen_addr()`.
|
|
||||||
let inject_new_listen_addr_stmts = {
|
|
||||||
data_struct
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(move |(field_n, field)| match field.ident {
|
|
||||||
Some(ref i) => quote! { self.#i.inject_new_listen_addr(id, addr); },
|
|
||||||
None => quote! { self.#field_n.inject_new_listen_addr(id, addr); },
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_expired_listen_addr()`.
|
|
||||||
let inject_expired_listen_addr_stmts = {
|
|
||||||
data_struct
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(move |(field_n, field)| match field.ident {
|
|
||||||
Some(ref i) => quote! { self.#i.inject_expired_listen_addr(id, addr); },
|
|
||||||
None => quote! { self.#field_n.inject_expired_listen_addr(id, addr); },
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_new_external_addr()`.
|
|
||||||
let inject_new_external_addr_stmts = {
|
|
||||||
data_struct
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(move |(field_n, field)| match field.ident {
|
|
||||||
Some(ref i) => quote! { self.#i.inject_new_external_addr(addr); },
|
|
||||||
None => quote! { self.#field_n.inject_new_external_addr(addr); },
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_expired_external_addr()`.
|
|
||||||
let inject_expired_external_addr_stmts = {
|
|
||||||
data_struct
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(move |(field_n, field)| match field.ident {
|
|
||||||
Some(ref i) => quote! { self.#i.inject_expired_external_addr(addr); },
|
|
||||||
None => quote! { self.#field_n.inject_expired_external_addr(addr); },
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_listener_error()`.
|
|
||||||
let inject_listener_error_stmts = {
|
|
||||||
data_struct
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(move |(field_n, field)| match field.ident {
|
|
||||||
Some(ref i) => quote!(self.#i.inject_listener_error(id, err);),
|
|
||||||
None => quote!(self.#field_n.inject_listener_error(id, err);),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `inject_listener_closed()`.
|
|
||||||
let inject_listener_closed_stmts = {
|
|
||||||
data_struct
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(move |(field_n, field)| match field.ident {
|
|
||||||
Some(ref i) => quote!(self.#i.inject_listener_closed(id, reason);),
|
|
||||||
None => quote!(self.#field_n.inject_listener_closed(id, reason);),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the list of variants to put in the body of `inject_event()`.
|
|
||||||
//
|
|
||||||
// The event type is a construction of nested `#either_ident`s of the events of the children.
|
|
||||||
// We call `inject_event` on the corresponding child.
|
|
||||||
let inject_node_event_stmts = data_struct.fields.iter().enumerate().enumerate().map(|(enum_n, (field_n, field))| {
|
|
||||||
let mut elem = if enum_n != 0 {
|
|
||||||
quote!{ #either_ident::Second(ev) }
|
|
||||||
} else {
|
|
||||||
quote!{ ev }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for _ in 0 .. data_struct.fields.len() - 1 - enum_n {
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
elem = quote!{ #either_ident::First(#elem) };
|
// for the `FromSwarm::NewListener` variant.
|
||||||
}
|
let on_new_listener_stmts = {
|
||||||
|
data_struct
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_new_listener(listener_id);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_new_listener(listener_id);},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
Some(match field.ident {
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
Some(ref i) => quote!{ #elem => #trait_to_impl::inject_event(&mut self.#i, peer_id, connection_id, ev) },
|
// for the `FromSwarm::NewListenAddr` variant.
|
||||||
None => quote!{ #elem => #trait_to_impl::inject_event(&mut self.#field_n, peer_id, connection_id, ev) },
|
let on_new_listen_addr_stmts = {
|
||||||
})
|
data_struct
|
||||||
});
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_new_listen_addr(listener_id, addr);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_new_listen_addr(listener_id, addr);},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
|
// for the `FromSwarm::ExpiredListenAddr` variant.
|
||||||
|
let on_expired_listen_addr_stmts = {
|
||||||
|
data_struct
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_expired_listen_addr(listener_id, addr);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_expired_listen_addr(listener_id, addr);},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
|
// for the `FromSwarm::NewExternalAddr` variant.
|
||||||
|
let on_new_external_addr_stmts = {
|
||||||
|
data_struct
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_new_external_addr(addr);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_new_external_addr(addr);},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
|
// for the `FromSwarm::ExpiredExternalAddr` variant.
|
||||||
|
let on_expired_external_addr_stmts = {
|
||||||
|
data_struct
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_expired_external_addr(addr);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_expired_external_addr(addr);},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
|
// for the `FromSwarm::ListenerError` variant.
|
||||||
|
let on_listener_error_stmts = {
|
||||||
|
data_struct
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_listener_error(listener_id, err);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_listener_error(listener_id, err);},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build the list of statements to put in the body of `on_swarm_event()`
|
||||||
|
// for the `FromSwarm::ListenerClosed` variant.
|
||||||
|
let on_listener_closed_stmts = {
|
||||||
|
data_struct
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(field_n, field)| match field.ident {
|
||||||
|
Some(ref i) => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#i.inject_listener_closed(listener_id, reason);},
|
||||||
|
None => quote! {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.#field_n.inject_listener_closed(listener_id, reason);},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build the list of variants to put in the body of `on_connection_handler_event()`.
|
||||||
|
//
|
||||||
|
// The event type is a construction of nested `#either_ident`s of the events of the children.
|
||||||
|
// We call `on_connection_handler_event` on the corresponding child.
|
||||||
|
let on_node_event_stmts =
|
||||||
|
data_struct
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(enum_n, (field_n, field))| {
|
||||||
|
let mut elem = if enum_n != 0 {
|
||||||
|
quote! { #either_ident::Second(ev) }
|
||||||
|
} else {
|
||||||
|
quote! { ev }
|
||||||
|
};
|
||||||
|
|
||||||
|
for _ in 0..data_struct.fields.len() - 1 - enum_n {
|
||||||
|
elem = quote! { #either_ident::First(#elem) };
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(match field.ident {
|
||||||
|
Some(ref i) => quote! { #elem => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
#trait_to_impl::inject_event(&mut self.#i, peer_id, connection_id, ev) }},
|
||||||
|
None => quote! { #elem => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
#trait_to_impl::inject_event(&mut self.#field_n, peer_id, connection_id, ev) }},
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
// The [`ConnectionHandler`] associated type.
|
// The [`ConnectionHandler`] associated type.
|
||||||
let connection_handler_ty = {
|
let connection_handler_ty = {
|
||||||
@ -555,62 +631,14 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_established(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, endpoint: &#connected_point, errors: #dial_errors, other_established: usize) {
|
fn on_connection_handler_event(
|
||||||
#(#inject_connection_established_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_address_change(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, old: &#connected_point, new: &#connected_point) {
|
|
||||||
#(#inject_address_change_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_closed(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, endpoint: &#connected_point, handlers: <Self::ConnectionHandler as #into_connection_handler>::Handler, remaining_established: usize) {
|
|
||||||
#(#inject_connection_closed_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_dial_failure(&mut self, peer_id: Option<#peer_id>, handlers: Self::ConnectionHandler, error: &#dial_error) {
|
|
||||||
#(#inject_dial_failure_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listen_failure(&mut self, local_addr: &#multiaddr, send_back_addr: &#multiaddr, handlers: Self::ConnectionHandler) {
|
|
||||||
#(#inject_listen_failure_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listener(&mut self, id: #listener_id) {
|
|
||||||
#(#inject_new_listener_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listen_addr(&mut self, id: #listener_id, addr: &#multiaddr) {
|
|
||||||
#(#inject_new_listen_addr_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_listen_addr(&mut self, id: #listener_id, addr: &#multiaddr) {
|
|
||||||
#(#inject_expired_listen_addr_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_external_addr(&mut self, addr: &#multiaddr) {
|
|
||||||
#(#inject_new_external_addr_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_external_addr(&mut self, addr: &#multiaddr) {
|
|
||||||
#(#inject_expired_external_addr_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_error(&mut self, id: #listener_id, err: &(dyn std::error::Error + 'static)) {
|
|
||||||
#(#inject_listener_error_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_closed(&mut self, id: #listener_id, reason: std::result::Result<(), &std::io::Error>) {
|
|
||||||
#(#inject_listener_closed_stmts);*
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_event(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: #peer_id,
|
peer_id: #peer_id,
|
||||||
connection_id: #connection_id,
|
connection_id: #connection_id,
|
||||||
event: <<Self::ConnectionHandler as #into_connection_handler>::Handler as #connection_handler>::OutEvent
|
event: <<Self::ConnectionHandler as #into_connection_handler>::Handler as #connection_handler>::OutEvent
|
||||||
) {
|
) {
|
||||||
match event {
|
match event {
|
||||||
#(#inject_node_event_stmts),*
|
#(#on_node_event_stmts),*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,6 +647,48 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
#(#poll_stmts)*
|
#(#poll_stmts)*
|
||||||
std::task::Poll::Pending
|
std::task::Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: #from_swarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
#from_swarm::ConnectionEstablished(
|
||||||
|
#connection_established { peer_id, connection_id, endpoint, failed_addresses, other_established })
|
||||||
|
=> { #(#on_connection_established_stmts)* }
|
||||||
|
#from_swarm::AddressChange(
|
||||||
|
#address_change { peer_id, connection_id, old, new })
|
||||||
|
=> { #(#on_address_change_stmts)* }
|
||||||
|
#from_swarm::ConnectionClosed(
|
||||||
|
#connection_closed { peer_id, connection_id, endpoint, handler: handlers, remaining_established })
|
||||||
|
=> { #(#on_connection_closed_stmts)* }
|
||||||
|
#from_swarm::DialFailure(
|
||||||
|
#dial_failure { peer_id, handler: handlers, error })
|
||||||
|
=> { #(#on_dial_failure_stmts)* }
|
||||||
|
#from_swarm::ListenFailure(
|
||||||
|
#listen_failure { local_addr, send_back_addr, handler: handlers })
|
||||||
|
=> { #(#on_listen_failure_stmts)* }
|
||||||
|
#from_swarm::NewListener(
|
||||||
|
#new_listener { listener_id })
|
||||||
|
=> { #(#on_new_listener_stmts)* }
|
||||||
|
#from_swarm::NewListenAddr(
|
||||||
|
#new_listen_addr { listener_id, addr })
|
||||||
|
=> { #(#on_new_listen_addr_stmts)* }
|
||||||
|
#from_swarm::ExpiredListenAddr(
|
||||||
|
#expired_listen_addr { listener_id, addr })
|
||||||
|
=> { #(#on_expired_listen_addr_stmts)* }
|
||||||
|
#from_swarm::NewExternalAddr(
|
||||||
|
#new_external_addr { addr })
|
||||||
|
=> { #(#on_new_external_addr_stmts)* }
|
||||||
|
#from_swarm::ExpiredExternalAddr(
|
||||||
|
#expired_external_addr { addr })
|
||||||
|
=> { #(#on_expired_external_addr_stmts)* }
|
||||||
|
#from_swarm::ListenerError(
|
||||||
|
#listener_error { listener_id, err })
|
||||||
|
=> { #(#on_listener_error_stmts)* }
|
||||||
|
#from_swarm::ListenerClosed(
|
||||||
|
#listener_closed { listener_id, reason })
|
||||||
|
=> { #(#on_listener_closed_stmts)* }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
- Update to `libp2p-core` `v0.38.0`.
|
- Update to `libp2p-core` `v0.38.0`.
|
||||||
|
|
||||||
|
- Add new `on_swarm_event` method to `NetworkBehaviour` that accepts a `FromSwarm` enum and update
|
||||||
|
`inject_*` methods to call `on_swarm_event` with the respective `FromSwarm` variant and deprecate
|
||||||
|
`inject_*`.
|
||||||
|
To migrate, users should replace the `NetworkBehaviour::inject_*` calls with a single
|
||||||
|
implementation of `NetworkBehaviour::on_swarm_event` treating each `FromSwarm` variant in
|
||||||
|
the same way its corresponding `inject_*` call was treated.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
|
- Add new `on_connection_handler_event` method with the same signature as `inject_event`, make the
|
||||||
|
default implementation of `inject_event` call `on_connection_handler_event` and deprecate it.
|
||||||
|
To migrate, users should replace the `NetworkBehaviour::inject_event` call
|
||||||
|
with `NetworkBehaviour::on_connection_handler_event`.
|
||||||
|
See [PR 3011].
|
||||||
|
|
||||||
- Export `NetworkBehaviour` derive as `libp2p_swarm::NetworkBehaviour`.
|
- Export `NetworkBehaviour` derive as `libp2p_swarm::NetworkBehaviour`.
|
||||||
This follows the convention of other popular libraries. `serde` for example exports the `Serialize` trait and macro as
|
This follows the convention of other popular libraries. `serde` for example exports the `Serialize` trait and macro as
|
||||||
`serde::Serialize`. See [PR 3055].
|
`serde::Serialize`. See [PR 3055].
|
||||||
@ -9,7 +23,7 @@
|
|||||||
- Feature-gate `NetworkBehaviour` macro behind `macros` feature flag. See [PR 3055].
|
- Feature-gate `NetworkBehaviour` macro behind `macros` feature flag. See [PR 3055].
|
||||||
|
|
||||||
- Make executor in Swarm constructor explicit. See [PR 3097].
|
- Make executor in Swarm constructor explicit. See [PR 3097].
|
||||||
|
|
||||||
Supported executors:
|
Supported executors:
|
||||||
- Tokio
|
- Tokio
|
||||||
|
|
||||||
@ -26,7 +40,7 @@
|
|||||||
let swarm = Swarm::with_tokio_executor(transport, behaviour, peer_id);
|
let swarm = Swarm::with_tokio_executor(transport, behaviour, peer_id);
|
||||||
```
|
```
|
||||||
- Async Std
|
- Async Std
|
||||||
|
|
||||||
Previously
|
Previously
|
||||||
```rust
|
```rust
|
||||||
let swarm = SwarmBuilder::new(transport, behaviour, peer_id)
|
let swarm = SwarmBuilder::new(transport, behaviour, peer_id)
|
||||||
@ -40,7 +54,7 @@
|
|||||||
let swarm = Swarm::with_async_std_executor(transport, behaviour, peer_id);
|
let swarm = Swarm::with_async_std_executor(transport, behaviour, peer_id);
|
||||||
```
|
```
|
||||||
- ThreadPool (see [Issue 3107])
|
- ThreadPool (see [Issue 3107])
|
||||||
|
|
||||||
In most cases ThreadPool can be replaced by executors or spawning on the local task.
|
In most cases ThreadPool can be replaced by executors or spawning on the local task.
|
||||||
|
|
||||||
Previously
|
Previously
|
||||||
@ -53,19 +67,20 @@
|
|||||||
let swarm = Swarm::with_threadpool_executor(transport, behaviour, peer_id);
|
let swarm = Swarm::with_threadpool_executor(transport, behaviour, peer_id);
|
||||||
```
|
```
|
||||||
- Without
|
- Without
|
||||||
|
|
||||||
Spawns the tasks on the current task, this may result in bad performance so try to use an executor where possible. Previously this was just a fallback when no executor was specified and constructing a `ThreadPool` failed.
|
Spawns the tasks on the current task, this may result in bad performance so try to use an executor where possible. Previously this was just a fallback when no executor was specified and constructing a `ThreadPool` failed.
|
||||||
|
|
||||||
New
|
New
|
||||||
```rust
|
```rust
|
||||||
let swarm = Swarm::without_executor(transport, behaviour, peer_id);
|
let swarm = Swarm::without_executor(transport, behaviour, peer_id);
|
||||||
```
|
```
|
||||||
|
|
||||||
Deprecated APIs:
|
Deprecated APIs:
|
||||||
- `Swarm::new`
|
- `Swarm::new`
|
||||||
- `SwarmBuilder::new`
|
- `SwarmBuilder::new`
|
||||||
- `SwarmBuilder::executor`
|
- `SwarmBuilder::executor`
|
||||||
|
|
||||||
|
[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011
|
||||||
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
|
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
|
||||||
[PR 3097]: https://github.com/libp2p/rust-libp2p/pull/3097
|
[PR 3097]: https://github.com/libp2p/rust-libp2p/pull/3097
|
||||||
[Issue 3107]: https://github.com/libp2p/rust-libp2p/issues/3107
|
[Issue 3107]: https://github.com/libp2p/rust-libp2p/issues/3107
|
||||||
|
@ -153,39 +153,90 @@ pub trait NetworkBehaviour: 'static {
|
|||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Informs the behaviour about an event from the [`Swarm`](crate::Swarm).
|
||||||
|
fn on_swarm_event(&mut self, _event: FromSwarm<Self::ConnectionHandler>) {}
|
||||||
|
|
||||||
|
/// Informs the behaviour about an event generated by the [`ConnectionHandler`] dedicated to the
|
||||||
|
/// peer identified by `peer_id`. for the behaviour.
|
||||||
|
///
|
||||||
|
/// The [`PeerId`] is guaranteed to be in a connected state. In other words,
|
||||||
|
/// [`FromSwarm::ConnectionEstablished`] has previously been received with this [`PeerId`].
|
||||||
|
fn on_connection_handler_event(
|
||||||
|
&mut self,
|
||||||
|
_peer_id: PeerId,
|
||||||
|
_connection_id: ConnectionId,
|
||||||
|
_event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
|
||||||
|
ConnectionHandler>::OutEvent,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/// Informs the behaviour about a newly established connection to a peer.
|
/// Informs the behaviour about a newly established connection to a peer.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::ConnectionEstablished` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
fn inject_connection_established(
|
fn inject_connection_established(
|
||||||
&mut self,
|
&mut self,
|
||||||
_peer_id: &PeerId,
|
peer_id: &PeerId,
|
||||||
_connection_id: &ConnectionId,
|
connection_id: &ConnectionId,
|
||||||
_endpoint: &ConnectedPoint,
|
endpoint: &ConnectedPoint,
|
||||||
_failed_addresses: Option<&Vec<Multiaddr>>,
|
failed_addresses: Option<&Vec<Multiaddr>>,
|
||||||
_other_established: usize,
|
other_established: usize,
|
||||||
) {
|
) {
|
||||||
|
self.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
|
peer_id: *peer_id,
|
||||||
|
connection_id: *connection_id,
|
||||||
|
endpoint,
|
||||||
|
failed_addresses: failed_addresses
|
||||||
|
.map(|v| v.as_slice())
|
||||||
|
.unwrap_or_else(|| &[]),
|
||||||
|
other_established,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Informs the behaviour about a closed connection to a peer.
|
/// Informs the behaviour about a closed connection to a peer.
|
||||||
///
|
///
|
||||||
/// A call to this method is always paired with an earlier call to
|
/// A call to this method is always paired with an earlier call to
|
||||||
/// [`NetworkBehaviour::inject_connection_established`] with the same peer ID, connection ID and endpoint.
|
/// [`NetworkBehaviour::inject_connection_established`] with the same peer ID, connection ID and endpoint.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::ConnectionClosed` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
fn inject_connection_closed(
|
fn inject_connection_closed(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &PeerId,
|
peer_id: &PeerId,
|
||||||
_: &ConnectionId,
|
connection_id: &ConnectionId,
|
||||||
_: &ConnectedPoint,
|
endpoint: &ConnectedPoint,
|
||||||
_: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
||||||
_remaining_established: usize,
|
remaining_established: usize,
|
||||||
) {
|
) {
|
||||||
|
self.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
|
peer_id: *peer_id,
|
||||||
|
connection_id: *connection_id,
|
||||||
|
endpoint,
|
||||||
|
handler,
|
||||||
|
remaining_established,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Informs the behaviour that the [`ConnectedPoint`] of an existing connection has changed.
|
/// Informs the behaviour that the [`ConnectedPoint`] of an existing connection has changed.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::AddressChange` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
fn inject_address_change(
|
fn inject_address_change(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &PeerId,
|
peer_id: &PeerId,
|
||||||
_: &ConnectionId,
|
connection_id: &ConnectionId,
|
||||||
_old: &ConnectedPoint,
|
old: &ConnectedPoint,
|
||||||
_new: &ConnectedPoint,
|
new: &ConnectedPoint,
|
||||||
) {
|
) {
|
||||||
|
self.on_swarm_event(FromSwarm::AddressChange(AddressChange {
|
||||||
|
peer_id: *peer_id,
|
||||||
|
connection_id: *connection_id,
|
||||||
|
old,
|
||||||
|
new,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Informs the behaviour about an event generated by the handler dedicated to the peer identified by `peer_id`.
|
/// Informs the behaviour about an event generated by the handler dedicated to the peer identified by `peer_id`.
|
||||||
@ -193,20 +244,35 @@ pub trait NetworkBehaviour: 'static {
|
|||||||
///
|
///
|
||||||
/// The `peer_id` is guaranteed to be in a connected state. In other words,
|
/// The `peer_id` is guaranteed to be in a connected state. In other words,
|
||||||
/// [`NetworkBehaviour::inject_connection_established`] has previously been called with this `PeerId`.
|
/// [`NetworkBehaviour::inject_connection_established`] has previously been called with this `PeerId`.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Implement `NetworkBehaviour::on_connection_handler_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
fn inject_event(
|
fn inject_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
connection: ConnectionId,
|
connection: ConnectionId,
|
||||||
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
||||||
);
|
) {
|
||||||
|
self.on_connection_handler_event(peer_id, connection, event);
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicates to the behaviour that the dial to a known or unknown node failed.
|
/// Indicates to the behaviour that the dial to a known or unknown node failed.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `InEvent::DialFailure` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
fn inject_dial_failure(
|
fn inject_dial_failure(
|
||||||
&mut self,
|
&mut self,
|
||||||
_peer_id: Option<PeerId>,
|
peer_id: Option<PeerId>,
|
||||||
_handler: Self::ConnectionHandler,
|
handler: Self::ConnectionHandler,
|
||||||
_error: &DialError,
|
error: &DialError,
|
||||||
) {
|
) {
|
||||||
|
self.on_swarm_event(FromSwarm::DialFailure(DialFailure {
|
||||||
|
peer_id,
|
||||||
|
handler,
|
||||||
|
error,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates to the behaviour that an error happened on an incoming connection during its
|
/// Indicates to the behaviour that an error happened on an incoming connection during its
|
||||||
@ -214,36 +280,98 @@ pub trait NetworkBehaviour: 'static {
|
|||||||
///
|
///
|
||||||
/// This can include, for example, an error during the handshake of the encryption layer, or the
|
/// This can include, for example, an error during the handshake of the encryption layer, or the
|
||||||
/// connection unexpectedly closed.
|
/// connection unexpectedly closed.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::ListenFailure` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
fn inject_listen_failure(
|
fn inject_listen_failure(
|
||||||
&mut self,
|
&mut self,
|
||||||
_local_addr: &Multiaddr,
|
local_addr: &Multiaddr,
|
||||||
_send_back_addr: &Multiaddr,
|
send_back_addr: &Multiaddr,
|
||||||
_handler: Self::ConnectionHandler,
|
handler: Self::ConnectionHandler,
|
||||||
) {
|
) {
|
||||||
|
self.on_swarm_event(FromSwarm::ListenFailure(ListenFailure {
|
||||||
|
local_addr,
|
||||||
|
send_back_addr,
|
||||||
|
handler,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates to the behaviour that a new listener was created.
|
/// Indicates to the behaviour that a new listener was created.
|
||||||
fn inject_new_listener(&mut self, _id: ListenerId) {}
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::NewListener` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
|
fn inject_new_listener(&mut self, id: ListenerId) {
|
||||||
|
self.on_swarm_event(FromSwarm::NewListener(NewListener { listener_id: id }));
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicates to the behaviour that we have started listening on a new multiaddr.
|
/// Indicates to the behaviour that we have started listening on a new multiaddr.
|
||||||
fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {}
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::NewListenAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
|
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
|
||||||
|
self.on_swarm_event(FromSwarm::NewListenAddr(NewListenAddr {
|
||||||
|
listener_id: id,
|
||||||
|
addr,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicates to the behaviour that a multiaddr we were listening on has expired,
|
/// Indicates to the behaviour that a multiaddr we were listening on has expired,
|
||||||
/// which means that we are no longer listening in it.
|
/// which means that we are no longer listening on it.
|
||||||
fn inject_expired_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {}
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::ExpiredListenAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
|
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
|
||||||
|
self.on_swarm_event(FromSwarm::ExpiredListenAddr(ExpiredListenAddr {
|
||||||
|
listener_id: id,
|
||||||
|
addr,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/// A listener experienced an error.
|
/// A listener experienced an error.
|
||||||
fn inject_listener_error(&mut self, _id: ListenerId, _err: &(dyn std::error::Error + 'static)) {
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::ListenerError` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
|
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) {
|
||||||
|
self.on_swarm_event(FromSwarm::ListenerError(ListenerError {
|
||||||
|
listener_id: id,
|
||||||
|
err,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A listener closed.
|
/// A listener closed.
|
||||||
fn inject_listener_closed(&mut self, _id: ListenerId, _reason: Result<(), &std::io::Error>) {}
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::ListenerClosed` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
|
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) {
|
||||||
|
self.on_swarm_event(FromSwarm::ListenerClosed(ListenerClosed {
|
||||||
|
listener_id: id,
|
||||||
|
reason,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicates to the behaviour that we have discovered a new external address for us.
|
/// Indicates to the behaviour that we have discovered a new external address for us.
|
||||||
fn inject_new_external_addr(&mut self, _addr: &Multiaddr) {}
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::NewExternalAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
|
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
|
||||||
|
self.on_swarm_event(FromSwarm::NewExternalAddr(NewExternalAddr { addr }));
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicates to the behaviour that an external address was removed.
|
/// Indicates to the behaviour that an external address was removed.
|
||||||
fn inject_expired_external_addr(&mut self, _addr: &Multiaddr) {}
|
#[deprecated(
|
||||||
|
since = "0.40.2",
|
||||||
|
note = "Handle `FromSwarm::ExpiredExternalAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it."
|
||||||
|
)]
|
||||||
|
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
|
||||||
|
self.on_swarm_event(FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }));
|
||||||
|
}
|
||||||
|
|
||||||
/// Polls for things that swarm should do.
|
/// Polls for things that swarm should do.
|
||||||
///
|
///
|
||||||
@ -722,3 +850,364 @@ impl Default for CloseConnection {
|
|||||||
CloseConnection::All
|
CloseConnection::All
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enumeration with the list of the possible events
|
||||||
|
/// to pass to [`on_swarm_event`](NetworkBehaviour::on_swarm_event).
|
||||||
|
pub enum FromSwarm<'a, Handler: IntoConnectionHandler> {
|
||||||
|
/// Informs the behaviour about a newly established connection to a peer.
|
||||||
|
ConnectionEstablished(ConnectionEstablished<'a>),
|
||||||
|
/// Informs the behaviour about a closed connection to a peer.
|
||||||
|
///
|
||||||
|
/// This event is always paired with an earlier
|
||||||
|
/// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID
|
||||||
|
/// and endpoint.
|
||||||
|
ConnectionClosed(ConnectionClosed<'a, Handler>),
|
||||||
|
/// Informs the behaviour that the [`ConnectedPoint`] of an existing
|
||||||
|
/// connection has changed.
|
||||||
|
AddressChange(AddressChange<'a>),
|
||||||
|
/// Informs the behaviour that the dial to a known
|
||||||
|
/// or unknown node failed.
|
||||||
|
DialFailure(DialFailure<'a, Handler>),
|
||||||
|
/// Informs the behaviour that an error
|
||||||
|
/// happened on an incoming connection during its initial handshake.
|
||||||
|
///
|
||||||
|
/// This can include, for example, an error during the handshake of the encryption layer, or the
|
||||||
|
/// connection unexpectedly closed.
|
||||||
|
ListenFailure(ListenFailure<'a, Handler>),
|
||||||
|
/// Informs the behaviour that a new listener was created.
|
||||||
|
NewListener(NewListener),
|
||||||
|
/// Informs the behaviour that we have started listening on a new multiaddr.
|
||||||
|
NewListenAddr(NewListenAddr<'a>),
|
||||||
|
/// Informs the behaviour that a multiaddr
|
||||||
|
/// we were listening on has expired,
|
||||||
|
/// which means that we are no longer listening on it.
|
||||||
|
ExpiredListenAddr(ExpiredListenAddr<'a>),
|
||||||
|
/// Informs the behaviour that a listener experienced an error.
|
||||||
|
ListenerError(ListenerError<'a>),
|
||||||
|
/// Informs the behaviour that a listener closed.
|
||||||
|
ListenerClosed(ListenerClosed<'a>),
|
||||||
|
/// Informs the behaviour that we have discovered a new external address for us.
|
||||||
|
NewExternalAddr(NewExternalAddr<'a>),
|
||||||
|
/// Informs the behaviour that an external address was removed.
|
||||||
|
ExpiredExternalAddr(ExpiredExternalAddr<'a>),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour about a newly established connection to a peer.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ConnectionEstablished<'a> {
|
||||||
|
pub peer_id: PeerId,
|
||||||
|
pub connection_id: ConnectionId,
|
||||||
|
pub endpoint: &'a ConnectedPoint,
|
||||||
|
pub failed_addresses: &'a [Multiaddr],
|
||||||
|
pub other_established: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour about a closed connection to a peer.
|
||||||
|
///
|
||||||
|
/// This event is always paired with an earlier
|
||||||
|
/// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID
|
||||||
|
/// and endpoint.
|
||||||
|
pub struct ConnectionClosed<'a, Handler: IntoConnectionHandler> {
|
||||||
|
pub peer_id: PeerId,
|
||||||
|
pub connection_id: ConnectionId,
|
||||||
|
pub endpoint: &'a ConnectedPoint,
|
||||||
|
pub handler: <Handler as IntoConnectionHandler>::Handler,
|
||||||
|
pub remaining_established: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour that the [`ConnectedPoint`] of an existing
|
||||||
|
/// connection has changed.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct AddressChange<'a> {
|
||||||
|
pub peer_id: PeerId,
|
||||||
|
pub connection_id: ConnectionId,
|
||||||
|
pub old: &'a ConnectedPoint,
|
||||||
|
pub new: &'a ConnectedPoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour that the dial to a known
|
||||||
|
/// or unknown node failed.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct DialFailure<'a, Handler> {
|
||||||
|
pub peer_id: Option<PeerId>,
|
||||||
|
pub handler: Handler,
|
||||||
|
pub error: &'a DialError,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour that an error
|
||||||
|
/// happened on an incoming connection during its initial handshake.
|
||||||
|
///
|
||||||
|
/// This can include, for example, an error during the handshake of the encryption layer, or the
|
||||||
|
/// connection unexpectedly closed.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ListenFailure<'a, Handler> {
|
||||||
|
pub local_addr: &'a Multiaddr,
|
||||||
|
pub send_back_addr: &'a Multiaddr,
|
||||||
|
pub handler: Handler,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour that a new listener was created.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct NewListener {
|
||||||
|
pub listener_id: ListenerId,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour
|
||||||
|
/// that we have started listening on a new multiaddr.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct NewListenAddr<'a> {
|
||||||
|
pub listener_id: ListenerId,
|
||||||
|
pub addr: &'a Multiaddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour that a multiaddr
|
||||||
|
/// we were listening on has expired,
|
||||||
|
/// which means that we are no longer listening on it.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ExpiredListenAddr<'a> {
|
||||||
|
pub listener_id: ListenerId,
|
||||||
|
pub addr: &'a Multiaddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour that a listener experienced an error.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ListenerError<'a> {
|
||||||
|
pub listener_id: ListenerId,
|
||||||
|
pub err: &'a (dyn std::error::Error + 'static),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour that a listener closed.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ListenerClosed<'a> {
|
||||||
|
pub listener_id: ListenerId,
|
||||||
|
pub reason: Result<(), &'a std::io::Error>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour
|
||||||
|
/// that we have discovered a new external address for us.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct NewExternalAddr<'a> {
|
||||||
|
pub addr: &'a Multiaddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`FromSwarm`] variant that informs the behaviour that an external address was removed.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ExpiredExternalAddr<'a> {
|
||||||
|
pub addr: &'a Multiaddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> {
|
||||||
|
fn map_handler<NewHandler>(
|
||||||
|
self,
|
||||||
|
map_into_handler: impl FnOnce(Handler) -> NewHandler,
|
||||||
|
map_handler: impl FnOnce(
|
||||||
|
<Handler as IntoConnectionHandler>::Handler,
|
||||||
|
) -> <NewHandler as IntoConnectionHandler>::Handler,
|
||||||
|
) -> FromSwarm<'a, NewHandler>
|
||||||
|
where
|
||||||
|
NewHandler: IntoConnectionHandler,
|
||||||
|
{
|
||||||
|
self.maybe_map_handler(|h| Some(map_into_handler(h)), |h| Some(map_handler(h)))
|
||||||
|
.expect("To return Some as all closures return Some.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_map_handler<NewHandler>(
|
||||||
|
self,
|
||||||
|
map_into_handler: impl FnOnce(Handler) -> Option<NewHandler>,
|
||||||
|
map_handler: impl FnOnce(
|
||||||
|
<Handler as IntoConnectionHandler>::Handler,
|
||||||
|
) -> Option<<NewHandler as IntoConnectionHandler>::Handler>,
|
||||||
|
) -> Option<FromSwarm<'a, NewHandler>>
|
||||||
|
where
|
||||||
|
NewHandler: IntoConnectionHandler,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
handler,
|
||||||
|
remaining_established,
|
||||||
|
}) => Some(FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
handler: map_handler(handler)?,
|
||||||
|
remaining_established,
|
||||||
|
})),
|
||||||
|
FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
failed_addresses,
|
||||||
|
other_established,
|
||||||
|
}) => Some(FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
failed_addresses,
|
||||||
|
other_established,
|
||||||
|
})),
|
||||||
|
FromSwarm::AddressChange(AddressChange {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
old,
|
||||||
|
new,
|
||||||
|
}) => Some(FromSwarm::AddressChange(AddressChange {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
old,
|
||||||
|
new,
|
||||||
|
})),
|
||||||
|
FromSwarm::DialFailure(DialFailure {
|
||||||
|
peer_id,
|
||||||
|
handler,
|
||||||
|
error,
|
||||||
|
}) => Some(FromSwarm::DialFailure(DialFailure {
|
||||||
|
peer_id,
|
||||||
|
handler: map_into_handler(handler)?,
|
||||||
|
error,
|
||||||
|
})),
|
||||||
|
FromSwarm::ListenFailure(ListenFailure {
|
||||||
|
local_addr,
|
||||||
|
send_back_addr,
|
||||||
|
handler,
|
||||||
|
}) => Some(FromSwarm::ListenFailure(ListenFailure {
|
||||||
|
local_addr,
|
||||||
|
send_back_addr,
|
||||||
|
handler: map_into_handler(handler)?,
|
||||||
|
})),
|
||||||
|
FromSwarm::NewListener(NewListener { listener_id }) => {
|
||||||
|
Some(FromSwarm::NewListener(NewListener { listener_id }))
|
||||||
|
}
|
||||||
|
FromSwarm::NewListenAddr(NewListenAddr { listener_id, addr }) => {
|
||||||
|
Some(FromSwarm::NewListenAddr(NewListenAddr {
|
||||||
|
listener_id,
|
||||||
|
addr,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredListenAddr(ExpiredListenAddr { listener_id, addr }) => {
|
||||||
|
Some(FromSwarm::ExpiredListenAddr(ExpiredListenAddr {
|
||||||
|
listener_id,
|
||||||
|
addr,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
FromSwarm::ListenerError(ListenerError { listener_id, err }) => {
|
||||||
|
Some(FromSwarm::ListenerError(ListenerError { listener_id, err }))
|
||||||
|
}
|
||||||
|
FromSwarm::ListenerClosed(ListenerClosed {
|
||||||
|
listener_id,
|
||||||
|
reason,
|
||||||
|
}) => Some(FromSwarm::ListenerClosed(ListenerClosed {
|
||||||
|
listener_id,
|
||||||
|
reason,
|
||||||
|
})),
|
||||||
|
FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => {
|
||||||
|
Some(FromSwarm::NewExternalAddr(NewExternalAddr { addr }))
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) => {
|
||||||
|
Some(FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to call [`NetworkBehaviour`]'s `inject_*` methods given a `FromSwarm.
|
||||||
|
/// TODO: Remove this function when we remove the remaining `inject_*` calls
|
||||||
|
/// from [`Either`] and [`Toggle`].
|
||||||
|
pub(crate) fn inject_from_swarm<T: NetworkBehaviour>(
|
||||||
|
behaviour: &mut T,
|
||||||
|
event: FromSwarm<T::ConnectionHandler>,
|
||||||
|
) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(ConnectionEstablished {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
failed_addresses,
|
||||||
|
other_established,
|
||||||
|
}) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_connection_established(
|
||||||
|
&peer_id,
|
||||||
|
&connection_id,
|
||||||
|
endpoint,
|
||||||
|
Some(&failed_addresses.into()),
|
||||||
|
other_established,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
endpoint,
|
||||||
|
handler,
|
||||||
|
remaining_established,
|
||||||
|
}) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_connection_closed(
|
||||||
|
&peer_id,
|
||||||
|
&connection_id,
|
||||||
|
endpoint,
|
||||||
|
handler,
|
||||||
|
remaining_established,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
FromSwarm::AddressChange(AddressChange {
|
||||||
|
peer_id,
|
||||||
|
connection_id,
|
||||||
|
old,
|
||||||
|
new,
|
||||||
|
}) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_address_change(&peer_id, &connection_id, old, new);
|
||||||
|
}
|
||||||
|
FromSwarm::DialFailure(DialFailure {
|
||||||
|
peer_id,
|
||||||
|
handler,
|
||||||
|
error,
|
||||||
|
}) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_dial_failure(peer_id, handler, error);
|
||||||
|
}
|
||||||
|
FromSwarm::ListenFailure(ListenFailure {
|
||||||
|
local_addr,
|
||||||
|
send_back_addr,
|
||||||
|
handler,
|
||||||
|
}) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_listen_failure(local_addr, send_back_addr, handler);
|
||||||
|
}
|
||||||
|
FromSwarm::NewListener(NewListener { listener_id }) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_new_listener(listener_id);
|
||||||
|
}
|
||||||
|
FromSwarm::NewListenAddr(NewListenAddr { listener_id, addr }) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_new_listen_addr(listener_id, addr);
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredListenAddr(ExpiredListenAddr { listener_id, addr }) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_expired_listen_addr(listener_id, addr);
|
||||||
|
}
|
||||||
|
FromSwarm::ListenerError(ListenerError { listener_id, err }) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_listener_error(listener_id, err);
|
||||||
|
}
|
||||||
|
FromSwarm::ListenerClosed(ListenerClosed {
|
||||||
|
listener_id,
|
||||||
|
reason,
|
||||||
|
}) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_listener_closed(listener_id, reason);
|
||||||
|
}
|
||||||
|
FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_new_external_addr(addr);
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) =>
|
||||||
|
{
|
||||||
|
#[allow(deprecated)]
|
||||||
|
behaviour.inject_expired_external_addr(addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use crate::handler::{either::IntoEitherHandler, ConnectionHandler, IntoConnectionHandler};
|
use crate::behaviour::{
|
||||||
use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
|
||||||
use either::Either;
|
|
||||||
use libp2p_core::{
|
|
||||||
connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId,
|
|
||||||
};
|
};
|
||||||
|
use crate::handler::either::IntoEitherHandler;
|
||||||
|
use either::Either;
|
||||||
|
use libp2p_core::{Multiaddr, PeerId};
|
||||||
use std::{task::Context, task::Poll};
|
use std::{task::Context, task::Poll};
|
||||||
|
|
||||||
/// Implementation of [`NetworkBehaviour`] that can be either of two implementations.
|
/// Implementation of [`NetworkBehaviour`] that can be either of two implementations.
|
||||||
@ -49,173 +49,50 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_established(
|
fn on_swarm_event(&mut self, event: behaviour::FromSwarm<Self::ConnectionHandler>) {
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
connection: &ConnectionId,
|
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
errors: Option<&Vec<Multiaddr>>,
|
|
||||||
other_established: usize,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
Either::Left(a) => a.inject_connection_established(
|
Either::Left(b) => inject_from_swarm(
|
||||||
peer_id,
|
b,
|
||||||
connection,
|
event.map_handler(
|
||||||
endpoint,
|
|h| h.unwrap_left(),
|
||||||
errors,
|
|h| match h {
|
||||||
other_established,
|
Either::Left(h) => h,
|
||||||
),
|
Either::Right(_) => unreachable!(),
|
||||||
Either::Right(b) => b.inject_connection_established(
|
},
|
||||||
peer_id,
|
|
||||||
connection,
|
|
||||||
endpoint,
|
|
||||||
errors,
|
|
||||||
other_established,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_closed(
|
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
connection: &ConnectionId,
|
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
|
||||||
remaining_established: usize,
|
|
||||||
) {
|
|
||||||
match (self, handler) {
|
|
||||||
(Either::Left(behaviour), Either::Left(handler)) => behaviour.inject_connection_closed(
|
|
||||||
peer_id,
|
|
||||||
connection,
|
|
||||||
endpoint,
|
|
||||||
handler,
|
|
||||||
remaining_established,
|
|
||||||
),
|
|
||||||
(Either::Right(behaviour), Either::Right(handler)) => behaviour
|
|
||||||
.inject_connection_closed(
|
|
||||||
peer_id,
|
|
||||||
connection,
|
|
||||||
endpoint,
|
|
||||||
handler,
|
|
||||||
remaining_established,
|
|
||||||
),
|
),
|
||||||
_ => unreachable!(),
|
),
|
||||||
|
Either::Right(b) => inject_from_swarm(
|
||||||
|
b,
|
||||||
|
event.map_handler(
|
||||||
|
|h| h.unwrap_right(),
|
||||||
|
|h| match h {
|
||||||
|
Either::Right(h) => h,
|
||||||
|
Either::Left(_) => unreachable!(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_address_change(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
connection: &ConnectionId,
|
|
||||||
old: &ConnectedPoint,
|
|
||||||
new: &ConnectedPoint,
|
|
||||||
) {
|
|
||||||
match self {
|
|
||||||
Either::Left(a) => a.inject_address_change(peer_id, connection, old, new),
|
|
||||||
Either::Right(b) => b.inject_address_change(peer_id, connection, old, new),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_event(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
connection: ConnectionId,
|
connection_id: libp2p_core::connection::ConnectionId,
|
||||||
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
event: crate::THandlerOutEvent<Self>,
|
||||||
) {
|
) {
|
||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Either::Left(behaviour), Either::Left(event)) => {
|
(Either::Left(left), Either::Left(event)) => {
|
||||||
behaviour.inject_event(peer_id, connection, event)
|
#[allow(deprecated)]
|
||||||
|
left.inject_event(peer_id, connection_id, event);
|
||||||
}
|
}
|
||||||
(Either::Right(behaviour), Either::Right(event)) => {
|
(Either::Right(right), Either::Right(event)) => {
|
||||||
behaviour.inject_event(peer_id, connection, event)
|
#[allow(deprecated)]
|
||||||
|
right.inject_event(peer_id, connection_id, event);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_dial_failure(
|
|
||||||
&mut self,
|
|
||||||
peer_id: Option<PeerId>,
|
|
||||||
handler: Self::ConnectionHandler,
|
|
||||||
error: &DialError,
|
|
||||||
) {
|
|
||||||
match (self, handler) {
|
|
||||||
(Either::Left(behaviour), IntoEitherHandler::Left(handler)) => {
|
|
||||||
behaviour.inject_dial_failure(peer_id, handler, error)
|
|
||||||
}
|
|
||||||
(Either::Right(behaviour), IntoEitherHandler::Right(handler)) => {
|
|
||||||
behaviour.inject_dial_failure(peer_id, handler, error)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listen_failure(
|
|
||||||
&mut self,
|
|
||||||
local_addr: &Multiaddr,
|
|
||||||
send_back_addr: &Multiaddr,
|
|
||||||
handler: Self::ConnectionHandler,
|
|
||||||
) {
|
|
||||||
match (self, handler) {
|
|
||||||
(Either::Left(behaviour), IntoEitherHandler::Left(handler)) => {
|
|
||||||
behaviour.inject_listen_failure(local_addr, send_back_addr, handler)
|
|
||||||
}
|
|
||||||
(Either::Right(behaviour), IntoEitherHandler::Right(handler)) => {
|
|
||||||
behaviour.inject_listen_failure(local_addr, send_back_addr, handler)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listener(&mut self, id: ListenerId) {
|
|
||||||
match self {
|
|
||||||
Either::Left(a) => a.inject_new_listener(id),
|
|
||||||
Either::Right(b) => b.inject_new_listener(id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
|
|
||||||
match self {
|
|
||||||
Either::Left(a) => a.inject_new_listen_addr(id, addr),
|
|
||||||
Either::Right(b) => b.inject_new_listen_addr(id, addr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
|
|
||||||
match self {
|
|
||||||
Either::Left(a) => a.inject_expired_listen_addr(id, addr),
|
|
||||||
Either::Right(b) => b.inject_expired_listen_addr(id, addr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
|
|
||||||
match self {
|
|
||||||
Either::Left(a) => a.inject_new_external_addr(addr),
|
|
||||||
Either::Right(b) => b.inject_new_external_addr(addr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
|
|
||||||
match self {
|
|
||||||
Either::Left(a) => a.inject_expired_external_addr(addr),
|
|
||||||
Either::Right(b) => b.inject_expired_external_addr(addr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) {
|
|
||||||
match self {
|
|
||||||
Either::Left(a) => a.inject_listener_error(id, err),
|
|
||||||
Either::Right(b) => b.inject_listener_error(id, err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) {
|
|
||||||
match self {
|
|
||||||
Either::Left(a) => a.inject_listener_closed(id, reason),
|
|
||||||
Either::Right(b) => b.inject_listener_closed(id, reason),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll(
|
fn poll(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
|
@ -18,17 +18,16 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
use crate::behaviour::{inject_from_swarm, FromSwarm};
|
||||||
use crate::handler::{
|
use crate::handler::{
|
||||||
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler,
|
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler,
|
||||||
KeepAlive, SubstreamProtocol,
|
KeepAlive, SubstreamProtocol,
|
||||||
};
|
};
|
||||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper};
|
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper};
|
||||||
use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
connection::ConnectionId,
|
|
||||||
either::{EitherError, EitherOutput},
|
either::{EitherError, EitherOutput},
|
||||||
transport::ListenerId,
|
|
||||||
upgrade::{DeniedUpgrade, EitherUpgrade},
|
upgrade::{DeniedUpgrade, EitherUpgrade},
|
||||||
ConnectedPoint, Multiaddr, PeerId,
|
ConnectedPoint, Multiaddr, PeerId,
|
||||||
};
|
};
|
||||||
@ -84,134 +83,23 @@ where
|
|||||||
.unwrap_or_else(Vec::new)
|
.unwrap_or_else(Vec::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_established(
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
&mut self,
|
if let Some(behaviour) = &mut self.inner {
|
||||||
peer_id: &PeerId,
|
if let Some(event) = event.maybe_map_handler(|h| h.inner, |h| h.inner) {
|
||||||
connection: &ConnectionId,
|
inject_from_swarm(behaviour, event);
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
errors: Option<&Vec<Multiaddr>>,
|
|
||||||
other_established: usize,
|
|
||||||
) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_connection_established(
|
|
||||||
peer_id,
|
|
||||||
connection,
|
|
||||||
endpoint,
|
|
||||||
errors,
|
|
||||||
other_established,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_closed(
|
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
connection: &ConnectionId,
|
|
||||||
endpoint: &ConnectedPoint,
|
|
||||||
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
|
||||||
remaining_established: usize,
|
|
||||||
) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
if let Some(handler) = handler.inner {
|
|
||||||
inner.inject_connection_closed(
|
|
||||||
peer_id,
|
|
||||||
connection,
|
|
||||||
endpoint,
|
|
||||||
handler,
|
|
||||||
remaining_established,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_address_change(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
|
||||||
peer_id: &PeerId,
|
|
||||||
connection: &ConnectionId,
|
|
||||||
old: &ConnectedPoint,
|
|
||||||
new: &ConnectedPoint,
|
|
||||||
) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_address_change(peer_id, connection, old, new)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_event(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
connection: ConnectionId,
|
connection_id: libp2p_core::connection::ConnectionId,
|
||||||
event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
event: crate::THandlerOutEvent<Self>,
|
||||||
) {
|
) {
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
if let Some(behaviour) = &mut self.inner {
|
||||||
inner.inject_event(peer_id, connection, event);
|
#[allow(deprecated)]
|
||||||
}
|
behaviour.inject_event(peer_id, connection_id, event)
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_dial_failure(
|
|
||||||
&mut self,
|
|
||||||
peer_id: Option<PeerId>,
|
|
||||||
handler: Self::ConnectionHandler,
|
|
||||||
error: &DialError,
|
|
||||||
) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
if let Some(handler) = handler.inner {
|
|
||||||
inner.inject_dial_failure(peer_id, handler, error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listen_failure(
|
|
||||||
&mut self,
|
|
||||||
local_addr: &Multiaddr,
|
|
||||||
send_back_addr: &Multiaddr,
|
|
||||||
handler: Self::ConnectionHandler,
|
|
||||||
) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
if let Some(handler) = handler.inner {
|
|
||||||
inner.inject_listen_failure(local_addr, send_back_addr, handler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listener(&mut self, id: ListenerId) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_new_listener(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_new_listen_addr(id, addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_expired_listen_addr(id, addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_external_addr(&mut self, addr: &Multiaddr) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_new_external_addr(addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_external_addr(&mut self, addr: &Multiaddr) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_expired_external_addr(addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_listener_error(id, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) {
|
|
||||||
if let Some(inner) = self.inner.as_mut() {
|
|
||||||
inner.inject_listener_closed(id, reason)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::behaviour::{NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
||||||
use crate::handler::{InboundUpgradeSend, OutboundUpgradeSend};
|
use crate::handler::{InboundUpgradeSend, OutboundUpgradeSend};
|
||||||
use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol};
|
use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol};
|
||||||
use libp2p_core::connection::ConnectionId;
|
use libp2p_core::connection::ConnectionId;
|
||||||
@ -19,7 +19,7 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
ConnectionHandler
|
ConnectionHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(&mut self, _: PeerId, _: ConnectionId, event: Void) {
|
fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) {
|
||||||
void::unreachable(event)
|
void::unreachable(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +30,23 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
|
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::ConnectionClosed(_)
|
||||||
|
| FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An implementation of [`ConnectionHandler`] that neither handles any protocols nor does it keep the connection alive.
|
/// An implementation of [`ConnectionHandler`] that neither handles any protocols nor does it keep the connection alive.
|
||||||
|
@ -29,6 +29,8 @@ use libp2p_core::upgrade::{EitherUpgrade, UpgradeError};
|
|||||||
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId};
|
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
|
/// Auxiliary type to allow implementing [`IntoConnectionHandler`]. As [`IntoConnectionHandler`] is
|
||||||
|
/// already implemented for T, we cannot implement it for Either<A, B>.
|
||||||
pub enum IntoEitherHandler<L, R> {
|
pub enum IntoEitherHandler<L, R> {
|
||||||
Left(L),
|
Left(L),
|
||||||
Right(R),
|
Right(R),
|
||||||
@ -64,6 +66,29 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Taken from https://github.com/bluss/either.
|
||||||
|
impl<L, R> IntoEitherHandler<L, R> {
|
||||||
|
/// Returns the left value.
|
||||||
|
pub fn unwrap_left(self) -> L {
|
||||||
|
match self {
|
||||||
|
IntoEitherHandler::Left(l) => l,
|
||||||
|
IntoEitherHandler::Right(_) => {
|
||||||
|
panic!("called `IntoEitherHandler::unwrap_left()` on a `Right` value.",)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the right value.
|
||||||
|
pub fn unwrap_right(self) -> R {
|
||||||
|
match self {
|
||||||
|
IntoEitherHandler::Right(r) => r,
|
||||||
|
IntoEitherHandler::Left(_) => {
|
||||||
|
panic!("called `IntoEitherHandler::unwrap_right()` on a `Left` value.",)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Implementation of a [`ConnectionHandler`] that represents either of two [`ConnectionHandler`]
|
/// Implementation of a [`ConnectionHandler`] that represents either of two [`ConnectionHandler`]
|
||||||
/// implementations.
|
/// implementations.
|
||||||
impl<L, R> ConnectionHandler for Either<L, R>
|
impl<L, R> ConnectionHandler for Either<L, R>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::behaviour::{NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters};
|
||||||
use crate::handler::{
|
use crate::handler::{
|
||||||
ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol,
|
ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol,
|
||||||
};
|
};
|
||||||
@ -29,7 +29,7 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
ConnectionHandler
|
ConnectionHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(&mut self, _: PeerId, _: ConnectionId, event: Void) {
|
fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) {
|
||||||
void::unreachable(event)
|
void::unreachable(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +40,23 @@ impl NetworkBehaviour for Behaviour {
|
|||||||
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
|
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::ConnectionClosed(_)
|
||||||
|
| FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of [`ConnectionHandler`] that doesn't handle anything but keeps the connection alive.
|
/// Implementation of [`ConnectionHandler`] that doesn't handle anything but keeps the connection alive.
|
||||||
|
@ -71,6 +71,19 @@ pub mod keep_alive;
|
|||||||
/// Bundles all symbols required for the [`libp2p_swarm_derive::NetworkBehaviour`] macro.
|
/// Bundles all symbols required for the [`libp2p_swarm_derive::NetworkBehaviour`] macro.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod derive_prelude {
|
pub mod derive_prelude {
|
||||||
|
pub use crate::behaviour::AddressChange;
|
||||||
|
pub use crate::behaviour::ConnectionClosed;
|
||||||
|
pub use crate::behaviour::ConnectionEstablished;
|
||||||
|
pub use crate::behaviour::DialFailure;
|
||||||
|
pub use crate::behaviour::ExpiredExternalAddr;
|
||||||
|
pub use crate::behaviour::ExpiredListenAddr;
|
||||||
|
pub use crate::behaviour::FromSwarm;
|
||||||
|
pub use crate::behaviour::ListenFailure;
|
||||||
|
pub use crate::behaviour::ListenerClosed;
|
||||||
|
pub use crate::behaviour::ListenerError;
|
||||||
|
pub use crate::behaviour::NewExternalAddr;
|
||||||
|
pub use crate::behaviour::NewListenAddr;
|
||||||
|
pub use crate::behaviour::NewListener;
|
||||||
pub use crate::ConnectionHandler;
|
pub use crate::ConnectionHandler;
|
||||||
pub use crate::DialError;
|
pub use crate::DialError;
|
||||||
pub use crate::IntoConnectionHandler;
|
pub use crate::IntoConnectionHandler;
|
||||||
@ -432,6 +445,7 @@ where
|
|||||||
/// Depending on the underlying transport, one listener may have multiple listening addresses.
|
/// Depending on the underlying transport, one listener may have multiple listening addresses.
|
||||||
pub fn listen_on(&mut self, addr: Multiaddr) -> Result<ListenerId, TransportError<io::Error>> {
|
pub fn listen_on(&mut self, addr: Multiaddr) -> Result<ListenerId, TransportError<io::Error>> {
|
||||||
let id = self.transport.listen_on(addr)?;
|
let id = self.transport.listen_on(addr)?;
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_new_listener(id);
|
self.behaviour.inject_new_listener(id);
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
@ -500,6 +514,7 @@ where
|
|||||||
PeerCondition::Always => true,
|
PeerCondition::Always => true,
|
||||||
};
|
};
|
||||||
if !condition_matched {
|
if !condition_matched {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_dial_failure(
|
self.behaviour.inject_dial_failure(
|
||||||
Some(peer_id),
|
Some(peer_id),
|
||||||
handler,
|
handler,
|
||||||
@ -512,6 +527,7 @@ where
|
|||||||
// Check if peer is banned.
|
// Check if peer is banned.
|
||||||
if self.banned_peers.contains(&peer_id) {
|
if self.banned_peers.contains(&peer_id) {
|
||||||
let error = DialError::Banned;
|
let error = DialError::Banned;
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour
|
self.behaviour
|
||||||
.inject_dial_failure(Some(peer_id), handler, &error);
|
.inject_dial_failure(Some(peer_id), handler, &error);
|
||||||
return Err(error);
|
return Err(error);
|
||||||
@ -549,6 +565,7 @@ where
|
|||||||
|
|
||||||
if addresses.is_empty() {
|
if addresses.is_empty() {
|
||||||
let error = DialError::NoAddresses;
|
let error = DialError::NoAddresses;
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour
|
self.behaviour
|
||||||
.inject_dial_failure(Some(peer_id), handler, &error);
|
.inject_dial_failure(Some(peer_id), handler, &error);
|
||||||
return Err(error);
|
return Err(error);
|
||||||
@ -632,6 +649,7 @@ where
|
|||||||
Ok(_connection_id) => Ok(()),
|
Ok(_connection_id) => Ok(()),
|
||||||
Err((connection_limit, handler)) => {
|
Err((connection_limit, handler)) => {
|
||||||
let error = DialError::ConnectionLimit(connection_limit);
|
let error = DialError::ConnectionLimit(connection_limit);
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_dial_failure(peer_id, handler, &error);
|
self.behaviour.inject_dial_failure(peer_id, handler, &error);
|
||||||
Err(error)
|
Err(error)
|
||||||
}
|
}
|
||||||
@ -673,12 +691,14 @@ where
|
|||||||
let result = self.external_addrs.add(a.clone(), s);
|
let result = self.external_addrs.add(a.clone(), s);
|
||||||
let expired = match &result {
|
let expired = match &result {
|
||||||
AddAddressResult::Inserted { expired } => {
|
AddAddressResult::Inserted { expired } => {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_new_external_addr(&a);
|
self.behaviour.inject_new_external_addr(&a);
|
||||||
expired
|
expired
|
||||||
}
|
}
|
||||||
AddAddressResult::Updated { expired } => expired,
|
AddAddressResult::Updated { expired } => expired,
|
||||||
};
|
};
|
||||||
for a in expired {
|
for a in expired {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_expired_external_addr(&a.addr);
|
self.behaviour.inject_expired_external_addr(&a.addr);
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
@ -692,6 +712,7 @@ where
|
|||||||
/// otherwise.
|
/// otherwise.
|
||||||
pub fn remove_external_address(&mut self, addr: &Multiaddr) -> bool {
|
pub fn remove_external_address(&mut self, addr: &Multiaddr) -> bool {
|
||||||
if self.external_addrs.remove(addr) {
|
if self.external_addrs.remove(addr) {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_expired_external_addr(addr);
|
self.behaviour.inject_expired_external_addr(addr);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@ -798,6 +819,7 @@ where
|
|||||||
let failed_addresses = concurrent_dial_errors
|
let failed_addresses = concurrent_dial_errors
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|es| es.iter().map(|(a, _)| a).cloned().collect());
|
.map(|es| es.iter().map(|(a, _)| a).cloned().collect());
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_connection_established(
|
self.behaviour.inject_connection_established(
|
||||||
&peer_id,
|
&peer_id,
|
||||||
&id,
|
&id,
|
||||||
@ -821,6 +843,7 @@ where
|
|||||||
} => {
|
} => {
|
||||||
let error = error.into();
|
let error = error.into();
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_dial_failure(peer, handler, &error);
|
self.behaviour.inject_dial_failure(peer, handler, &error);
|
||||||
|
|
||||||
if let Some(peer) = peer {
|
if let Some(peer) = peer {
|
||||||
@ -842,6 +865,7 @@ where
|
|||||||
handler,
|
handler,
|
||||||
} => {
|
} => {
|
||||||
log::debug!("Incoming connection failed: {:?}", error);
|
log::debug!("Incoming connection failed: {:?}", error);
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour
|
self.behaviour
|
||||||
.inject_listen_failure(&local_addr, &send_back_addr, handler);
|
.inject_listen_failure(&local_addr, &send_back_addr, handler);
|
||||||
return Some(SwarmEvent::IncomingConnectionError {
|
return Some(SwarmEvent::IncomingConnectionError {
|
||||||
@ -882,6 +906,7 @@ where
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|conn_id| !self.banned_peer_connections.contains(conn_id))
|
.filter(|conn_id| !self.banned_peer_connections.contains(conn_id))
|
||||||
.count();
|
.count();
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_connection_closed(
|
self.behaviour.inject_connection_closed(
|
||||||
&peer_id,
|
&peer_id,
|
||||||
&id,
|
&id,
|
||||||
@ -901,6 +926,7 @@ where
|
|||||||
if self.banned_peer_connections.contains(&id) {
|
if self.banned_peer_connections.contains(&id) {
|
||||||
log::debug!("Ignoring event from banned peer: {} {:?}.", peer_id, id);
|
log::debug!("Ignoring event from banned peer: {} {:?}.", peer_id, id);
|
||||||
} else {
|
} else {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_event(peer_id, id, event);
|
self.behaviour.inject_event(peer_id, id, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -911,6 +937,7 @@ where
|
|||||||
old_endpoint,
|
old_endpoint,
|
||||||
} => {
|
} => {
|
||||||
if !self.banned_peer_connections.contains(&id) {
|
if !self.banned_peer_connections.contains(&id) {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_address_change(
|
self.behaviour.inject_address_change(
|
||||||
&peer_id,
|
&peer_id,
|
||||||
&id,
|
&id,
|
||||||
@ -954,6 +981,7 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err((connection_limit, handler)) => {
|
Err((connection_limit, handler)) => {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour
|
self.behaviour
|
||||||
.inject_listen_failure(&local_addr, &send_back_addr, handler);
|
.inject_listen_failure(&local_addr, &send_back_addr, handler);
|
||||||
log::warn!("Incoming connection rejected: {:?}", connection_limit);
|
log::warn!("Incoming connection rejected: {:?}", connection_limit);
|
||||||
@ -969,6 +997,7 @@ where
|
|||||||
if !addrs.contains(&listen_addr) {
|
if !addrs.contains(&listen_addr) {
|
||||||
addrs.push(listen_addr.clone())
|
addrs.push(listen_addr.clone())
|
||||||
}
|
}
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour
|
self.behaviour
|
||||||
.inject_new_listen_addr(listener_id, &listen_addr);
|
.inject_new_listen_addr(listener_id, &listen_addr);
|
||||||
return Some(SwarmEvent::NewListenAddr {
|
return Some(SwarmEvent::NewListenAddr {
|
||||||
@ -988,6 +1017,7 @@ where
|
|||||||
if let Some(addrs) = self.listened_addrs.get_mut(&listener_id) {
|
if let Some(addrs) = self.listened_addrs.get_mut(&listener_id) {
|
||||||
addrs.retain(|a| a != &listen_addr);
|
addrs.retain(|a| a != &listen_addr);
|
||||||
}
|
}
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour
|
self.behaviour
|
||||||
.inject_expired_listen_addr(listener_id, &listen_addr);
|
.inject_expired_listen_addr(listener_id, &listen_addr);
|
||||||
return Some(SwarmEvent::ExpiredListenAddr {
|
return Some(SwarmEvent::ExpiredListenAddr {
|
||||||
@ -1002,8 +1032,10 @@ where
|
|||||||
log::debug!("Listener {:?}; Closed by {:?}.", listener_id, reason);
|
log::debug!("Listener {:?}; Closed by {:?}.", listener_id, reason);
|
||||||
let addrs = self.listened_addrs.remove(&listener_id).unwrap_or_default();
|
let addrs = self.listened_addrs.remove(&listener_id).unwrap_or_default();
|
||||||
for addr in addrs.iter() {
|
for addr in addrs.iter() {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_expired_listen_addr(listener_id, addr);
|
self.behaviour.inject_expired_listen_addr(listener_id, addr);
|
||||||
}
|
}
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_listener_closed(
|
self.behaviour.inject_listener_closed(
|
||||||
listener_id,
|
listener_id,
|
||||||
match &reason {
|
match &reason {
|
||||||
@ -1018,6 +1050,7 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
TransportEvent::ListenerError { listener_id, error } => {
|
TransportEvent::ListenerError { listener_id, error } => {
|
||||||
|
#[allow(deprecated)]
|
||||||
self.behaviour.inject_listener_error(listener_id, &error);
|
self.behaviour.inject_listener_error(listener_id, &error);
|
||||||
return Some(SwarmEvent::ListenerError { listener_id, error });
|
return Some(SwarmEvent::ListenerError { listener_id, error });
|
||||||
}
|
}
|
||||||
@ -1868,7 +1901,7 @@ mod tests {
|
|||||||
// The banned connection was established. Check that it was not reported to
|
// The banned connection was established. Check that it was not reported to
|
||||||
// the behaviour of the banning swarm.
|
// the behaviour of the banning swarm.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
swarm2.behaviour.inject_connection_established.len(), s2_expected_conns,
|
swarm2.behaviour.on_connection_established.len(), s2_expected_conns,
|
||||||
"No additional closed connections should be reported for the banned peer"
|
"No additional closed connections should be reported for the banned peer"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1882,7 +1915,7 @@ mod tests {
|
|||||||
if swarm2.network_info().num_peers() == 0 {
|
if swarm2.network_info().num_peers() == 0 {
|
||||||
// The banned connection has closed. Check that it was not reported.
|
// The banned connection has closed. Check that it was not reported.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
swarm2.behaviour.inject_connection_closed.len(), s2_expected_conns,
|
swarm2.behaviour.on_connection_closed.len(), s2_expected_conns,
|
||||||
"No additional closed connections should be reported for the banned peer"
|
"No additional closed connections should be reported for the banned peer"
|
||||||
);
|
);
|
||||||
assert!(swarm2.banned_peer_connections.is_empty());
|
assert!(swarm2.banned_peer_connections.is_empty());
|
||||||
@ -1897,7 +1930,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Stage::Reconnecting => {
|
Stage::Reconnecting => {
|
||||||
if swarm1.behaviour.inject_connection_established.len() == s1_expected_conns
|
if swarm1.behaviour.on_connection_established.len() == s1_expected_conns
|
||||||
&& swarm2.behaviour.assert_connected(s2_expected_conns, 2)
|
&& swarm2.behaviour.assert_connected(s2_expected_conns, 2)
|
||||||
{
|
{
|
||||||
return Poll::Ready(());
|
return Poll::Ready(());
|
||||||
@ -2082,9 +2115,8 @@ mod tests {
|
|||||||
State::Connecting => {
|
State::Connecting => {
|
||||||
if swarms_connected(&swarm1, &swarm2, num_connections) {
|
if swarms_connected(&swarm1, &swarm2, num_connections) {
|
||||||
disconnected_conn_id = {
|
disconnected_conn_id = {
|
||||||
let conn_id = swarm2.behaviour.inject_connection_established
|
let conn_id =
|
||||||
[num_connections / 2]
|
swarm2.behaviour.on_connection_established[num_connections / 2].1;
|
||||||
.1;
|
|
||||||
swarm2.behaviour.inner().next_action.replace(
|
swarm2.behaviour.inner().next_action.replace(
|
||||||
NetworkBehaviourAction::CloseConnection {
|
NetworkBehaviourAction::CloseConnection {
|
||||||
peer_id: swarm1_id,
|
peer_id: swarm1_id,
|
||||||
@ -2100,20 +2132,17 @@ mod tests {
|
|||||||
for s in &[&swarm1, &swarm2] {
|
for s in &[&swarm1, &swarm2] {
|
||||||
assert!(s
|
assert!(s
|
||||||
.behaviour
|
.behaviour
|
||||||
.inject_connection_closed
|
.on_connection_closed
|
||||||
.iter()
|
.iter()
|
||||||
.all(|(.., remaining_conns)| *remaining_conns > 0));
|
.all(|(.., remaining_conns)| *remaining_conns > 0));
|
||||||
assert_eq!(
|
assert_eq!(s.behaviour.on_connection_established.len(), num_connections);
|
||||||
s.behaviour.inject_connection_established.len(),
|
|
||||||
num_connections
|
|
||||||
);
|
|
||||||
s.behaviour.assert_connected(num_connections, 1);
|
s.behaviour.assert_connected(num_connections, 1);
|
||||||
}
|
}
|
||||||
if [&swarm1, &swarm2]
|
if [&swarm1, &swarm2]
|
||||||
.iter()
|
.iter()
|
||||||
.all(|s| s.behaviour.inject_connection_closed.len() == 1)
|
.all(|s| s.behaviour.on_connection_closed.len() == 1)
|
||||||
{
|
{
|
||||||
let conn_id = swarm2.behaviour.inject_connection_closed[0].1;
|
let conn_id = swarm2.behaviour.on_connection_closed[0].1;
|
||||||
assert_eq!(Some(conn_id), disconnected_conn_id);
|
assert_eq!(Some(conn_id), disconnected_conn_id);
|
||||||
return Poll::Ready(());
|
return Poll::Ready(());
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,12 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
use crate::behaviour::{
|
||||||
|
ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr,
|
||||||
|
FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener,
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ConnectionHandler, DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction,
|
ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction,
|
||||||
PollParameters,
|
PollParameters,
|
||||||
};
|
};
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
@ -76,8 +80,6 @@ where
|
|||||||
self.addresses.get(p).map_or(Vec::new(), |v| v.clone())
|
self.addresses.get(p).map_or(Vec::new(), |v| v.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(&mut self, _: PeerId, _: ConnectionId, _: THandler::OutEvent) {}
|
|
||||||
|
|
||||||
fn poll(
|
fn poll(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut Context,
|
_: &mut Context,
|
||||||
@ -85,6 +87,32 @@ where
|
|||||||
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
|
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
|
||||||
self.next_action.take().map_or(Poll::Pending, Poll::Ready)
|
self.next_action.take().map_or(Poll::Pending, Poll::Ready)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::ConnectionClosed(_)
|
||||||
|
| FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_handler_event(
|
||||||
|
&mut self,
|
||||||
|
_peer_id: PeerId,
|
||||||
|
_connection_id: ConnectionId,
|
||||||
|
_event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
|
||||||
|
ConnectionHandler>::OutEvent,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `CallTraceBehaviour` is a `NetworkBehaviour` that tracks
|
/// A `CallTraceBehaviour` is a `NetworkBehaviour` that tracks
|
||||||
@ -97,43 +125,45 @@ where
|
|||||||
inner: TInner,
|
inner: TInner,
|
||||||
|
|
||||||
pub addresses_of_peer: Vec<PeerId>,
|
pub addresses_of_peer: Vec<PeerId>,
|
||||||
pub inject_connection_established: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>,
|
pub on_connection_established: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>,
|
||||||
pub inject_connection_closed: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>,
|
pub on_connection_closed: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>,
|
||||||
pub inject_event: Vec<(
|
pub on_event: Vec<(
|
||||||
PeerId,
|
PeerId,
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
<<TInner::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
<<TInner::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
||||||
)>,
|
)>,
|
||||||
pub inject_dial_failure: Vec<Option<PeerId>>,
|
pub on_dial_failure: Vec<Option<PeerId>>,
|
||||||
pub inject_new_listener: Vec<ListenerId>,
|
pub on_new_listener: Vec<ListenerId>,
|
||||||
pub inject_new_listen_addr: Vec<(ListenerId, Multiaddr)>,
|
pub on_new_listen_addr: Vec<(ListenerId, Multiaddr)>,
|
||||||
pub inject_new_external_addr: Vec<Multiaddr>,
|
pub on_new_external_addr: Vec<Multiaddr>,
|
||||||
pub inject_expired_listen_addr: Vec<(ListenerId, Multiaddr)>,
|
pub on_expired_listen_addr: Vec<(ListenerId, Multiaddr)>,
|
||||||
pub inject_expired_external_addr: Vec<Multiaddr>,
|
pub on_expired_external_addr: Vec<Multiaddr>,
|
||||||
pub inject_listener_error: Vec<ListenerId>,
|
pub on_listener_error: Vec<ListenerId>,
|
||||||
pub inject_listener_closed: Vec<(ListenerId, bool)>,
|
pub on_listener_closed: Vec<(ListenerId, bool)>,
|
||||||
pub poll: usize,
|
pub poll: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TInner> CallTraceBehaviour<TInner>
|
impl<TInner> CallTraceBehaviour<TInner>
|
||||||
where
|
where
|
||||||
TInner: NetworkBehaviour,
|
TInner: NetworkBehaviour,
|
||||||
|
<<TInner::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent:
|
||||||
|
Clone,
|
||||||
{
|
{
|
||||||
pub fn new(inner: TInner) -> Self {
|
pub fn new(inner: TInner) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner,
|
inner,
|
||||||
addresses_of_peer: Vec::new(),
|
addresses_of_peer: Vec::new(),
|
||||||
inject_connection_established: Vec::new(),
|
on_connection_established: Vec::new(),
|
||||||
inject_connection_closed: Vec::new(),
|
on_connection_closed: Vec::new(),
|
||||||
inject_event: Vec::new(),
|
on_event: Vec::new(),
|
||||||
inject_dial_failure: Vec::new(),
|
on_dial_failure: Vec::new(),
|
||||||
inject_new_listener: Vec::new(),
|
on_new_listener: Vec::new(),
|
||||||
inject_new_listen_addr: Vec::new(),
|
on_new_listen_addr: Vec::new(),
|
||||||
inject_new_external_addr: Vec::new(),
|
on_new_external_addr: Vec::new(),
|
||||||
inject_expired_listen_addr: Vec::new(),
|
on_expired_listen_addr: Vec::new(),
|
||||||
inject_expired_external_addr: Vec::new(),
|
on_expired_external_addr: Vec::new(),
|
||||||
inject_listener_error: Vec::new(),
|
on_listener_error: Vec::new(),
|
||||||
inject_listener_closed: Vec::new(),
|
on_listener_closed: Vec::new(),
|
||||||
poll: 0,
|
poll: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,15 +171,15 @@ where
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.addresses_of_peer = Vec::new();
|
self.addresses_of_peer = Vec::new();
|
||||||
self.inject_connection_established = Vec::new();
|
self.on_connection_established = Vec::new();
|
||||||
self.inject_connection_closed = Vec::new();
|
self.on_connection_closed = Vec::new();
|
||||||
self.inject_event = Vec::new();
|
self.on_event = Vec::new();
|
||||||
self.inject_dial_failure = Vec::new();
|
self.on_dial_failure = Vec::new();
|
||||||
self.inject_new_listen_addr = Vec::new();
|
self.on_new_listen_addr = Vec::new();
|
||||||
self.inject_new_external_addr = Vec::new();
|
self.on_new_external_addr = Vec::new();
|
||||||
self.inject_expired_listen_addr = Vec::new();
|
self.on_expired_listen_addr = Vec::new();
|
||||||
self.inject_listener_error = Vec::new();
|
self.on_listener_error = Vec::new();
|
||||||
self.inject_listener_closed = Vec::new();
|
self.on_listener_closed = Vec::new();
|
||||||
self.poll = 0;
|
self.poll = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,12 +188,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_connections_to_peer(&self, peer: PeerId) -> usize {
|
pub fn num_connections_to_peer(&self, peer: PeerId) -> usize {
|
||||||
self.inject_connection_established
|
self.on_connection_established
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(peer_id, _, _, _)| *peer_id == peer)
|
.filter(|(peer_id, _, _, _)| *peer_id == peer)
|
||||||
.count()
|
.count()
|
||||||
- self
|
- self
|
||||||
.inject_connection_closed
|
.on_connection_closed
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(peer_id, _, _, _)| *peer_id == peer)
|
.filter(|(peer_id, _, _, _)| *peer_id == peer)
|
||||||
.count()
|
.count()
|
||||||
@ -178,9 +208,9 @@ where
|
|||||||
expected_closed_connections: usize,
|
expected_closed_connections: usize,
|
||||||
expected_disconnections: usize,
|
expected_disconnections: usize,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if self.inject_connection_closed.len() == expected_closed_connections {
|
if self.on_connection_closed.len() == expected_closed_connections {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.inject_connection_closed
|
self.on_connection_closed
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(.., remaining_established)| { *remaining_established == 0 })
|
.filter(|(.., remaining_established)| { *remaining_established == 0 })
|
||||||
.count(),
|
.count(),
|
||||||
@ -201,9 +231,9 @@ where
|
|||||||
expected_established_connections: usize,
|
expected_established_connections: usize,
|
||||||
expected_connections: usize,
|
expected_connections: usize,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if self.inject_connection_established.len() == expected_established_connections {
|
if self.on_connection_established.len() == expected_established_connections {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.inject_connection_established
|
self.on_connection_established
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(.., reported_aditional_connections)| {
|
.filter(|(.., reported_aditional_connections)| {
|
||||||
*reported_aditional_connections == 0
|
*reported_aditional_connections == 0
|
||||||
@ -216,40 +246,23 @@ where
|
|||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<TInner> NetworkBehaviour for CallTraceBehaviour<TInner>
|
fn on_connection_established(
|
||||||
where
|
|
||||||
TInner: NetworkBehaviour,
|
|
||||||
<<TInner::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent:
|
|
||||||
Clone,
|
|
||||||
{
|
|
||||||
type ConnectionHandler = TInner::ConnectionHandler;
|
|
||||||
type OutEvent = TInner::OutEvent;
|
|
||||||
|
|
||||||
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
|
||||||
self.inner.new_handler()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn addresses_of_peer(&mut self, p: &PeerId) -> Vec<Multiaddr> {
|
|
||||||
self.addresses_of_peer.push(*p);
|
|
||||||
self.inner.addresses_of_peer(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_connection_established(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
p: &PeerId,
|
ConnectionEstablished {
|
||||||
c: &ConnectionId,
|
peer_id,
|
||||||
e: &ConnectedPoint,
|
connection_id,
|
||||||
errors: Option<&Vec<Multiaddr>>,
|
endpoint,
|
||||||
other_established: usize,
|
failed_addresses,
|
||||||
|
other_established,
|
||||||
|
}: ConnectionEstablished,
|
||||||
) {
|
) {
|
||||||
let mut other_peer_connections = self
|
let mut other_peer_connections = self
|
||||||
.inject_connection_established
|
.on_connection_established
|
||||||
.iter()
|
.iter()
|
||||||
.rev() // take last to first
|
.rev() // take last to first
|
||||||
.filter_map(|(peer, .., other_established)| {
|
.filter_map(|(peer, .., other_established)| {
|
||||||
if p == peer {
|
if &peer_id == peer {
|
||||||
Some(other_established)
|
Some(other_established)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -271,26 +284,39 @@ where
|
|||||||
} else {
|
} else {
|
||||||
assert_eq!(other_established, 0)
|
assert_eq!(other_established, 0)
|
||||||
}
|
}
|
||||||
self.inject_connection_established
|
self.on_connection_established.push((
|
||||||
.push((*p, *c, e.clone(), other_established));
|
peer_id,
|
||||||
self.inner
|
connection_id,
|
||||||
.inject_connection_established(p, c, e, errors, other_established);
|
endpoint.clone(),
|
||||||
|
other_established,
|
||||||
|
));
|
||||||
|
let errors = Some(failed_addresses.to_vec());
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_connection_established(
|
||||||
|
&peer_id,
|
||||||
|
&connection_id,
|
||||||
|
endpoint,
|
||||||
|
errors.as_ref(),
|
||||||
|
other_established,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_connection_closed(
|
fn on_connection_closed(
|
||||||
&mut self,
|
&mut self,
|
||||||
p: &PeerId,
|
ConnectionClosed {
|
||||||
c: &ConnectionId,
|
peer_id,
|
||||||
e: &ConnectedPoint,
|
connection_id,
|
||||||
handler: <Self::ConnectionHandler as IntoConnectionHandler>::Handler,
|
endpoint,
|
||||||
remaining_established: usize,
|
handler,
|
||||||
|
remaining_established,
|
||||||
|
}: ConnectionClosed<<Self as NetworkBehaviour>::ConnectionHandler>,
|
||||||
) {
|
) {
|
||||||
let mut other_closed_connections = self
|
let mut other_closed_connections = self
|
||||||
.inject_connection_established
|
.on_connection_established
|
||||||
.iter()
|
.iter()
|
||||||
.rev() // take last to first
|
.rev() // take last to first
|
||||||
.filter_map(|(peer, .., remaining_established)| {
|
.filter_map(|(peer, .., remaining_established)| {
|
||||||
if p == peer {
|
if &peer_id == peer {
|
||||||
Some(remaining_established)
|
Some(remaining_established)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -313,87 +339,133 @@ where
|
|||||||
assert_eq!(remaining_established, 0)
|
assert_eq!(remaining_established, 0)
|
||||||
}
|
}
|
||||||
assert!(
|
assert!(
|
||||||
self.inject_connection_established
|
self.on_connection_established
|
||||||
.iter()
|
.iter()
|
||||||
.any(|(peer, conn_id, endpoint, _)| (peer, conn_id, endpoint) == (p, c, e)),
|
.any(|(peer, conn_id, endpoint, _)| (peer, conn_id, endpoint)
|
||||||
|
== (&peer_id, &connection_id, endpoint)),
|
||||||
"`inject_connection_closed` is called only for connections for \
|
"`inject_connection_closed` is called only for connections for \
|
||||||
which `inject_connection_established` was called first."
|
which `inject_connection_established` was called first."
|
||||||
);
|
);
|
||||||
self.inject_connection_closed
|
self.on_connection_closed.push((
|
||||||
.push((*p, *c, e.clone(), remaining_established));
|
peer_id,
|
||||||
self.inner
|
connection_id,
|
||||||
.inject_connection_closed(p, c, e, handler, remaining_established);
|
endpoint.clone(),
|
||||||
|
remaining_established,
|
||||||
|
));
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_connection_closed(
|
||||||
|
&peer_id,
|
||||||
|
&connection_id,
|
||||||
|
endpoint,
|
||||||
|
handler,
|
||||||
|
remaining_established,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<TInner> NetworkBehaviour for CallTraceBehaviour<TInner>
|
||||||
|
where
|
||||||
|
TInner: NetworkBehaviour,
|
||||||
|
<<TInner::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent:
|
||||||
|
Clone,
|
||||||
|
{
|
||||||
|
type ConnectionHandler = TInner::ConnectionHandler;
|
||||||
|
type OutEvent = TInner::OutEvent;
|
||||||
|
|
||||||
|
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
||||||
|
self.inner.new_handler()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(
|
fn addresses_of_peer(&mut self, p: &PeerId) -> Vec<Multiaddr> {
|
||||||
|
self.addresses_of_peer.push(*p);
|
||||||
|
self.inner.addresses_of_peer(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(connection_established) => {
|
||||||
|
self.on_connection_established(connection_established)
|
||||||
|
}
|
||||||
|
FromSwarm::ConnectionClosed(connection_closed) => {
|
||||||
|
self.on_connection_closed(connection_closed)
|
||||||
|
}
|
||||||
|
FromSwarm::DialFailure(DialFailure {
|
||||||
|
peer_id,
|
||||||
|
handler,
|
||||||
|
error,
|
||||||
|
}) => {
|
||||||
|
self.on_dial_failure.push(peer_id);
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_dial_failure(peer_id, handler, error);
|
||||||
|
}
|
||||||
|
FromSwarm::NewListener(NewListener { listener_id }) => {
|
||||||
|
self.on_new_listener.push(listener_id);
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_new_listener(listener_id);
|
||||||
|
}
|
||||||
|
FromSwarm::NewListenAddr(NewListenAddr { listener_id, addr }) => {
|
||||||
|
self.on_new_listen_addr.push((listener_id, addr.clone()));
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_new_listen_addr(listener_id, addr);
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredListenAddr(ExpiredListenAddr { listener_id, addr }) => {
|
||||||
|
self.on_expired_listen_addr
|
||||||
|
.push((listener_id, addr.clone()));
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_expired_listen_addr(listener_id, addr);
|
||||||
|
}
|
||||||
|
FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => {
|
||||||
|
self.on_new_external_addr.push(addr.clone());
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_new_external_addr(addr);
|
||||||
|
}
|
||||||
|
FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) => {
|
||||||
|
self.on_expired_external_addr.push(addr.clone());
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_expired_external_addr(addr);
|
||||||
|
}
|
||||||
|
FromSwarm::ListenerError(ListenerError { listener_id, err }) => {
|
||||||
|
self.on_listener_error.push(listener_id);
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_listener_error(listener_id, err);
|
||||||
|
}
|
||||||
|
FromSwarm::ListenerClosed(ListenerClosed {
|
||||||
|
listener_id,
|
||||||
|
reason,
|
||||||
|
}) => {
|
||||||
|
self.on_listener_closed.push((listener_id, reason.is_ok()));
|
||||||
|
#[allow(deprecated)]
|
||||||
|
self.inner.inject_listener_closed(listener_id, reason);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
p: PeerId,
|
p: PeerId,
|
||||||
c: ConnectionId,
|
c: ConnectionId,
|
||||||
e: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
e: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
|
||||||
) {
|
) {
|
||||||
assert!(
|
assert!(
|
||||||
self.inject_connection_established
|
self.on_connection_established
|
||||||
.iter()
|
.iter()
|
||||||
.any(|(peer_id, conn_id, ..)| *peer_id == p && c == *conn_id),
|
.any(|(peer_id, conn_id, ..)| *peer_id == p && c == *conn_id),
|
||||||
"`inject_event` is called for reported connections."
|
"`on_connection_handler_event` is called for reported connections."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!self
|
!self
|
||||||
.inject_connection_closed
|
.on_connection_closed
|
||||||
.iter()
|
.iter()
|
||||||
.any(|(peer_id, conn_id, ..)| *peer_id == p && c == *conn_id),
|
.any(|(peer_id, conn_id, ..)| *peer_id == p && c == *conn_id),
|
||||||
"`inject_event` is never called for closed connections."
|
"`on_connection_handler_event` is never called for closed connections."
|
||||||
);
|
);
|
||||||
|
|
||||||
self.inject_event.push((p, c, e.clone()));
|
self.on_event.push((p, c, e.clone()));
|
||||||
|
#[allow(deprecated)]
|
||||||
self.inner.inject_event(p, c, e);
|
self.inner.inject_event(p, c, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_dial_failure(
|
|
||||||
&mut self,
|
|
||||||
p: Option<PeerId>,
|
|
||||||
handler: Self::ConnectionHandler,
|
|
||||||
error: &DialError,
|
|
||||||
) {
|
|
||||||
self.inject_dial_failure.push(p);
|
|
||||||
self.inner.inject_dial_failure(p, handler, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listener(&mut self, id: ListenerId) {
|
|
||||||
self.inject_new_listener.push(id);
|
|
||||||
self.inner.inject_new_listener(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_listen_addr(&mut self, id: ListenerId, a: &Multiaddr) {
|
|
||||||
self.inject_new_listen_addr.push((id, a.clone()));
|
|
||||||
self.inner.inject_new_listen_addr(id, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_listen_addr(&mut self, id: ListenerId, a: &Multiaddr) {
|
|
||||||
self.inject_expired_listen_addr.push((id, a.clone()));
|
|
||||||
self.inner.inject_expired_listen_addr(id, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_new_external_addr(&mut self, a: &Multiaddr) {
|
|
||||||
self.inject_new_external_addr.push(a.clone());
|
|
||||||
self.inner.inject_new_external_addr(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_expired_external_addr(&mut self, a: &Multiaddr) {
|
|
||||||
self.inject_expired_external_addr.push(a.clone());
|
|
||||||
self.inner.inject_expired_external_addr(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_error(&mut self, l: ListenerId, e: &(dyn std::error::Error + 'static)) {
|
|
||||||
self.inject_listener_error.push(l);
|
|
||||||
self.inner.inject_listener_error(l, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject_listener_closed(&mut self, l: ListenerId, r: Result<(), &std::io::Error>) {
|
|
||||||
self.inject_listener_closed.push((l, r.is_ok()));
|
|
||||||
self.inner.inject_listener_closed(l, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll(
|
fn poll(
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut Context,
|
cx: &mut Context,
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use libp2p_identify as identify;
|
use libp2p_identify as identify;
|
||||||
use libp2p_ping as ping;
|
use libp2p_ping as ping;
|
||||||
use libp2p_swarm::{dummy, NetworkBehaviour, SwarmEvent};
|
use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
/// Small utility to check that a type implements `NetworkBehaviour`.
|
/// Small utility to check that a type implements `NetworkBehaviour`.
|
||||||
@ -390,7 +390,7 @@ fn custom_out_event_no_type_parameters() {
|
|||||||
dummy::ConnectionHandler
|
dummy::ConnectionHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_event(
|
fn on_connection_handler_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_peer: PeerId,
|
_peer: PeerId,
|
||||||
_connection: ConnectionId,
|
_connection: ConnectionId,
|
||||||
@ -406,6 +406,23 @@ fn custom_out_event_no_type_parameters() {
|
|||||||
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
|
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>) {
|
||||||
|
match event {
|
||||||
|
FromSwarm::ConnectionEstablished(_)
|
||||||
|
| FromSwarm::ConnectionClosed(_)
|
||||||
|
| FromSwarm::AddressChange(_)
|
||||||
|
| FromSwarm::DialFailure(_)
|
||||||
|
| FromSwarm::ListenFailure(_)
|
||||||
|
| FromSwarm::NewListener(_)
|
||||||
|
| FromSwarm::NewListenAddr(_)
|
||||||
|
| FromSwarm::ExpiredListenAddr(_)
|
||||||
|
| FromSwarm::ListenerError(_)
|
||||||
|
| FromSwarm::ListenerClosed(_)
|
||||||
|
| FromSwarm::NewExternalAddr(_)
|
||||||
|
| FromSwarm::ExpiredExternalAddr(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(NetworkBehaviour)]
|
#[derive(NetworkBehaviour)]
|
||||||
|
Reference in New Issue
Block a user