From 0f6c783f4515f05e0967add16f31cdc8e268e4bb Mon Sep 17 00:00:00 2001 From: Godefroy Ponsinet Date: Mon, 11 Mar 2019 13:02:23 +0100 Subject: [PATCH] chore(network): permit to update network dynamically Signed-off-by: Godefroy Ponsinet --- core/cmd/berty/daemon.go | 3 +++ core/go.mod | 2 ++ core/network/config/config.go | 41 +++++++++++++++++++++++++++------- core/network/config/persist.go | 39 ++++++++++++++++++++++++++++++++ core/network/network.go | 23 +++++++++++++++---- core/network/options.go | 39 ++++++++++++++++++++------------ 6 files changed, 121 insertions(+), 26 deletions(-) create mode 100644 core/network/config/persist.go diff --git a/core/cmd/berty/daemon.go b/core/cmd/berty/daemon.go index 599cd68bd4..116ca3fa5b 100644 --- a/core/cmd/berty/daemon.go +++ b/core/cmd/berty/daemon.go @@ -152,6 +152,7 @@ func daemon(opts *daemonOptions) error { Bind: opts.bindP2P, MDNS: opts.mdns, DHT: opts.dhtServer, + WS: true, TCP: true, BLE: opts.ble, QUIC: true, @@ -162,6 +163,8 @@ func daemon(opts *daemonOptions) error { HOP: opts.hop, SwarmKey: swarmKey, Identity: opts.identity, + Persist: false, + OverridePersist: false, }), ), )) diff --git a/core/go.mod b/core/go.mod index 37093200b2..715314b5ce 100644 --- a/core/go.mod +++ b/core/go.mod @@ -62,6 +62,8 @@ require ( github.com/libp2p/go-reuseport v0.0.1 github.com/libp2p/go-reuseport-transport v0.0.1 github.com/libp2p/go-stream-muxer v0.0.1 + github.com/libp2p/go-tcp-transport v0.0.1 + github.com/libp2p/go-ws-transport v0.0.1 github.com/maruel/circular v0.0.0-20161028021427-97eeabbe7b43 github.com/maruel/ut v1.0.0 // indirect github.com/multiformats/go-multiaddr v0.0.1 diff --git a/core/network/config/config.go b/core/network/config/config.go index 5bca216a58..14777a6c38 100644 --- a/core/network/config/config.go +++ b/core/network/config/config.go @@ -56,7 +56,7 @@ var BootstrapIpfs = []string{ } type Config struct { - libp2p_config.Config + libp2p_config.Config `json:"-"` Bind []string @@ -82,36 +82,61 @@ type Config struct { Identity string - routing *host.BertyRouting // needed to get it from berty host + Persist bool `json:"-"` + OverridePersist bool `json:"-"` // override persist config when apply } type Option func(cfg *Config) error +// Override override safely the current config +func (cfg *Config) Override(override *Config) error { + cfg.MDNS = override.MDNS + cfg.WS = override.WS + cfg.TCP = override.TCP + cfg.DHT = override.DHT + cfg.BLE = override.BLE + cfg.QUIC = override.QUIC + cfg.DefaultBootstrap = override.DefaultBootstrap + cfg.Bootstrap = override.Bootstrap + cfg.Ping = override.Ping + cfg.HOP = override.HOP + cfg.Identity = override.Identity + cfg.SwarmKey = override.SwarmKey + return nil +} + // Apply applies the given options to the config, returning the first error // encountered (if any). func (cfg *Config) Apply(ctx context.Context, opts ...Option) error { + libp2pOpts := []libp2p_config.Option{} + for _, opt := range opts { if err := opt(cfg); err != nil { return err } } - libp2pOpts := []libp2p_config.Option{} + if cfg.OverridePersist { + if err := cfg.OverridePersistConfig(); err != nil { + return err + } + } + + if cfg.Persist { + if err := cfg.ApplyPersistConfig(); err != nil { + return err + } + } - logger().Debug(fmt.Sprintf("bootstrap: %+v", cfg.Bootstrap)) if cfg.DefaultBootstrap { cfg.Bootstrap = append(cfg.Bootstrap, DefaultBootstrap...) } - logger().Debug(fmt.Sprintf("bootstrap: %+v", cfg.Bootstrap)) libp2pOpts = append(libp2pOpts, libp2p.DefaultListenAddrs) if len(cfg.Bind) > 0 { libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings(cfg.Bind...)) } - // transport - libp2pOpts = append(libp2pOpts, libp2p.DefaultTransports) - // add ws transport if cfg.WS { libp2pOpts = append(libp2pOpts, libp2p.Transport(ws.New)) diff --git a/core/network/config/persist.go b/core/network/config/persist.go new file mode 100644 index 0000000000..e8428e34dd --- /dev/null +++ b/core/network/config/persist.go @@ -0,0 +1,39 @@ +package config + +import ( + "encoding/json" + "io/ioutil" + "os" + + "berty.tech/core/pkg/deviceinfo" +) + +func getPersistFilePath() string { + return deviceinfo.GetStoragePath() + "/" + "network-config.json" +} + +func (cfg *Config) ApplyPersistConfig() error { + data, err := ioutil.ReadFile(getPersistFilePath()) + if err != nil { + return err + } + if len(data) == 0 { + return nil + } + override := &Config{} + if err := json.Unmarshal(data, override); err != nil { + return err + } + return cfg.Override(override) +} + +func (cfg *Config) OverridePersistConfig() error { + data, err := json.Marshal(cfg) + if err != nil { + return err + } + if err := ioutil.WriteFile(getPersistFilePath(), data, os.ModePerm); err != nil { + return err + } + return nil +} diff --git a/core/network/network.go b/core/network/network.go index d9b0ae52a0..ee98d3530b 100644 --- a/core/network/network.go +++ b/core/network/network.go @@ -8,10 +8,13 @@ import ( "berty.tech/core/network/config" host "berty.tech/core/network/host" "berty.tech/core/pkg/tracing" + "github.com/pkg/errors" "go.uber.org/zap" ) type Network struct { + config *config.Config + host *host.BertyHost handler func(context.Context, *entity.Envelope) (*entity.Void, error) @@ -38,18 +41,18 @@ func New(ctx context.Context, opts ...config.Option) (*Network, error) { ctx, cancel := context.WithCancel(ctx) var err error - var cfg config.Config net := &Network{ + config: &config.Config{}, shutdown: cancel, } - if err := cfg.Apply(ctx, opts...); err != nil { + if err := net.config.Apply(ctx, opts...); err != nil { cancel() return nil, err } - net.host, err = cfg.NewNode(ctx) + net.host, err = net.config.NewNode(ctx) if err != nil { cancel() return nil, err @@ -64,7 +67,7 @@ func New(ctx context.Context, opts ...config.Option) (*Network, error) { // bootstrap default peers // TOOD: infinite bootstrap + don't permit routing to provide when no peers are discovered for { - if err := net.Bootstrap(ctx, true, cfg.Bootstrap...); err != nil { + if err := net.Bootstrap(ctx, true, net.config.Bootstrap...); err != nil { logger().Error(err.Error()) time.Sleep(time.Second) continue @@ -94,3 +97,15 @@ func (net *Network) Close(ctx context.Context) error { return nil } + +// Update create new network and permit to override previous config +func (net *Network) Update(ctx context.Context, opts ...config.Option) error { + updated, err := New(ctx, append([]config.Option{WithConfig(net.config)}, opts...)...) + if err != nil { + return errors.Wrap(err, "cannot update network: abort") + } + swap := *net + *net = *updated + (&swap).Close(ctx) + return nil +} diff --git a/core/network/options.go b/core/network/options.go index 8a591b4d1c..53ed5ac06c 100644 --- a/core/network/options.go +++ b/core/network/options.go @@ -11,19 +11,7 @@ import ( // WithConfig func WithConfig(override *config.Config) config.Option { return func(cfg *config.Config) error { - cfg.MDNS = override.MDNS - cfg.WS = override.WS - cfg.TCP = override.TCP - cfg.DHT = override.DHT - cfg.BLE = override.BLE - cfg.QUIC = override.QUIC - cfg.DefaultBootstrap = override.DefaultBootstrap - cfg.Bootstrap = override.Bootstrap - cfg.Ping = override.Ping - cfg.HOP = override.HOP - cfg.Identity = override.Identity - cfg.SwarmKey = override.SwarmKey - return nil + return cfg.Override(override) } } @@ -40,6 +28,7 @@ func WithDefaultOptions() config.Option { DisableDHT(), EnableMetric(), DisableHOP(), + DisablePersistConfig(), ) } @@ -48,7 +37,7 @@ func WithDefaultMobileOptions() config.Option { WithDefaultOptions(), DisableDHT(), DisableHOP(), - // ... + EnablePersistConfig(), ) } @@ -63,6 +52,28 @@ func WithDefaultRelayOptions() config.Option { // Custom options +func EnablePersistConfig() config.Option { + return func(cfg *config.Config) error { + cfg.Persist = true + return nil + } +} + +func OverridePersistConfig() config.Option { + return func(cfg *config.Config) error { + cfg.OverridePersist = true + return nil + } +} + +func DisablePersistConfig() config.Option { + return func(cfg *config.Config) error { + cfg.Persist = false + cfg.OverridePersist = false + return nil + } +} + func WithIdentity(identity string) config.Option { return func(cfg *config.Config) error { cfg.Identity = identity