*: Rework reporting of invalid and wrong PeerIds (#2441)

Previously, the negotiated PeerId was included in the swarm event and
inject_dial_failure’s arguments while the expected one was absent. This
patch adds the negotiated PeerId to the DialError and includes the expected
one in the notifications.

Co-authored-by: Roland Kuhn <rk@rkuhn.info>
This commit is contained in:
Max Inden
2022-01-18 21:21:11 +01:00
committed by GitHub
parent 30fc882037
commit 4001b565b6
9 changed files with 170 additions and 73 deletions

View File

@ -14,14 +14,17 @@
- Enable overriding _dial concurrency factor_ per dial via - Enable overriding _dial concurrency factor_ per dial via
`DialOpts::override_dial_concurrency_factor`. `DialOpts::override_dial_concurrency_factor`.
- Introduces `libp2p_core::DialOpts` mirroring `libp2p_swarm::DialOpts`. - Introduces `libp2p_core::DialOpts` mirroring `libp2p_swarm::DialOpts`.
Passed as an argument to `Network::dial`. Passed as an argument to `Network::dial`.
- Removes `Peer::dial` in favor of `Network::dial`. - Removes `Peer::dial` in favor of `Network::dial`.
See [PR 2404]. See [PR 2404].
- Implement `Serialize` and `Deserialize` for `PeerId` (see [PR 2408]) - Implement `Serialize` and `Deserialize` for `PeerId` (see [PR 2408])
- Report negotiated and expected `PeerId` as well as remote address in
`DialError::WrongPeerId` (see [PR 2428]).
- Allow overriding role when dialing. This option is needed for NAT and firewall - Allow overriding role when dialing. This option is needed for NAT and firewall
hole punching. hole punching.
@ -39,6 +42,7 @@
[PR 2392]: https://github.com/libp2p/rust-libp2p/pull/2392 [PR 2392]: https://github.com/libp2p/rust-libp2p/pull/2392
[PR 2404]: https://github.com/libp2p/rust-libp2p/pull/2404 [PR 2404]: https://github.com/libp2p/rust-libp2p/pull/2404
[PR 2408]: https://github.com/libp2p/rust-libp2p/pull/2408 [PR 2408]: https://github.com/libp2p/rust-libp2p/pull/2408
[PR 2428]: https://github.com/libp2p/rust-libp2p/pull/2428
[PR 2363]: https://github.com/libp2p/rust-libp2p/pull/2363 [PR 2363]: https://github.com/libp2p/rust-libp2p/pull/2363
# 0.30.1 [2021-11-16] # 0.30.1 [2021-11-16]
@ -127,7 +131,7 @@
# 0.28.3 [2021-04-26] # 0.28.3 [2021-04-26]
- Fix build with secp256k1 disabled [PR 2057](https://github.com/libp2p/rust-libp2p/pull/2057]. - Fix build with secp256k1 disabled [PR 2057](https://github.com/libp2p/rust-libp2p/pull/2057).
# 0.28.2 [2021-04-13] # 0.28.2 [2021-04-13]

View File

@ -18,9 +18,9 @@
// 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::connection::ConnectionLimit;
use crate::transport::TransportError; use crate::transport::TransportError;
use crate::Multiaddr; use crate::Multiaddr;
use crate::{connection::ConnectionLimit, ConnectedPoint, PeerId};
use std::{fmt, io}; use std::{fmt, io};
/// Errors that can occur in the context of an established `Connection`. /// Errors that can occur in the context of an established `Connection`.
@ -84,14 +84,33 @@ pub enum PendingConnectionError<TTransErr> {
Aborted, Aborted,
/// The peer identity obtained on the connection did not /// The peer identity obtained on the connection did not
/// match the one that was expected or is otherwise invalid. /// match the one that was expected or is the local one.
InvalidPeerId, WrongPeerId {
obtained: PeerId,
endpoint: ConnectedPoint,
},
/// An I/O error occurred on the connection. /// An I/O error occurred on the connection.
// TODO: Eventually this should also be a custom error? // TODO: Eventually this should also be a custom error?
IO(io::Error), IO(io::Error),
} }
impl<T> PendingConnectionError<T> {
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> PendingConnectionError<U> {
match self {
PendingConnectionError::Transport(t) => PendingConnectionError::Transport(f(t)),
PendingConnectionError::ConnectionLimit(l) => {
PendingConnectionError::ConnectionLimit(l)
}
PendingConnectionError::Aborted => PendingConnectionError::Aborted,
PendingConnectionError::WrongPeerId { obtained, endpoint } => {
PendingConnectionError::WrongPeerId { obtained, endpoint }
}
PendingConnectionError::IO(e) => PendingConnectionError::IO(e),
}
}
}
impl<TTransErr> fmt::Display for PendingConnectionError<TTransErr> impl<TTransErr> fmt::Display for PendingConnectionError<TTransErr>
where where
TTransErr: fmt::Display + fmt::Debug, TTransErr: fmt::Display + fmt::Debug,
@ -110,8 +129,12 @@ where
PendingConnectionError::ConnectionLimit(l) => { PendingConnectionError::ConnectionLimit(l) => {
write!(f, "Connection error: Connection limit: {}.", l) write!(f, "Connection error: Connection limit: {}.", l)
} }
PendingConnectionError::InvalidPeerId => { PendingConnectionError::WrongPeerId { obtained, endpoint } => {
write!(f, "Pending connection: Invalid peer ID.") write!(
f,
"Pending connection: Unexpected peer ID {} at {:?}.",
obtained, endpoint
)
} }
} }
} }
@ -125,7 +148,7 @@ where
match self { match self {
PendingConnectionError::IO(err) => Some(err), PendingConnectionError::IO(err) => Some(err),
PendingConnectionError::Transport(_) => None, PendingConnectionError::Transport(_) => None,
PendingConnectionError::InvalidPeerId => None, PendingConnectionError::WrongPeerId { .. } => None,
PendingConnectionError::Aborted => None, PendingConnectionError::Aborted => None,
PendingConnectionError::ConnectionLimit(..) => None, PendingConnectionError::ConnectionLimit(..) => None,
} }

