Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,4 @@ onchain
cli
ENR
UPnP
Golang
10 changes: 4 additions & 6 deletions anchor/client/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,12 @@ pub struct Node {
long,
value_name = "PORT",
help = "The TCP/UDP ports to listen on. There are two UDP ports. \
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 \
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 \
--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 \
will apply to the IPv4 address and --port6 to the IPv6 address.",
default_value = "13001",
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.",
action = ArgAction::Set,
)]
pub port: u16,
pub port: Option<u16>,

#[clap(
long,
Expand All @@ -277,8 +276,7 @@ pub struct Node {
#[clap(
long,
value_name = "PORT",
help = "The UDP port that discovery will listen on. Defaults to `12001`",
default_value = "12001",
help = "The UDP port that discovery will listen on. Defaults to --port if --port is explicitly specified, and `12001` otherwise.",
action = ArgAction::Set,
)]
pub discovery_port: Option<u16>,
Expand Down
59 changes: 42 additions & 17 deletions anchor/client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::{fs, net::IpAddr, path::PathBuf};

use multiaddr::{Multiaddr, Protocol};
use network::{ListenAddr, ListenAddress};
use network::{DEFAULT_DISC_PORT, DEFAULT_TCP_PORT, ListenAddr, ListenAddress};
use sensitive_url::SensitiveUrl;
use ssv_network_config::SsvNetworkConfig;
use ssv_types::OperatorId;
Expand Down Expand Up @@ -360,22 +360,34 @@ pub fn parse_listening_addresses(cli_args: &Node) -> Result<ListenAddress, Strin
)
}

// use zero ports if required. If not, use the given port.
// Select the QUIC port in the following order of precedence:
// 1. If use_zero_ports is set, use an unused TCP6 port.
// 2. Else, if port is specified, use it.
// 3. If none of the above are set, use the default TCP port (DEFAULT_TCP_PORT).
let tcp_port = cli_args
.use_zero_ports
.then(unused_port::unused_tcp6_port)
.transpose()?
.unwrap_or(cli_args.port);

// use zero ports if required. If not, use the specific udp port. If none given, use
// the tcp port.
.or(cli_args.port)
.unwrap_or(DEFAULT_TCP_PORT);

// Select the discovery port in the following order of precedence:
// 1. If use_zero_ports is set, use an unused UDP6 port.
// 2. Else, if discovery_port is specified in CLI args, use it.
// 3. Else, if port is specified, use it as the fallback.
// 4. If none of the above are set, use the default discovery port (DEFAULT_DISC_PORT).
let disc_port = cli_args
.use_zero_ports
.then(unused_port::unused_udp6_port)
.transpose()?
.or(cli_args.discovery_port)
.unwrap_or(tcp_port);
.or(cli_args.port)
.unwrap_or(DEFAULT_DISC_PORT);

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

