diff --git a/client/react-native/gomobile/core.go b/client/react-native/gomobile/core.go index 3005c78296..d173126254 100644 --- a/client/react-native/gomobile/core.go +++ b/client/react-native/gomobile/core.go @@ -17,12 +17,7 @@ func logger() *zap.Logger { return zap.L().Named("client.rn.gomobile") } -var ( - defaultBootstrap = []string{ - "/ip4/104.248.78.238/tcp/4004/ipfs/QmPCbsVWDtLTdCtwfp5ftZ96xccUNe4hegKStgbss8YACT", - } - accountName = "new-berty-user" -) +var accountName = "new-berty-user" func getRandomPort() (int, error) { listener, err := reuse.Listen("tcp", "0.0.0.0:0") @@ -104,16 +99,7 @@ func daemon(datastorePath string, loggerNative Logger) error { Path: datastorePath, Drop: false, }), - account.WithP2PNetwork( - &account.P2PNetworkOptions{ - Bind: nil, - Bootstrap: defaultBootstrap, - MDNS: false, - Relay: false, - Metrics: true, - Identity: "", - }, - ), + account.WithP2PNetwork(createNetworkConfig()), account.WithGrpcServer(&account.GrpcServerOptions{ Bind: fmt.Sprintf(":%d", grpcPort), Interceptors: false, diff --git a/client/react-native/gomobile/network.go b/client/react-native/gomobile/network.go new file mode 100644 index 0000000000..c5db8275f6 --- /dev/null +++ b/client/react-native/gomobile/network.go @@ -0,0 +1,77 @@ +package core + +import ( + "encoding/json" + + account "berty.tech/core/manager/account" +) + +type networkConfig struct { + DefaultTransport bool + BluetoothTransport bool + DefaultBootstrap bool + CustomBootstrap []string + MDNS bool + Relay bool +} + +var currentNetworkConfig = networkConfig{ + DefaultTransport: true, + BluetoothTransport: false, + DefaultBootstrap: true, + CustomBootstrap: []string{}, + MDNS: false, + Relay: false, +} + +func createNetworkConfig() *account.P2PNetworkOptions { + var transport []string + + if currentNetworkConfig.DefaultTransport { + transport = append(transport, "default") + } + if currentNetworkConfig.BluetoothTransport { + transport = append(transport, "ble") + } + + return &account.P2PNetworkOptions{ + Bind: []string{"/ip4/0.0.0.0/tcp/0", "/ble/00000000-0000-0000-0000-000000000000"}, + Transport: transport, + Bootstrap: currentNetworkConfig.CustomBootstrap, + DefaultBootstrap: currentNetworkConfig.DefaultBootstrap, + MDNS: currentNetworkConfig.MDNS, + Relay: currentNetworkConfig.Relay, + Metrics: true, + Identity: "", + } +} + +func GetNetworkConfig() (string, error) { + json, err := json.Marshal(currentNetworkConfig) + if err != nil { + return "", err + } + + return string(json), nil +} + +func UpdateNetworkConfig(jsonConf string) error { + currentAccount, _ := account.Get(accountName) + if currentAccount == nil { + return errors.New("account not running") + } + + var newNetworkConfig networkConfig + + if err := json.Unmarshal([]byte(jsonConf), &newNetworkConfig); err != nil { + return err + } + + currentNetworkConfig = newNetworkConfig + + if err := currentAccount.UpdateP2PNetwork(createNetworkConfig()); err != nil { + return err + } + + return nil +} diff --git a/core/manager/account/p2p.go b/core/manager/account/p2p.go index 2039c9ac4c..7213fafa5b 100644 --- a/core/manager/account/p2p.go +++ b/core/manager/account/p2p.go @@ -4,7 +4,9 @@ import ( "context" "encoding/base64" + "berty.tech/core/network" "berty.tech/core/network/p2p" + "github.com/jinzhu/gorm" p2pcrypto "github.com/libp2p/go-libp2p-crypto" "github.com/pkg/errors" ) @@ -20,91 +22,118 @@ type P2PNetworkOptions struct { Identity string } -func WithP2PNetwork(opts *P2PNetworkOptions) NewOption { - return func(a *Account) error { - var err error +func createP2PNetwork(opts *P2PNetworkOptions, db *gorm.DB) (network.Driver, network.Metrics, error) { + if opts == nil { + opts = &P2PNetworkOptions{} + } - if opts == nil { - opts = &P2PNetworkOptions{} - } + p2pOptions := []p2p.Option{} - p2pOptions := []p2p.Option{} + // Bind + if opts.Bind == nil { + opts.Bind = []string{"/ip4/0.0.0.0/tcp/0"} + } - // Bind - if opts.Bind == nil { - opts.Bind = []string{"/ip4/0.0.0.0/tcp/0"} - } + // Bootstrap + if opts.Bootstrap == nil { + opts.Bootstrap = []string{} + } + if opts.DefaultBootstrap { + opts.Bootstrap = append( + opts.Bootstrap, + "/ip4/104.248.78.238/tcp/4004/ipfs/QmPCbsVWDtLTdCtwfp5ftZ96xccUNe4hegKStgbss8YACT", + ) + } - // Bootstrap - if opts.Bootstrap == nil { - opts.Bootstrap = []string{} - } - if opts.DefaultBootstrap { - opts.Bootstrap = append( - opts.Bootstrap, - "/ip4/104.248.78.238/tcp/4004/ipfs/QmPCbsVWDtLTdCtwfp5ftZ96xccUNe4hegKStgbss8YACT", - ) + var identity p2p.Option + if opts.Identity == "" { + identity = p2p.WithRandomIdentity() + } else { + bytes, err := base64.StdEncoding.DecodeString(opts.Identity) + if err != nil { + return nil, nil, errors.Wrap(err, "failed to decode identity opt, should be base64 encoded") } - var identity p2p.Option - if opts.Identity == "" { - identity = p2p.WithRandomIdentity() - } else { - bytes, err := base64.StdEncoding.DecodeString(opts.Identity) - if err != nil { - return errors.Wrap(err, "failed to decode identity opt, should be base64 encoded") - } - - prvKey, err := p2pcrypto.UnmarshalPrivateKey(bytes) - if err != nil { - return errors.Wrap(err, "failed to unmarshal private key") - } - - identity = p2p.WithIdentity(prvKey) + prvKey, err := p2pcrypto.UnmarshalPrivateKey(bytes) + if err != nil { + return nil, nil, errors.Wrap(err, "failed to unmarshal private key") } - for _, v := range opts.Transport { - switch v { - case "default": - p2pOptions = append(p2pOptions, p2p.WithDefaultTransports()) - case "ble": - p2pOptions = append(p2pOptions, p2p.WithTransportBle(opts.Bind, a.db)) - } + identity = p2p.WithIdentity(prvKey) + } + + for _, v := range opts.Transport { + switch v { + case "default": + p2pOptions = append(p2pOptions, p2p.WithDefaultTransports()) + case "ble": + p2pOptions = append(p2pOptions, p2p.WithTransportBle(opts.Bind, db)) } + } - p2pOptions = append(p2pOptions, - p2p.WithDefaultMuxers(), - p2p.WithDefaultPeerstore(), - p2p.WithDefaultSecurity(), - // @TODO: Allow static identity loaded from a file (useful for relay - // server for creating static endpoint for bootstrap) - // p2p.WithIdentity(), - p2p.WithNATPortMap(), // @TODO: Is this a pb on mobile? - p2p.WithListenAddrStrings(opts.Bind...), - p2p.WithBootstrap(opts.Bootstrap...), - identity, - ) + p2pOptions = append(p2pOptions, + p2p.WithDefaultMuxers(), + p2p.WithDefaultPeerstore(), + p2p.WithDefaultSecurity(), + // @TODO: Allow static identity loaded from a file (useful for relay + // server for creating static endpoint for bootstrap) + // p2p.WithIdentity(), + p2p.WithNATPortMap(), // @TODO: Is this a pb on mobile? + p2p.WithListenAddrStrings(opts.Bind...), + p2p.WithBootstrap(opts.Bootstrap...), + identity, + ) + + if opts.MDNS { + p2pOptions = append(p2pOptions, p2p.WithMDNS()) + } - if opts.MDNS { - p2pOptions = append(p2pOptions, p2p.WithMDNS()) - } + if opts.Relay { + p2pOptions = append(p2pOptions, p2p.WithRelayHOP()) + } else { + p2pOptions = append(p2pOptions, p2p.WithRelayClient()) + } - if opts.Relay { - p2pOptions = append(p2pOptions, p2p.WithRelayHOP()) - } else { - p2pOptions = append(p2pOptions, p2p.WithRelayClient()) - } + driver, err := p2p.NewDriver(context.Background(), p2pOptions...) + if err != nil { + return nil, nil, err + } + + var metrics network.Metrics + if opts.Metrics { + metrics = p2p.NewMetrics(driver) + } + + return driver, metrics, nil +} + +func WithP2PNetwork(opts *P2PNetworkOptions) NewOption { + return func(a *Account) error { + var err error - driver, err := p2p.NewDriver(context.Background(), p2pOptions...) + a.network, a.metrics, err = createP2PNetwork(opts, a.db) if err != nil { return err } - a.network = driver - if opts.Metrics { - a.metrics = p2p.NewMetrics(driver) - } - return nil } } + +func (a *Account) UpdateP2PNetwork(opts *P2PNetworkOptions) error { + var err error + + err = a.network.Close() + if err != nil { + return err + } + + a.network, a.metrics, err = createP2PNetwork(opts, a.db) + if err != nil { + return err + } + + a.node.UseNetworkDriver(a.network) + + return nil +}