Skip to content

Commit 7a91e3e

Browse files
authored
Fix port selection (#423)
My previous PR introduced a regression, as `--port` was only respected for the TCP port, but not the discovery port. Also I noticed that `--port6` was not correctly set at all. Ensure that: - ports are set as in Go-SSV when `--port` is not specified. - if only `--port` is specified, that is used for both TCP and discovery UDP. - if `--discovery-port` is specified, that value is used for discovery UDP regardless of whether `--port` is specified. - `--port6` is respected
1 parent e738340 commit 7a91e3e

File tree

7 files changed

+61
-31
lines changed

7 files changed

+61
-31
lines changed

.github/wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,4 @@ onchain
8989
cli
9090
ENR
9191
UPnP
92+
Golang

anchor/client/src/cli.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,12 @@ pub struct Node {
257257
long,
258258
value_name = "PORT",
259259
help = "The TCP/UDP ports to listen on. There are two UDP ports. \
260-
The discovery UDP port will be set to this value and the Quic UDP port will be set to this value + 1. The discovery port can be modified by the \
260+
The discovery UDP and TCP port will be set to this value. The Quic UDP port will be set to this value + 1. The discovery port can be modified by the \
261261
--discovery-port flag and the quic port can be modified by the --quic-port flag. If listening over both IPv4 and IPv6 the --port flag \
262-
will apply to the IPv4 address and --port6 to the IPv6 address.",
263-
default_value = "13001",
262+
will apply to the IPv4 address and --port6 to the IPv6 address. If this flag is not set, the default values will be 12001 for discovery and 13001 for TCP.",
264263
action = ArgAction::Set,
265264
)]
266-
pub port: u16,
265+
pub port: Option<u16>,
267266

268267
#[clap(
269268
long,
@@ -277,8 +276,7 @@ pub struct Node {
277276
#[clap(
278277
long,
279278
value_name = "PORT",
280-
help = "The UDP port that discovery will listen on. Defaults to `12001`",
281-
default_value = "12001",
279+
help = "The UDP port that discovery will listen on. Defaults to --port if --port is explicitly specified, and `12001` otherwise.",
282280
action = ArgAction::Set,
283281
)]
284282
pub discovery_port: Option<u16>,

anchor/client/src/config.rs

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use std::{fs, net::IpAddr, path::PathBuf};
55

66
use multiaddr::{Multiaddr, Protocol};
7-
use network::{ListenAddr, ListenAddress};
7+
use network::{DEFAULT_DISC_PORT, DEFAULT_TCP_PORT, ListenAddr, ListenAddress};
88
use sensitive_url::SensitiveUrl;
99
use ssv_network_config::SsvNetworkConfig;
1010
use ssv_types::OperatorId;
@@ -360,22 +360,34 @@ pub fn parse_listening_addresses(cli_args: &Node) -> Result<ListenAddress, Strin
360360
)
361361
}
362362

363-
// use zero ports if required. If not, use the given port.
363+
// Select the QUIC port in the following order of precedence:
364+
// 1. If use_zero_ports is set, use an unused TCP6 port.
365+
// 2. Else, if port is specified, use it.
366+
// 3. If none of the above are set, use the default TCP port (DEFAULT_TCP_PORT).
364367
let tcp_port = cli_args
365368
.use_zero_ports
366369
.then(unused_port::unused_tcp6_port)
367370
.transpose()?
368-
.unwrap_or(cli_args.port);
369-
370-
// use zero ports if required. If not, use the specific udp port. If none given, use
371-
// the tcp port.
371+
.or(cli_args.port)
372+
.unwrap_or(DEFAULT_TCP_PORT);
373+
374+
// Select the discovery port in the following order of precedence:
375+
// 1. If use_zero_ports is set, use an unused UDP6 port.
376+
// 2. Else, if discovery_port is specified in CLI args, use it.
377+
// 3. Else, if port is specified, use it as the fallback.
378+
// 4. If none of the above are set, use the default discovery port (DEFAULT_DISC_PORT).
372379
let disc_port = cli_args
373380
.use_zero_ports
374381
.then(unused_port::unused_udp6_port)
375382
.transpose()?
376383
.or(cli_args.discovery_port)
377-
.unwrap_or(tcp_port);
384+
.or(cli_args.port)
385+
.unwrap_or(DEFAULT_DISC_PORT);
378386