// use zero ports if required. If not, use the given port.
// Select the TCP port in the following order of precedence:
// 1. If use_zero_ports is set, use an unused TCP4 port.
// 2. Else, if port is specified, use it.
// 3. If none of the above are set, use the default TCP port (DEFAULT_TCP_PORT).
let tcp_port = cli_args
.use_zero_ports
.then(unused_port::unused_tcp4_port)
.transpose()?
.unwrap_or(cli_args.port);
// use zero ports if required. If not, use the specific discovery port. If none given,
// use the tcp port.
.or(cli_args.port)
.unwrap_or(DEFAULT_TCP_PORT);
// Select the discovery port in the following order of precedence:
// 1. If use_zero_ports is set, use an unused UDP4 port.
// 2. Else, if discovery_port is specified in CLI args, use it.
// 3. Else, if port is specified, use it as the fallback.
// 4. If none of the above are set, use the default discovery port (DEFAULT_DISC_PORT).
let disc_port = cli_args
.use_zero_ports
.then(unused_port::unused_udp4_port)
.transpose()?
.or(cli_args.discovery_port)
.unwrap_or(tcp_port);
// use zero ports if required. If not, use the specific quic port. If none given, use
// the tcp port + 1.
.or(cli_args.port)
.unwrap_or(DEFAULT_DISC_PORT);
// Select the QUIC port in the following order of precedence:
// 1. If use_zero_ports is set, use an unused UDP4 port.
// 2. Else, if quic_port is specified, use it.
// 3. If none of the above are set, use the selected TCP port + 1.
let quic_port = cli_args
.use_zero_ports
.then(unused_port::unused_udp4_port)
Expand All @@ -428,13 +450,15 @@ pub fn parse_listening_addresses(cli_args: &Node) -> Result<ListenAddress, Strin
.use_zero_ports
.then(unused_port::unused_tcp4_port)
.transpose()?
.unwrap_or(cli_args.port);
.or(cli_args.port)
.unwrap_or(DEFAULT_TCP_PORT);
let ipv4_disc_port = cli_args
.use_zero_ports
.then(unused_port::unused_udp4_port)
.transpose()?
.or(cli_args.discovery_port)
.unwrap_or(ipv4_tcp_port);
.or(cli_args.port)
.unwrap_or(DEFAULT_DISC_PORT);
let ipv4_quic_port = cli_args
.use_zero_ports
.then(unused_port::unused_udp4_port)
Expand All @@ -450,7 +474,8 @@ pub fn parse_listening_addresses(cli_args: &Node) -> Result<ListenAddress, Strin
.use_zero_ports
.then(unused_port::unused_tcp6_port)
.transpose()?
.unwrap_or(cli_args.port);
.or(cli_args.port6)
.unwrap_or(ipv4_tcp_port);
let ipv6_disc_port = cli_args
.use_zero_ports
.then(unused_port::unused_udp6_port)
Expand Down
3 changes: 3 additions & 0 deletions anchor/network/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ impl AnchorBehaviour {
.message_id_fn(gossip_message_id)
.flood_publish(false)
.validation_mode(ValidationMode::Permissive)
// Do not punish identical messages generated by us and other nodes. This can happen for
// `Decided` messages.
.allow_self_origin(true)
.mesh_n(8) // D
.mesh_n_low(6) // Dlo
.mesh_n_high(12) // Dhi
Expand Down
2 changes: 1 addition & 1 deletion anchor/network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod peer_manager;
mod scoring;
mod transport;

pub use config::Config;
pub use config::{Config, DEFAULT_DISC_PORT, DEFAULT_QUIC_PORT, DEFAULT_TCP_PORT};
pub use lighthouse_network::{ListenAddr, ListenAddress};
pub use network::Network;
pub type Enr = discv5::enr::Enr<discv5::enr::CombinedKey>;
2 changes: 1 addition & 1 deletion book/src/advanced_networking.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ Anchor's networking stack is closely based on Lighthouse's. We refer to
but want to outline several important differences:

- Currently, Anchor does not support UPnP.
- Anchor uses ports 12001 (UDP), 13001 (TCP), and 9101 (UDP) by default.
- Anchor uses ports 12001 (UDP), 13001 (TCP), and 12002 (UDP) by default.
- Anchor does not yet support ENR auto-update - we therefore recommend manually setting publicly reachable ports via the
`--enr*-port` CLI parameters to advertise your node as reachable on the network.
2 changes: 1 addition & 1 deletion book/src/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ anchor node [OPTIONS]
| `--listen-address <ADDRESS>` | Network address to listen for UDP & TCP connections | `0.0.0.0` |
| `--port <PORT>` | Base port for all network connections | `13001` |
| `--port6 <PORT>` | Base port for IPv6 network connections | Same as `--port` |
| `--discovery-port <PORT>` | UDP port for discovery | `12001` |
| `--discovery-port <PORT>` | UDP port for discovery | Same as `--port` if specified, otherwise `12001` |
| `--discovery-port6 <PORT>` | UDP port for IPv6 discovery | Same as `--discovery-port` |
| `--quic-port <PORT>` | UDP port for QUIC protocol | `--port` + 1 |
| `--quic-port6 <PORT>` | UDP port for IPv6 QUIC protocol | `--port6` + 1 |
Expand Down
16 changes: 11 additions & 5 deletions book/src/running_node.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

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.

If you want to migrate an existing key from the Golang implementation of SSV, you can directly proceed to Step 3.

**Step 1: Generate RSA keys**

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

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

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

```bash
mkdir -p ~/.anchor
mkdir -p ~/.anchor/hoodi

mv encrypted_private_key.json ~/.anchor
mv encrypted_private_key.json ~/.anchor/hoodi
```

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.

```bash
anchor node \
--network hoodi \
--datadir ~/.anchor \
--datadir ~/.anchor/hoodi \
--beacon-nodes http://localhost:5052 \
--execution-rpc http://localhost:8545 \
--execution-ws ws://localhost:8546 \
--metrics \
--password-file /path/to/file
```

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.

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