From d2bf1bc7b646b85b3480cb0e0828b6e979093a23 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 2 Dec 2019 12:52:24 +0100 Subject: [PATCH] config: Add PeerAddresses This adds a PeerAddresses entry to the main cluster configuration. The peer will ingest and potentially connect to those peer addresses during the start (similarly to the ones in the peerstore). This allows to provide "bootstrap" (as in "peers we connect to") addresses directly in the configuration, which is useful when distributing a single configuration template that will allow a cluster peer to know where to connect on the first boot. --- cluster.go | 3 ++- cluster_config.go | 22 +++++++++++++++++++++- cluster_config_test.go | 10 +++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/cluster.go b/cluster.go index ed06058b..6f6f7325 100644 --- a/cluster.go +++ b/cluster.go @@ -165,9 +165,10 @@ func NewCluster( readyB: false, } - // Import known cluster peers from peerstore file. Set + // Import known cluster peers from peerstore file and config. Set // a non permanent TTL. c.peerManager.ImportPeersFromPeerstore(false, peerstore.AddressTTL) + c.peerManager.ImportPeers(c.config.PeerAddresses, false, peerstore.AddressTTL) // Attempt to connect to some peers (up to bootstrapCount) connectedPeers := c.peerManager.Bootstrap(bootstrapCount) // We cannot warn when count is low as this as this is normal if going diff --git a/cluster_config.go b/cluster_config.go index bdb39b4f..53b63b34 100644 --- a/cluster_config.go +++ b/cluster_config.go @@ -155,6 +155,11 @@ type Config struct { // libp2p host peerstore addresses. This file is regularly saved. PeerstoreFile string + // PeerAddresses stores additional addresses for peers that may or may + // not be in the peerstore file. These are considered high priority + // when bootstrapping the initial cluster connections. + PeerAddresses []ma.Multiaddr + // Tracing flag used to skip tracing specific paths when not enabled. Tracing bool } @@ -182,6 +187,7 @@ type configJSON struct { DisableRepinning bool `json:"disable_repinning"` FollowerMode bool `json:"follower_mode,omitempty"` PeerstoreFile string `json:"peerstore_file,omitempty"` + PeerAddresses []string `json:"peer_addresses"` } // connMgrConfigJSON configures the libp2p host connection manager. @@ -369,8 +375,9 @@ func (cfg *Config) setDefaults() { cfg.PeerWatchInterval = DefaultPeerWatchInterval cfg.MDNSInterval = DefaultMDNSInterval cfg.DisableRepinning = DefaultDisableRepinning - cfg.PeerstoreFile = "" // empty so it gets ommited. cfg.FollowerMode = DefaultFollowerMode + cfg.PeerstoreFile = "" // empty so it gets ommited. + cfg.PeerAddresses = []ma.Multiaddr{} cfg.RPCPolicy = DefaultRPCPolicy } @@ -444,6 +451,16 @@ func (cfg *Config) applyConfigJSON(jcfg *configJSON) error { return err } + // PeerAddresses + for _, addr := range jcfg.PeerAddresses { + peerAddr, err := ma.NewMultiaddr(addr) + if err != nil { + err = fmt.Errorf("error parsing peer_addresses: %s", err) + return err + } + cfg.PeerAddresses = append(cfg.PeerAddresses, peerAddr) + } + cfg.LeaveOnShutdown = jcfg.LeaveOnShutdown cfg.DisableRepinning = jcfg.DisableRepinning cfg.FollowerMode = jcfg.FollowerMode @@ -497,6 +514,9 @@ func (cfg *Config) toConfigJSON() (jcfg *configJSON, err error) { jcfg.MDNSInterval = cfg.MDNSInterval.String() jcfg.DisableRepinning = cfg.DisableRepinning jcfg.PeerstoreFile = cfg.PeerstoreFile + for _, addr := range cfg.PeerAddresses { + jcfg.PeerAddresses = append(jcfg.PeerAddresses, addr.String()) + } jcfg.FollowerMode = cfg.FollowerMode return diff --git a/cluster_config_test.go b/cluster_config_test.go index 3ca3e120..e30798f9 100644 --- a/cluster_config_test.go +++ b/cluster_config_test.go @@ -29,7 +29,8 @@ var ccfgTestJSON = []byte(` "replication_factor_min": 5, "replication_factor_max": 5, "monitor_ping_interval": "2s", - "disable_repinning": true + "disable_repinning": true, + "peer_addresses": [ "/ip4/127.0.0.1/tcp/1234/p2p/QmXZrtE5jQwXNqCJMfHUTQkvhQ4ZAnqMnmzFMJfLewuabc" ] } `) @@ -92,6 +93,13 @@ func TestLoadJSON(t *testing.T) { } }) + t.Run("expected peer addresses", func(t *testing.T) { + cfg := loadJSON(t) + if len(cfg.PeerAddresses) != 1 { + t.Error("expected 1 peer address") + } + }) + loadJSON2 := func(t *testing.T, f func(j *configJSON)) (*Config, error) { cfg := &Config{} j := &configJSON{}