Skip to content

Commit

Permalink
Rename beacon to boostrapper, define bootstrappers in JSON file for c…
Browse files Browse the repository at this point in the history
…ross-language compatiblity (ava-labs#1439)

Co-authored-by: Stephen Buttolph <stephen@avalabs.org>
  • Loading branch information
gyuho and StephenButtolph committed May 30, 2023
1 parent 243e313 commit 6ba90f7
Show file tree
Hide file tree
Showing 11 changed files with 371 additions and 218 deletions.
42 changes: 27 additions & 15 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const (

var (
// Deprecated key --> deprecation message (i.e. which key replaces it)
// TODO: deprecate "BootstrapIDsKey" and "BootstrapIPsKey"
deprecatedKeys = map[string]string{
NetworkCompressionEnabledKey: fmt.Sprintf("use --%s instead", NetworkCompressionTypeKey),
GenesisConfigFileKey: fmt.Sprintf("use --%s instead", GenesisFileKey),
Expand Down Expand Up @@ -532,6 +533,8 @@ func getBootstrapConfig(v *viper.Viper, networkID uint32) (node.BootstrapConfig,
BootstrapAncestorsMaxContainersReceived: int(v.GetUint(BootstrapAncestorsMaxContainersReceivedKey)),
}

// TODO: Add a "BootstrappersKey" flag to more clearly enforce ID and IP
// length equality.
ipsSet := v.IsSet(BootstrapIPsKey)
idsSet := v.IsSet(BootstrapIDsKey)
if ipsSet && !idsSet {
Expand All @@ -540,40 +543,49 @@ func getBootstrapConfig(v *viper.Viper, networkID uint32) (node.BootstrapConfig,
if !ipsSet && idsSet {
return node.BootstrapConfig{}, fmt.Errorf("set %q but didn't set %q", BootstrapIDsKey, BootstrapIPsKey)
}

bootstrapIPs, bootstrapIDs := genesis.SampleBeacons(networkID, 5)
if ipsSet {
bootstrapIPs = strings.Split(v.GetString(BootstrapIPsKey), ",")
if !ipsSet && !idsSet {
config.Bootstrappers = genesis.SampleBootstrappers(networkID, 5)
return config, nil
}
for _, ip := range bootstrapIPs {

bootstrapIPs := strings.Split(v.GetString(BootstrapIPsKey), ",")
config.Bootstrappers = make([]genesis.Bootstrapper, 0, len(bootstrapIPs))
for _, bootstrapIP := range bootstrapIPs {
ip := strings.TrimSpace(bootstrapIP)
if ip == "" {
continue
}

addr, err := ips.ToIPPort(ip)
if err != nil {
return node.BootstrapConfig{}, fmt.Errorf("couldn't parse bootstrap ip %s: %w", ip, err)
}
config.BootstrapIPs = append(config.BootstrapIPs, addr)
config.Bootstrappers = append(config.Bootstrappers, genesis.Bootstrapper{
// ID is populated below
IP: ips.IPDesc(addr),
})
}

if idsSet {
bootstrapIDs = strings.Split(v.GetString(BootstrapIDsKey), ",")
}
for _, id := range bootstrapIDs {
bootstrapIDs := strings.Split(v.GetString(BootstrapIDsKey), ",")
bootstrapNodeIDs := make([]ids.NodeID, 0, len(bootstrapIDs))
for _, bootstrapID := range bootstrapIDs {
id := strings.TrimSpace(bootstrapID)
if id == "" {
continue
}

nodeID, err := ids.NodeIDFromString(id)
if err != nil {
return node.BootstrapConfig{}, fmt.Errorf("couldn't parse bootstrap peer id %s: %w", id, err)
}
config.BootstrapIDs = append(config.BootstrapIDs, nodeID)
bootstrapNodeIDs = append(bootstrapNodeIDs, nodeID)
}

lenIPs := len(config.BootstrapIPs)
lenIDs := len(config.BootstrapIDs)
if lenIPs != lenIDs {
return node.BootstrapConfig{}, fmt.Errorf("expected the number of bootstrapIPs (%d) to match the number of bootstrapIDs (%d)", lenIPs, lenIDs)
if len(config.Bootstrappers) != len(bootstrapNodeIDs) {
return node.BootstrapConfig{}, fmt.Errorf("expected the number of bootstrapIPs (%d) to match the number of bootstrapIDs (%d)", len(config.Bootstrappers), len(bootstrapNodeIDs))
}
for i, nodeID := range bootstrapNodeIDs {
config.Bootstrappers[i].ID = nodeID
}

return config, nil
Expand Down
1 change: 1 addition & 0 deletions config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ func addNodeFlags(fs *pflag.FlagSet) {
fs.String(StateSyncIDsKey, "", "Comma separated list of state sync peer ids to connect to. Example: NodeID-JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,NodeID-8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")

// Bootstrapping
// TODO: combine "BootstrapIPsKey" and "BootstrapIDsKey" into one flag
fs.String(BootstrapIPsKey, "", "Comma separated list of bootstrap peer ips to connect to. Example: 127.0.0.1:9630,127.0.0.1:9631")
fs.String(BootstrapIDsKey, "", "Comma separated list of bootstrap peer ids to connect to. Example: NodeID-JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,NodeID-8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")
fs.Bool(RetryBootstrapKey, true, "Specifies whether bootstrap should be retried")
Expand Down
150 changes: 0 additions & 150 deletions genesis/beacons.go

This file was deleted.

54 changes: 54 additions & 0 deletions genesis/bootstrappers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package genesis

import (
"encoding/json"
"fmt"

_ "embed"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/ips"
"github.com/ava-labs/avalanchego/utils/math"
"github.com/ava-labs/avalanchego/utils/sampler"
)

var (
//go:embed bootstrappers.json
bootstrappersPerNetworkJSON []byte

bootstrappersPerNetwork map[string][]Bootstrapper
)

func init() {
if err := json.Unmarshal(bootstrappersPerNetworkJSON, &bootstrappersPerNetwork); err != nil {
panic(fmt.Sprintf("failed to decode bootstrappers.json %v", err))
}
}

// Represents the relationship between the nodeID and the nodeIP.
// The bootstrapper is sometimes called "anchor" or "beacon" node.
type Bootstrapper struct {
ID ids.NodeID `json:"id"`
IP ips.IPDesc `json:"ip"`
}

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

s := sampler.NewUniform()
s.Initialize(uint64(len(bootstrappers)))
indices, _ := s.Sample(count)

sampled := make([]Bootstrapper, 0, len(indices))
for _, index := range indices {
sampled = append(sampled, bootstrappers[int(index)])
}
return sampled
}

0 comments on commit 6ba90f7

Please sign in to comment.