Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion apps/evm/single/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ func InitCmd() *cobra.Command {
if err != nil {
return fmt.Errorf("error reading chain ID flag: %w", err)
}
if chainID == "" {
return fmt.Errorf("chain ID must be set, (example: ev-1, xo-1)")
}
// Initialize genesis without app state
err = rollgenesis.CreateGenesis(homePath, chainID, 1, proposerAddress)
genesisPath := rollgenesis.GenesisPath(homePath)
Expand All @@ -84,7 +87,8 @@ func InitCmd() *cobra.Command {

// Add flags to the command
rollconf.AddFlags(initCmd)
initCmd.Flags().String(rollgenesis.ChainIDFlag, "evolve-test", "chain ID")
initCmd.Flags().String(rollgenesis.ChainIDFlag, "", "chain ID must be set. It is used in the genesis file and to identify the network (examples: ev-1. xo-1)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make the flag as required or put chain-id as first command argument

initCmd.MarkFlagsOneRequired(rollgenesis.ChainIDFlag)

return initCmd
}
6 changes: 5 additions & 1 deletion apps/testapp/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ func InitCmd() *cobra.Command {
if err != nil {
return fmt.Errorf("error reading chain ID flag: %w", err)
}
if chainID == "" {
return fmt.Errorf("chain ID must be set, (example: ev-1, xo-1)")
}

// Initialize genesis without app state
err = rollgenesis.CreateGenesis(homePath, chainID, 1, proposerAddress)
Expand All @@ -85,7 +88,8 @@ func InitCmd() *cobra.Command {

// Add flags to the command
rollconf.AddFlags(initCmd)
initCmd.Flags().String(rollgenesis.ChainIDFlag, "rollkit-test", "chain ID")
initCmd.Flags().String(rollgenesis.ChainIDFlag, "", "chain ID must be set. It is used in the genesis file and to identify the network (examples: ev-1. xo-1)")
initCmd.MarkFlagsOneRequired(rollgenesis.ChainIDFlag)

return initCmd
}
2 changes: 1 addition & 1 deletion apps/testapp/cmd/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestInitCommand(t *testing.T) {
rollconf.AddGlobalFlags(cmd, "testapp")

// Set home flag to the test directory
cmd.SetArgs([]string{"init", "--home", dir, "--rollkit.node.aggregator", "--rollkit.signer.passphrase", "test"})
cmd.SetArgs([]string{"init", "--home", dir, "--evnode.node.aggregator", "--evnode.signer.passphrase", "test", "--chain_id", "ev-1", "--evnode.da.namespace", "test-namespace"})

// Execute the command
err = cmd.Execute()
Expand Down
4 changes: 2 additions & 2 deletions block/namespace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,15 @@ func TestLegacyNamespaceDetection(t *testing.T) {
if tt.namespace != "" {
assert.Equal(t, tt.namespace, headerNS)
} else {
assert.Equal(t, "rollkit-headers", headerNS) // Default
assert.Equal(t, "", headerNS) // Default
}

if tt.dataNamespace != "" {
assert.Equal(t, tt.dataNamespace, dataNS)
} else if tt.namespace != "" {
assert.Equal(t, tt.namespace, dataNS)
} else {
assert.Equal(t, "rollkit-headers", dataNS) // Falls back to default namespace
assert.Equal(t, "", dataNS)
}

// Test actual behavior in fetchBlobs
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/p2p_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func TestNetInfoCmd_Success(t *testing.T) {
rootCmd := &cobra.Command{Use: "root"}
rootCmd.PersistentFlags().String(config.FlagRootDir, tempDir, "Root directory for config and data")
rootCmd.PersistentFlags().String(config.FlagRPCAddress, rpcAddr, "RPC listen address")
rootCmd.PersistentFlags().String(config.FlagDANamespace, "ev-namespace", "DA Namespace")

err = v.BindPFlag(config.FlagRootDir, rootCmd.PersistentFlags().Lookup(config.FlagRootDir))
require.NoError(err)
Expand Down Expand Up @@ -174,6 +175,7 @@ func TestNetInfoCmd_NoPeers(t *testing.T) {
rootCmd := &cobra.Command{Use: "root"}
rootCmd.PersistentFlags().String(config.FlagRootDir, tempDir, "Root directory for config and data")
rootCmd.PersistentFlags().String(config.FlagRPCAddress, rpcAddr, "RPC listen address")
rootCmd.PersistentFlags().String(config.FlagDANamespace, "ev-namespace", "DA Namespace")

err = v.BindPFlag(config.FlagRootDir, rootCmd.PersistentFlags().Lookup(config.FlagRootDir))
require.NoError(err)
Expand Down
21 changes: 21 additions & 0 deletions pkg/cmd/run_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,27 @@ func ParseConfig(cmd *cobra.Command) (rollconf.Config, error) {
return nodeConfig, nil
}

// ParseConfigWithDefaults loads the node configuration, merges it with the provided defaults, and validates it.
// The precedence order is: command flags > config file > provided defaults
func ParseConfigWithDefaults(cmd *cobra.Command, defaults rollconf.Config) (rollconf.Config, error) {
// Load config from flags and file
nodeConfig, err := rollconf.Load(cmd)
if err != nil {
return rollconf.Config{}, fmt.Errorf("failed to load node config: %w", err)
}

// Merge with defaults - only set values that are still at their zero values
// This preserves the precedence: flags > file > defaults
if nodeConfig.DA.Namespace == "" && defaults.DA.Namespace != "" {
nodeConfig.DA.Namespace = defaults.DA.Namespace
}

if err := nodeConfig.Validate(); err != nil {
return rollconf.Config{}, fmt.Errorf("failed to validate node config: %w", err)
}
return nodeConfig, nil
}

// SetupLogger configures and returns a logger based on the provided configuration.
// It applies the following settings from the config:
// - Log format (text or JSON)
Expand Down
16 changes: 10 additions & 6 deletions pkg/cmd/run_node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,13 @@ func TestParseFlags(t *testing.T) {
func TestAggregatorFlagInvariants(t *testing.T) {
flagVariants := [][]string{{
"--rollkit.node.aggregator=false",
"--evnode.da.namespace=test-namespace",
}, {
"--rollkit.node.aggregator=true",
"--evnode.da.namespace=test-namespace",
}, {
"--rollkit.node.aggregator",
"--evnode.da.namespace=test-namespace",
}}

validValues := []bool{false, true, true}
Expand All @@ -166,21 +169,20 @@ func TestAggregatorFlagInvariants(t *testing.T) {

nodeConfig := rollconf.DefaultConfig
nodeConfig.RootDir = t.TempDir()

newRunNodeCmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, p2pClient, ds, nodeConfig)
_ = newRunNodeCmd.Flags().Set(rollconf.FlagRootDir, "custom/root/dir")

if err := newRunNodeCmd.ParseFlags(args); err != nil {
t.Errorf("Error: %v", err)
}

nodeConfig, err := ParseConfig(newRunNodeCmd)
parsedConfig, err := ParseConfig(newRunNodeCmd)
if err != nil {
t.Errorf("Error: %v", err)
}

if nodeConfig.Node.Aggregator != validValues[i] {
t.Errorf("Expected %v, got %v", validValues[i], nodeConfig.Node.Aggregator)
if parsedConfig.Node.Aggregator != validValues[i] {
t.Errorf("Expected %v, got %v", validValues[i], parsedConfig.Node.Aggregator)
}
}
}
Expand Down Expand Up @@ -209,9 +211,9 @@ func TestDefaultAggregatorValue(t *testing.T) {
// Create a new command without specifying any flags
var args []string
if tc.expected {
args = []string{"start", "--rollkit.node.aggregator"}
args = []string{"start", "--evnode.node.aggregator", "--evnode.da.namespace=ev-namespace"}
} else {
args = []string{"start", "--rollkit.node.aggregator=false"}
args = []string{"start", "--evnode.da.namespace=ev-namespace"}
}

if err := newRunNodeCmd.ParseFlags(args); err != nil {
Expand Down Expand Up @@ -277,6 +279,7 @@ func TestCentralizedAddresses(t *testing.T) {
args := []string{
"start",
"--rollkit.da.address=http://central-da:26657",
"--rollkit.da.namespace=test-namespace",
}

executor, sequencer, dac, keyProvider, p2pClient, ds, stopDAHeightTicker := createTestComponents(context.Background(), t)
Expand Down Expand Up @@ -631,6 +634,7 @@ func TestStartNodeErrors(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
nodeConfig := rollconf.DefaultConfig
nodeConfig.RootDir = tmpDir
nodeConfig.DA.Namespace = "test-namespace" // Set namespace in config

if tc.configModifier != nil {
tc.configModifier(&nodeConfig)
Expand Down
4 changes: 3 additions & 1 deletion pkg/cmd/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"path/filepath"
"testing"

"github.com/evstack/ev-node/pkg/config"
"github.com/spf13/cobra"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -60,7 +61,8 @@ func TestStoreUnsafeCleanCmd(t *testing.T) {

// Create a root command and add the subcommand
rootCmd := &cobra.Command{Use: "root"}
rootCmd.PersistentFlags().String("home", tempDir, "root directory")
rootCmd.PersistentFlags().String(config.FlagRootDir, tempDir, "root directory")
rootCmd.PersistentFlags().String(config.FlagDANamespace, "ev-namespace", "DA Namespace")
rootCmd.AddCommand(StoreUnsafeCleanCmd)

// Capture output
Expand Down
11 changes: 6 additions & 5 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,7 @@ type DAConfig struct {

// GetNamespace returns the namespace for header submittions.
func (d *DAConfig) GetNamespace() string {
if d.Namespace != "" {
return d.Namespace
}
return "rollkit-headers" // Default value
return d.Namespace
}

// GetDataNamespace returns the namespace for data submissions, falling back to the header namespace if not set
Expand Down Expand Up @@ -227,14 +224,18 @@ type RPCConfig struct {
// It creates the directory if it does not exist.
func (c *Config) Validate() error {
if c.RootDir == "" {
return fmt.Errorf("root directory cannot be empty")
return errors.New("root directory cannot be empty")
}

fullDir := filepath.Dir(c.ConfigPath())
if err := os.MkdirAll(fullDir, 0o750); err != nil {
return fmt.Errorf("could not create directory %q: %w", fullDir, err)
}

if c.DA.Namespace == "" {
return errors.New("namespace cannot be empty")
}

return nil
}

Expand Down
9 changes: 6 additions & 3 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestDefaultConfig(t *testing.T) {
assert.Equal(t, float64(-1), def.DA.GasPrice)
assert.Equal(t, float64(0), def.DA.GasMultiplier)
assert.Equal(t, "", def.DA.SubmitOptions)
assert.Equal(t, "rollkit-headers", def.DA.Namespace)
assert.Equal(t, "", def.DA.Namespace)
assert.Equal(t, 1*time.Second, def.Node.BlockTime.Duration)
assert.Equal(t, 6*time.Second, def.DA.BlockTime.Duration)
assert.Equal(t, uint64(0), def.DA.StartHeight)
Expand All @@ -39,6 +39,8 @@ func TestDefaultConfig(t *testing.T) {
assert.Equal(t, "file", def.Signer.SignerType)
assert.Equal(t, "config", def.Signer.SignerPath)
assert.Equal(t, "127.0.0.1:7331", def.RPC.Address)

def.DA.Namespace = "test"
assert.NoError(t, def.Validate())
}

Expand Down Expand Up @@ -136,6 +138,7 @@ node:

da:
address: "http://yaml-da:26657"
namespace: "test"

signer:
signer_type: "file"
Expand Down Expand Up @@ -300,10 +303,10 @@ func TestDAConfig_GetDataNamespace(t *testing.T) {
expectedNamespace: "namespace",
},
{
name: "Both empty, use default value from default namespace",
name: "Both empty, return empty string",
dataNamespace: "",
defaultNamespace: "",
expectedNamespace: "rollkit-headers",
expectedNamespace: "",
},
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ var DefaultConfig = Config{
GasPrice: -1,
GasMultiplier: 0,
MaxSubmitAttempts: 30,
Namespace: "rollkit-headers",
Namespace: "",
DataNamespace: "",
},
Instrumentation: DefaultInstrumentationConfig(),
Expand Down
1 change: 1 addition & 0 deletions pkg/config/yaml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func TestYamlConfigOperations(t *testing.T) {

cfg, err := Load(cmd)
require.NoError(t, err)
cfg.DA.Namespace = "test"
require.NoError(t, cfg.Validate())

// Validate the config
Expand Down
25 changes: 13 additions & 12 deletions test/docker-e2e/docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ func (s *DockerTestSuite) FundWallet(ctx context.Context, wallet tastoratypes.Wa

// StartEvNode initializes and starts an Ev node.
func (s *DockerTestSuite) StartEvNode(ctx context.Context, bridgeNode tastoratypes.DANode, evNode tastoratypes.RollkitNode) {
err := evNode.Init(ctx)
namespace := "test"
err := evNode.Init(ctx, "--evnode.da.namespace", namespace)
s.Require().NoError(err)

bridgeNodeHostName, err := bridgeNode.GetInternalHostName()
Expand All @@ -216,19 +217,19 @@ func (s *DockerTestSuite) StartEvNode(ctx context.Context, bridgeNode tastoratyp

daAddress := fmt.Sprintf("http://%s:26658", bridgeNodeHostName)
err = evNode.Start(ctx,
"--rollkit.da.address", daAddress,
"--rollkit.da.gas_price", "0.025",
"--rollkit.da.auth_token", authToken,
"--rollkit.rpc.address", "0.0.0.0:7331", // bind to 0.0.0.0 so rpc is reachable from test host.
"--rollkit.da.namespace", generateValidNamespaceHex(),
"--evnode.da.address", daAddress,
"--evnode.da.gas_price", "0.025",
"--evnode.da.auth_token", authToken,
"--evnode.da.namespace", namespace,
"--evnode.rpc.address", "0.0.0.0:7331", // bind to 0.0.0.0 so rpc is reachable from test host.
"--kv-endpoint", "0.0.0.0:8080",
)
s.Require().NoError(err)
}

// StartRollkitNodeWithNamespace initializes and starts a Rollkit node with a specific namespace.
func (s *DockerTestSuite) StartRollkitNodeWithNamespace(ctx context.Context, bridgeNode tastoratypes.DANode, rollkitNode tastoratypes.RollkitNode, namespace string) {
err := rollkitNode.Init(ctx)
func (s *DockerTestSuite) StartEvNodeWithNamespace(ctx context.Context, bridgeNode tastoratypes.DANode, rollkitNode tastoratypes.RollkitNode, namespace string) {
err := rollkitNode.Init(ctx, "--evnode.da.namespace", namespace)
s.Require().NoError(err)

bridgeNodeHostName, err := bridgeNode.GetInternalHostName()
Expand All @@ -240,10 +241,10 @@ func (s *DockerTestSuite) StartRollkitNodeWithNamespace(ctx context.Context, bri
daAddress := fmt.Sprintf("http://%s:26658", bridgeNodeHostName)
err = rollkitNode.Start(ctx,
"--rollkit.da.address", daAddress,
"--rollkit.da.gas_price", "0.025",
"--rollkit.da.auth_token", authToken,
"--rollkit.rpc.address", "0.0.0.0:7331", // bind to 0.0.0.0 so rpc is reachable from test host.
"--rollkit.da.namespace", namespace,
"--evnode.da.gas_price", "0.025",
"--evnode.da.auth_token", authToken,
"--evnode.rpc.address", "0.0.0.0:7331", // bind to 0.0.0.0 so rpc is reachable from test host.
"--evnode.da.namespace", namespace,
"--kv-endpoint", "0.0.0.0:8080",
)
s.Require().NoError(err)
Expand Down
6 changes: 3 additions & 3 deletions test/docker-e2e/resiliency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (s *DockerTestSuite) TestRollkitNodeRestart() {

// Start rollkit node with stored namespace
rollkitNode = s.evNodeChain.GetNodes()[0]
s.StartRollkitNodeWithNamespace(ctx, bridgeNode, rollkitNode, namespace)
s.StartEvNodeWithNamespace(ctx, bridgeNode, rollkitNode, namespace)

// Create HTTP client for testing
httpPortStr := rollkitNode.GetHostHTTPPort()
Expand Down Expand Up @@ -205,7 +205,7 @@ func (s *DockerTestSuite) TestCelestiaDANetworkPartitionE2E() {

// Start rollkit node with stored namespace
rollkitNode = s.evNodeChain.GetNodes()[0]
s.StartRollkitNodeWithNamespace(ctx, bridgeNode, rollkitNode, namespace)
s.StartEvNodeWithNamespace(ctx, bridgeNode, rollkitNode, namespace)
t.Log("✅ Rollkit node started")

// Create HTTP client for testing
Expand Down Expand Up @@ -487,7 +487,7 @@ func (s *DockerTestSuite) TestDataCorruptionRecovery() {

// Start rollkit node
rollkitNode = s.evNodeChain.GetNodes()[0]
s.StartRollkitNodeWithNamespace(ctx, bridgeNode, rollkitNode, namespace)
s.StartEvNodeWithNamespace(ctx, bridgeNode, rollkitNode, namespace)
t.Log("✅ Rollkit node started")

// Create HTTP client
Expand Down
Loading
Loading