View File

@ -733,7 +733,7 @@ where
match event { match event {
task::PendingConnectionEvent::ConnectionEstablished { task::PendingConnectionEvent::ConnectionEstablished {
id, id,
output: (peer_id, muxer), output: (obtained_peer_id, muxer),
outgoing, outgoing,
} => { } => {
let PendingConnectionInfo { let PendingConnectionInfo {
@ -777,49 +777,42 @@ where
), ),
}; };
enum Error { let error: Result<(), PendingInboundConnectionError<_>> = self
ConnectionLimit(ConnectionLimit),
InvalidPeerId,
}
impl<TransportError> From<Error> for PendingConnectionError<TransportError> {
fn from(error: Error) -> Self {
match error {
Error::ConnectionLimit(limit) => {
PendingConnectionError::ConnectionLimit(limit)
}
Error::InvalidPeerId => PendingConnectionError::InvalidPeerId,
}
}
}
let error = self
.counters .counters
// Check general established connection limit. // Check general established connection limit.
.check_max_established(&endpoint) .check_max_established(&endpoint)
.map_err(Error::ConnectionLimit) .map_err(PendingConnectionError::ConnectionLimit)
// Check per-peer established connection limit. // Check per-peer established connection limit.
.and_then(|()| { .and_then(|()| {
self.counters self.counters
.check_max_established_per_peer(num_peer_established( .check_max_established_per_peer(num_peer_established(
&self.established, &self.established,
peer_id, obtained_peer_id,
)) ))
.map_err(Error::ConnectionLimit) .map_err(PendingConnectionError::ConnectionLimit)
}) })
// Check expected peer id matches. // Check expected peer id matches.
.and_then(|()| { .and_then(|()| {
if let Some(peer) = expected_peer_id { if let Some(peer) = expected_peer_id {
if peer != peer_id { if peer != obtained_peer_id {
return Err(Error::InvalidPeerId); Err(PendingConnectionError::WrongPeerId {
obtained: obtained_peer_id,
endpoint: endpoint.clone(),
})
} else {
Ok(())
} }
} else {
Ok(())
} }
Ok(())
}) })
// Check peer is not local peer. // Check peer is not local peer.
.and_then(|()| { .and_then(|()| {
if self.local_id == peer_id { if self.local_id == obtained_peer_id {
Err(Error::InvalidPeerId) Err(PendingConnectionError::WrongPeerId {
obtained: obtained_peer_id,
endpoint: endpoint.clone(),
})
} else { } else {
Ok(()) Ok(())
} }
@ -832,7 +825,7 @@ where
log::debug!( log::debug!(
"Failed to close connection {:?} to peer {}: {:?}", "Failed to close connection {:?} to peer {}: {:?}",
id, id,
peer_id, obtained_peer_id,
e e
); );
} }
@ -845,9 +838,10 @@ where
ConnectedPoint::Dialer { .. } => { ConnectedPoint::Dialer { .. } => {
return Poll::Ready(PoolEvent::PendingOutboundConnectionError { return Poll::Ready(PoolEvent::PendingOutboundConnectionError {
id, id,
error: error.into(), error: error
.map(|t| vec![(endpoint.get_remote_address().clone(), t)]),
handler, handler,
peer: Some(peer_id), peer: expected_peer_id.or(Some(obtained_peer_id)),
}) })
} }
ConnectedPoint::Listener { ConnectedPoint::Listener {
@ -856,7 +850,7 @@ where
} => { } => {
return Poll::Ready(PoolEvent::PendingInboundConnectionError { return Poll::Ready(PoolEvent::PendingInboundConnectionError {
id, id,
error: error.into(), error,
handler, handler,
send_back_addr, send_back_addr,
local_addr, local_addr,
@ -866,7 +860,7 @@ where
} }
// Add the connection to the pool. // Add the connection to the pool.
let conns = self.established.entry(peer_id).or_default(); let conns = self.established.entry(obtained_peer_id).or_default();
let other_established_connection_ids = conns.keys().cloned().collect(); let other_established_connection_ids = conns.keys().cloned().collect();
self.counters.inc_established(&endpoint); self.counters.inc_established(&endpoint);
@ -875,20 +869,23 @@ where
conns.insert( conns.insert(
id, id,
EstablishedConnectionInfo { EstablishedConnectionInfo {
peer_id, peer_id: obtained_peer_id,
endpoint: endpoint.clone(), endpoint: endpoint.clone(),
sender: command_sender, sender: command_sender,
}, },
); );
let connected = Connected { peer_id, endpoint }; let connected = Connected {
peer_id: obtained_peer_id,
endpoint,
};
let connection = let connection =
super::Connection::new(muxer, handler.into_handler(&connected)); super::Connection::new(muxer, handler.into_handler(&connected));
self.spawn( self.spawn(
task::new_for_established_connection( task::new_for_established_connection(
id, id,
peer_id, obtained_peer_id,
connection, connection,
command_receiver, command_receiver,
self.established_connection_events_tx.clone(), self.established_connection_events_tx.clone(),

View File

@ -37,6 +37,7 @@ use crate::{
Executor, Multiaddr, PeerId, Executor, Multiaddr, PeerId,
}; };
use either::Either; use either::Either;
use multihash::Multihash;
use std::{ use std::{
convert::TryFrom as _, convert::TryFrom as _,
error, fmt, error, fmt,
@ -241,7 +242,7 @@ where
.transpose() .transpose()
{ {
Ok(peer_id) => peer_id, Ok(peer_id) => peer_id,
Err(_) => return Err(DialError::InvalidPeerId { handler }), Err(multihash) => return Err(DialError::InvalidPeerId { handler, multihash }),
}; };
( (
@ -576,11 +577,10 @@ pub enum DialError<THandler> {
handler: THandler, handler: THandler,
}, },
/// The dialing attempt is rejected because the peer being dialed is the local peer. /// The dialing attempt is rejected because the peer being dialed is the local peer.
LocalPeerId { LocalPeerId { handler: THandler },
handler: THandler,
},
InvalidPeerId { InvalidPeerId {
handler: THandler, handler: THandler,
multihash: Multihash,
}, },
} }

View File

@ -27,7 +27,7 @@ use libp2p_core::{
connection::PendingConnectionError, connection::PendingConnectionError,
multiaddr::Protocol, multiaddr::Protocol,
network::{NetworkConfig, NetworkEvent}, network::{NetworkConfig, NetworkEvent},
PeerId, ConnectedPoint, Endpoint, PeerId,
}; };
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use std::{io, task::Poll}; use std::{io, task::Poll};
@ -42,7 +42,7 @@ fn deny_incoming_connec() {
swarm1.listen_on("/memory/0".parse().unwrap()).unwrap(); swarm1.listen_on("/memory/0".parse().unwrap()).unwrap();
let address = async_std::task::block_on(future::poll_fn(|cx| match swarm1.poll(cx) { let address = futures::executor::block_on(future::poll_fn(|cx| match swarm1.poll(cx) {
Poll::Ready(NetworkEvent::NewListenerAddress { listen_addr, .. }) => { Poll::Ready(NetworkEvent::NewListenerAddress { listen_addr, .. }) => {
Poll::Ready(listen_addr) Poll::Ready(listen_addr)
} }
@ -59,7 +59,7 @@ fn deny_incoming_connec() {
) )
.unwrap(); .unwrap();
async_std::task::block_on(future::poll_fn(|cx| -> Poll<Result<(), io::Error>> { futures::executor::block_on(future::poll_fn(|cx| -> Poll<Result<(), io::Error>> {
match swarm1.poll(cx) { match swarm1.poll(cx) {
Poll::Ready(NetworkEvent::IncomingConnection { connection, .. }) => drop(connection), Poll::Ready(NetworkEvent::IncomingConnection { connection, .. }) => drop(connection),
Poll::Ready(_) => unreachable!(), Poll::Ready(_) => unreachable!(),
@ -88,6 +88,58 @@ fn deny_incoming_connec() {
.unwrap(); .unwrap();
} }
#[test]
fn invalid_peer_id() {
// Checks whether dialing an address containing the wrong peer id raises an error
// for the expected peer id instead of the obtained peer id.
let mut swarm1 = test_network(NetworkConfig::default());
let mut swarm2 = test_network(NetworkConfig::default());
swarm1.listen_on("/memory/0".parse().unwrap()).unwrap();
let address = futures::executor::block_on(future::poll_fn(|cx| match swarm1.poll(cx) {
Poll::Ready(NetworkEvent::NewListenerAddress { listen_addr, .. }) => {
Poll::Ready(listen_addr)
}
Poll::Pending => Poll::Pending,
_ => panic!("Was expecting the listen address to be reported"),
}));
let other_id = PeerId::random();
let other_addr = address.with(Protocol::P2p(other_id.into()));
swarm2.dial(TestHandler(), other_addr.clone()).unwrap();
let (peer_id, error) = futures::executor::block_on(future::poll_fn(|cx| {
if let Poll::Ready(NetworkEvent::IncomingConnection { connection, .. }) = swarm1.poll(cx) {
swarm1.accept(connection, TestHandler()).unwrap();
}
match swarm2.poll(cx) {
Poll::Ready(NetworkEvent::DialError { peer_id, error, .. }) => {
Poll::Ready((peer_id, error))
}
Poll::Ready(x) => panic!("unexpected {:?}", x),
Poll::Pending => Poll::Pending,
}
}));
assert_eq!(peer_id, other_id);
match error {
PendingConnectionError::WrongPeerId { obtained, endpoint } => {
assert_eq!(obtained, *swarm1.local_peer_id());
assert_eq!(
endpoint,
ConnectedPoint::Dialer {
address: other_addr,
role_override: Endpoint::Dialer,
}
);
}
x => panic!("wrong error {:?}", x),
}
}
#[test] #[test]
fn dial_self() { fn dial_self() {
// Check whether dialing ourselves correctly fails. // Check whether dialing ourselves correctly fails.
@ -103,7 +155,7 @@ fn dial_self() {
let mut swarm = test_network(NetworkConfig::default()); let mut swarm = test_network(NetworkConfig::default());
swarm.listen_on("/memory/0".parse().unwrap()).unwrap(); swarm.listen_on("/memory/0".parse().unwrap()).unwrap();
let local_address = async_std::task::block_on(future::poll_fn(|cx| match swarm.poll(cx) { let local_address = futures::executor::block_on(future::poll_fn(|cx| match swarm.poll(cx) {
Poll::Ready(NetworkEvent::NewListenerAddress { listen_addr, .. }) => { Poll::Ready(NetworkEvent::NewListenerAddress { listen_addr, .. }) => {
Poll::Ready(listen_addr) Poll::Ready(listen_addr)
} }
@ -115,12 +167,12 @@ fn dial_self() {
let mut got_dial_err = false; let mut got_dial_err = false;
let mut got_inc_err = false; let mut got_inc_err = false;
async_std::task::block_on(future::poll_fn(|cx| -> Poll<Result<(), io::Error>> { futures::executor::block_on(future::poll_fn(|cx| -> Poll<Result<(), io::Error>> {
loop { loop {
match swarm.poll(cx) { match swarm.poll(cx) {
Poll::Ready(NetworkEvent::DialError { Poll::Ready(NetworkEvent::DialError {
peer_id, peer_id,
error: PendingConnectionError::InvalidPeerId { .. }, error: PendingConnectionError::WrongPeerId { .. },
.. ..
}) => { }) => {
assert_eq!(&peer_id, swarm.local_peer_id()); assert_eq!(&peer_id, swarm.local_peer_id());
@ -157,7 +209,7 @@ fn dial_self_by_id() {
// Trying to dial self by passing the same `PeerId` shouldn't even be possible in the first // Trying to dial self by passing the same `PeerId` shouldn't even be possible in the first
// place. // place.
let mut swarm = test_network(NetworkConfig::default()); let mut swarm = test_network(NetworkConfig::default());
let peer_id = swarm.local_peer_id().clone(); let peer_id = *swarm.local_peer_id();
assert!(swarm.peer(peer_id).into_disconnected().is_none()); assert!(swarm.peer(peer_id).into_disconnected().is_none());
} }
@ -181,13 +233,13 @@ fn multiple_addresses_err() {
swarm swarm
.dial( .dial(
TestHandler(), TestHandler(),
DialOpts::peer_id(target.clone()) DialOpts::peer_id(target)
.addresses(addresses.clone()) .addresses(addresses.clone())
.build(), .build(),
) )
.unwrap(); .unwrap();
async_std::task::block_on(future::poll_fn(|cx| -> Poll<Result<(), io::Error>> { futures::executor::block_on(future::poll_fn(|cx| -> Poll<Result<(), io::Error>> {
loop { loop {
match swarm.poll(cx) { match swarm.poll(cx) {
Poll::Ready(NetworkEvent::DialError { Poll::Ready(NetworkEvent::DialError {

View File

@ -216,9 +216,12 @@ impl<TBvEv, THandleErr> super::Recorder<libp2p_swarm::SwarmEvent<TBvEv, THandleE
libp2p_swarm::DialError::Aborted => { libp2p_swarm::DialError::Aborted => {
record(OutgoingConnectionErrorError::Aborted) record(OutgoingConnectionErrorError::Aborted)
} }
libp2p_swarm::DialError::InvalidPeerId => { libp2p_swarm::DialError::InvalidPeerId { .. } => {
record(OutgoingConnectionErrorError::InvalidPeerId) record(OutgoingConnectionErrorError::InvalidPeerId)
} }
libp2p_swarm::DialError::WrongPeerId { .. } => {
record(OutgoingConnectionErrorError::WrongPeerId)
}
libp2p_swarm::DialError::ConnectionIo(_) => { libp2p_swarm::DialError::ConnectionIo(_) => {
record(OutgoingConnectionErrorError::ConnectionIo) record(OutgoingConnectionErrorError::ConnectionIo)
} }
@ -292,6 +295,7 @@ enum OutgoingConnectionErrorError {
DialPeerConditionFalse, DialPeerConditionFalse,
Aborted, Aborted,
InvalidPeerId, InvalidPeerId,
WrongPeerId,
ConnectionIo, ConnectionIo,
TransportMultiaddrNotSupported, TransportMultiaddrNotSupported,
TransportOther, TransportOther,
@ -304,7 +308,7 @@ struct IncomingConnectionErrorLabels {
#[derive(Encode, Hash, Clone, Eq, PartialEq)] #[derive(Encode, Hash, Clone, Eq, PartialEq)]
enum PendingInboundConnectionError { enum PendingInboundConnectionError {
InvalidPeerId, WrongPeerId,
TransportErrorMultiaddrNotSupported, TransportErrorMultiaddrNotSupported,
TransportErrorOther, TransportErrorOther,
Aborted, Aborted,
@ -317,8 +321,8 @@ impl<TTransErr> From<&libp2p_core::connection::PendingInboundConnectionError<TTr
{ {
fn from(error: &libp2p_core::connection::PendingInboundConnectionError<TTransErr>) -> Self { fn from(error: &libp2p_core::connection::PendingInboundConnectionError<TTransErr>) -> Self {
match error { match error {
libp2p_core::connection::PendingInboundConnectionError::InvalidPeerId => { libp2p_core::connection::PendingInboundConnectionError::WrongPeerId { .. } => {
PendingInboundConnectionError::InvalidPeerId PendingInboundConnectionError::WrongPeerId
} }
libp2p_core::connection::PendingInboundConnectionError::ConnectionLimit(_) => { libp2p_core::connection::PendingInboundConnectionError::ConnectionLimit(_) => {
PendingInboundConnectionError::ConnectionLimit PendingInboundConnectionError::ConnectionLimit

View File

@ -1919,7 +1919,8 @@ where
DialError::Banned DialError::Banned
| DialError::ConnectionLimit(_) | DialError::ConnectionLimit(_)
| DialError::LocalPeerId | DialError::LocalPeerId
| DialError::InvalidPeerId | DialError::InvalidPeerId { .. }
| DialError::WrongPeerId { .. }
| DialError::Aborted | DialError::Aborted
| DialError::ConnectionIo(_) | DialError::ConnectionIo(_)
| DialError::Transport(_) | DialError::Transport(_)

View File

@ -17,6 +17,9 @@
- Allow overriding _dial concurrency factor_ per dial via - Allow overriding _dial concurrency factor_ per dial via
`DialOpts::override_dial_concurrency_factor`. See [PR 2404]. `DialOpts::override_dial_concurrency_factor`. See [PR 2404].
- Report negotiated and expected `PeerId` as well as remote address in
`DialError::WrongPeerId` (see [PR 2428]).
- Allow overriding role when dialing through `override_role` option on - Allow overriding role when dialing through `override_role` option on
`DialOpts`. This option is needed for NAT and firewall hole punching. See [PR `DialOpts`. This option is needed for NAT and firewall hole punching. See [PR
2363]. 2363].
@ -28,6 +31,7 @@
[PR 2375]: https://github.com/libp2p/rust-libp2p/pull/2375 [PR 2375]: https://github.com/libp2p/rust-libp2p/pull/2375
[PR 2378]: https://github.com/libp2p/rust-libp2p/pull/2378 [PR 2378]: https://github.com/libp2p/rust-libp2p/pull/2378
[PR 2404]: https://github.com/libp2p/rust-libp2p/pull/2404 [PR 2404]: https://github.com/libp2p/rust-libp2p/pull/2404
[PR 2428]: https://github.com/libp2p/rust-libp2p/pull/2428
[PR 2363]: https://github.com/libp2p/rust-libp2p/pull/2363 [PR 2363]: https://github.com/libp2p/rust-libp2p/pull/2363
# 0.32.0 [2021-11-16] # 0.32.0 [2021-11-16]
@ -41,16 +45,17 @@
Changes required to maintain status quo: Changes required to maintain status quo:
- Previously `swarm.dial(peer_id)` - Previously `swarm.dial(peer_id)`
now `swarm.dial(DialOpts::peer_id(peer_id).build())` now `swarm.dial(DialOpts::peer_id(peer_id).build())`
or `swarm.dial(peer_id)` given that `DialOpts` implements `From<PeerId>`. or `swarm.dial(peer_id)` given that `DialOpts` implements `From<PeerId>`.
- Previously `swarm.dial_addr(addr)` - Previously `swarm.dial_addr(addr)`
now `swarm.dial(DialOpts::unknown_peer_id().address(addr).build())` now `swarm.dial(DialOpts::unknown_peer_id().address(addr).build())`
or `swarm.dial(addr)` given that `DialOpts` implements `From<Multiaddr>`. or `swarm.dial(addr)` given that `DialOpts` implements `From<Multiaddr>`.
- Previously `NetworkBehaviourAction::DialPeer { peer_id, condition, handler }` - Previously `NetworkBehaviourAction::DialPeer { peer_id, condition, handler }`
now now
```rust ```rust
NetworkBehaviourAction::Dial { NetworkBehaviourAction::Dial {
opts: DialOpts::peer_id(peer_id) opts: DialOpts::peer_id(peer_id)
@ -60,8 +65,9 @@
} }
``` ```
- Previously `NetworkBehaviourAction::DialAddress { address, handler }` - Previously `NetworkBehaviourAction::DialAddress { address, handler }`
now now
```rust ```rust
NetworkBehaviourAction::Dial { NetworkBehaviourAction::Dial {
opts: DialOpts::unknown_peer_id() opts: DialOpts::unknown_peer_id()

View File

@ -81,6 +81,7 @@ use libp2p_core::{
EstablishedConnection, IntoConnectionHandler, ListenerId, PendingConnectionError, EstablishedConnection, IntoConnectionHandler, ListenerId, PendingConnectionError,
PendingInboundConnectionError, PendingOutboundConnectionError, Substream, PendingInboundConnectionError, PendingOutboundConnectionError, Substream,
}, },
multihash::Multihash,
muxing::StreamMuxerBox, muxing::StreamMuxerBox,
network::{ network::{
self, peer::ConnectedPeer, ConnectionLimits, Network, NetworkConfig, NetworkEvent, self, peer::ConnectedPeer, ConnectionLimits, Network, NetworkConfig, NetworkEvent,
@ -1332,10 +1333,13 @@ pub enum DialError {
DialPeerConditionFalse(dial_opts::PeerCondition), DialPeerConditionFalse(dial_opts::PeerCondition),
/// Pending connection attempt has been aborted. /// Pending connection attempt has been aborted.
Aborted, Aborted,
/// The provided peer identity is invalid or the peer identity obtained on /// The provided peer identity is invalid.
/// the connection did not match the one that was expected or is otherwise InvalidPeerId(Multihash),
/// invalid. /// The peer identity obtained on the connection did not match the one that was expected.
InvalidPeerId, WrongPeerId {
obtained: PeerId,
endpoint: ConnectedPoint,
},
/// An I/O error occurred on the connection. /// An I/O error occurred on the connection.
ConnectionIo(io::Error), ConnectionIo(io::Error),
/// An error occurred while negotiating the transport protocol(s) on a connection. /// An error occurred while negotiating the transport protocol(s) on a connection.
@ -1349,7 +1353,9 @@ impl DialError {
(DialError::ConnectionLimit(limit), handler) (DialError::ConnectionLimit(limit), handler)
} }
network::DialError::LocalPeerId { handler } => (DialError::LocalPeerId, handler), network::DialError::LocalPeerId { handler } => (DialError::LocalPeerId, handler),
network::DialError::InvalidPeerId { handler } => (DialError::InvalidPeerId, handler), network::DialError::InvalidPeerId { handler, multihash } => {
(DialError::InvalidPeerId(multihash), handler)
}
} }
} }
} }
@ -1359,7 +1365,9 @@ impl From<PendingOutboundConnectionError<io::Error>> for DialError {
match error { match error {
PendingConnectionError::ConnectionLimit(limit) => DialError::ConnectionLimit(limit), PendingConnectionError::ConnectionLimit(limit) => DialError::ConnectionLimit(limit),
PendingConnectionError::Aborted => DialError::Aborted, PendingConnectionError::Aborted => DialError::Aborted,
PendingConnectionError::InvalidPeerId => DialError::InvalidPeerId, PendingConnectionError::WrongPeerId { obtained, endpoint } => {
DialError::WrongPeerId { obtained, endpoint }
}
PendingConnectionError::IO(e) => DialError::ConnectionIo(e), PendingConnectionError::IO(e) => DialError::ConnectionIo(e),
PendingConnectionError::Transport(e) => DialError::Transport(e), PendingConnectionError::Transport(e) => DialError::Transport(e),
} }
@ -1384,7 +1392,8 @@ impl fmt::Display for DialError {
f, f,
"Dial error: Pending connection attempt has been aborted." "Dial error: Pending connection attempt has been aborted."
), ),
DialError::InvalidPeerId => write!(f, "Dial error: Invalid peer ID."), DialError::InvalidPeerId(multihash) => write!(f, "Dial error: multihash {:?} is not a PeerId", multihash),
DialError::WrongPeerId { obtained, endpoint} => write!(f, "Dial error: Unexpected peer ID {} at {:?}.", obtained, endpoint),
DialError::ConnectionIo(e) => write!( DialError::ConnectionIo(e) => write!(
f, f,
"Dial error: An I/O error occurred on the connection: {:?}.", e "Dial error: An I/O error occurred on the connection: {:?}.", e
@ -1403,7 +1412,8 @@ impl error::Error for DialError {
DialError::Banned => None, DialError::Banned => None,
DialError::DialPeerConditionFalse(_) => None, DialError::DialPeerConditionFalse(_) => None,
DialError::Aborted => None, DialError::Aborted => None,
DialError::InvalidPeerId => None, DialError::InvalidPeerId { .. } => None,
DialError::WrongPeerId { .. } => None,
DialError::ConnectionIo(_) => None, DialError::ConnectionIo(_) => None,
DialError::Transport(_) => None, DialError::Transport(_) => None,
} }