refactor: move --generate-key to a generate-key subcommand

This commit is contained in:
Richard Ramos 2023-08-09 14:14:54 -04:00 committed by richΛrd
parent 164c92554b
commit b88907c5ee
9 changed files with 137 additions and 76 deletions

View File

@ -115,16 +115,6 @@ var (
Destination: &options.KeyPasswd,
EnvVars: []string{"WAKUNODE2_KEY_PASSWORD"},
})
GenerateKey = altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "generate-key",
Usage: "Generate private key file at path specified in --key-file with the password defined by --key-password",
Destination: &options.GenerateKey,
})
Overwrite = altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "overwrite",
Usage: "When generating a keyfile, overwrite the nodekey file if it already exists",
Destination: &options.Overwrite,
})
StaticNode = cliutils.NewGenericFlagMultiValue(&cli.GenericFlag{
Name: "staticnode",
Usage: "Multiaddr of peer to directly connect with. Option may be repeated",

View File

@ -0,0 +1,80 @@
package keygen
import (
"encoding/json"
"fmt"
"os"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/crypto"
"github.com/urfave/cli/v2"
"github.com/waku-org/go-waku/waku/v2/utils"
"go.uber.org/zap"
)
// Command generates a key file used to generate the node's peerID, encrypted with an optional password
var Command = cli.Command{
Name: "generate-key",
Usage: "Generate private key file at path specified in --key-file with the password defined by --key-password",
Action: func(cCtx *cli.Context) error {
if err := generateKeyFile(Options.KeyFile, []byte(Options.KeyPasswd), Options.Overwrite); err != nil {
utils.Logger().Fatal("could not write keyfile", zap.Error(err))
}
return nil
},
Flags: []cli.Flag{
KeyFile,
KeyPassword,
Overwrite,
},
}
func checkForFileExistence(path string, overwrite bool) error {
_, err := os.Stat(path)
if err == nil && !overwrite {
return fmt.Errorf("%s already exists. Use --overwrite to overwrite the file", path)
}
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
return err
}
return nil
}
func generatePrivateKey() ([]byte, error) {
key, err := crypto.GenerateKey()
if err != nil {
return nil, err
}
return key.D.Bytes(), nil
}
func writeKeyFile(path string, key []byte, passwd []byte) error {
encryptedK, err := keystore.EncryptDataV3(key, passwd, keystore.StandardScryptN, keystore.StandardScryptP)
if err != nil {
return err
}
output, err := json.Marshal(encryptedK)
if err != nil {
return err
}
return os.WriteFile(path, output, 0600)
}
func generateKeyFile(path string, passwd []byte, overwrite bool) error {
if err := checkForFileExistence(path, overwrite); err != nil {
return err
}
key, err := generatePrivateKey()
if err != nil {
return err
}
return writeKeyFile(path, key, passwd)
}

35
cmd/waku/keygen/flags.go Normal file
View File

@ -0,0 +1,35 @@
package keygen
import (
cli "github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc"
)
// Options contain the settings used for generating a key file
var Options GenerateKeyOptions
var (
// KeyFile is a flag that contains the path where the node key will be written
KeyFile = altsrc.NewPathFlag(&cli.PathFlag{
Name: "key-file",
Value: "./nodekey",
Usage: "Path to a file containing the private key for the P2P node",
Destination: &Options.KeyFile,
EnvVars: []string{"WAKUNODE2_KEY_FILE"},
})
// KeyPassword is a flag to set the password used to encrypt the file
KeyPassword = altsrc.NewStringFlag(&cli.StringFlag{
Name: "key-password",
Value: "secret",
Usage: "Password used for the private key file",
Destination: &Options.KeyPasswd,
EnvVars: []string{"WAKUNODE2_KEY_PASSWORD"},
})
// Overwrite is a flag used to overwrite an existing key file
Overwrite = altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "overwrite",
Value: false,
Usage: "Overwrite the nodekey file if it already exists",
Destination: &Options.Overwrite,
})
)

View File

@ -0,0 +1,9 @@
package keygen
// GenerateKeyOptions contains all the settings that can be used when generating
// a keyfile with the generate-key command
type GenerateKeyOptions struct {
KeyFile string
KeyPasswd string
Overwrite bool
}

View File

