Commit 9287808c authored by Ralph Pichler's avatar Ralph Pichler Committed by GitHub

add init command (#944)

parent 6888fcc2
...@@ -96,6 +96,10 @@ func newCommand(opts ...option) (c *command, err error) { ...@@ -96,6 +96,10 @@ func newCommand(opts ...option) (c *command, err error) {
return nil, err return nil, err
} }
if err := c.initInitCmd(); err != nil {
return nil, err
}
c.initVersionCmd() c.initVersionCmd()
if err := c.initConfigurateOptionsCmd(); err != nil { if err := c.initConfigurateOptionsCmd(); err != nil {
......
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cmd
import (
"fmt"
"io/ioutil"
"strings"
"github.com/ethersphere/bee/pkg/logging"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
func (c *command) initInitCmd() (err error) {
cmd := &cobra.Command{
Use: "init",
Short: "Initialise a Swarm node",
RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) > 0 {
return cmd.Help()
}
var logger logging.Logger
switch v := strings.ToLower(c.config.GetString(optionNameVerbosity)); v {
case "0", "silent":
logger = logging.New(ioutil.Discard, 0)
case "1", "error":
logger = logging.New(cmd.OutOrStdout(), logrus.ErrorLevel)
case "2", "warn":
logger = logging.New(cmd.OutOrStdout(), logrus.WarnLevel)
case "3", "info":
logger = logging.New(cmd.OutOrStdout(), logrus.InfoLevel)
case "4", "debug":
logger = logging.New(cmd.OutOrStdout(), logrus.DebugLevel)
case "5", "trace":
logger = logging.New(cmd.OutOrStdout(), logrus.TraceLevel)
default:
return fmt.Errorf("unknown verbosity level %q", v)
}
_, err = c.configureSigner(cmd, logger)
return err
},
PreRunE: func(cmd *cobra.Command, args []string) error {
return c.config.BindPFlags(cmd.Flags())
},
}
c.setAllFlags(cmd)
c.root.AddCommand(cmd)
return nil
}
...@@ -94,106 +94,15 @@ Welcome to the Swarm.... Bzzz Bzzzz Bzzzz ...@@ -94,106 +94,15 @@ Welcome to the Swarm.... Bzzz Bzzzz Bzzzz
debugAPIAddr = "" debugAPIAddr = ""
} }
var keystore keystore.Service signerConfig, err := c.configureSigner(cmd, logger)
if c.config.GetString(optionNameDataDir) == "" { if err != nil {
keystore = memkeystore.New() return err
logger.Warning("data directory not provided, keys are not persisted")
} else {
keystore = filekeystore.New(filepath.Join(c.config.GetString(optionNameDataDir), "keys"))
}
var password string
if p := c.config.GetString(optionNamePassword); p != "" {
password = p
} else if pf := c.config.GetString(optionNamePasswordFile); pf != "" {
b, err := ioutil.ReadFile(pf)
if err != nil {
return err
}
password = string(bytes.Trim(b, "\n"))
} else {
exists, err := keystore.Exists("swarm")
if err != nil {
return err
}
if exists {
password, err = terminalPromptPassword(cmd, c.passwordReader, "Password")
if err != nil {
return err
}
} else {
password, err = terminalPromptCreatePassword(cmd, c.passwordReader)
if err != nil {
return err
}
}
}
var signer crypto.Signer
var address swarm.Address
var publicKey *ecdsa.PublicKey
if c.config.GetBool(optionNameClefSignerEnable) {
endpoint := c.config.GetString(optionNameClefSignerEndpoint)
if endpoint == "" {
endpoint, err = clef.DefaultIpcPath()
if err != nil {
return err
}
}
externalSigner, err := external.NewExternalSigner(endpoint)
if err != nil {
return err
}
clefRPC, err := rpc.Dial(endpoint)
if err != nil {
return err
}
signer, err = clef.NewSigner(externalSigner, clefRPC, crypto.Recover)
if err != nil {
return err
}
publicKey, err = signer.PublicKey()
if err != nil {
return err
}
address, err = crypto.NewOverlayAddress(*publicKey, c.config.GetUint64(optionNameNetworkID))
if err != nil {
return err
}
logger.Infof("using swarm network address through clef: %s", address)
} else {
swarmPrivateKey, created, err := keystore.Key("swarm", password)
if err != nil {
return fmt.Errorf("swarm key: %w", err)
}
signer = crypto.NewDefaultSigner(swarmPrivateKey)
publicKey = &swarmPrivateKey.PublicKey
address, err = crypto.NewOverlayAddress(*publicKey, c.config.GetUint64(optionNameNetworkID))
if err != nil {
return err
}
if created {
logger.Infof("new swarm network address created: %s", address)
} else {
logger.Infof("using existing swarm network address: %s", address)
}
} }
logger.Infof("swarm public key %x", crypto.EncodeSecp256k1PublicKey(publicKey)) b, err := node.NewBee(c.config.GetString(optionNameP2PAddr), signerConfig.address, *signerConfig.publicKey, signerConfig.keystore, signerConfig.signer, c.config.GetUint64(optionNameNetworkID), logger, signerConfig.libp2pPrivateKey, node.Options{
b, err := node.NewBee(c.config.GetString(optionNameP2PAddr), address, *publicKey, keystore, signer, c.config.GetUint64(optionNameNetworkID), logger, node.Options{
DataDir: c.config.GetString(optionNameDataDir), DataDir: c.config.GetString(optionNameDataDir),
DBCapacity: c.config.GetUint64(optionNameDBCapacity), DBCapacity: c.config.GetUint64(optionNameDBCapacity),
Password: password, Password: signerConfig.password,
APIAddr: c.config.GetString(optionNameAPIAddr), APIAddr: c.config.GetString(optionNameAPIAddr),
DebugAPIAddr: debugAPIAddr, DebugAPIAddr: debugAPIAddr,
Addr: c.config.GetString(optionNameP2PAddr), Addr: c.config.GetString(optionNameP2PAddr),
...@@ -266,3 +175,128 @@ Welcome to the Swarm.... Bzzz Bzzzz Bzzzz ...@@ -266,3 +175,128 @@ Welcome to the Swarm.... Bzzz Bzzzz Bzzzz
c.root.AddCommand(cmd) c.root.AddCommand(cmd)
return nil return nil
} }
type signerConfig struct {
keystore keystore.Service
signer crypto.Signer
address swarm.Address
publicKey *ecdsa.PublicKey
libp2pPrivateKey *ecdsa.PrivateKey
password string
}
func (c *command) configureSigner(cmd *cobra.Command, logger logging.Logger) (config *signerConfig, err error) {
var keystore keystore.Service
if c.config.GetString(optionNameDataDir) == "" {
keystore = memkeystore.New()
logger.Warning("data directory not provided, keys are not persisted")
} else {
keystore = filekeystore.New(filepath.Join(c.config.GetString(optionNameDataDir), "keys"))
}
var signer crypto.Signer
var address swarm.Address
var password string
var publicKey *ecdsa.PublicKey
if p := c.config.GetString(optionNamePassword); p != "" {
password = p
} else if pf := c.config.GetString(optionNamePasswordFile); pf != "" {
b, err := ioutil.ReadFile(pf)
if err != nil {
return nil, err
}
password = string(bytes.Trim(b, "\n"))
} else {
exists, err := keystore.Exists("swarm")
if err != nil {
return nil, err
}
if exists {
password, err = terminalPromptPassword(cmd, c.passwordReader, "Password")
if err != nil {
return nil, err
}
} else {
password, err = terminalPromptCreatePassword(cmd, c.passwordReader)
if err != nil {
return nil, err
}
}
}
if c.config.GetBool(optionNameClefSignerEnable) {
endpoint := c.config.GetString(optionNameClefSignerEndpoint)
if endpoint == "" {
endpoint, err = clef.DefaultIpcPath()
if err != nil {
return nil, err
}
}
externalSigner, err := external.NewExternalSigner(endpoint)
if err != nil {
return nil, err
}
clefRPC, err := rpc.Dial(endpoint)
if err != nil {
return nil, err
}
signer, err = clef.NewSigner(externalSigner, clefRPC, crypto.Recover)
if err != nil {
return nil, err
}
publicKey, err = signer.PublicKey()
if err != nil {
return nil, err
}
address, err = crypto.NewOverlayAddress(*publicKey, c.config.GetUint64(optionNameNetworkID))
if err != nil {
return nil, err
}
logger.Infof("using swarm network address through clef: %s", address)
} else {
swarmPrivateKey, created, err := keystore.Key("swarm", password)
if err != nil {
return nil, fmt.Errorf("swarm key: %w", err)
}
signer = crypto.NewDefaultSigner(swarmPrivateKey)
publicKey = &swarmPrivateKey.PublicKey
address, err = crypto.NewOverlayAddress(*publicKey, c.config.GetUint64(optionNameNetworkID))
if err != nil {
return nil, err
}
if created {
logger.Infof("new swarm network address created: %s", address)
} else {
logger.Infof("using existing swarm network address: %s", address)
}
}
logger.Infof("swarm public key %x", crypto.EncodeSecp256k1PublicKey(publicKey))
libp2pPrivateKey, created, err := keystore.Key("libp2p", password)
if err != nil {
return nil, fmt.Errorf("libp2p key: %w", err)
}
if created {
logger.Debugf("new libp2p key created")
} else {
logger.Debugf("using existing libp2p key")
}
return &signerConfig{
keystore: keystore,
signer: signer,
address: address,
publicKey: publicKey,
libp2pPrivateKey: libp2pPrivateKey,
password: password,
}, nil
}
...@@ -111,7 +111,7 @@ type Options struct { ...@@ -111,7 +111,7 @@ type Options struct {
SwapEnable bool SwapEnable bool
} }
func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey, keystore keystore.Service, signer crypto.Signer, networkID uint64, logger logging.Logger, o Options) (*Bee, error) { func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey, keystore keystore.Service, signer crypto.Signer, networkID uint64, logger logging.Logger, libp2pPrivateKey *ecdsa.PrivateKey, o Options) (*Bee, error) {
tracer, tracerCloser, err := tracing.NewTracer(&tracing.Options{ tracer, tracerCloser, err := tracing.NewTracer(&tracing.Options{
Enabled: o.TracingEnabled, Enabled: o.TracingEnabled,
Endpoint: o.TracingEndpoint, Endpoint: o.TracingEndpoint,
...@@ -129,17 +129,6 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey, ...@@ -129,17 +129,6 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey,
tracerCloser: tracerCloser, tracerCloser: tracerCloser,
} }
// Construct P2P service.
libp2pPrivateKey, created, err := keystore.Key("libp2p", o.Password)
if err != nil {
return nil, fmt.Errorf("libp2p key: %w", err)
}
if created {
logger.Debugf("new libp2p key created")
} else {
logger.Debugf("using existing libp2p key")
}
var stateStore storage.StateStorer var stateStore storage.StateStorer
if o.DataDir == "" { if o.DataDir == "" {
stateStore = mockinmem.NewStateStore() stateStore = mockinmem.NewStateStore()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment