Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(swarm)!: remove handler from NetworkBehaviourAction::Dial #3328

Merged
merged 63 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
3a84c14
Use single quotes to avoid running commands
thomaseizinger Jan 11, 2023
458aa53
Use intermediary variable
thomaseizinger Jan 13, 2023
d0d8b77
Make connection IDs globally unique
thomaseizinger Jan 16, 2023
11e5f74
Deprecate old new function
thomaseizinger Jan 16, 2023
47cf01f
Add changelog entry
thomaseizinger Jan 16, 2023
341d096
Merge branch 'master' into no-run-title-as-command
thomaseizinger Jan 16, 2023
f77e443
Remove `handler` field from `NetworkBehaviourAction::Dial`
thomaseizinger Jan 16, 2023
f6cf751
Port dcutr protocol
thomaseizinger Jan 16, 2023
08c5160
Port relay protocol
thomaseizinger Jan 16, 2023
8e0d7d8
Add changelog entry to swarm
thomaseizinger Jan 16, 2023
b337ec1
Merge branch 'no-run-title-as-command' into 2824-unique-connection-ids
thomaseizinger Jan 16, 2023
3c4ab32
Merge branch '2824-unique-connection-ids' into 2824-no-handler-in-dial
thomaseizinger Jan 16, 2023
1beec8c
Remove ordering functionality from `ConnectionId`
thomaseizinger Jan 17, 2023
eb48acb
Merge branch '2824-unique-connection-ids' of github.com:libp2p/rust-l…
thomaseizinger Jan 17, 2023
de9f152
Remove unnecessary visibility qualifiers
thomaseizinger Jan 17, 2023
7692c77
Convert `DialOpts` to struct variant
thomaseizinger Jan 17, 2023
b492236
Eagerly set defaults in `DialOpts`
thomaseizinger Jan 17, 2023
92b2985
Merge branch '2824-refactor-dial-opts' into 2824-no-handler-in-dial
thomaseizinger Jan 17, 2023
951a0dc
Make `ConnectionId` part of `DialOpts`
thomaseizinger Jan 17, 2023
41e49a5
Inline `_dial`
thomaseizinger Jan 17, 2023
3547b53
Rustfmt
thomaseizinger Jan 17, 2023
75b30ac
Fix wrong default
thomaseizinger Jan 17, 2023
30df5c8
Merge branch '2824-refactor-dial-opts' into 2824-no-handler-in-dial
thomaseizinger Jan 17, 2023
3d91173
Merge branch 'master' into 2824-unique-connection-ids
thomaseizinger Jan 18, 2023
aa19d69
Merge branch '2824-unique-connection-ids' of github.com:libp2p/rust-l…
thomaseizinger Jan 18, 2023
0f53692
Merge branch 'master' into 2824-unique-connection-ids
thomaseizinger Jan 18, 2023
4084846
Merge branch '2824-unique-connection-ids' into 2824-no-handler-in-dial
thomaseizinger Jan 18, 2023
42c9758
Expand changelog entry
thomaseizinger Jan 18, 2023
14b9841
Move most important changelog entry to the top
thomaseizinger Jan 18, 2023
1a3a100
Add more text to changelog entry
thomaseizinger Jan 18, 2023
5535395
Fix formatting
thomaseizinger Jan 18, 2023
244c171
Merge branch 'master' into 2824-unique-connection-ids
thomaseizinger Jan 20, 2023
a82e087
Merge branch '2824-unique-connection-ids' into 2824-no-handler-in-dial
thomaseizinger Jan 20, 2023
b536773
Merge branch 'master' into 2824-unique-connection-ids
mergify[bot] Jan 23, 2023
64a333d
Merge branch 'master' into 2824-unique-connection-ids
thomaseizinger Jan 23, 2023
867c880
Merge branch '2824-unique-connection-ids' into 2824-no-handler-in-dial
thomaseizinger Jan 23, 2023
e97d899
Merge branch 'master' into 2824-no-handler-in-dial
thomaseizinger Jan 24, 2023
c0a7d2a
Remove unnecessary `..`
thomaseizinger Jan 24, 2023
8e20996
Merge branch 'master' into 2824-no-handler-in-dial
thomaseizinger Jan 24, 2023
9a420e4
Don't use else block if we return in the previous one
thomaseizinger Jan 26, 2023
f5f37ab
Remove closure in favor of spawning connection from the outside
thomaseizinger Jan 26, 2023
e867b26
Merge branch 'master' into 2824-no-handler-in-dial
thomaseizinger Jan 26, 2023
dd1eb8c
Add `ConnectionId` to `ListenFailure`
thomaseizinger Jan 26, 2023
32a465b
Clean up pending commands on failure
thomaseizinger Jan 26, 2023
91f942f
Add docs and fix bug
thomaseizinger Jan 26, 2023
6f19246
Merge branch 'master' into 2824-no-handler-in-dial
thomaseizinger Jan 26, 2023
d704e89
Consistently use `THandlerInEvent`
thomaseizinger Jan 26, 2023
55baab1
Use type alias
thomaseizinger Jan 26, 2023
2c84f28
Remove unnecessary indentation and "quote"-ing
thomaseizinger Jan 26, 2023
cf77246
Fix bad changelog entry
thomaseizinger Jan 26, 2023
92a9625
Spawn connection at right point in time
thomaseizinger Jan 27, 2023
d90ac81
Fix rustdoc
thomaseizinger Jan 27, 2023
cfe9f95
One more missing rustdoc link
thomaseizinger Jan 27, 2023
3f8f73c
Remove `banned_peer_connections`
thomaseizinger Jan 27, 2023
063ef5c
Fix test
thomaseizinger Jan 27, 2023
26f6cf0
Merge branch 'master' into 2824-no-handler-in-dial
thomaseizinger Jan 27, 2023
c3ba2e3
Merge branch 'master' into 2824-no-handler-in-dial
thomaseizinger Feb 1, 2023
3ecd623
Inline `spawn` function
thomaseizinger Feb 10, 2023
02cbf42
Box future inside `spawn`
thomaseizinger Feb 10, 2023
1c906db
Merge impl blocks
thomaseizinger Feb 10, 2023
87cf5fd
Gracefully close connection to banned peer
thomaseizinger Feb 10, 2023
f204859
Ignore error when closing connection
thomaseizinger Feb 10, 2023
21f0c46
Merge branch 'master' into 2824-no-handler-in-dial
mergify[bot] Feb 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,12 @@ jobs:
require_scope: false

