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

swarm/: Support generic connection management through NetworkBehaviour #2828

Closed
wants to merge 12 commits into from

Conversation

mxinden
Copy link
Member

@mxinden mxinden commented Aug 19, 2022

Description

This pull request enables generic connection management by implementing option (2) of #2824:

Extend NetworkBehaviour with methods called to review a pending or established connection.

Very much work in progress at this point.

Links to any relevant issues

Open Questions

Change checklist

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • A changelog entry has been made in the appropriate crates

mxinden added 12 commits August 14, 2022 13:37
When generating the `OutEvent` for a `NetworkBehaviour`, add the `where` clause of the
`NetworkBehaviour` `struct` to the generated `enum`.
When generating an `OutEvent` `enum` definition for a user, derive `Debug`
for that `enum`.

Why not derive `Clone`, `PartialEq` and `Eq` for the generated `enum`
definition?

While I think it is fine to require all sub-`OutEvent`s to implement
`Debug`, I don't think the same applies to traits like `Clone`. I
suggest users that need `Clone` to define their own `OutEvent`.
Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

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

Hope you don't mind the early, unsolicited review :)
I've added a few thoughts but overall, this looks really interesting. I like how we move more and more to a plugin system and libp2p-swarm is becoming a kind of "executor" for these plugins.

Comment on lines +16 to +17
# TODO: Should this really be a default?
"connection-limit",
Copy link
Contributor

Choose a reason for hiding this comment

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

Long term, I would say no because of #2173. For consistency with the current way of doing things, probably yes.

@@ -0,0 +1,24 @@
[package]
name = "libp2p-connection-limit"
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this have to be its own crate? I think this could also live in libp2p-swarm.

It can still be feature-flagged there if we want but looking at the dependencies of this crate, we don't really gain much at the moment from separating this out.

Copy link
Member Author

Choose a reason for hiding this comment

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

Separate crate forces us to deliver on the promise of being able to implement ones own.

That said, agreed that we don't gain much more and instead add complexity.


impl NetworkBehaviour for Behaviour {
type ConnectionHandler = DummyConnectionHandler;
type OutEvent = ();
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps use Void instead?

// TODO: Needed in the first place? Are there some common errors that we want?
#[derive(Debug)]
pub enum ReviewDenied {
Error(Box<dyn Error>),
Copy link
Contributor

Choose a reason for hiding this comment

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

This should definitely have a 'static bound.

@@ -778,3 +808,9 @@ impl Default for CloseConnection {
CloseConnection::All
}
}

// TODO: Needed in the first place? Are there some common errors that we want?
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps just having these function return Box<dyn Error + 'static> is enough?

Copy link
Member

Choose a reason for hiding this comment

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

Something like LimitReached seems to very common to me, so would be nice to have that as a specifc one, maybe with an optional message for customizability

for _ in 0..outbound {
swarm
.dial(
DialOpts::peer_id(PeerId::random())
Copy link
Contributor

Choose a reason for hiding this comment

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

Does PeerId::random only work here because we never poll the swarm?

I think this is misleading, why not dial without PeerId instead?


#[test]
fn enforces_pending_outbound_connection_limit() {
fn prop(outbound: u8) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for OT but we have so many different ways of testing swarms in our repo, it makes me uneasy every time 😅

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll put this on my list to work on from September forward :D

@@ -282,6 +285,7 @@ where
/// similar mechanisms.
external_addrs: Addresses,

// TODO: I think this should move into the connection manager behaviour as well.
Copy link
Contributor

Choose a reason for hiding this comment

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

Into the behaviour or into a behaviour. I was thinking the same thing when I thought about this topic. Keeping a record of banned peers can likely be a NetworkBehaviour itself IMO.

_peer_id: Option<PeerId>,
// TODO: Maybe an iterator is better?
_addresses: &[Multiaddr],
_endpoint: Endpoint,
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of passing the endpoint, would it make sense to have two different callbacks, one for incoming and one for outgoing?

@@ -191,6 +192,35 @@ pub trait NetworkBehaviour: 'static {
vec![]
}

// TODO: Make sure this and all the methods below are really implemented across all behaviours.
fn review_pending_connection(
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not fully sold on the "review" terminology but I also can't think of something better off the top of my head.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not a fan of "review" either. Grateful for naming suggestions!

@thomaseizinger
Copy link
Contributor

I am closing this in favor of #3099.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants