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

remove nat module and use libp2p upnp #4840

Merged
merged 14 commits into from
Feb 27, 2024
Merged

remove nat module and use libp2p upnp #4840

merged 14 commits into from
Feb 27, 2024

Conversation

jxs
Copy link
Member

@jxs jxs commented Oct 12, 2023

Issue Addressed

uses the new libp2p upnp module to map internal ports to the external network instead of the local nat module.

Additional Info

This is a first move on fulfilling #4816 as we can just use libp2p to understand if ports are publicly accessible and it will act accordingly with the FromSwarm::ExternalAdrConfirmed.
There's a downside though, we lose the ability to map the DiscV5 udp port, for that I suggest we implement it as a feature in Discovery itself wdyt? I can submit a PR for that

@divagant-martian
Copy link
Collaborator

divagant-martian commented Oct 12, 2023

can't libp2p-upnp be extended to track arbitrary user ports? adding to discovery is something I would prefer not to do in part to avoid the double underlying upnp dependency, and the fact that it's simply duplicated code.

Making libp2p-upnp handle this I don't think is egregious. It's not too different to allow-block-list handling bans and allows for peers libp2p is unaware for example. It could simply need to be able to report that the external address is not one from the libp2p ports, but an user managed one

@AgeManning
Copy link
Member

ahh yeah good point. When we were discussing this I didn't consider discovery.

My opinion is that the code in lh for UPnP isn't great. It was written a while ago and I consider it to always fail (i.e dont rely on it in any way).

If libp2p is going to maintain its own version as a dep I think it kind of makes sense to export it there. Perhaps we want to do a similar thing in discovery. I agree that its ugly that we duplicate the dependencies and then attempt UPnP twice this way, but the benefit is that its then logically grouped into each transport that needs it and I guess discovery users independently can benefit from its own internal UPnP functionality.

The overhead of running it twice on boot prob isn't that bad. What do you think @divagant-martian?

@jxs
Copy link
Member Author

jxs commented Oct 18, 2023

Hi Diva, I don't think allow-block-list is comparable as it works by listening on handle_established_{inbound_outbound}_connection methods which happen after libp2p's noise handshake and check for PeerId's one has banned/allowed, PeerIds are a libp2p property and exist after the noise handshake.

I also don't think it doesn't make sense to invent a new multiaddress for this.
But I can understand though that having UPnP in Discovery might be out of scope, so I refactored the nat module with some changes as spoken with @AgeManning:

  • make it async and use the same dep as libp2p to avoid multiple igd deps
  • use timed leases so we don't need Drop logic
  • use the listening address instead of using if-watch to search for interfaces

@divagant-martian
Copy link
Collaborator

divagant-martian commented Oct 18, 2023

thanks @jxs ot sure what you mean about creating a new multi address? in any case, this is what I discussed and proposed to @AgeManning a couple days ago and what we decided would be best, ty!

Copy link
Member

@AgeManning AgeManning left a comment

Choose a reason for hiding this comment

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

This looks good.

However there is a CLI flag --disable-upnp. I think we still need to respect that and therefore not use libp2p upnp or discovery upnp when that flag is set.

)
.await
.context("Could not UPnP map port: {port} on the gateway")?;
info!(log, "Discovery UPnP port mapped"; "port" => %port);
Copy link
Member

Choose a reason for hiding this comment

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

We have a few info logs at the moment.
We have one from creating in libp2p, one from creating discovery and then the results from both.

I think its probably safe to assume if libp2p works, then discovery probably will to. Maybe we make the discovery logs debug?

Copy link
Member Author

Choose a reason for hiding this comment

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

yup, makes sense Age. Updated!

Copy link

@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.

Great to see libp2p-upnp in action soon.

Copy link
Member

@ackintosh ackintosh left a comment

Choose a reason for hiding this comment

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

This looks good to me, but I left some minor comments.

"UPnP",
);
}
if let (true, Some(v4)) = (config.upnp_enabled, config.listen_addrs().v4()) {
Copy link
Member

Choose a reason for hiding this comment

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

I think we need to respect config.disable_discovery too.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah makes sense, updated!

"Lighthouse Discovery port",
)
.await
.context("Could not UPnP map port: {port} on the gateway")?;
Copy link
Member