@ -5,10 +5,11 @@ import (
cli "github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc"
"github.com/waku-org/go-waku/cmd/waku/keygen"
"github.com/waku-org/go-waku/waku/v2/node"
)
var options Options
var options NodeOptions
func main() {
// Defaults
@ -31,8 +32,6 @@ func main() {
NodeKey,
KeyFile,
KeyPassword,
GenerateKey,
Overwrite,
StaticNode,
KeepAlive,
PersistPeers,
@ -111,6 +110,9 @@ func main() {
Execute(options)
return nil
},
Commands: []*cli.Command{
&keygen.Command,
},
}
err := app.Run(os.Args)

View File

@ -63,7 +63,7 @@ func failOnErr(err error, msg string) {
}
}
func requiresDB(options Options) bool {
func requiresDB(options NodeOptions) bool {
return options.Store.Enable || options.Rendezvous.Enable
}
@ -82,14 +82,7 @@ func scalePerc(value float64) float64 {
const dialTimeout = 7 * time.Second
// Execute starts a go-waku node with settings determined by the Options parameter
func Execute(options Options) {
if options.GenerateKey {
if err := writePrivateKeyToFile(options.KeyFile, []byte(options.KeyPasswd), options.Overwrite); err != nil {
failOnErr(err, "nodekey error")
}
return
}
func Execute(options NodeOptions) {
hostAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", options.Address, options.Port))
failOnErr(err, "invalid host address")
@ -527,53 +520,7 @@ func loadPrivateKeyFromFile(path string, passwd string) (*ecdsa.PrivateKey, erro
return crypto.ToECDSA(pKey)
}
func checkForFileExistence(path string, overwrite bool) error {
_, err := os.Stat(path)
if err == nil && !overwrite {
return fmt.Errorf("%s already exists. Use --overwrite to overwrite the file", path)
}
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
return err
}
return nil
}
func generatePrivateKey() ([]byte, error) {
key, err := crypto.GenerateKey()
if err != nil {
return nil, err
}
return key.D.Bytes(), nil
}
func writePrivateKeyToFile(path string, passwd []byte, overwrite bool) error {
if err := checkForFileExistence(path, overwrite); err != nil {
return err
}
key, err := generatePrivateKey()
if err != nil {
return err
}
encryptedK, err := keystore.EncryptDataV3(key, passwd, keystore.StandardScryptN, keystore.StandardScryptP)
if err != nil {
return err
}
output, err := json.Marshal(encryptedK)
if err != nil {
return err
}
return os.WriteFile(path, output, 0600)
}
func getPrivKey(options Options) (*ecdsa.PrivateKey, error) {
func getPrivKey(options NodeOptions) (*ecdsa.PrivateKey, error) {
var prvKey *ecdsa.PrivateKey
// get private key from nodeKey or keyFile
if options.NodeKey != nil {
@ -596,7 +543,7 @@ func getPrivKey(options Options) (*ecdsa.PrivateKey, error) {
return prvKey, nil
}
func printListeningAddresses(ctx context.Context, nodeOpts []node.WakuNodeOption, options Options) {
func printListeningAddresses(ctx context.Context, nodeOpts []node.WakuNodeOption, options NodeOptions) {
params := new(node.WakuNodeParameters)
for _, opt := range nodeOpts {
err := opt(params)

View File

@ -8,6 +8,6 @@ import (
"go.uber.org/zap"
)
func checkForRLN(logger *zap.Logger, options Options, nodeOpts *[]node.WakuNodeOption) {
func checkForRLN(logger *zap.Logger, options NodeOptions, nodeOpts *[]node.WakuNodeOption) {
// Do nothing
}

View File

@ -12,7 +12,7 @@ import (
"go.uber.org/zap"
)
func checkForRLN(logger *zap.Logger, options Options, nodeOpts *[]node.WakuNodeOption) {
func checkForRLN(logger *zap.Logger, options NodeOptions, nodeOpts *[]node.WakuNodeOption) {
if options.RLNRelay.Enable {
if !options.Relay.Enable {
failOnErr(errors.New("relay not available"), "Could not enable RLN Relay")

View File

@ -142,17 +142,15 @@ type RendezvousOptions struct {
Nodes []multiaddr.Multiaddr
}
// Options contains all the available features and settings that can be
// NodeOptions contains all the available features and settings that can be
// configured via flags when executing go-waku as a service.
type Options struct {
type NodeOptions struct {
Port int
Address string
DNS4DomainName string
NodeKey *ecdsa.PrivateKey
KeyFile string
KeyPasswd string
GenerateKey bool
Overwrite bool
StaticNodes []multiaddr.Multiaddr
KeepAlive time.Duration
AdvertiseAddresses []multiaddr.Multiaddr