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

feat(swarm): Add deny_list behaviour #3156

Conversation

thomaseizinger
Copy link
Contributor

@thomaseizinger thomaseizinger commented Nov 22, 2022

Description

Notes

To actually land this, we would obviously do it in a backwards-compatible way. This PR is just meant to serve as a showcase to see what it would look like to implement various capabilities on top of the new, generic connection management.

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

Comment on lines -527 to -533
// Check if peer is banned.
if self.banned_peers.contains(&peer_id) {
let error = DialError::Banned;
#[allow(deprecated)]
self.behaviour.inject_dial_failure(Some(peer_id), &error);
return Err(error);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We lose this early check here, i.e. we will initiate a dial and then immediately drop the connection instead of aborting the connection early. I guess that is the price for implementing this kind of functionality in a generic way.

Copy link
Contributor

@rkuhn rkuhn left a comment

Choose a reason for hiding this comment

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

Yes, looks quite clean to me!

impl Behaviour {
pub fn add_peer(&mut self, peer: PeerId) {
self.list.insert(peer);
self.to_disconnect.push_back(peer);
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 also lead to waking up the swarm. Perhaps using an async channel is the easiest and most readable solution? (instead of rebuilding such functionality with a VecDeque and an Option<Waker>)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mxinden was talking about building a WakingVec abstraction because we are coming across this very often actually.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had a quick search on crates.io but couldn't find anything that does what we need. It might be possible that I used the wrong keywords!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made a PoC here: #3160

Copy link
Contributor

Choose a reason for hiding this comment

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

While that may have independent merit (not yet reviewed), I meant simply using async-channel instead of the VecDeque.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

While that may have independent merit (not yet reviewed), I meant simply using async-channel instead of the VecDeque.

I always find it confusing when the same data structure holds both ends of a channel.

But I agree with you that it would solve the problem.

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

Wow, this is surprisingly simple. I am very much in favor of the direction this is going.

@thomaseizinger thomaseizinger force-pushed the 2824-remove-into-connection-handler branch from 7369cc1 to dcb4f96 Compare December 7, 2022 01:54
Comment on lines +8 to +15
pub struct Behaviour {
list: HashSet<PeerId>,
to_disconnect: VecDeque<PeerId>,
}

impl Behaviour {
pub fn add_peer(&mut self, peer: PeerId) {
self.list.insert(peer);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
pub struct Behaviour {
list: HashSet<PeerId>,
to_disconnect: VecDeque<PeerId>,
}
impl Behaviour {
pub fn add_peer(&mut self, peer: PeerId) {
self.list.insert(peer);
pub struct Behaviour<T = ()> {
list: HashMap<PeerId, T>,
to_disconnect: VecDeque<PeerId>,
}
impl Behaviour<()> {
pub fn add_peer(&mut self, peer: PeerId) {
self.list.insert(peer, ());
self.to_disconnect.push_back(peer);
}
}
impl<T> Behaviour<T> {
pub fn add_peer_because(&mut self, peer: PeerId, reason: T) {
self.list.insert(peer, reason);

We could allow an optional reason parameter that we'd then also include in the Denied struct. Might be useful if there are multiple reasons why a peer can be banned.
If we'd additionally expose what peers are currently banned (and for what reason) it would allow a more sophisticated management of banned peers. E.g. if a peer was only banned because an Application-Layer limit was reached.

But not sure if it's worth the extra complexity. Could wait until there is actually a use-case for this.

use std::collections::{HashSet, VecDeque};
use std::task::{Context, Poll};

#[derive(Default)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
#[derive(Default)]
#[derive(Default, Debug, Clone)]

@thomaseizinger
Copy link
Contributor Author

Closing for now as I am working on a new version of the connection management idea here: #3254

@thomaseizinger thomaseizinger deleted the 2824-generic-connection-management branch February 24, 2023 14:46
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.

4 participants