Choose a reason for hiding this comment

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

It seems that the context() doesn't parse the {port} placeholder correctly.

Here is a log when I run beacon node with branch:

Nov 04 23:05:30.569 INFO Could not UPnP map Discovery port, error: Could not UPnP map port: {port} on the gateway, module: network::service:240

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks for trying this and providing feedback, updated!

@@ -1516,6 +1517,47 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
}
}

fn parse_upnp_event(&mut self, event: libp2p_upnp::Event) {
Copy link
Member

Choose a reason for hiding this comment

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

Since the existing methods for handling events are named with the prefix inject_, perhaps we should align with this naming convention? For example, we could name it inject_upnp_event.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah makes sense. Updated, thanks!

@ackintosh ackintosh mentioned this pull request Jan 7, 2024
@dapplion dapplion added the waiting-on-author The reviewer has suggested changes and awaits thier implementation. label Jan 19, 2024
Copy link
Member Author

@jxs jxs left a comment

Choose a reason for hiding this comment

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

Thanks for the review Akihito!

@@ -1516,6 +1517,47 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
}
}

fn parse_upnp_event(&mut self, event: libp2p_upnp::Event) {
Copy link
Member Author

Choose a reason for hiding this comment

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

yeah makes sense. Updated, thanks!

"Lighthouse Discovery port",
)
.await
.context("Could not UPnP map port: {port} on the gateway")?;
Copy link
Member Author

Choose a reason for hiding this comment

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

thanks for trying this and providing feedback, updated!

"UPnP",
);
}
if let (true, Some(v4)) = (config.upnp_enabled, config.listen_addrs().v4()) {
Copy link
Member Author

Choose a reason for hiding this comment

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

yeah makes sense, updated!

@jxs jxs added ready-for-review The code is ready for review and removed waiting-on-author The reviewer has suggested changes and awaits thier implementation. labels Feb 8, 2024
@jxs jxs requested a review from ackintosh February 12, 2024 14:47
@AgeManning AgeManning removed the ready-for-review The code is ready for review label Feb 18, 2024
@AgeManning AgeManning added the waiting-on-author The reviewer has suggested changes and awaits thier implementation. label Feb 18, 2024
) {
let nw = network_log.clone();
let v4 = v4.clone();
tokio::spawn(async move {
Copy link
Member

Choose a reason for hiding this comment

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

Should we use executor.spawn to spawn a future here, since we were using executor.spawn_blocking before?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, thanks for the catch Akihito! Updated

@jxs jxs requested a review from ackintosh February 19, 2024 11:21
Copy link
Member

@ackintosh ackintosh left a comment

Choose a reason for hiding this comment

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

Thanks for the update! Looks good to me.

@jxs
Copy link
Member Author

jxs commented Feb 22, 2024

@Mergifyio queue

Copy link

mergify bot commented Feb 22, 2024

queue

🟠 Waiting for conditions to match

  • any of: [🔀 queue conditions]
    • all of: [📌 queue conditions of queue default]
      • #approved-reviews-by >= 1
      • check-success=license/cla
      • check-success=target-branch-check
  • -draft [📌 queue requirement]
  • any of: [📌 queue -> configuration change requirements]
    • -mergify-configuration-changed
    • check-success=Configuration changed

@AgeManning
Copy link
Member

@Mergifyio queue

Copy link

mergify bot commented Feb 27, 2024

queue

✅ The pull request has been merged automatically

The pull request has been merged automatically at abd9965

mergify bot added a commit that referenced this pull request Feb 27, 2024
@mergify mergify bot merged commit abd9965 into sigp:unstable Feb 27, 2024
29 checks passed
pawanjay176 pushed a commit to pawanjay176/lighthouse that referenced this pull request Mar 5, 2024
* remove nat module and use libp2p upnp

* update Cargo.lock

* remove no longer used dependencies

* restore nat module refactored

* log successful mapping

* only activate upnp if config enabled

reduce logs to debug!

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into libp2p-nat

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into libp2p-nat

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into libp2p-nat

* address review

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into libp2p-nat

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into libp2p-nat

* Merge branch 'unstable' of https://github.com/sigp/lighthouse into libp2p-nat

* address review
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting-on-author The reviewer has suggested changes and awaits thier implementation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants