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

Replace PeerListAck with GetPeerList #2580

Merged
merged 100 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from 97 commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
c2154c4
Remove PeerListAck support
StephenButtolph Jan 2, 2024
093498c
Enable parsing of bloom filters
StephenButtolph Jan 2, 2024
e6785bc
Remove peerlist tracking from the network
StephenButtolph Jan 2, 2024
64a54b2
Implement validator tracker
StephenButtolph Jan 2, 2024
8d9371f
Remove gossip tracker
StephenButtolph Jan 2, 2024
eb0b771
Add BloomFilter support in the Handshake message
StephenButtolph Jan 2, 2024
db7f595
Remove TxID from claimed IP address
StephenButtolph Jan 2, 2024
8d2b459
Optimize bloom filter
StephenButtolph Jan 4, 2024
1a845f0
remove murmur
StephenButtolph Jan 4, 2024
d94b846
Update serialization logic and invert probability calculations
StephenButtolph Jan 5, 2024
de764ef
special cases
StephenButtolph Jan 5, 2024
83cbe38
test
StephenButtolph Jan 5, 2024
1d0b0a3
add fuzzing
StephenButtolph Jan 5, 2024
e1b9490
Prevent undefined behavior
StephenButtolph Jan 5, 2024
2ef237e
nits
StephenButtolph Jan 5, 2024
ef2cb2b
nit
StephenButtolph Jan 5, 2024
97e4958
nit
StephenButtolph Jan 5, 2024
5ab52b0
cleanup edge case handling
StephenButtolph Jan 5, 2024
7104b09
add comment
StephenButtolph Jan 5, 2024
7ac29af
nit
StephenButtolph Jan 5, 2024
6eaf8d9
Remove test flaking on platform specific results from math.Log
StephenButtolph Jan 5, 2024
5369c92
Merge branch 'dev' into optimize-bloom-filter
StephenButtolph Jan 5, 2024
7d87eb5
merged
StephenButtolph Jan 5, 2024
98d1424
Add local bloom filter
StephenButtolph Jan 5, 2024
4f6aea3
periodically reset the bloom filter
StephenButtolph Jan 5, 2024
e888a3b
add TODO
StephenButtolph Jan 5, 2024
fa3d0a3
Remove peerID from Track
StephenButtolph Jan 5, 2024
9a7bece
Add GetPeerList message
StephenButtolph Jan 5, 2024
a7d56c2
Add bloom filter to version message
StephenButtolph Jan 5, 2024
75a7cb5
periodically send getPeerList requests
StephenButtolph Jan 6, 2024
0463e98
Add new configs
StephenButtolph Jan 6, 2024
fac4698
fixes
StephenButtolph Jan 6, 2024
56e7df4
nit
StephenButtolph Jan 6, 2024
d08dda9
wip
StephenButtolph Jan 8, 2024
17adfbd
typo
StephenButtolph Jan 8, 2024
3f5c203
Merge branch 'dev' into optimize-bloom-filter
StephenButtolph Jan 8, 2024
8058987
typo
StephenButtolph Jan 8, 2024
60ce520
Merge branch 'optimize-bloom-filter' of github.com:ava-labs/avalanche…
StephenButtolph Jan 8, 2024
41c5297
nits
StephenButtolph Jan 8, 2024
91942a7
Merge branch 'optimize-bloom-filter' into ip-pull-gossip
StephenButtolph Jan 8, 2024
2312f00
update manual tracking
StephenButtolph Jan 8, 2024
b1045d9
validator tracker -> ip tracker
StephenButtolph Jan 8, 2024
d82f00a
resolve TODO + minimize gossipID
StephenButtolph Jan 8, 2024
1cf3c0b
cleanup ip tracker
StephenButtolph Jan 8, 2024
bb697e3
merged
StephenButtolph Jan 8, 2024
46a68b2
nits
StephenButtolph Jan 8, 2024
e3b1161
nits
StephenButtolph Jan 8, 2024
a75b119
add manually track tests
StephenButtolph Jan 9, 2024
5b008b7
Add AddIP tests
StephenButtolph Jan 9, 2024
4d0570f
Add more ip tracker tests
StephenButtolph Jan 9, 2024
b5d7c80
Remove TLS key gen from networking tests
StephenButtolph Jan 9, 2024
9b849cd
Merge branch 'remove-test-tls-key-gen' into ip-pull-gossip
StephenButtolph Jan 9, 2024
d9e17b5
Remove TLS key gen from new tests
StephenButtolph Jan 9, 2024
9591672
reduce diff
StephenButtolph Jan 9, 2024
2af9913
nit
StephenButtolph Jan 9, 2024
991f81f
Merge branch 'remove-test-tls-key-gen' into ip-pull-gossip
StephenButtolph Jan 9, 2024
c3f2c0e
add getPeerList tests
StephenButtolph Jan 9, 2024
f9c5a50
rename
StephenButtolph Jan 9, 2024
cdd936a
nit
StephenButtolph Jan 9, 2024
0665d60
nit
StephenButtolph Jan 9, 2024
ac48e3b
reduce diff
StephenButtolph Jan 9, 2024
5fbe20b
remove useless disconnected calls
StephenButtolph Jan 9, 2024
80b2d1d
nit
StephenButtolph Jan 9, 2024
e726f99
nit
StephenButtolph Jan 9, 2024
e89aa59
nit
StephenButtolph Jan 9, 2024
b4d1351
address nits
StephenButtolph Jan 9, 2024
5d0b1ad
remove dead code
StephenButtolph Jan 9, 2024
ee7d340
Merge branch 'dev' into ip-pull-gossip
StephenButtolph Jan 9, 2024
84af051
Merge branch 'dev' into ip-pull-gossip
StephenButtolph Jan 9, 2024
3b42d0e
Merge branch 'dev' into ip-pull-gossip
StephenButtolph Jan 9, 2024
008b71d
wip readme
StephenButtolph Jan 9, 2024
04624a5
wip readme
StephenButtolph Jan 9, 2024
29c3c15
wip readme
StephenButtolph Jan 9, 2024
d94927a
wip readme
StephenButtolph Jan 9, 2024
79f89be
wip readme
StephenButtolph Jan 9, 2024
bd9be3f
wip readme
StephenButtolph Jan 9, 2024
901ea16
wip readme
StephenButtolph Jan 9, 2024
e6b3ea1
wip readme
StephenButtolph Jan 9, 2024
ddfc174
wip readme
StephenButtolph Jan 9, 2024
fa34839
wip readme
StephenButtolph Jan 9, 2024
2e7678f
wip readme
StephenButtolph Jan 9, 2024
7a379c6
wip readme
StephenButtolph Jan 9, 2024
ed37d85
nit remove multiple init functions
StephenButtolph Jan 9, 2024
39119f6
nit
StephenButtolph Jan 10, 2024
6b367af
add more comments
StephenButtolph Jan 10, 2024
fdc9af3
ok
StephenButtolph Jan 10, 2024
6f92e95
Merge branch 'dev' into ip-pull-gossip
StephenButtolph Jan 11, 2024
fb9fd84
Add logs and checks
StephenButtolph Jan 11, 2024
5a51f7b
Merge branch 'dev' into dynamic-staking-port-fix
StephenButtolph Jan 11, 2024
35ae4f1
nit comment
StephenButtolph Jan 11, 2024
3661156
move nat traversal into the node
StephenButtolph Jan 12, 2024
a05c340
test nit
StephenButtolph Jan 12, 2024
194dee8
fix CI
StephenButtolph Jan 12, 2024
4844189
Merge branch 'dev' into dynamic-staking-port-fix
StephenButtolph Jan 12, 2024
ee9486c
nit
StephenButtolph Jan 13, 2024
37bcb38
Merge branch 'dynamic-staking-port-fix' of github.com:ava-labs/avalan…
StephenButtolph Jan 13, 2024
2b3aca3
Merge branch 'dynamic-staking-port-fix' into ip-pull-gossip
StephenButtolph Jan 13, 2024
e2097d7
merged
StephenButtolph Jan 14, 2024
40f6d11
typo
StephenButtolph Jan 14, 2024
229666b
cleanup proto reservations
StephenButtolph Jan 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 11 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,17 @@ jobs:
- name: Build AvalancheGo Binary
shell: bash
run: ./scripts/build.sh
- name: Run e2e tests
shell: bash
run: ./scripts/tests.upgrade.sh
- name: Upload tmpnet network dir
uses: actions/upload-artifact@v3
if: always()
with:
name: upgrade-tmpnet-data
path: ${{ env.tmpnet_data_path }}
if-no-files-found: error
# TODO: re-activate this test after there is a compatible tag to use
# - name: Run e2e tests
# shell: bash
# run: ./scripts/tests.upgrade.sh
# - name: Upload tmpnet network dir
# uses: actions/upload-artifact@v3
# if: always()
# with:
# name: upgrade-tmpnet-data
# path: ${{ env.tmpnet_data_path }}
# if-no-files-found: error
Lint:
runs-on: ubuntu-latest
steps:
Expand Down
99 changes: 2 additions & 97 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,20 @@ import (

"golang.org/x/sync/errgroup"

"github.com/ava-labs/avalanchego/nat"
"github.com/ava-labs/avalanchego/node"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/ips"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/utils/perms"
"github.com/ava-labs/avalanchego/utils/ulimit"
)