387+
// Select the QUIC port in the following order of precedence:
388+
// 1. If use_zero_ports is set, use an unused UDP6 port.
389+
// 2. Else, if quic_port is specified, use it.
390+
// 3. If none of the above are set, use the selected TCP port + 1.
379391
let quic_port = cli_args
380392
.use_zero_ports
381393
.then(unused_port::unused_udp6_port)
@@ -393,22 +405,32 @@ pub fn parse_listening_addresses(cli_args: &Node) -> Result<ListenAddress, Strin
393405
(Some(ipv4), None) => {
394406
// A single ipv4 address was provided. Set the ports
395407

396-
// use zero ports if required. If not, use the given port.
408+
// Select the TCP port in the following order of precedence:
409+
// 1. If use_zero_ports is set, use an unused TCP4 port.
410+
// 2. Else, if port is specified, use it.
411+
// 3. If none of the above are set, use the default TCP port (DEFAULT_TCP_PORT).
397412
let tcp_port = cli_args
398413
.use_zero_ports
399414
.then(unused_port::unused_tcp4_port)
400415
.transpose()?
401-
.unwrap_or(cli_args.port);
402-
// use zero ports if required. If not, use the specific discovery port. If none given,
403-
// use the tcp port.
416+
.or(cli_args.port)
417+
.unwrap_or(DEFAULT_TCP_PORT);
418+
// Select the discovery port in the following order of precedence:
419+
// 1. If use_zero_ports is set, use an unused UDP4 port.
420+
// 2. Else, if discovery_port is specified in CLI args, use it.
421+
// 3. Else, if port is specified, use it as the fallback.
422+
// 4. If none of the above are set, use the default discovery port (DEFAULT_DISC_PORT).
404423
let disc_port = cli_args
405424
.use_zero_ports
406425
.then(unused_port::unused_udp4_port)
407426
.transpose()?
408427
.or(cli_args.discovery_port)
409-
.unwrap_or(tcp_port);
410-
// use zero ports if required. If not, use the specific quic port. If none given, use
411-
// the tcp port + 1.
428+
.or(cli_args.port)
429+
.unwrap_or(DEFAULT_DISC_PORT);
430+
// Select the QUIC port in the following order of precedence:
431+
// 1. If use_zero_ports is set, use an unused UDP4 port.
432+
// 2. Else, if quic_port is specified, use it.
433+
// 3. If none of the above are set, use the selected TCP port + 1.
412434
let quic_port = cli_args
413435
.use_zero_ports
414436
.then(unused_port::unused_udp4_port)
@@ -428,13 +450,15 @@ pub fn parse_listening_addresses(cli_args: &Node) -> Result<ListenAddress, Strin
428450
.use_zero_ports
429451
.then(unused_port::unused_tcp4_port)
430452
.transpose()?
431-
.unwrap_or(cli_args.port);
453+
.or(cli_args.port)
454+
.unwrap_or(DEFAULT_TCP_PORT);
432455
let ipv4_disc_port = cli_args
433456
.use_zero_ports
434457
.then(unused_port::unused_udp4_port)
435458
.transpose()?
436459
.or(cli_args.discovery_port)
437-
.unwrap_or(ipv4_tcp_port);
460+
.or(cli_args.port)
461+
.unwrap_or(DEFAULT_DISC_PORT);
438462
let ipv4_quic_port = cli_args
439463
.use_zero_ports
440464
.then(unused_port::unused_udp4_port)
@@ -450,7 +474,8 @@ pub fn parse_listening_addresses(cli_args: &Node) -> Result<ListenAddress, Strin
450474
.use_zero_ports
451475
.then(unused_port::unused_tcp6_port)
452476
.transpose()?
453-
.unwrap_or(cli_args.port);
477+
.or(cli_args.port6)
478+
.unwrap_or(ipv4_tcp_port);
454479
let ipv6_disc_port = cli_args
455480
.use_zero_ports
456481
.then(unused_port::unused_udp6_port)

anchor/network/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod peer_manager;
1010
mod scoring;
1111
mod transport;
1212

13-
pub use config::Config;
13+
pub use config::{Config, DEFAULT_DISC_PORT, DEFAULT_QUIC_PORT, DEFAULT_TCP_PORT};
1414
pub use lighthouse_network::{ListenAddr, ListenAddress};
1515
pub use network::Network;
1616
pub type Enr = discv5::enr::Enr<discv5::enr::CombinedKey>;

book/src/advanced_networking.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ Anchor's networking stack is closely based on Lighthouse's. We refer to
55
but want to outline several important differences:
66

77
- Currently, Anchor does not support UPnP.
8-
- Anchor uses ports 12001 (UDP), 13001 (TCP), and 9101 (UDP) by default.
8+
- Anchor uses ports 12001 (UDP), 13001 (TCP), and 12002 (UDP) by default.
99
- Anchor does not yet support ENR auto-update - we therefore recommend manually setting publicly reachable ports via the
1010
`--enr*-port` CLI parameters to advertise your node as reachable on the network.

book/src/cli.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ anchor node [OPTIONS]
7373
| `--listen-address <ADDRESS>` | Network address to listen for UDP & TCP connections | `0.0.0.0` |
7474
| `--port <PORT>` | Base port for all network connections | `13001` |
7575
| `--port6 <PORT>` | Base port for IPv6 network connections | Same as `--port` |
76-
| `--discovery-port <PORT>` | UDP port for discovery | `12001` |
76+
| `--discovery-port <PORT>` | UDP port for discovery | Same as `--port` if specified, otherwise `12001` |
7777
| `--discovery-port6 <PORT>` | UDP port for IPv6 discovery | Same as `--discovery-port` |
7878
| `--quic-port <PORT>` | UDP port for QUIC protocol | `--port` + 1 |
7979
| `--quic-port6 <PORT>` | UDP port for IPv6 QUIC protocol | `--port6` + 1 |

book/src/running_node.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
An SSV operator is a node that holds shares of validators' keys and participates in committees to perform Ethereum validation duties. The SSV network enables distributed validation where multiple operators collectively validate without any single operator having access to the complete validator key.
66

7+
If you want to migrate an existing key from the Golang implementation of SSV, you can directly proceed to Step 3.
8+
79
**Step 1: Generate RSA keys**
810

911
Anchor includes a key generation tool to create the RSA keys needed for operator identity:
@@ -30,23 +32,27 @@ To register an operator, follow the instructions for the official
3032

3133
**Step 3: Configure and run your Anchor node**
3234

33-
Create a directory for Anchor-related data and move the generated private key into the directory.
35+
Create a directory for Anchor-related data and move the generated private key into the directory. By default, Anchor
36+
uses `~/.anchor/<network>`, where `<network>` is `hoodi` or `holesky`. We use `hoodi` below:
3437

3538
```bash
36-
mkdir -p ~/.anchor
39+
mkdir -p ~/.anchor/hoodi
3740

38-
mv encrypted_private_key.json ~/.anchor
41+
mv encrypted_private_key.json ~/.anchor/hoodi
3942
```
4043

4144
Use the [CLI Reference](./cli.md) or `--help` to launch the node. If you use an encrypted key, you must specify the password via a password file or interactively input it when starting the node.
4245

4346
```bash
4447
anchor node \
4548
--network hoodi \
46-
--datadir ~/.anchor \
49+
--datadir ~/.anchor/hoodi \
4750
--beacon-nodes http://localhost:5052 \
4851
--execution-rpc http://localhost:8545 \
4952
--execution-ws ws://localhost:8546 \
50-
--metrics \
5153
--password-file /path/to/file
5254
```
55+
56+
All options used in this example (except for the `password-file`) are actually used with the default values and can therefore be omitted, or adjusted to your setup.
57+
58+
The Anchor node will use the same ports as used by Go-SSV unless explicitly overridden. See [Advanced Networking](./advanced_networking.md) for more information

0 commit comments

Comments
 (0)