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

chore: Circuit relay #3112

Merged
merged 23 commits into from
Oct 28, 2024
Merged

chore: Circuit relay #3112

merged 23 commits into from
Oct 28, 2024

Conversation

Ivansete-status
Copy link
Collaborator

@Ivansete-status Ivansete-status commented Oct 14, 2024

Description

Allow a node to act as a circuit-relay client/server. Also, start the Hole Punch server.
This is useful for nodes that are behind a NAT or firewall and hence are not reachable.

Special kudos to @richard-ramos , @lchenut and @diegomrsantos. This PR is yours and also inspired by this PR: #1766

Changes

  • Undo installation of libpcre because we forced ubuntu 22.04 (unrelated change.)
  • Make Waku a ref object so that it's always passed as by ref.
  • Move autonat service code into a separate module, autonate_service and check self-reachability every 30 sec instead of every 2 min.
  • New external parameter, relay-client, which allows setting the node as a circuit-relay client. (we will need to document that.)
  • Update ENR when a circuit-relay-client reserves a slot in a circuit-relay-server.
  • Update announced IP address to avoid announcing 0.0.0.0 or 127.0.0.1.
  • Spawn nim-libp2p DiscoveryManager with rendezvous to advertise rendezvous namespaces based on the subscribed pubsub topics.
  • nat: add exception protection when calling getExternalIP.

How to test

Three nodes need to run. Two configured as relay-client and a third one configured as a relay server (default.)

  1. Start service node with the following in a VPS so that it is reachable:
ports-shift = 10
cluster-id = 2
log-level = "DEBUG"
nodekey = "1264d111d729a6eb6d2e6113e163f017b5ef03a6f94c9b5b7bb1bb36fa5cb07a9"

relay = false
  1. Start node A with the following configuration and behind a NAT. This will connect to the service node.
ports-shift = 1
cluster-id = 2
staticnode = [ "/ip4/162.19.247.156/tcp/60010/p2p/16Uiu2HAmCzWcYBCw3xKW8De16X9wtcbQrqD8x7CRRv4xpsFJ4oN8" ]

log-level = "DEBUG"
nodekey = "364d111d729a6eb6d2e6113e163f017b5ef03a6f94c9b5b7bb1bb36fa5cb07a9"

relay-client = true

Wait for two minutes until the node A determines that it is not reachable. When that happens, the node A reserves a circuit-relay slot in the relay service node.

  1. Start node B that will establish a relay connection with node A, through the relay sever:
ports-shift = 3
cluster-id = 2
staticnode = [ "/ip4/162.19.247.156/tcp/60010/p2p/16Uiu2HAmCzWcYBCw3xKW8De16X9wtcbQrqD8x7CRRv4xpsFJ4oN8/p2p-circuit/p2p/16Uiu2HAm2eqzqp6xn32fzgGi8K4BuF88W4Xy6yxsmDcW8h1gj6ie" ]
log-level = "DEBUG"
nodekey = "764d111d729a6eb6d2e6113e163f017b5ef03a6f94c9b5b7bb1bb36fa5cb07a9"

relay-client = true
  1. Stop the service node. In that case, node A and node B will still be connected even though they are not reachable due to the NAT condition.

Issue

closes #2514

Copy link

github-actions bot commented Oct 14, 2024

You can find the image built from this PR at

quay.io/wakuorg/nwaku-pr:3112

Built from f4b8a6f

@Ivansete-status Ivansete-status force-pushed the circuit-relay branch 4 times, most recently from a00afcb to d869cd3 Compare October 19, 2024 18:19
Copy link
Contributor

@gabrielmer gabrielmer left a comment

Choose a reason for hiding this comment

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

Wooow, amazing PR! 😍 😍

Thanks so much!

tests/wakunode_rest/test_rest_admin.nim Outdated Show resolved Hide resolved
tests/test_waku_switch.nim Show resolved Hide resolved
waku/discovery/waku_discv5.nim Outdated Show resolved Hide resolved
waku/factory/waku.nim Outdated Show resolved Hide resolved
Ivansete-status and others added 2 commits October 24, 2024 18:01
Co-authored-by: gabrielmer <101006718+gabrielmer@users.noreply.github.com>
Co-authored-by: gabrielmer <101006718+gabrielmer@users.noreply.github.com>
Copy link
Contributor

@NagyZoltanPeter NagyZoltanPeter left a comment

Choose a reason for hiding this comment

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

I think its a great work! Left some little suggestions though.
Thank you!

@@ -270,12 +270,12 @@ procSuite "Peer Manager":
storage = WakuPeerStorage.new(database)[]
node1 = newTestWakuNode(
generateSecp256k1Key(),
ValidIpAddress.init("127.0.0.1"),
ValidIpAddress.init($getPrimaryIPAddr()),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think getPrimaryIPAddr can be used here directly... no need to convert to string and than from string.

@@ -169,7 +169,7 @@ suite "WakuNode":
nodeKey = generateSecp256k1Key()
bindIp = parseIpAddress("0.0.0.0")
bindPort = Port(61006)
extIp = some(parseIpAddress("127.0.0.1"))
extIp = some(parseIpAddress($getPrimaryIPAddr()))
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, with getPrimaryIPAddr, no need to conver vica-versa, that shall give a valid IP IMHO.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks so much! I've applied your suggestions and much more cleaner now:)

Comment on lines 226 to 230
var relay = Relay.new()
if confCopy.isRelayClient:
relay = RelayClient.new()

let nodeRes = setupNode(confCopy, rng, relay)
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
var relay = Relay.new()
if confCopy.isRelayClient:
relay = RelayClient.new()
let nodeRes = setupNode(confCopy, rng, relay)
let relay =
if confCopy.isRelayClient: RelayClient.new()
else: Relay.new()
let nodeRes = setupNode(confCopy, rng, relay)

Maybe more straightforward and eliminates a possible useless initialization.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for the comment! I'd like to apply it but I came across a weird compilation issue (related to RelayClient, LPProtocol, templates, etc.) and due to that I need to initialize the circuitRelay component in a separate proc.

I assigned reviewers a bit prematurely in that one ¬¬ Sorry for upcoming spam!

Copy link
Member

@richard-ramos richard-ramos left a comment

Choose a reason for hiding this comment

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

Code lgtm but I couldnt find how do you indicate to nwaku which nodes to use for circuit relay server

@Ivansete-status
Copy link
Collaborator Author

Code lgtm but I couldnt find how do you indicate to nwaku which nodes to use for circuit relay server

Thanks for checking! In the tests I've used the staticnode argument.
Do you think we need a more explicit CLI argument?

@Ivansete-status Ivansete-status merged commit cfde7ee into master Oct 28, 2024
10 of 11 checks passed
@Ivansete-status Ivansete-status deleted the circuit-relay branch October 28, 2024 08:17
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.

Support for discovery of circuit-relay peers
4 participants