const (
Header = ` _____ .__ .__
const Header = ` _____ .__ .__
/ _ \___ _______ | | _____ ____ ____ | |__ ____ ,_ o
/ /_\ \ \/ /\__ \ | | \__ \ / \_/ ___\| | \_/ __ \ / //\,
/ | \ / / __ \| |__/ __ \| | \ \___| Y \ ___/ \>> |
\____|__ /\_/ (____ /____(____ /___| /\___ >___| /\___ > \\
\/ \/ \/ \/ \/ \/ \/`
)

var (
stakingPortName = fmt.Sprintf("%s-staking", constants.AppName)
httpPortName = fmt.Sprintf("%s-http", constants.AppName)

_ App = (*app)(nil)
)
var _ App = (*app)(nil)

type App interface {
// Start kicks off the application and returns immediately.
Expand Down Expand Up @@ -144,88 +134,6 @@ type app struct {
// Does not block until the node is done. Errors returned from this method
// are not logged.
func (a *app) Start() error {
// Track if sybil control is enforced
if !a.config.SybilProtectionEnabled {
a.log.Warn("sybil control is not enforced")
}

// TODO move this to config
// SupportsNAT() for NoRouter is false.
// Which means we tried to perform a NAT activity but we were not successful.
if a.config.AttemptedNATTraversal && !a.config.Nat.SupportsNAT() {
a.log.Warn("UPnP and NAT-PMP router attach failed, " +
"you may not be listening publicly. " +
"Please confirm the settings in your router")
}

if ip := a.config.IPPort.IPPort().IP; ip.IsLoopback() || ip.IsPrivate() {
a.log.Warn("P2P IP is private, you will not be publicly discoverable",
zap.Stringer("ip", ip),
)
}

// An empty host is treated as a wildcard to match all addresses, so it is
// considered public.
hostIsPublic := a.config.HTTPHost == ""
if !hostIsPublic {
ip, err := ips.Lookup(a.config.HTTPHost)
if err != nil {
a.log.Fatal("failed to lookup HTTP host",
zap.String("host", a.config.HTTPHost),
zap.Error(err),
)
a.logFactory.Close()
return err
}
hostIsPublic = !ip.IsLoopback() && !ip.IsPrivate()

a.log.Debug("finished HTTP host lookup",
zap.String("host", a.config.HTTPHost),
zap.Stringer("ip", ip),
zap.Bool("isPublic", hostIsPublic),
)
}

mapper := nat.NewPortMapper(a.log, a.config.Nat)

// Open staking port we want for NAT traversal to have the external port
// (config.IP.Port) to connect to our internal listening port
// (config.InternalStakingPort) which should be the same in most cases.
if port := a.config.IPPort.IPPort().Port; port != 0 {
mapper.Map(
port,
port,
stakingPortName,
a.config.IPPort,
a.config.IPResolutionFreq,
)
}

// Don't open the HTTP port if the HTTP server is private
if hostIsPublic {
a.log.Warn("HTTP server is binding to a potentially public host. "+
"You may be vulnerable to a DoS attack if your HTTP port is publicly accessible",
zap.String("host", a.config.HTTPHost),
)

// For NAT traversal we want to route from the external port
// (config.ExternalHTTPPort) to our internal port (config.HTTPPort).
if a.config.HTTPPort != 0 {
mapper.Map(
a.config.HTTPPort,
a.config.HTTPPort,
httpPortName,
nil,
a.config.IPResolutionFreq,
)
}
}

// Regularly update our public IP.
// Note that if the node config said to not dynamically resolve and
// update our public IP, [p.config.IPUdater] is a no-op implementation.
go a.config.IPUpdater.Dispatch(a.log)

// [p.ExitCode] will block until [p.exitWG.Done] is called
a.exitWG.Add(1)
go func() {
Expand All @@ -238,9 +146,6 @@ func (a *app) Start() error {
a.exitWG.Done()
}()
defer func() {
mapper.UnmapAllPorts()
a.config.IPUpdater.Stop()

// If [p.node.Dispatch()] panics, then we should log the panic and
// then re-raise the panic. This is why the above defer is broken
// into two parts.
Expand Down
74 changes: 15 additions & 59 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@
package config

import (
"context"
"crypto/tls"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/fs"
"math"
"net"
"os"
"path/filepath"
"strings"
Expand All @@ -25,7 +23,6 @@ import (
"github.com/ava-labs/avalanchego/genesis"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/ipcs"
"github.com/ava-labs/avalanchego/nat"
"github.com/ava-labs/avalanchego/network"
"github.com/ava-labs/avalanchego/network/dialer"
"github.com/ava-labs/avalanchego/network/throttling"
Expand All @@ -40,7 +37,6 @@ import (
"github.com/ava-labs/avalanchego/utils/compression"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/crypto/bls"
"github.com/ava-labs/avalanchego/utils/dynamicip"
"github.com/ava-labs/avalanchego/utils/ips"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/utils/password"
Expand All @@ -58,7 +54,6 @@ const (
chainConfigFileName = "config"
chainUpgradeFileName = "upgrade"
subnetConfigFileExt = ".json"
ipResolutionTimeout = 30 * time.Second

ipcDeprecationMsg = "IPC API is deprecated"
keystoreDeprecationMsg = "keystore API is deprecated"
Expand Down Expand Up @@ -432,6 +427,8 @@ func getNetworkConfig(
PeerListNonValidatorGossipSize: v.GetUint32(NetworkPeerListNonValidatorGossipSizeKey),
PeerListPeersGossipSize: v.GetUint32(NetworkPeerListPeersGossipSizeKey),
PeerListGossipFreq: v.GetDuration(NetworkPeerListGossipFreqKey),
PeerListPullGossipFreq: v.GetDuration(NetworkPeerListPullGossipFreqKey),
PeerListBloomResetFreq: v.GetDuration(NetworkPeerListBloomResetFreqKey),
},

DelayConfig: network.DelayConfig{
Expand Down Expand Up @@ -467,6 +464,10 @@ func getNetworkConfig(
return network.Config{}, fmt.Errorf("%q must be >= 0", NetworkOutboundConnectionTimeoutKey)
case config.PeerListGossipFreq < 0:
return network.Config{}, fmt.Errorf("%s must be >= 0", NetworkPeerListGossipFreqKey)
case config.PeerListPullGossipFreq < 0:
return network.Config{}, fmt.Errorf("%s must be >= 0", NetworkPeerListPullGossipFreqKey)
case config.PeerListBloomResetFreq < 0:
return network.Config{}, fmt.Errorf("%s must be >= 0", NetworkPeerListBloomResetFreqKey)
case config.ThrottlerConfig.InboundMsgThrottlerConfig.CPUThrottlerConfig.MaxRecheckDelay < constants.MinInboundThrottlerMaxRecheckDelay:
return network.Config{}, fmt.Errorf("%s must be >= %d", InboundThrottlerCPUMaxRecheckDelayKey, constants.MinInboundThrottlerMaxRecheckDelay)
case config.ThrottlerConfig.InboundMsgThrottlerConfig.DiskThrottlerConfig.MaxRecheckDelay < constants.MinInboundThrottlerMaxRecheckDelay:
Expand Down Expand Up @@ -617,64 +618,19 @@ func getBootstrapConfig(v *viper.Viper, networkID uint32) (node.BootstrapConfig,
}

func getIPConfig(v *viper.Viper) (node.IPConfig, error) {
ipResolutionService := v.GetString(PublicIPResolutionServiceKey)
ipResolutionFreq := v.GetDuration(PublicIPResolutionFreqKey)
if ipResolutionFreq <= 0 {
return node.IPConfig{}, fmt.Errorf("%q must be > 0", PublicIPResolutionFreqKey)
}

stakingPort := uint16(v.GetUint(StakingPortKey))
publicIP := v.GetString(PublicIPKey)
if publicIP != "" && ipResolutionService != "" {
return node.IPConfig{}, fmt.Errorf("only one of --%s and --%s can be given", PublicIPKey, PublicIPResolutionServiceKey)
}

// Define default configuration
ipConfig := node.IPConfig{
IPUpdater: dynamicip.NewNoUpdater(),
IPResolutionFreq: ipResolutionFreq,
Nat: nat.NewNoRouter(),
ListenHost: v.GetString(StakingHostKey),
}

if publicIP != "" {
// User specified a specific public IP to use.
ip := net.ParseIP(publicIP)
if ip == nil {
return node.IPConfig{}, fmt.Errorf("invalid IP Address %s", publicIP)
}
ipConfig.IPPort = ips.NewDynamicIPPort(ip, stakingPort)
return ipConfig, nil
PublicIP: v.GetString(PublicIPKey),
PublicIPResolutionService: v.GetString(PublicIPResolutionServiceKey),
PublicIPResolutionFreq: v.GetDuration(PublicIPResolutionFreqKey),
ListenHost: v.GetString(StakingHostKey),
ListenPort: uint16(v.GetUint(StakingPortKey)),
}
if ipResolutionService != "" {
// User specified to use dynamic IP resolution.
resolver, err := dynamicip.NewResolver(ipResolutionService)
if err != nil {
return node.IPConfig{}, fmt.Errorf("couldn't create IP resolver: %w", err)
}

// Use that to resolve our public IP.
ctx, cancel := context.WithTimeout(context.Background(), ipResolutionTimeout)
defer cancel()
ip, err := resolver.Resolve(ctx)
if err != nil {
return node.IPConfig{}, fmt.Errorf("couldn't resolve public IP: %w", err)
}
ipConfig.IPPort = ips.NewDynamicIPPort(ip, stakingPort)
ipConfig.IPUpdater = dynamicip.NewUpdater(ipConfig.IPPort, resolver, ipResolutionFreq)
return ipConfig, nil
if ipConfig.PublicIPResolutionFreq <= 0 {
return node.IPConfig{}, fmt.Errorf("%q must be > 0", PublicIPResolutionFreqKey)
}

// User didn't specify a public IP to use, and they didn't specify a public IP resolution
// service to use. Try to resolve public IP with NAT traversal.
nat := nat.GetRouter()
ip, err := nat.ExternalIP()
if err != nil {
return node.IPConfig{}, fmt.Errorf("public IP / IP resolution service not given and failed to resolve IP with NAT: %w", err)
if ipConfig.PublicIP != "" && ipConfig.PublicIPResolutionService != "" {
return node.IPConfig{}, fmt.Errorf("only one of --%s and --%s can be given", PublicIPKey, PublicIPResolutionServiceKey)
}
ipConfig.IPPort = ips.NewDynamicIPPort(ip, stakingPort)
ipConfig.Nat = nat
ipConfig.AttemptedNATTraversal = true
return ipConfig, nil
}

Expand Down
2 changes: 2 additions & 0 deletions config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ func addNodeFlags(fs *pflag.FlagSet) {
fs.Uint(NetworkPeerListNonValidatorGossipSizeKey, constants.DefaultNetworkPeerListNonValidatorGossipSize, "Number of non-validators that the node will gossip peer list to")
fs.Uint(NetworkPeerListPeersGossipSizeKey, constants.DefaultNetworkPeerListPeersGossipSize, "Number of total peers (including non-validators and validators) that the node will gossip peer list to")
fs.Duration(NetworkPeerListGossipFreqKey, constants.DefaultNetworkPeerListGossipFreq, "Frequency to gossip peers to other nodes")
fs.Duration(NetworkPeerListPullGossipFreqKey, constants.DefaultNetworkPeerListPullGossipFreq, "Frequency to request peers from other nodes")
fs.Duration(NetworkPeerListBloomResetFreqKey, constants.DefaultNetworkPeerListBloomResetFreq, "Frequency to recalculate the bloom filter used to request new peers from other nodes")

// Public IP Resolution
fs.String(PublicIPKey, "", "Public IP of this node for P2P communication. If empty, try to discover with NAT")
Expand Down
2 changes: 2 additions & 0 deletions config/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ const (
NetworkPeerListNonValidatorGossipSizeKey = "network-peer-list-non-validator-gossip-size"
NetworkPeerListPeersGossipSizeKey = "network-peer-list-peers-gossip-size"
NetworkPeerListGossipFreqKey = "network-peer-list-gossip-frequency"
NetworkPeerListPullGossipFreqKey = "network-peer-list-pull-gossip-frequency"
NetworkPeerListBloomResetFreqKey = "network-peer-list-bloom-reset-frequency"
NetworkInitialReconnectDelayKey = "network-initial-reconnect-delay"
NetworkReadHandshakeTimeoutKey = "network-read-handshake-timeout"
NetworkPingTimeoutKey = "network-ping-timeout"
Expand Down
9 changes: 7 additions & 2 deletions genesis/bootstrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,15 @@ type Bootstrapper struct {
IP ips.IPDesc `json:"ip"`
}

// GetBootstrappers returns all default bootstrappers for the provided network.
func GetBootstrappers(networkID uint32) []Bootstrapper {
networkName := constants.NetworkIDToNetworkName[networkID]
return bootstrappersPerNetwork[networkName]
}

// SampleBootstrappers returns the some beacons this node should connect to
func SampleBootstrappers(networkID uint32, count int) []Bootstrapper {
networkName := constants.NetworkIDToNetworkName[networkID]
bootstrappers := bootstrappersPerNetwork[networkName]
bootstrappers := GetBootstrappers(networkID)
count = math.Min(count, len(bootstrappers))

s := sampler.NewUniform()
Expand Down