Skip to content

Commit

Permalink
fix(cmd/celestia): Only provide necessary flags to aux subcmds
Browse files Browse the repository at this point in the history
  • Loading branch information
renaynay committed Feb 19, 2025
1 parent 5dbc2b7 commit 8584152
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 98 deletions.
2 changes: 1 addition & 1 deletion cmd/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func AuthCmd(fsets ...*flag.FlagSet) *cobra.Command {
Short: "Signs and outputs a hex-encoded JWT token with the given permissions.",
Long: "Signs and outputs a hex-encoded JWT token with the given permissions. NOTE: only use this command when " +
"the node has already been initialized and started.",
PreRunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(cmd *cobra.Command, _ []string) error {
return ParseMinimumFlags(cmd)
},
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
52 changes: 51 additions & 1 deletion cmd/celestia/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ package main
import (
"bytes"
"context"
"io"
"os"
"reflect"
"testing"

"github.com/cristalhq/jwt/v5"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/celestiaorg/celestia-node/api/rpc/perms"
"github.com/celestiaorg/celestia-node/header"
"github.com/celestiaorg/celestia-node/libs/authtoken"
"github.com/celestiaorg/celestia-node/libs/keystore"
nodemod "github.com/celestiaorg/celestia-node/nodebuilder/node"
)

func TestCompletionHelpString(t *testing.T) {
Expand Down Expand Up @@ -49,7 +56,7 @@ func TestLight(t *testing.T) {
output := &bytes.Buffer{}
rootCmd.SetOut(output)
rootCmd.SetArgs([]string{
"bridge",
"light",
"--node.store", ".celestia-light",
"init",
})
Expand Down Expand Up @@ -102,6 +109,49 @@ func TestBridge(t *testing.T) {
err := rootCmd.ExecuteContext(context.Background())
require.NoError(t, err)
})
// tests that auth admin token generated by node via CLI
// can be verified + contains expected perms
t.Run("auth", func(t *testing.T) {
rootCmd.SetOut(&bytes.Buffer{})
rootCmd.SetArgs([]string{
"bridge",
"--node.store", ".celestia-bridge",
"init",
})
err := rootCmd.ExecuteContext(context.Background())
require.NoError(t, err)

ogStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

rootCmd.SetArgs([]string{
"bridge",
"auth", "admin",
"--node.store", ".celestia-bridge",
})

err = rootCmd.ExecuteContext(context.Background())
require.NoError(t, err)

err = w.Close()
require.NoError(t, err)
os.Stdout = ogStdout

ks, err := keystore.NewFSKeystore(".celestia-bridge/keys", nil)
require.NoError(t, err)
key, err := ks.Get(nodemod.SecretName)
require.NoError(t, err)
verifier, err := jwt.NewVerifierHS(jwt.HS256, key.Body)
require.NoError(t, err)

token, err := io.ReadAll(r)
require.NoError(t, err)

permissions, err := authtoken.ExtractSignedPermissions(verifier, string(token))
require.NoError(t, err)
assert.Equal(t, permissions, perms.AllPerms)
})

t.Cleanup(func() {
if err := os.Chdir(testDir); err != nil {
Expand Down
25 changes: 17 additions & 8 deletions cmd/celestia/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,23 @@ import (
"github.com/spf13/pflag"

cmdnode "github.com/celestiaorg/celestia-node/cmd"
"github.com/celestiaorg/celestia-node/nodebuilder/node"
)

func WithSubcommands() func(*cobra.Command, node.Type, []*pflag.FlagSet) {
return func(c *cobra.Command, tp node.Type, flags []*pflag.FlagSet) {
// WithSubcommands returns the set of commands that require the full flagset.
func WithSubcommands() func(*cobra.Command, []*pflag.FlagSet) {
return func(c *cobra.Command, flags []*pflag.FlagSet) {
c.AddCommand(
cmdnode.Init(flags...),
cmdnode.Start(cmdnode.WithFlagSet(flags)),
)
}
}

// WithAuxiliarySubcommands returns the set of commands that require only the
// minimum flagset for node store determination.
func WithAuxiliarySubcommands() func(*cobra.Command, []*pflag.FlagSet) {
return func(c *cobra.Command, flags []*pflag.FlagSet) {
c.AddCommand(
cmdnode.Init(tp, flags...),
cmdnode.Start(tp, cmdnode.WithFlagSet(flags)),
cmdnode.AuthCmd(flags...),
cmdnode.ResetStore(flags...),
cmdnode.RemoveConfigCmd(flags...),
Expand All @@ -25,9 +34,9 @@ func WithSubcommands() func(*cobra.Command, node.Type, []*pflag.FlagSet) {
}

func init() {
bridgeCmd := cmdnode.NewBridge(WithSubcommands())
lightCmd := cmdnode.NewLight(WithSubcommands())
fullCmd := cmdnode.NewFull(WithSubcommands())
bridgeCmd := cmdnode.NewBridge(WithSubcommands(), WithAuxiliarySubcommands())
lightCmd := cmdnode.NewLight(WithSubcommands(), WithAuxiliarySubcommands())
fullCmd := cmdnode.NewFull(WithSubcommands(), WithAuxiliarySubcommands())
rootCmd.AddCommand(
bridgeCmd,
lightCmd,
Expand Down
4 changes: 2 additions & 2 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func RemoveConfigCmd(fsets ...*flag.FlagSet) *cobra.Command {
Use: "config-remove",
Short: "Deletes the node's config",
Args: cobra.NoArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(cmd *cobra.Command, _ []string) error {
return ParseMinimumFlags(cmd)
},
RunE: func(cmd *cobra.Command, _ []string) error {
Expand All @@ -34,7 +34,7 @@ func UpdateConfigCmd(fsets ...*flag.FlagSet) *cobra.Command {
Long: "Updates the node's outdated config with default values from newly-added fields. Check the config " +
" afterwards to ensure all old custom values were preserved.",
Args: cobra.NoArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(cmd *cobra.Command, _ []string) error {
return ParseMinimumFlags(cmd)
},
RunE: func(cmd *cobra.Command, _ []string) error {
Expand Down
26 changes: 22 additions & 4 deletions cmd/flags_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,24 @@ const (
nodeConfigFlag = "node.config"
)

// NodeFlags gives a set of hardcoded Node package flags.
func NodeFlags() *flag.FlagSet {
func NodeStoreFlag() *flag.FlagSet {
flags := &flag.FlagSet{}

flags.String(
nodeStoreFlag,
"",
"The path to root/home directory of your Celestia Node Store",
)

return flags
}

// NodeFlags gives a set of hardcoded Node package flags.
func NodeFlags() *flag.FlagSet {
flags := &flag.FlagSet{}

flags.AddFlagSet(NodeStoreFlag())

flags.String(
nodeConfigFlag,
"",
Expand All @@ -36,8 +45,7 @@ func NodeFlags() *flag.FlagSet {
return flags
}

// ParseNodeFlags parses Node flags from the given cmd and applies values to Env.
func ParseNodeFlags(ctx context.Context, cmd *cobra.Command, network p2p.Network) (context.Context, error) {
func ParseNodeStore(ctx context.Context, cmd *cobra.Command, network p2p.Network) (context.Context, error) {
store := cmd.Flag(nodeStoreFlag).Value.String()
if store == "" {
tp := NodeType(ctx)
Expand All @@ -47,7 +55,17 @@ func ParseNodeFlags(ctx context.Context, cmd *cobra.Command, network p2p.Network
return ctx, err
}
}

ctx = WithStorePath(ctx, store)
return ctx, nil
}

// ParseNodeFlags parses Node flags from the given cmd and applies values to Env.
func ParseNodeFlags(ctx context.Context, cmd *cobra.Command, network p2p.Network) (context.Context, error) {
ctx, err := ParseNodeStore(ctx, cmd, network)
if err != nil {
return ctx, err
}

nodeConfig := cmd.Flag(nodeConfigFlag).Value.String()
if nodeConfig != "" {
Expand Down
13 changes: 5 additions & 8 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@ import (
flag "github.com/spf13/pflag"

"github.com/celestiaorg/celestia-node/nodebuilder"
"github.com/celestiaorg/celestia-node/nodebuilder/node"
)

// Init constructs a CLI command to initialize Celestia Node of any type with the given flags.
func Init(tp node.Type, fsets ...*flag.FlagSet) *cobra.Command {
func Init(fsets ...*flag.FlagSet) *cobra.Command {
cmd := &cobra.Command{
Use: "init",
Short: "Initialization for Celestia Node. Passed flags have persisted effect.",
Args: cobra.NoArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
return PersistentPreRunEnv(cmd, tp, args)
},
Use: "init",
Short: "Initialization for Celestia Node. Passed flags have persisted effect.",
Args: cobra.NoArgs,
PreRunE: PreRunEnv,
RunE: func(cmd *cobra.Command, _ []string) error {
ctx := cmd.Context()

Expand Down
90 changes: 32 additions & 58 deletions cmd/node.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package cmd

import (
"fmt"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/pflag"

Expand All @@ -14,83 +17,54 @@ import (
"github.com/celestiaorg/celestia-node/nodebuilder/state"
)

func NewBridge(options ...func(*cobra.Command, node.Type, []*pflag.FlagSet)) *cobra.Command {
flags := []*pflag.FlagSet{
NodeFlags(),
p2p.Flags(),
MiscFlags(),
core.Flags(),
rpc.Flags(),
gateway.Flags(),
state.Flags(),
pruner.Flags(),
}
cmd := &cobra.Command{
Use: "bridge [subcommand]",
Args: cobra.NoArgs,
Short: "Manage your Bridge node",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
ctx := WithNodeType(cmd.Context(), node.Bridge)
cmd.SetContext(ctx)
},
}
func NewBridge(addFullFlags, addMinFlags func(*cobra.Command, []*pflag.FlagSet)) *cobra.Command {
return createTopLevelCmd(node.Bridge, addFullFlags, addMinFlags)
}

for _, option := range options {
option(cmd, node.Bridge, flags)
}
return cmd
func NewFull(addFullFlags, addMinFlags func(*cobra.Command, []*pflag.FlagSet)) *cobra.Command {
return createTopLevelCmd(node.Full, addFullFlags, addMinFlags)
}

func NewLight(addFullFlags, addMinFlags func(*cobra.Command, []*pflag.FlagSet)) *cobra.Command {
return createTopLevelCmd(node.Light, addFullFlags, addMinFlags)
}

func NewLight(options ...func(*cobra.Command, node.Type, []*pflag.FlagSet)) *cobra.Command {
flags := []*pflag.FlagSet{
func createTopLevelCmd(
nodeType node.Type,
addFullFlags,
addMinFlags func(*cobra.Command, []*pflag.FlagSet),
) *cobra.Command {
fullFlags := []*pflag.FlagSet{
NodeFlags(),
p2p.Flags(),
header.Flags(),
MiscFlags(),
core.Flags(),
rpc.Flags(),
gateway.Flags(),
state.Flags(),
pruner.Flags(),
}
cmd := &cobra.Command{
Use: "light [subcommand]",
Args: cobra.NoArgs,
Short: "Manage your Light node",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
ctx := WithNodeType(cmd.Context(), node.Light)
cmd.SetContext(ctx)
},
}
for _, option := range options {
option(cmd, node.Light, flags)
if nodeType != node.Bridge {
fullFlags = append(fullFlags, header.Flags())
}
return cmd
}

func NewFull(options ...func(*cobra.Command, node.Type, []*pflag.FlagSet)) *cobra.Command {
flags := []*pflag.FlagSet{
NodeFlags(),
p2p.Flags(),
header.Flags(),
MiscFlags(),
core.Flags(),
rpc.Flags(),
gateway.Flags(),
state.Flags(),
pruner.Flags(),
minFlags := []*pflag.FlagSet{
NodeStoreFlag(),
p2p.NetworkFlag(),
}

cmd := &cobra.Command{
Use: "full [subcommand]",
Use: fmt.Sprintf("%s [subcommand]", strings.ToLower(nodeType.String())),
Args: cobra.NoArgs,
Short: "Manage your Full node",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
ctx := WithNodeType(cmd.Context(), node.Full)
Short: fmt.Sprintf("Manage your %s node", strings.ToLower(nodeType.String())),
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
ctx := WithNodeType(cmd.Context(), nodeType)
cmd.SetContext(ctx)
},
}
for _, option := range options {
option(cmd, node.Full, flags)
}

addFullFlags(cmd, fullFlags)
addMinFlags(cmd, minFlags)

return cmd
}
2 changes: 1 addition & 1 deletion cmd/reset_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func ResetStore(fsets ...*flag.FlagSet) *cobra.Command {
Use: "unsafe-reset-store",
Short: "Resets the node's store to a new state. Leaves the keystore and config intact.",
Args: cobra.NoArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(cmd *cobra.Command, _ []string) error {
return ParseMinimumFlags(cmd)
},
RunE: func(cmd *cobra.Command, _ []string) error {
Expand Down
7 changes: 2 additions & 5 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,18 @@ import (
"github.com/celestiaorg/celestia-app/v3/app/encoding"

"github.com/celestiaorg/celestia-node/nodebuilder"
"github.com/celestiaorg/celestia-node/nodebuilder/node"
)

// Start constructs a CLI command to start Celestia Node daemon of any type with the given flags.
func Start(tp node.Type, options ...func(*cobra.Command)) *cobra.Command {
func Start(options ...func(*cobra.Command)) *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: `Starts Node daemon. First stopping signal gracefully stops the Node and second terminates it.
Options passed on start override configuration options only on start and are not persisted in config.`,
Aliases: []string{"run", "daemon"},
Args: cobra.NoArgs,
SilenceUsage: true,
PreRunE: func(cmd *cobra.Command, args []string) error {
return PersistentPreRunEnv(cmd, tp, args)
},
PreRunE: PreRunEnv,
RunE: func(cmd *cobra.Command, _ []string) (err error) {
ctx := cmd.Context()

Expand Down
Loading

0 comments on commit 8584152

Please sign in to comment.