- name: Check PR title length
env:
TITLE: ${{ github.event.pull_request.title }}
run: |
title="${{ github.event.pull_request.title }}"
title_length=${#title}
title_length=${#TITLE}
if [ $title_length -gt 72 ]
then
echo "PR title is too long (greater than 72 characters)"
exit 1
fi
fi
6 changes: 6 additions & 0 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.39.0 [unreleased]

- Deprecate `ConnectionId::new` in favor of `ConnectionId::next`. See [PR 3327].

[PR 3327]: https://github.com/libp2p/rust-libp2p/pull/3327

# 0.38.0

- Remove deprecated functions `StreamMuxerExt::next_{inbound,outbound}`. See [PR 3031].
Expand Down
13 changes: 7 additions & 6 deletions core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
// DEALINGS IN THE SOFTWARE.

use crate::multiaddr::{Multiaddr, Protocol};
use std::sync::atomic::{AtomicUsize, Ordering};

static NEXT_CONNECTION_ID: AtomicUsize = AtomicUsize::new(0);

/// Connection identifier.
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
Expand All @@ -30,16 +33,14 @@ impl ConnectionId {
/// This is primarily useful for creating connection IDs
/// in test environments. There is in general no guarantee
/// that all connection IDs are based on non-negative integers.
#[deprecated(since = "0.39.0", note = "Use `ConnectionId::next` instead.")]
pub fn new(id: usize) -> Self {
Self(id)
}
}

impl std::ops::Add<usize> for ConnectionId {
type Output = Self;

fn add(self, other: usize) -> Self {
Self(self.0 + other)
/// Returns the next available [`ConnectionId`].
pub fn next() -> Self {
Self(NEXT_CONNECTION_ID.fetch_add(1, Ordering::SeqCst))
}
}

Expand Down
19 changes: 7 additions & 12 deletions protocols/autonat/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use libp2p_swarm::{
ExpiredListenAddr, FromSwarm,
},
ConnectionHandler, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour,
NetworkBehaviourAction, PollParameters,
NetworkBehaviourAction, PollParameters, THandlerInEvent,
};
use std::{
collections::{HashMap, VecDeque},
Expand Down Expand Up @@ -210,10 +210,7 @@ pub struct Behaviour {
last_probe: Option<Instant>,

pending_actions: VecDeque<
NetworkBehaviourAction<
<Self as NetworkBehaviour>::OutEvent,
<Self as NetworkBehaviour>::ConnectionHandler,
>,
NetworkBehaviourAction<<Self as NetworkBehaviour>::OutEvent, THandlerInEvent<Self>>,
>,

probe_id: ProbeId,
Expand Down Expand Up @@ -391,14 +388,14 @@ impl Behaviour {
&mut self,
DialFailure {
peer_id,
handler,
connection_id,
error,
}: DialFailure<<Self as NetworkBehaviour>::ConnectionHandler>,
}: DialFailure,
) {
self.inner
.on_swarm_event(FromSwarm::DialFailure(DialFailure {
peer_id,
handler,
connection_id,
error,
}));
if let Some(event) = self.as_server().on_outbound_dial_error(peer_id, error) {
Expand Down Expand Up @@ -563,10 +560,8 @@ impl NetworkBehaviour for Behaviour {
}
}

type Action = NetworkBehaviourAction<
<Behaviour as NetworkBehaviour>::OutEvent,
<Behaviour as NetworkBehaviour>::ConnectionHandler,
>;
type Action =
NetworkBehaviourAction<<Behaviour as NetworkBehaviour>::OutEvent, THandlerInEvent<Behaviour>>;

// Trait implemented for `AsClient` and `AsServer` to handle events from the inner [`request_response::Behaviour`] Protocol.
trait HandleInnerEvent {
Expand Down
4 changes: 2 additions & 2 deletions protocols/autonat/src/behaviour/as_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use libp2p_request_response::{
};
use libp2p_swarm::{
dial_opts::{DialOpts, PeerCondition},
DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
DialError, NetworkBehaviourAction, PollParameters,
};
use std::{
collections::{HashMap, HashSet, VecDeque},
Expand Down Expand Up @@ -138,7 +138,7 @@ impl<'a> HandleInnerEvent for AsServer<'a> {
)
.addresses(addrs)
.build(),
handler: self.inner.new_handler(),
connection_id: ConnectionId::next(),
},
])
}
Expand Down
148 changes: 91 additions & 57 deletions protocols/dcutr/src/behaviour_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailu
use libp2p_swarm::dial_opts::{self, DialOpts};
use libp2p_swarm::{
ConnectionHandler, ConnectionHandlerUpgrErr, ExternalAddresses, IntoConnectionHandler,
NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent,
};
use std::collections::{HashMap, HashSet, VecDeque};
use std::task::{Context, Poll};
use thiserror::Error;
use void::Void;

const MAX_NUMBER_OF_UPGRADE_ATTEMPTS: u8 = 3;

Expand Down Expand Up @@ -67,14 +68,18 @@ pub enum Error {

pub struct Behaviour {
/// Queue of actions to return when polled.
queued_events: VecDeque<NetworkBehaviourAction<Event, handler::Prototype>>,
queued_events: VecDeque<NetworkBehaviourAction<Event, Either<handler::relayed::Command, Void>>>,

/// All direct (non-relayed) connections.
direct_connections: HashMap<PeerId, HashSet<ConnectionId>>,

external_addresses: ExternalAddresses,

local_peer_id: PeerId,

direct_to_relayed_connections: HashMap<ConnectionId, ConnectionId>,

outgoing_direct_connection_attempts: HashMap<(ConnectionId, PeerId), u8>,
thomaseizinger marked this conversation as resolved.
Show resolved Hide resolved
}

impl Behaviour {
Expand All @@ -84,6 +89,8 @@ impl Behaviour {
direct_connections: Default::default(),
external_addresses: Default::default(),
local_peer_id,
direct_to_relayed_connections: Default::default(),
outgoing_direct_connection_attempts: Default::default(),
}
}

Expand Down Expand Up @@ -147,40 +154,57 @@ impl Behaviour {
fn on_dial_failure(
&mut self,
DialFailure {
peer_id, handler, ..
}: DialFailure<<Self as NetworkBehaviour>::ConnectionHandler>,
peer_id,
connection_id: failed_direct_connection,
..
}: DialFailure,
) {
if let handler::Prototype::DirectConnection {
relayed_connection_id,
role: handler::Role::Initiator { attempt },
} = handler
let peer_id = if let Some(peer_id) = peer_id {
peer_id
} else {
return;
};
thomaseizinger marked this conversation as resolved.
Show resolved Hide resolved

let relayed_connection_id = if let Some(relayed_connection_id) = self
.direct_to_relayed_connections
.get(&failed_direct_connection)
{
let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known.");
if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS {
self.queued_events
.push_back(NetworkBehaviourAction::NotifyHandler {
handler: NotifyHandler::One(relayed_connection_id),
peer_id,
event: Either::Left(handler::relayed::Command::Connect {
attempt: attempt + 1,
obs_addrs: self.observed_addreses(),
}),
})
} else {
self.queued_events.extend([
NetworkBehaviourAction::NotifyHandler {
peer_id,
handler: NotifyHandler::One(relayed_connection_id),
event: Either::Left(
handler::relayed::Command::UpgradeFinishedDontKeepAlive,
),
},
NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed {
remote_peer_id: peer_id,
error: Error::Dial,
*relayed_connection_id
} else {
return;
};

let attempt = if let Some(attempt) = self
.outgoing_direct_connection_attempts
.get(&(relayed_connection_id, peer_id))
{
*attempt
} else {
return;
};

if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS {
self.queued_events
.push_back(NetworkBehaviourAction::NotifyHandler {
handler: NotifyHandler::One(relayed_connection_id),
peer_id,
event: Either::Left(handler::relayed::Command::Connect {
attempt: attempt + 1,
obs_addrs: self.observed_addreses(),
}),
]);
}
})
} else {
self.queued_events.extend([
NetworkBehaviourAction::NotifyHandler {
peer_id,
handler: NotifyHandler::One(relayed_connection_id),
event: Either::Left(handler::relayed::Command::UpgradeFinishedDontKeepAlive),
},
NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed {
remote_peer_id: peer_id,
error: Error::Dial,
}),
]);
}
}

Expand Down Expand Up @@ -214,24 +238,34 @@ impl NetworkBehaviour for Behaviour {
type OutEvent = Event;

fn new_handler(&mut self) -> Self::ConnectionHandler {
handler::Prototype::UnknownConnection
handler::Prototype
}

fn on_connection_handler_event(
&mut self,
event_source: PeerId,
connection: ConnectionId,
handler_event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as
ConnectionHandler>::OutEvent,
connection_id: ConnectionId,
handler_event: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
) {
let relayed_connection_id = match handler_event.as_ref() {
Either::Left(_) => connection_id,
Either::Right(_) => match self.direct_to_relayed_connections.get(&connection_id) {
None => {
// If the connection ID is unknown to us, it means we didn't create it so ignore any event coming from it.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. This will be handled by the type-system once we have #3254. Then we can return a dummy::ConnectionHandler for connections that we didn't initiate ourselves and thus every event we get here is always from a connection that we initiated.

return;
}
Some(relayed_connection_id) => *relayed_connection_id,
},
};

match handler_event {
Either::Left(handler::relayed::Event::InboundConnectRequest {
inbound_connect,
remote_addr,
}) => {
self.queued_events.extend([
NetworkBehaviourAction::NotifyHandler {
handler: NotifyHandler::One(connection),
handler: NotifyHandler::One(relayed_connection_id),
peer_id: event_source,
event: Either::Left(handler::relayed::Command::AcceptInboundConnect {
inbound_connect,
Expand All @@ -256,15 +290,17 @@ impl NetworkBehaviour for Behaviour {
));
}
Either::Left(handler::relayed::Event::InboundConnectNegotiated(remote_addrs)) => {
let maybe_direct_connection_id = ConnectionId::next();

self.direct_to_relayed_connections
.insert(maybe_direct_connection_id, relayed_connection_id);

self.queued_events.push_back(NetworkBehaviourAction::Dial {
opts: DialOpts::peer_id(event_source)
.addresses(remote_addrs)
.condition(dial_opts::PeerCondition::Always)
.build(),
handler: handler::Prototype::DirectConnection {
relayed_connection_id: connection,
role: handler::Role::Listener,
},
connection_id: maybe_direct_connection_id,
});
}
Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => {
Expand All @@ -276,27 +312,26 @@ impl NetworkBehaviour for Behaviour {
},
));
}
Either::Left(handler::relayed::Event::OutboundConnectNegotiated {
remote_addrs,
attempt,
}) => {
Either::Left(handler::relayed::Event::OutboundConnectNegotiated { remote_addrs }) => {
let maybe_direct_connection_id = ConnectionId::next();

self.direct_to_relayed_connections
.insert(maybe_direct_connection_id, relayed_connection_id);
*self
.outgoing_direct_connection_attempts
.entry((maybe_direct_connection_id, event_source))
.or_default() += 1;

self.queued_events.push_back(NetworkBehaviourAction::Dial {
opts: DialOpts::peer_id(event_source)
.condition(dial_opts::PeerCondition::Always)
.addresses(remote_addrs)
.override_role()
.build(),
handler: handler::Prototype::DirectConnection {
relayed_connection_id: connection,
role: handler::Role::Initiator { attempt },
},
connection_id: maybe_direct_connection_id,
});
}
Either::Right(Either::Left(
handler::direct::Event::DirectConnectionUpgradeSucceeded {
relayed_connection_id,
},
)) => {
Either::Right(handler::direct::Event::DirectConnectionEstablished) => {
self.queued_events.extend([
NetworkBehaviourAction::NotifyHandler {
peer_id: event_source,
Expand All @@ -312,15 +347,14 @@ impl NetworkBehaviour for Behaviour {
),
]);
}
Either::Right(Either::Right(event)) => void::unreachable(event),
};
}

fn poll(
&mut self,
_cx: &mut Context<'_>,
_: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
) -> Poll<NetworkBehaviourAction<Self::OutEvent, THandlerInEvent<Self>>> {
if let Some(event) = self.queued_events.pop_front() {
return Poll::Ready(event);
}
Expand Down
Loading