Skip to content

Commit

Permalink
feat: update node config to support remote signer
Browse files Browse the repository at this point in the history
  • Loading branch information
aeddi committed Feb 19, 2025
1 parent efc8b70 commit 030a273
Show file tree
Hide file tree
Showing 18 changed files with 352 additions and 274 deletions.
40 changes: 12 additions & 28 deletions gno.land/cmd/gnoland/config_get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,50 +194,34 @@ func TestConfig_Get_Base(t *testing.T) {
true,
},
{
"validator key fetched",
"priv_validator_key_file",
"validator sign state fetched",
"priv_validator.sign_state",
func(loadedCfg *config.Config, value []byte) {
assert.Equal(t, loadedCfg.PrivValidatorKey, unmarshalJSONCommon[string](t, value))
assert.Equal(t, loadedCfg.PrivValidator.SignState, unmarshalJSONCommon[string](t, value))
},
false,
},
{
"validator key fetched, raw",
"priv_validator_key_file",
"validator sign state fetched, raw",
"priv_validator.sign_state",
func(loadedCfg *config.Config, value []byte) {
assert.Equal(t, loadedCfg.PrivValidatorKey, escapeNewline(value))
assert.Equal(t, loadedCfg.PrivValidator.SignState, escapeNewline(value))
},
true,
},
{
"validator state file fetched",
"priv_validator_state_file",
"validator local signer fetched",
"priv_validator.local_signer",
func(loadedCfg *config.Config, value []byte) {
assert.Equal(t, loadedCfg.PrivValidatorState, unmarshalJSONCommon[string](t, value))
assert.Equal(t, loadedCfg.PrivValidator.LocalSigner, unmarshalJSONCommon[string](t, value))
},
false,
},
{
"validator state file fetched, raw",
"priv_validator_state_file",
"validator local_signer fetched, raw",
"priv_validator.local_signer",
func(loadedCfg *config.Config, value []byte) {
assert.Equal(t, loadedCfg.PrivValidatorState, escapeNewline(value))
},
true,
},
{
"validator listen addr fetched",
"priv_validator_laddr",
func(loadedCfg *config.Config, value []byte) {
assert.Equal(t, loadedCfg.PrivValidatorListenAddr, unmarshalJSONCommon[string](t, value))
},
false,
},
{
"validator listen addr fetched, raw",
"priv_validator_laddr",
func(loadedCfg *config.Config, value []byte) {
assert.Equal(t, loadedCfg.PrivValidatorListenAddr, escapeNewline(value))
assert.Equal(t, loadedCfg.PrivValidator.LocalSigner, escapeNewline(value))
},
true,
},
Expand Down
22 changes: 6 additions & 16 deletions gno.land/cmd/gnoland/config_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,33 +185,23 @@ func TestConfig_Set_Base(t *testing.T) {
},
},
{
"validator key updated",
"validator sign state updated",
[]string{
"priv_validator_key_file",
"priv_validator.sign_state",
"example path",
},
func(loadedCfg *config.Config, value string) {
assert.Equal(t, value, loadedCfg.PrivValidatorKey)
assert.Equal(t, value, loadedCfg.PrivValidator.SignState)
},
},
{
"validator state file updated",
"validator local signer updated",
[]string{
"priv_validator_state_file",
"priv_validator.local_signer",
"example path",
},
func(loadedCfg *config.Config, value string) {
assert.Equal(t, value, loadedCfg.PrivValidatorState)
},
},
{
"validator listen addr updated",
[]string{
"priv_validator_laddr",
"0.0.0.0:0",
},
func(loadedCfg *config.Config, value string) {
assert.Equal(t, value, loadedCfg.PrivValidatorListenAddr)
assert.Equal(t, value, loadedCfg.PrivValidator.LocalSigner)
},
},
{
Expand Down
2 changes: 1 addition & 1 deletion gno.land/cmd/gnoland/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func execStart(ctx context.Context, c *startCfg, io commands.IO) error {
}

// Load existing or generate a new private validator key
fileKey, err := signer.NewFileKey(cfg.PrivValidatorKeyFile())
fileKey, err := signer.NewFileKey(cfg.PrivValidator.LocalSignerPath())
if err != nil {
return fmt.Errorf("unable to instantiate validator key: %w", err)
}

Check warning on line 220 in gno.land/cmd/gnoland/start.go

View check run for this annotation

Codecov / codecov/patch

gno.land/cmd/gnoland/start.go#L219-L220

Added lines #L219 - L220 were not covered by tests
Expand Down
135 changes: 49 additions & 86 deletions tm2/pkg/bft/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
cns "github.com/gnolang/gno/tm2/pkg/bft/consensus/config"
mem "github.com/gnolang/gno/tm2/pkg/bft/mempool/config"
"github.com/gnolang/gno/tm2/pkg/bft/privval"
rpc "github.com/gnolang/gno/tm2/pkg/bft/rpc/config"
eventstore "github.com/gnolang/gno/tm2/pkg/bft/state/eventstore/types"
"github.com/gnolang/gno/tm2/pkg/db"
Expand All @@ -23,15 +24,12 @@ import (
)

var (
errInvalidMoniker = errors.New("moniker not set")
errInvalidDBBackend = errors.New("invalid DB backend")
errInvalidDBPath = errors.New("invalid DB path")
errInvalidPrivValidatorKeyPath = errors.New("invalid private validator key path")
errInvalidPrivValidatorStatePath = errors.New("invalid private validator state file path")
errInvalidABCIMechanism = errors.New("invalid ABCI mechanism")
errInvalidPrivValidatorListenAddress = errors.New("invalid PrivValidator listen address")
errInvalidProfListenAddress = errors.New("invalid profiling server listen address")
errInvalidNodeKeyPath = errors.New("invalid p2p node key path")
errInvalidMoniker = errors.New("moniker not set")
errInvalidDBBackend = errors.New("invalid DB backend")
errInvalidDBPath = errors.New("invalid DB path")
errInvalidABCIMechanism = errors.New("invalid ABCI mechanism")
errInvalidProfListenAddress = errors.New("invalid profiling server listen address")
errInvalidNodeKeyPath = errors.New("invalid p2p node key path")
)

const (
Expand All @@ -50,26 +48,28 @@ type Config struct {
BaseConfig `toml:",squash"`

// Options for services
RPC *rpc.RPCConfig `json:"rpc" toml:"rpc" comment:"##### rpc server configuration options #####"`
P2P *p2p.P2PConfig `json:"p2p" toml:"p2p" comment:"##### peer to peer configuration options #####"`
Mempool *mem.MempoolConfig `json:"mempool" toml:"mempool" comment:"##### mempool configuration options #####"`
Consensus *cns.ConsensusConfig `json:"consensus" toml:"consensus" comment:"##### consensus configuration options #####"`
TxEventStore *eventstore.Config `json:"tx_event_store" toml:"tx_event_store" comment:"##### event store #####"`
Telemetry *telemetry.Config `json:"telemetry" toml:"telemetry" comment:"##### node telemetry #####"`
Application *sdk.AppConfig `json:"application" toml:"application" comment:"##### app settings #####"`
RPC *rpc.RPCConfig `json:"rpc" toml:"rpc" comment:"##### rpc server configuration options #####"`
P2P *p2p.P2PConfig `json:"p2p" toml:"p2p" comment:"##### peer to peer configuration options #####"`
PrivValidator *privval.PrivValidatorConfig `json:"priv_validator" toml:"priv_validator" comment:"##### private validator configuration options #####"`
Mempool *mem.MempoolConfig `json:"mempool" toml:"mempool" comment:"##### mempool configuration options #####"`
Consensus *cns.ConsensusConfig `json:"consensus" toml:"consensus" comment:"##### consensus configuration options #####"`
TxEventStore *eventstore.Config `json:"tx_event_store" toml:"tx_event_store" comment:"##### event store #####"`
Telemetry *telemetry.Config `json:"telemetry" toml:"telemetry" comment:"##### node telemetry #####"`
Application *sdk.AppConfig `json:"application" toml:"application" comment:"##### app settings #####"`
}

// DefaultConfig returns a default configuration for a Tendermint node
func DefaultConfig() *Config {
return &Config{
BaseConfig: DefaultBaseConfig(),
RPC: rpc.DefaultRPCConfig(),
P2P: p2p.DefaultP2PConfig(),
Mempool: mem.DefaultMempoolConfig(),
Consensus: cns.DefaultConsensusConfig(),
TxEventStore: eventstore.DefaultEventStoreConfig(),
Telemetry: telemetry.DefaultTelemetryConfig(),
Application: sdk.DefaultAppConfig(),
BaseConfig: DefaultBaseConfig(),
RPC: rpc.DefaultRPCConfig(),
P2P: p2p.DefaultP2PConfig(),
PrivValidator: privval.DefaultPrivValidatorConfig(),
Mempool: mem.DefaultMempoolConfig(),
Consensus: cns.DefaultConsensusConfig(),
TxEventStore: eventstore.DefaultEventStoreConfig(),
Telemetry: telemetry.DefaultTelemetryConfig(),
Application: sdk.DefaultAppConfig(),
}
}

Expand Down Expand Up @@ -179,14 +179,15 @@ func testP2PConfig() *p2p.P2PConfig {
// TestConfig returns a configuration that can be used for testing
func TestConfig() *Config {
return &Config{
BaseConfig: testBaseConfig(),
RPC: rpc.TestRPCConfig(),
P2P: testP2PConfig(),
Mempool: mem.TestMempoolConfig(),
Consensus: cns.TestConsensusConfig(),
TxEventStore: eventstore.DefaultEventStoreConfig(),
Telemetry: telemetry.DefaultTelemetryConfig(),
Application: sdk.DefaultAppConfig(),
BaseConfig: testBaseConfig(),
RPC: rpc.TestRPCConfig(),
P2P: testP2PConfig(),
PrivValidator: privval.TestPrivValidatorConfig(),
Mempool: mem.TestMempoolConfig(),
Consensus: cns.TestConsensusConfig(),
TxEventStore: eventstore.DefaultEventStoreConfig(),
Telemetry: telemetry.DefaultTelemetryConfig(),
Application: sdk.DefaultAppConfig(),
}
}

Expand All @@ -195,6 +196,7 @@ func (cfg *Config) SetRootDir(root string) *Config {
cfg.BaseConfig.RootDir = root
cfg.RPC.RootDir = root
cfg.P2P.RootDir = root
cfg.PrivValidator.RootDir = (filepath.Join(root, DefaultSecretsDir))
cfg.Mempool.RootDir = root
cfg.Consensus.RootDir = root

Expand Down Expand Up @@ -236,6 +238,9 @@ func (cfg *Config) ValidateBasic() error {
if err := cfg.P2P.ValidateBasic(); err != nil {
return errors.Wrap(err, "Error in [p2p] section")
}
if err := cfg.PrivValidator.ValidateBasic(); err != nil {
return errors.Wrap(err, "Error in [priv_validator] section")
}
if err := cfg.Mempool.ValidateBasic(); err != nil {
return errors.Wrap(err, "Error in [mempool] section")
}
Expand All @@ -255,15 +260,11 @@ var (
DefaultConfigDir = "config"
DefaultSecretsDir = "secrets"

DefaultConfigFileName = "config.toml"
defaultNodeKeyName = "node_key.json"
defaultPrivValKeyName = "priv_validator_key.json"
defaultPrivValStateName = "priv_validator_state.json"
DefaultConfigFileName = "config.toml"
defaultNodeKeyName = "node_key.json"

defaultConfigPath = filepath.Join(DefaultConfigDir, DefaultConfigFileName)
defaultPrivValKeyPath = filepath.Join(DefaultSecretsDir, defaultPrivValKeyName)
defaultPrivValStatePath = filepath.Join(DefaultSecretsDir, defaultPrivValStateName)
defaultNodeKeyPath = filepath.Join(DefaultSecretsDir, defaultNodeKeyName)
defaultConfigPath = filepath.Join(DefaultConfigDir, DefaultConfigFileName)
defaultNodeKeyPath = filepath.Join(DefaultSecretsDir, defaultNodeKeyName)
)

// BaseConfig defines the base configuration for a Tendermint node.
Expand Down Expand Up @@ -317,16 +318,6 @@ type BaseConfig struct {
// Database directory
DBPath string `toml:"db_dir" comment:"Database directory"`

// Path to the JSON file containing the private key to use as a validator in the consensus protocol
PrivValidatorKey string `toml:"priv_validator_key_file" comment:"Path to the JSON file containing the private key to use as a validator in the consensus protocol"`

// Path to the JSON file containing the last sign state of a validator
PrivValidatorState string `toml:"priv_validator_state_file" comment:"Path to the JSON file containing the last sign state of a validator"`

// TCP or UNIX socket address for Tendermint to listen on for
// connections from an external PrivValidator process
PrivValidatorListenAddr string `toml:"priv_validator_laddr" comment:"TCP or UNIX socket address for Tendermint to listen on for\n connections from an external PrivValidator process"`

// A JSON file containing the private key to use for p2p authenticated encryption
NodeKey string `toml:"node_key_file" comment:"Path to the JSON file containing the private key to use for node authentication in the p2p protocol"`

Expand All @@ -340,16 +331,14 @@ type BaseConfig struct {
// DefaultBaseConfig returns a default base configuration for a Tendermint node
func DefaultBaseConfig() BaseConfig {
return BaseConfig{
PrivValidatorKey: defaultPrivValKeyPath,
PrivValidatorState: defaultPrivValStatePath,
NodeKey: defaultNodeKeyPath,
Moniker: defaultMoniker,
ProxyApp: "tcp://127.0.0.1:26658",
ABCI: SocketABCI,
ProfListenAddress: "",
FastSyncMode: true,
DBBackend: db.GoLevelDBBackend.String(),
DBPath: DefaultDBDir,
NodeKey: defaultNodeKeyPath,
Moniker: defaultMoniker,
ProxyApp: "tcp://127.0.0.1:26658",
ABCI: SocketABCI,
ProfListenAddress: "",
FastSyncMode: true,
DBBackend: db.GoLevelDBBackend.String(),
DBPath: DefaultDBDir,
}
}

Expand All @@ -367,16 +356,6 @@ func (cfg BaseConfig) ChainID() string {
return cfg.chainID
}

// PrivValidatorKeyFile returns the full path to the priv_validator_key.json file
func (cfg BaseConfig) PrivValidatorKeyFile() string {
return filepath.Join(cfg.RootDir, cfg.PrivValidatorKey)
}

// PrivValidatorStateFile returns the full path to the priv_validator_state.json file
func (cfg BaseConfig) PrivValidatorStateFile() string {
return filepath.Join(cfg.RootDir, cfg.PrivValidatorState)
}

// NodeKeyFile returns the full path to the node_key.json file
func (cfg BaseConfig) NodeKeyFile() string {
return filepath.Join(cfg.RootDir, cfg.NodeKey)
Expand Down Expand Up @@ -424,22 +403,6 @@ func (cfg BaseConfig) ValidateBasic() error {
return errInvalidDBPath
}

// Verify the validator private key path is set
if cfg.PrivValidatorKey == "" {
return errInvalidPrivValidatorKeyPath
}

// Verify the validator state file path is set
if cfg.PrivValidatorState == "" {
return errInvalidPrivValidatorStatePath
}

// Verify the PrivValidator listen address
if cfg.PrivValidatorListenAddr != "" &&
!tcpUnixAddressRegex.MatchString(cfg.PrivValidatorListenAddr) {
return errInvalidPrivValidatorListenAddress
}

// Verify the p2p private key exists
if cfg.NodeKey == "" {
return errInvalidNodeKeyPath
Expand Down
27 changes: 0 additions & 27 deletions tm2/pkg/bft/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,33 +131,6 @@ func TestConfig_ValidateBaseConfig(t *testing.T) {
assert.ErrorIs(t, c.BaseConfig.ValidateBasic(), errInvalidDBPath)
})

t.Run("priv validator key path not set", func(t *testing.T) {
t.Parallel()

c := DefaultConfig()
c.PrivValidatorKey = ""

assert.ErrorIs(t, c.BaseConfig.ValidateBasic(), errInvalidPrivValidatorKeyPath)
})

t.Run("priv validator state path not set", func(t *testing.T) {
t.Parallel()

c := DefaultConfig()
c.PrivValidatorState = ""

assert.ErrorIs(t, c.BaseConfig.ValidateBasic(), errInvalidPrivValidatorStatePath)
})

t.Run("invalid priv validator listen address", func(t *testing.T) {
t.Parallel()

c := DefaultConfig()
c.PrivValidatorListenAddr = "beep.boop"

assert.ErrorIs(t, c.BaseConfig.ValidateBasic(), errInvalidPrivValidatorListenAddress)
})

t.Run("node key path not set", func(t *testing.T) {
t.Parallel()

Expand Down
Loading

0 comments on commit 030a273

Please sign in to comment.