mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-14 10:31:21 +00:00
feat(swarm): remove deprecated IntoConnectionHandler
This removes the deprecated `IntoConnectionHandler` trait and all its implementations. Consequently, `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` are now gone and the two `handle_` functions are now required to implement. Related: #3647. Pull-Request: #3884.
This commit is contained in:
@ -167,9 +167,6 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Configures the size of the LRU cache, caching addresses of discovered peers.
|
/// Configures the size of the LRU cache, caching addresses of discovered peers.
|
||||||
///
|
|
||||||
/// The [`Swarm`](libp2p_swarm::Swarm) may extend the set of addresses of an outgoing connection attempt via
|
|
||||||
/// [`Behaviour::addresses_of_peer`].
|
|
||||||
pub fn with_cache_size(mut self, cache_size: usize) -> Self {
|
pub fn with_cache_size(mut self, cache_size: usize) -> Self {
|
||||||
self.cache_size = cache_size;
|
self.cache_size = cache_size;
|
||||||
self
|
self
|
||||||
|
@ -47,7 +47,7 @@ pub struct Behaviour {
|
|||||||
|
|
||||||
/// Hold addresses of all peers that we have discovered so far.
|
/// Hold addresses of all peers that we have discovered so far.
|
||||||
///
|
///
|
||||||
/// Storing these internally allows us to assist the [`libp2p_swarm::Swarm`] in dialing by returning addresses from [`NetworkBehaviour::addresses_of_peer`].
|
/// Storing these internally allows us to assist the [`libp2p_swarm::Swarm`] in dialing by returning addresses from [`NetworkBehaviour::handle_pending_outbound_connection`].
|
||||||
discovered_peers: HashMap<(PeerId, Namespace), Vec<Multiaddr>>,
|
discovered_peers: HashMap<(PeerId, Namespace), Vec<Multiaddr>>,
|
||||||
|
|
||||||
/// Tracks the expiry of registrations that we have discovered and stored in `discovered_peers` otherwise we have a memory leak.
|
/// Tracks the expiry of registrations that we have discovered and stored in `discovered_peers` otherwise we have a memory leak.
|
||||||
|
@ -417,7 +417,7 @@ where
|
|||||||
|
|
||||||
/// Adds a known address for a peer that can be used for
|
/// Adds a known address for a peer that can be used for
|
||||||
/// dialing attempts by the `Swarm`, i.e. is returned
|
/// dialing attempts by the `Swarm`, i.e. is returned
|
||||||
/// by [`NetworkBehaviour::addresses_of_peer`].
|
/// by [`NetworkBehaviour::handle_pending_outbound_connection`].
|
||||||
///
|
///
|
||||||
/// Addresses added in this way are only removed by `remove_address`.
|
/// Addresses added in this way are only removed by `remove_address`.
|
||||||
pub fn add_address(&mut self, peer: &PeerId, address: Multiaddr) {
|
pub fn add_address(&mut self, peer: &PeerId, address: Multiaddr) {
|
||||||
|
@ -18,12 +18,18 @@
|
|||||||
This variant was never constructed and thus dead code.
|
This variant was never constructed and thus dead code.
|
||||||
See [PR 3605].
|
See [PR 3605].
|
||||||
|
|
||||||
[PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605
|
- Remove deprecated `IntoConnectionHandler` and all its implementations.
|
||||||
[PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746
|
This also removes the `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` methods.
|
||||||
|
See changelog for `0.42` on how to migrate.
|
||||||
|
See [PR 3884].
|
||||||
|
|
||||||
[PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715
|
[PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715
|
||||||
[PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746
|
[PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746
|
||||||
[PR 3865]: https://github.com/libp2p/rust-libp2p/pull/3865
|
[PR 3865]: https://github.com/libp2p/rust-libp2p/pull/3865
|
||||||
[PR 3886]: https://github.com/libp2p/rust-libp2p/pull/3886
|
[PR 3886]: https://github.com/libp2p/rust-libp2p/pull/3886
|
||||||
|
[PR 3884]: https://github.com/libp2p/rust-libp2p/pull/3884
|
||||||
|
[PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605
|
||||||
|
[PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746
|
||||||
|
|
||||||
## 0.42.2
|
## 0.42.2
|
||||||
|
|
||||||
|
@ -28,11 +28,9 @@ pub use listen_addresses::ListenAddresses;
|
|||||||
|
|
||||||
use crate::connection::ConnectionId;
|
use crate::connection::ConnectionId;
|
||||||
use crate::dial_opts::DialOpts;
|
use crate::dial_opts::DialOpts;
|
||||||
#[allow(deprecated)]
|
|
||||||
use crate::handler::IntoConnectionHandler;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AddressRecord, AddressScore, ConnectionDenied, DialError, ListenError, THandler,
|
AddressRecord, AddressScore, ConnectionDenied, ConnectionHandler, DialError, ListenError,
|
||||||
THandlerInEvent, THandlerOutEvent,
|
THandler, THandlerInEvent, THandlerOutEvent,
|
||||||
};
|
};
|
||||||
use libp2p_core::{transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr};
|
use libp2p_core::{transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr};
|
||||||
use libp2p_identity::PeerId;
|
use libp2p_identity::PeerId;
|
||||||
@ -77,9 +75,7 @@ use std::{task::Context, task::Poll};
|
|||||||
/// implementation for the custom `struct`. Each [`NetworkBehaviour`] trait method is simply
|
/// implementation for the custom `struct`. Each [`NetworkBehaviour`] trait method is simply
|
||||||
/// delegated to each `struct` member in the order the `struct` is defined. For example for
|
/// delegated to each `struct` member in the order the `struct` is defined. For example for
|
||||||
/// [`NetworkBehaviour::poll`] it will first poll the first `struct` member until it returns
|
/// [`NetworkBehaviour::poll`] it will first poll the first `struct` member until it returns
|
||||||
/// [`Poll::Pending`] before moving on to later members. For [`NetworkBehaviour::addresses_of_peer`]
|
/// [`Poll::Pending`] before moving on to later members.
|
||||||
/// it will delegate to each `struct` member and return a concatenated array of all addresses
|
|
||||||
/// returned by the struct members.
|
|
||||||
///
|
///
|
||||||
/// Events ([`NetworkBehaviour::OutEvent`]) returned by each `struct` member are wrapped in a new
|
/// Events ([`NetworkBehaviour::OutEvent`]) returned by each `struct` member are wrapped in a new
|
||||||
/// `enum` event, with an `enum` variant for each `struct` member. Users can define this event
|
/// `enum` event, with an `enum` variant for each `struct` member. Users can define this event
|
||||||
@ -122,37 +118,11 @@ use std::{task::Context, task::Poll};
|
|||||||
/// ```
|
/// ```
|
||||||
pub trait NetworkBehaviour: 'static {
|
pub trait NetworkBehaviour: 'static {
|
||||||
/// Handler for all the protocols the network behaviour supports.
|
/// Handler for all the protocols the network behaviour supports.
|
||||||
#[allow(deprecated)]
|
type ConnectionHandler: ConnectionHandler;
|
||||||
type ConnectionHandler: IntoConnectionHandler;
|
|
||||||
|
|
||||||
/// Event generated by the `NetworkBehaviour` and that the swarm will report back.
|
/// Event generated by the `NetworkBehaviour` and that the swarm will report back.
|
||||||
type OutEvent: Send + 'static;
|
type OutEvent: Send + 'static;
|
||||||
|
|
||||||
/// Creates a new [`ConnectionHandler`](crate::ConnectionHandler) for a connection with a peer.
|
|
||||||
///
|
|
||||||
/// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`]
|
|
||||||
/// emitted a dial request, this method is called.
|
|
||||||
///
|
|
||||||
/// The returned object is a handler for that specific connection, and will be moved to a
|
|
||||||
/// background task dedicated to that connection.
|
|
||||||
///
|
|
||||||
/// The network behaviour (ie. the implementation of this trait) and the handlers it has spawned
|
|
||||||
/// (ie. the objects returned by `new_handler`) can communicate by passing messages. Messages
|
|
||||||
/// sent from the handler to the behaviour are invoked with
|
|
||||||
/// [`NetworkBehaviour::on_connection_handler_event`],
|
|
||||||
/// and the behaviour can send a message to the handler by making [`NetworkBehaviour::poll`]
|
|
||||||
/// return [`ToSwarm::NotifyHandler`].
|
|
||||||
///
|
|
||||||
/// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and
|
|
||||||
/// connection closing.
|
|
||||||
#[deprecated(
|
|
||||||
since = "0.42.0",
|
|
||||||
note = "Use one or more of `NetworkBehaviour::{handle_pending_inbound_connection,handle_established_inbound_connection,handle_pending_outbound_connection,handle_established_outbound_connection}` instead."
|
|
||||||
)]
|
|
||||||
fn new_handler(&mut self) -> Self::ConnectionHandler {
|
|
||||||
panic!("You must implement `handle_established_inbound_connection` and `handle_established_outbound_connection`.")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Callback that is invoked for every new inbound connection.
|
/// Callback that is invoked for every new inbound connection.
|
||||||
///
|
///
|
||||||
/// At this point in the connection lifecycle, only the remote's and our local address are known.
|
/// At this point in the connection lifecycle, only the remote's and our local address are known.
|
||||||
@ -181,16 +151,7 @@ pub trait NetworkBehaviour: 'static {
|
|||||||
peer: PeerId,
|
peer: PeerId,
|
||||||
local_addr: &Multiaddr,
|
local_addr: &Multiaddr,
|
||||||
remote_addr: &Multiaddr,
|
remote_addr: &Multiaddr,
|
||||||
) -> Result<THandler<Self>, ConnectionDenied> {
|
) -> Result<THandler<Self>, ConnectionDenied>;
|
||||||
#[allow(deprecated)]
|
|
||||||
Ok(self.new_handler().into_handler(
|
|
||||||
&peer,
|
|
||||||
&ConnectedPoint::Listener {
|
|
||||||
local_addr: local_addr.clone(),
|
|
||||||
send_back_addr: remote_addr.clone(),
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Callback that is invoked for every outbound connection attempt.
|
/// Callback that is invoked for every outbound connection attempt.
|
||||||
///
|
///
|
||||||
@ -207,16 +168,11 @@ pub trait NetworkBehaviour: 'static {
|
|||||||
fn handle_pending_outbound_connection(
|
fn handle_pending_outbound_connection(
|
||||||
&mut self,
|
&mut self,
|
||||||
_connection_id: ConnectionId,
|
_connection_id: ConnectionId,
|
||||||
maybe_peer: Option<PeerId>,
|
_maybe_peer: Option<PeerId>,
|
||||||
_addresses: &[Multiaddr],
|
_addresses: &[Multiaddr],
|
||||||
_effective_role: Endpoint,
|
_effective_role: Endpoint,
|
||||||
) -> Result<Vec<Multiaddr>, ConnectionDenied> {
|
) -> Result<Vec<Multiaddr>, ConnectionDenied> {
|
||||||
#[allow(deprecated)]
|
Ok(vec![])
|
||||||
if let Some(peer_id) = maybe_peer {
|
|
||||||
Ok(self.addresses_of_peer(&peer_id))
|
|
||||||
} else {
|
|
||||||
Ok(vec![])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback that is invoked for every established outbound connection.
|
/// Callback that is invoked for every established outbound connection.
|
||||||
@ -231,27 +187,7 @@ pub trait NetworkBehaviour: 'static {
|
|||||||
peer: PeerId,
|
peer: PeerId,
|
||||||
addr: &Multiaddr,
|
addr: &Multiaddr,
|
||||||
role_override: Endpoint,
|
role_override: Endpoint,
|
||||||
) -> Result<THandler<Self>, ConnectionDenied> {
|
) -> Result<THandler<Self>, ConnectionDenied>;
|
||||||
#[allow(deprecated)]
|
|
||||||
Ok(self.new_handler().into_handler(
|
|
||||||
&peer,
|
|
||||||
&ConnectedPoint::Dialer {
|
|
||||||
address: addr.clone(),
|
|
||||||
role_override,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Addresses that this behaviour is aware of for this specific peer, and that may allow
|
|
||||||
/// reaching the peer.
|
|
||||||
///
|
|
||||||
/// The addresses will be tried in the order returned by this function, which means that they
|
|
||||||
/// should be ordered by decreasing likelihood of reachability. In other words, the first
|
|
||||||
/// address should be the most likely to be reachable.
|
|
||||||
#[deprecated(note = "Use `NetworkBehaviour::handle_pending_outbound_connection` instead.")]
|
|
||||||
fn addresses_of_peer(&mut self, _: &PeerId) -> Vec<Multiaddr> {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Informs the behaviour about an event from the [`Swarm`](crate::Swarm).
|
/// Informs the behaviour about an event from the [`Swarm`](crate::Swarm).
|
||||||
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>);
|
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>);
|
||||||
@ -480,7 +416,7 @@ pub enum CloseConnection {
|
|||||||
/// Enumeration with the list of the possible events
|
/// Enumeration with the list of the possible events
|
||||||
/// to pass to [`on_swarm_event`](NetworkBehaviour::on_swarm_event).
|
/// to pass to [`on_swarm_event`](NetworkBehaviour::on_swarm_event).
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub enum FromSwarm<'a, Handler: IntoConnectionHandler> {
|
pub enum FromSwarm<'a, Handler> {
|
||||||
/// Informs the behaviour about a newly established connection to a peer.
|
/// Informs the behaviour about a newly established connection to a peer.
|
||||||
ConnectionEstablished(ConnectionEstablished<'a>),
|
ConnectionEstablished(ConnectionEstablished<'a>),
|
||||||
/// Informs the behaviour about a closed connection to a peer.
|
/// Informs the behaviour about a closed connection to a peer.
|
||||||
@ -535,11 +471,11 @@ pub struct ConnectionEstablished<'a> {
|
|||||||
/// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID
|
/// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID
|
||||||
/// and endpoint.
|
/// and endpoint.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub struct ConnectionClosed<'a, Handler: IntoConnectionHandler> {
|
pub struct ConnectionClosed<'a, Handler> {
|
||||||
pub peer_id: PeerId,
|
pub peer_id: PeerId,
|
||||||
pub connection_id: ConnectionId,
|
pub connection_id: ConnectionId,
|
||||||
pub endpoint: &'a ConnectedPoint,
|
pub endpoint: &'a ConnectedPoint,
|
||||||
pub handler: <Handler as IntoConnectionHandler>::Handler,
|
pub handler: Handler,
|
||||||
pub remaining_established: usize,
|
pub remaining_established: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -625,30 +561,19 @@ pub struct ExpiredExternalAddr<'a> {
|
|||||||
pub addr: &'a Multiaddr,
|
pub addr: &'a Multiaddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
impl<'a, Handler> FromSwarm<'a, Handler> {
|
||||||
impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> {
|
|
||||||
fn map_handler<NewHandler>(
|
fn map_handler<NewHandler>(
|
||||||
self,
|
self,
|
||||||
map_handler: impl FnOnce(
|
map_handler: impl FnOnce(Handler) -> NewHandler,
|
||||||
<Handler as IntoConnectionHandler>::Handler,
|
) -> FromSwarm<'a, NewHandler> {
|
||||||
) -> <NewHandler as IntoConnectionHandler>::Handler,
|
|
||||||
) -> FromSwarm<'a, NewHandler>
|
|
||||||
where
|
|
||||||
NewHandler: IntoConnectionHandler,
|
|
||||||
{
|
|
||||||
self.maybe_map_handler(|h| Some(map_handler(h)))
|
self.maybe_map_handler(|h| Some(map_handler(h)))
|
||||||
.expect("To return Some as all closures return Some.")
|
.expect("To return Some as all closures return Some.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_map_handler<NewHandler>(
|
fn maybe_map_handler<NewHandler>(
|
||||||
self,
|
self,
|
||||||
map_handler: impl FnOnce(
|
map_handler: impl FnOnce(Handler) -> Option<NewHandler>,
|
||||||
<Handler as IntoConnectionHandler>::Handler,
|
) -> Option<FromSwarm<'a, NewHandler>> {
|
||||||
) -> Option<<NewHandler as IntoConnectionHandler>::Handler>,
|
|
||||||
) -> Option<FromSwarm<'a, NewHandler>>
|
|
||||||
where
|
|
||||||
NewHandler: IntoConnectionHandler,
|
|
||||||
{
|
|
||||||
match self {
|
match self {
|
||||||
FromSwarm::ConnectionClosed(ConnectionClosed {
|
FromSwarm::ConnectionClosed(ConnectionClosed {
|
||||||
peer_id,
|
peer_id,
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
use crate::behaviour::{ExpiredExternalAddr, FromSwarm, NewExternalAddr};
|
use crate::behaviour::{ExpiredExternalAddr, FromSwarm, NewExternalAddr};
|
||||||
#[allow(deprecated)]
|
|
||||||
use crate::IntoConnectionHandler;
|
|
||||||
use libp2p_core::Multiaddr;
|
use libp2p_core::Multiaddr;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
@ -34,11 +32,7 @@ impl ExternalAddresses {
|
|||||||
/// Feed a [`FromSwarm`] event to this struct.
|
/// Feed a [`FromSwarm`] event to this struct.
|
||||||
///
|
///
|
||||||
/// Returns whether the event changed our set of external addresses.
|
/// Returns whether the event changed our set of external addresses.
|
||||||
#[allow(deprecated)]
|
pub fn on_swarm_event<THandler>(&mut self, event: &FromSwarm<THandler>) -> bool {
|
||||||
pub fn on_swarm_event<THandler>(&mut self, event: &FromSwarm<THandler>) -> bool
|
|
||||||
where
|
|
||||||
THandler: IntoConnectionHandler,
|
|
||||||
{
|
|
||||||
match event {
|
match event {
|
||||||
FromSwarm::NewExternalAddr(NewExternalAddr { addr, .. }) => {
|
FromSwarm::NewExternalAddr(NewExternalAddr { addr, .. }) => {
|
||||||
if self.addresses.len() < self.limit {
|
if self.addresses.len() < self.limit {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
use crate::behaviour::{ExpiredListenAddr, FromSwarm, NewListenAddr};
|
use crate::behaviour::{ExpiredListenAddr, FromSwarm, NewListenAddr};
|
||||||
#[allow(deprecated)]
|
|
||||||
use crate::IntoConnectionHandler;
|
|
||||||
use libp2p_core::Multiaddr;
|
use libp2p_core::Multiaddr;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
@ -19,11 +17,7 @@ impl ListenAddresses {
|
|||||||
/// Feed a [`FromSwarm`] event to this struct.
|
/// Feed a [`FromSwarm`] event to this struct.
|
||||||
///
|
///
|
||||||
/// Returns whether the event changed our set of listen addresses.
|
/// Returns whether the event changed our set of listen addresses.
|
||||||
#[allow(deprecated)]
|
pub fn on_swarm_event<THandler>(&mut self, event: &FromSwarm<THandler>) -> bool {
|
||||||
pub fn on_swarm_event<THandler>(&mut self, event: &FromSwarm<THandler>) -> bool
|
|
||||||
where
|
|
||||||
THandler: IntoConnectionHandler,
|
|
||||||
{
|
|
||||||
match event {
|
match event {
|
||||||
FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => {
|
FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => {
|
||||||
self.addresses.insert((*addr).clone())
|
self.addresses.insert((*addr).clone())
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
use crate::connection::{Connection, ConnectionId, ConnectionLimit, PendingPoint};
|
use crate::connection::{Connection, ConnectionId, ConnectionLimit, PendingPoint};
|
||||||
#[allow(deprecated)]
|
|
||||||
use crate::IntoConnectionHandler;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
connection::{
|
connection::{
|
||||||
Connected, ConnectionError, IncomingInfo, PendingConnectionError,
|
Connected, ConnectionError, IncomingInfo, PendingConnectionError,
|
||||||
@ -512,7 +510,7 @@ where
|
|||||||
obtained_peer_id: PeerId,
|
obtained_peer_id: PeerId,
|
||||||
endpoint: &ConnectedPoint,
|
endpoint: &ConnectedPoint,
|
||||||
connection: NewConnection,
|
connection: NewConnection,
|
||||||
handler: <THandler as IntoConnectionHandler>::Handler,
|
handler: THandler,
|
||||||
) {
|
) {
|
||||||
let connection = connection.extract();
|
let connection = connection.extract();
|
||||||
|
|
||||||
|
@ -207,9 +207,6 @@ impl WithPeerId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Build the final [`DialOpts`].
|
/// Build the final [`DialOpts`].
|
||||||
///
|
|
||||||
/// Addresses to dial the peer are retrieved via
|
|
||||||
/// [`NetworkBehaviour::addresses_of_peer`](crate::behaviour::NetworkBehaviour::addresses_of_peer).
|
|
||||||
pub fn build(self) -> DialOpts {
|
pub fn build(self) -> DialOpts {
|
||||||
DialOpts {
|
DialOpts {
|
||||||
peer_id: Some(self.peer_id),
|
peer_id: Some(self.peer_id),
|
||||||
@ -241,7 +238,7 @@ impl WithPeerIdWithAddresses {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// In addition to the provided addresses, extend the set via
|
/// In addition to the provided addresses, extend the set via
|
||||||
/// [`NetworkBehaviour::addresses_of_peer`](crate::behaviour::NetworkBehaviour::addresses_of_peer).
|
/// [`NetworkBehaviour::handle_pending_outbound_connection`](crate::behaviour::NetworkBehaviour::handle_pending_outbound_connection).
|
||||||
pub fn extend_addresses_through_behaviour(mut self) -> Self {
|
pub fn extend_addresses_through_behaviour(mut self) -> Self {
|
||||||
self.extend_addresses_through_behaviour = true;
|
self.extend_addresses_through_behaviour = true;
|
||||||
self
|
self
|
||||||
|
@ -49,15 +49,14 @@ mod select;
|
|||||||
pub use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper, UpgradeInfoSend};
|
pub use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper, UpgradeInfoSend};
|
||||||
|
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use libp2p_core::{upgrade::UpgradeError, ConnectedPoint, Multiaddr};
|
use libp2p_core::{upgrade::UpgradeError, Multiaddr};
|
||||||
use libp2p_identity::PeerId;
|
|
||||||
use std::{cmp::Ordering, error, fmt, task::Context, task::Poll, time::Duration};
|
use std::{cmp::Ordering, error, fmt, task::Context, task::Poll, time::Duration};
|
||||||
|
|
||||||
pub use map_in::MapInEvent;
|
pub use map_in::MapInEvent;
|
||||||
pub use map_out::MapOutEvent;
|
pub use map_out::MapOutEvent;
|
||||||
pub use one_shot::{OneShotHandler, OneShotHandlerConfig};
|
pub use one_shot::{OneShotHandler, OneShotHandlerConfig};
|
||||||
pub use pending::PendingConnectionHandler;
|
pub use pending::PendingConnectionHandler;
|
||||||
pub use select::{ConnectionHandlerSelect, IntoConnectionHandlerSelect};
|
pub use select::ConnectionHandlerSelect;
|
||||||
|
|
||||||
/// A handler for a set of protocols used on a connection with a remote.
|
/// A handler for a set of protocols used on a connection with a remote.
|
||||||
///
|
///
|
||||||
@ -510,52 +509,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prototype for a [`ConnectionHandler`].
|
|
||||||
#[deprecated(
|
|
||||||
note = "Implement `ConnectionHandler` directly and use `NetworkBehaviour::{handle_pending_inbound_connection,handle_pending_outbound_connection}` to handle pending connections."
|
|
||||||
)]
|
|
||||||
pub trait IntoConnectionHandler: Send + 'static {
|
|
||||||
/// The protocols handler.
|
|
||||||
type Handler: ConnectionHandler;
|
|
||||||
|
|
||||||
/// Builds the protocols handler.
|
|
||||||
///
|
|
||||||
/// The `PeerId` is the id of the node the handler is going to handle.
|
|
||||||
fn into_handler(
|
|
||||||
self,
|
|
||||||
remote_peer_id: &PeerId,
|
|
||||||
connected_point: &ConnectedPoint,
|
|
||||||
) -> Self::Handler;
|
|
||||||
|
|
||||||
/// Return the handler's inbound protocol.
|
|
||||||
fn inbound_protocol(&self) -> <Self::Handler as ConnectionHandler>::InboundProtocol;
|
|
||||||
|
|
||||||
/// Builds an implementation of [`IntoConnectionHandler`] that handles both this protocol and the
|
|
||||||
/// other one together.
|
|
||||||
fn select<TProto2>(self, other: TProto2) -> IntoConnectionHandlerSelect<Self, TProto2>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
IntoConnectionHandlerSelect::new(self, other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl<T> IntoConnectionHandler for T
|
|
||||||
where
|
|
||||||
T: ConnectionHandler,
|
|
||||||
{
|
|
||||||
type Handler = Self;
|
|
||||||
|
|
||||||
fn into_handler(self, _: &PeerId, _: &ConnectedPoint) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inbound_protocol(&self) -> <Self::Handler as ConnectionHandler>::InboundProtocol {
|
|
||||||
self.listen_protocol().into_upgrade().0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// How long the connection should be kept alive.
|
/// How long the connection should be kept alive.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum KeepAlive {
|
pub enum KeepAlive {
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
use crate::handler::IntoConnectionHandler;
|
|
||||||
use crate::handler::{
|
use crate::handler::{
|
||||||
ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, FullyNegotiatedInbound,
|
ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, FullyNegotiatedInbound,
|
||||||
InboundUpgradeSend, KeepAlive, ListenUpgradeError, SubstreamProtocol,
|
InboundUpgradeSend, KeepAlive, ListenUpgradeError, SubstreamProtocol,
|
||||||
@ -27,71 +25,8 @@ use crate::handler::{
|
|||||||
use crate::upgrade::SendWrapper;
|
use crate::upgrade::SendWrapper;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use libp2p_core::ConnectedPoint;
|
|
||||||
use libp2p_identity::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> {
|
|
||||||
Left(L),
|
|
||||||
Right(R),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation of a [`IntoConnectionHandler`] that represents either of two [`IntoConnectionHandler`]
|
|
||||||
/// implementations.
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl<L, R> IntoConnectionHandler for IntoEitherHandler<L, R>
|
|
||||||
where
|
|
||||||
L: IntoConnectionHandler,
|
|
||||||
R: IntoConnectionHandler,
|
|
||||||
{
|
|
||||||
type Handler = Either<L::Handler, R::Handler>;
|
|
||||||
|
|
||||||
fn into_handler(self, p: &PeerId, c: &ConnectedPoint) -> Self::Handler {
|
|
||||||
match self {
|
|
||||||
IntoEitherHandler::Left(into_handler) => Either::Left(into_handler.into_handler(p, c)),
|
|
||||||
IntoEitherHandler::Right(into_handler) => {
|
|
||||||
Either::Right(into_handler.into_handler(p, c))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inbound_protocol(&self) -> <Self::Handler as ConnectionHandler>::InboundProtocol {
|
|
||||||
match self {
|
|
||||||
IntoEitherHandler::Left(into_handler) => {
|
|
||||||
Either::Left(SendWrapper(into_handler.inbound_protocol()))
|
|
||||||
}
|
|
||||||
IntoEitherHandler::Right(into_handler) => {
|
|
||||||
Either::Right(SendWrapper(into_handler.inbound_protocol()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.",)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<LIP, RIP, LIOI, RIOI>
|
impl<LIP, RIP, LIOI, RIOI>
|
||||||
FullyNegotiatedInbound<Either<SendWrapper<LIP>, SendWrapper<RIP>>, Either<LIOI, RIOI>>
|
FullyNegotiatedInbound<Either<SendWrapper<LIP>, SendWrapper<RIP>>, Either<LIOI, RIOI>>
|
||||||
where
|
where
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
//! A [`ConnectionHandler`] implementation that combines multiple other [`ConnectionHandler`]s
|
//! A [`ConnectionHandler`] implementation that combines multiple other [`ConnectionHandler`]s
|
||||||
//! indexed by some key.
|
//! indexed by some key.
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
use crate::handler::IntoConnectionHandler;
|
|
||||||
use crate::handler::{
|
use crate::handler::{
|
||||||
AddressChange, ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, DialUpgradeError,
|
AddressChange, ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, DialUpgradeError,
|
||||||
FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, ListenUpgradeError,
|
FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, ListenUpgradeError,
|
||||||
@ -31,8 +29,6 @@ use crate::handler::{
|
|||||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend};
|
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend};
|
||||||
use crate::NegotiatedSubstream;
|
use crate::NegotiatedSubstream;
|
||||||
use futures::{future::BoxFuture, prelude::*};
|
use futures::{future::BoxFuture, prelude::*};
|
||||||
use libp2p_core::ConnectedPoint;
|
|
||||||
use libp2p_identity::PeerId;
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::{
|
use std::{
|
||||||
cmp,
|
cmp,
|
||||||
@ -280,76 +276,6 @@ impl<K, H> IntoIterator for MultiHandler<K, H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [`IntoConnectionHandler`] for multiple other `IntoConnectionHandler`s.
|
|
||||||
#[derive(Clone)]
|
|
||||||
#[deprecated(note = "Use `MultiHandler` directly.")]
|
|
||||||
pub struct IntoMultiHandler<K, H> {
|
|
||||||
handlers: HashMap<K, H>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl<K, H> fmt::Debug for IntoMultiHandler<K, H>
|
|
||||||
where
|
|
||||||
K: fmt::Debug + Eq + Hash,
|
|
||||||
H: fmt::Debug,
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_struct("IntoMultiHandler")
|
|
||||||
.field("handlers", &self.handlers)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl<K, H> IntoMultiHandler<K, H>
|
|
||||||
where
|
|
||||||
K: Hash + Eq,
|
|
||||||
H: IntoConnectionHandler,
|
|
||||||
{
|
|
||||||
/// Create and populate an `IntoMultiHandler` from the given iterator.
|
|
||||||
///
|
|
||||||
/// It is an error for any two protocols handlers to share the same protocol name.
|
|
||||||
pub fn try_from_iter<I>(iter: I) -> Result<Self, DuplicateProtonameError>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = (K, H)>,
|
|
||||||
{
|
|
||||||
let m = IntoMultiHandler {
|
|
||||||
handlers: HashMap::from_iter(iter),
|
|
||||||
};
|
|
||||||
uniq_proto_names(m.handlers.values().map(|h| h.inbound_protocol()))?;
|
|
||||||
Ok(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl<K, H> IntoConnectionHandler for IntoMultiHandler<K, H>
|
|
||||||
where
|
|
||||||
K: Debug + Clone + Eq + Hash + Send + 'static,
|
|
||||||
H: IntoConnectionHandler,
|
|
||||||
{
|
|
||||||
type Handler = MultiHandler<K, H::Handler>;
|
|
||||||
|
|
||||||
fn into_handler(self, p: &PeerId, c: &ConnectedPoint) -> Self::Handler {
|
|
||||||
MultiHandler {
|
|
||||||
handlers: self
|
|
||||||
.handlers
|
|
||||||
.into_iter()
|
|
||||||
.map(|(k, h)| (k, h.into_handler(p, c)))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inbound_protocol(&self) -> <Self::Handler as ConnectionHandler>::InboundProtocol {
|
|
||||||
Upgrade {
|
|
||||||
upgrades: self
|
|
||||||
.handlers
|
|
||||||
.iter()
|
|
||||||
.map(|(k, h)| (k.clone(), h.inbound_protocol()))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Index and protocol name pair used as `UpgradeInfo::Info`.
|
/// Index and protocol name pair used as `UpgradeInfo::Info`.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct IndexedProtoName<H>(usize, H);
|
pub struct IndexedProtoName<H>(usize, H);
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
use crate::handler::IntoConnectionHandler;
|
|
||||||
use crate::handler::{
|
use crate::handler::{
|
||||||
AddressChange, ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent,
|
AddressChange, ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent,
|
||||||
ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound,
|
ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound,
|
||||||
@ -28,60 +26,9 @@ use crate::handler::{
|
|||||||
use crate::upgrade::SendWrapper;
|
use crate::upgrade::SendWrapper;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use libp2p_core::{
|
use libp2p_core::upgrade::{SelectUpgrade, UpgradeError};
|
||||||
upgrade::{SelectUpgrade, UpgradeError},
|
|
||||||
ConnectedPoint,
|
|
||||||
};
|
|
||||||
use libp2p_identity::PeerId;
|
|
||||||
use std::{cmp, task::Context, task::Poll};
|
use std::{cmp, task::Context, task::Poll};
|
||||||
|
|
||||||
/// Implementation of `IntoConnectionHandler` that combines two protocols into one.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct IntoConnectionHandlerSelect<TProto1, TProto2> {
|
|
||||||
/// The first protocol.
|
|
||||||
proto1: TProto1,
|
|
||||||
/// The second protocol.
|
|
||||||
proto2: TProto2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<TProto1, TProto2> IntoConnectionHandlerSelect<TProto1, TProto2> {
|
|
||||||
/// Builds a `IntoConnectionHandlerSelect`.
|
|
||||||
pub(crate) fn new(proto1: TProto1, proto2: TProto2) -> Self {
|
|
||||||
IntoConnectionHandlerSelect { proto1, proto2 }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_inner(self) -> (TProto1, TProto2) {
|
|
||||||
(self.proto1, self.proto2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl<TProto1, TProto2> IntoConnectionHandler for IntoConnectionHandlerSelect<TProto1, TProto2>
|
|
||||||
where
|
|
||||||
TProto1: IntoConnectionHandler,
|
|
||||||
TProto2: IntoConnectionHandler,
|
|
||||||
{
|
|
||||||
type Handler = ConnectionHandlerSelect<TProto1::Handler, TProto2::Handler>;
|
|
||||||
|
|
||||||
fn into_handler(
|
|
||||||
self,
|
|
||||||
remote_peer_id: &PeerId,
|
|
||||||
connected_point: &ConnectedPoint,
|
|
||||||
) -> Self::Handler {
|
|
||||||
ConnectionHandlerSelect {
|
|
||||||
proto1: self.proto1.into_handler(remote_peer_id, connected_point),
|
|
||||||
proto2: self.proto2.into_handler(remote_peer_id, connected_point),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inbound_protocol(&self) -> <Self::Handler as ConnectionHandler>::InboundProtocol {
|
|
||||||
SelectUpgrade::new(
|
|
||||||
SendWrapper(self.proto1.inbound_protocol()),
|
|
||||||
SendWrapper(self.proto2.inbound_protocol()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation of [`ConnectionHandler`] that combines two protocols into one.
|
/// Implementation of [`ConnectionHandler`] that combines two protocols into one.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ConnectionHandlerSelect<TProto1, TProto2> {
|
pub struct ConnectionHandlerSelect<TProto1, TProto2> {
|
||||||
|
@ -121,12 +121,9 @@ pub use behaviour::{
|
|||||||
pub use connection::pool::{ConnectionCounters, ConnectionLimits};
|
pub use connection::pool::{ConnectionCounters, ConnectionLimits};
|
||||||
pub use connection::{ConnectionError, ConnectionId};
|
pub use connection::{ConnectionError, ConnectionId};
|
||||||
pub use executor::Executor;
|
pub use executor::Executor;
|
||||||
#[allow(deprecated)]
|
|
||||||
pub use handler::IntoConnectionHandler;
|
|
||||||
pub use handler::{
|
pub use handler::{
|
||||||
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr,
|
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr,
|
||||||
IntoConnectionHandlerSelect, KeepAlive, OneShotHandler, OneShotHandlerConfig,
|
KeepAlive, OneShotHandler, OneShotHandlerConfig, SubstreamProtocol,
|
||||||
SubstreamProtocol,
|
|
||||||
};
|
};
|
||||||
#[cfg(feature = "macros")]
|
#[cfg(feature = "macros")]
|
||||||
pub use libp2p_swarm_derive::NetworkBehaviour;
|
pub use libp2p_swarm_derive::NetworkBehaviour;
|
||||||
@ -174,8 +171,7 @@ type TBehaviourOutEvent<TBehaviour> = <TBehaviour as NetworkBehaviour>::OutEvent
|
|||||||
/// [`ConnectionHandler`] of the [`NetworkBehaviour`] for all the protocols the [`NetworkBehaviour`]
|
/// [`ConnectionHandler`] of the [`NetworkBehaviour`] for all the protocols the [`NetworkBehaviour`]
|
||||||
/// supports.
|
/// supports.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub type THandler<TBehaviour> =
|
pub type THandler<TBehaviour> = <TBehaviour as NetworkBehaviour>::ConnectionHandler;
|
||||||
<<TBehaviour as NetworkBehaviour>::ConnectionHandler as IntoConnectionHandler>::Handler;
|
|
||||||
|
|
||||||
/// Custom event that can be received by the [`ConnectionHandler`] of the
|
/// Custom event that can be received by the [`ConnectionHandler`] of the
|
||||||
/// [`NetworkBehaviour`].
|
/// [`NetworkBehaviour`].
|
||||||
@ -1681,8 +1677,7 @@ pub enum DialError {
|
|||||||
LocalPeerId {
|
LocalPeerId {
|
||||||
endpoint: ConnectedPoint,
|
endpoint: ConnectedPoint,
|
||||||
},
|
},
|
||||||
/// [`NetworkBehaviour::addresses_of_peer`] returned no addresses
|
/// No addresses have been provided by [`NetworkBehaviour::handle_pending_outbound_connection`] and [`DialOpts`].
|
||||||
/// for the peer to dial.
|
|
||||||
NoAddresses,
|
NoAddresses,
|
||||||
/// The provided [`dial_opts::PeerCondition`] evaluated to false and thus
|
/// The provided [`dial_opts::PeerCondition`] evaluated to false and thus
|
||||||
/// the dial was aborted.
|
/// the dial was aborted.
|
||||||
|
@ -41,9 +41,9 @@ where
|
|||||||
TOutEvent: Send + 'static,
|
TOutEvent: Send + 'static,
|
||||||
{
|
{
|
||||||
/// The prototype protocols handler that is cloned for every
|
/// The prototype protocols handler that is cloned for every
|
||||||
/// invocation of `new_handler`.
|
/// invocation of [`NetworkBehaviour::handle_established_inbound_connection`] and [`NetworkBehaviour::handle_established_outbound_connection`]
|
||||||
pub(crate) handler_proto: THandler,
|
pub(crate) handler_proto: THandler,
|
||||||
/// The addresses to return from `addresses_of_peer`.
|
/// The addresses to return from [`NetworkBehaviour::handle_established_outbound_connection`].
|
||||||
pub(crate) addresses: HashMap<PeerId, Vec<Multiaddr>>,
|
pub(crate) addresses: HashMap<PeerId, Vec<Multiaddr>>,
|
||||||
/// The next action to return from `poll`.
|
/// The next action to return from `poll`.
|
||||||
///
|
///
|
||||||
|
Reference in New Issue
Block a user