Skip to content

Commit

Permalink
relative-path: flag add to the cli for adding relative path to the co…
Browse files Browse the repository at this point in the history
…nfig

To be able running the node from any working directory by simply
pointing the relative-path for set parameters in config.

Closes #3179.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
  • Loading branch information
AliceInHunterland committed Nov 20, 2023
1 parent de2a445 commit 9211120
Show file tree
Hide file tree
Showing 20 changed files with 70 additions and 31 deletions.
11 changes: 9 additions & 2 deletions cli/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ var ConfigFile = cli.StringFlag{
Usage: "path to the node configuration file (overrides --config-path option)",
}

var RelativePath = cli.StringFlag{
Name: "relative-path",
Usage: "path which is used to resolve relative paths in config files",
}

// Debug is a flag for commands that allow node in debug mode usage.
var Debug = cli.BoolFlag{
Name: "debug, d",
Expand Down Expand Up @@ -158,16 +163,18 @@ func GetRPCWithInvoker(gctx context.Context, ctx *cli.Context, signers []transac

// GetConfigFromContext looks at the path and the mode flags in the given config and
// returns an appropriate config.

func GetConfigFromContext(ctx *cli.Context) (config.Config, error) {
var configFile = ctx.String("config-file")
var relativePath = ctx.String("relative-path")
if len(configFile) != 0 {
return config.LoadFile(configFile)
return config.LoadFile(configFile, relativePath)
}
var configPath = "./config"
if argCp := ctx.String("config-path"); argCp != "" {
configPath = argCp
}
return config.Load(configPath, GetNetwork(ctx))
return config.Load(configPath, GetNetwork(ctx), relativePath)
}

var (
Expand Down
4 changes: 2 additions & 2 deletions cli/server/cli_dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestDBRestoreDump(t *testing.T) {

loadConfig := func(t *testing.T) config.Config {
chainPath := filepath.Join(tmpDir, "neogotestchain")
cfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"))
cfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"), "")
require.NoError(t, err, "could not load config")
cfg.ApplicationConfiguration.DBConfiguration.Type = dbconfig.LevelDB
cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath = chainPath
Expand Down Expand Up @@ -119,7 +119,7 @@ func TestDBDumpRestoreIncremental(t *testing.T) {
nonincDump := filepath.Join(tmpDir, "nonincDump.acc")
incDump := filepath.Join(tmpDir, "incDump.acc")

cfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"))
cfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"), "")
require.NoError(t, err, "could not load config")
cfg.ApplicationConfiguration.DBConfiguration.Type = dbconfig.LevelDB
cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath = chainPath
Expand Down
2 changes: 1 addition & 1 deletion cli/server/cli_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

func TestServerStart(t *testing.T) {
tmpDir := t.TempDir()
goodCfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"))
goodCfg, err := config.LoadFile(filepath.Join("..", "..", "config", "protocol.unit_testnet.yml"), "")
require.NoError(t, err, "could not load config")
ptr := &goodCfg
saveCfg := func(t *testing.T, f func(cfg *config.Config)) string {
Expand Down
2 changes: 1 addition & 1 deletion cli/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import (

// NewCommands returns 'node' command.
func NewCommands() []cli.Command {
cfgFlags := []cli.Flag{options.Config, options.ConfigFile}
cfgFlags := []cli.Flag{options.Config, options.ConfigFile, options.RelativePath}
cfgFlags = append(cfgFlags, options.Network...)
var cfgWithCountFlags = make([]cli.Flag, len(cfgFlags))
copy(cfgWithCountFlags, cfgFlags)
Expand Down
14 changes: 12 additions & 2 deletions cli/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ func TestGetConfigFromContext(t *testing.T) {
require.NoError(t, err)
require.Equal(t, netmode.TestNet, cfg.ProtocolConfiguration.Magic)
})
t.Run("relative-path", func(t *testing.T) {
set := flag.NewFlagSet("flagSet", flag.ExitOnError)
set.String("relative-path", "../../config", "")
set.Bool("testnet", true, "")
set.String("config-file", "../../config/protocol.testnet.yml", "")
ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := options.GetConfigFromContext(ctx)
require.NoError(t, err)
require.Equal(t, "../../config/cn_wallet.json", cfg.ApplicationConfiguration.Consensus.UnlockWallet.Path)
})
}

func TestHandleLoggingParams(t *testing.T) {
Expand Down Expand Up @@ -233,7 +243,7 @@ func TestRestoreDB(t *testing.T) {
badCfgDir := t.TempDir()
logfile := filepath.Join(badCfgDir, "logdir")
require.NoError(t, os.WriteFile(logfile, []byte{1, 2, 3}, os.ModePerm))
cfg, err := config.LoadFile(filepath.Join(goodCfg, "protocol.privnet.yml"))
cfg, err := config.LoadFile(filepath.Join(goodCfg, "protocol.privnet.yml"), "")
require.NoError(t, err, "could not load config")
cfg.ApplicationConfiguration.LogPath = filepath.Join(logfile, "file.log")
out, err := yaml.Marshal(cfg)
Expand All @@ -249,7 +259,7 @@ func TestRestoreDB(t *testing.T) {
})
t.Run("invalid bc config", func(t *testing.T) {
badCfgDir := t.TempDir()
cfg, err := config.LoadFile(filepath.Join(goodCfg, "protocol.privnet.yml"))
cfg, err := config.LoadFile(filepath.Join(goodCfg, "protocol.privnet.yml"), "")
require.NoError(t, err, "could not load config")
cfg.ApplicationConfiguration.DBConfiguration.Type = ""
out, err := yaml.Marshal(cfg)
Expand Down
4 changes: 2 additions & 2 deletions cli/vm/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func newTestVMCLIWithLogoAndCustomConfig(t *testing.T, printLogo bool, cfg *conf
if cfg == nil {
configPath := "../../config/protocol.unit_testnet.single.yml"
var err error
c, err = config.LoadFile(configPath)
c, err = config.LoadFile(configPath, "")
require.NoError(t, err, "could not load chain config")
c.ApplicationConfiguration.DBConfiguration.Type = dbconfig.InMemoryDB
} else {
Expand Down Expand Up @@ -140,7 +140,7 @@ func newTestVMClIWithState(t *testing.T) *executor {

// After that create CLI backed by created chain.
configPath := "../../config/protocol.unit_testnet.yml"
cfg, err := config.LoadFile(configPath)
cfg, err := config.LoadFile(configPath, "")
require.NoError(t, err)
cfg.ApplicationConfiguration.DBConfiguration.Type = dbconfig.LevelDB
cfg.ApplicationConfiguration.DBConfiguration.LevelDBOptions = opts
Expand Down
2 changes: 1 addition & 1 deletion cli/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

// NewCommands returns 'vm' command.
func NewCommands() []cli.Command {
cfgFlags := []cli.Flag{options.Config, options.ConfigFile}
cfgFlags := []cli.Flag{options.Config, options.ConfigFile, options.RelativePath}
cfgFlags = append(cfgFlags, options.Network...)
return []cli.Command{{
Name: "vm",
Expand Down
2 changes: 1 addition & 1 deletion internal/testcli/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func (w *ConcurrentBuffer) Reset() {

func NewTestChain(t *testing.T, f func(*config.Config), run bool) (*core.Blockchain, *rpcsrv.Server, *network.Server) {
configPath := "../../config/protocol.unit_testnet.single.yml"
cfg, err := config.LoadFile(configPath)
cfg, err := config.LoadFile(configPath, "")
require.NoError(t, err, "could not load config")
if f != nil {
f(&cfg)
Expand Down
4 changes: 2 additions & 2 deletions pkg/config/application_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ func TestApplicationConfigurationEquals(t *testing.T) {
require.True(t, o.EqualsButServices(a))
require.True(t, a.EqualsButServices(a))

cfg1, err := LoadFile(filepath.Join("..", "..", "config", "protocol.mainnet.yml"))
cfg1, err := LoadFile(filepath.Join("..", "..", "config", "protocol.mainnet.yml"), "")
require.NoError(t, err)
cfg2, err := LoadFile(filepath.Join("..", "..", "config", "protocol.testnet.yml"))
cfg2, err := LoadFile(filepath.Join("..", "..", "config", "protocol.testnet.yml"), "")
require.NoError(t, err)
require.False(t, cfg1.ApplicationConfiguration.EqualsButServices(&cfg2.ApplicationConfiguration))
}
Expand Down
28 changes: 25 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package config
import (
"fmt"
"os"
"path/filepath"
"time"

"github.com/nspcc-dev/neo-go/pkg/config/netmode"
Expand Down Expand Up @@ -57,14 +58,14 @@ func (c Config) Blockchain() Blockchain {

// Load attempts to load the config from the given
// path for the given netMode.
func Load(path string, netMode netmode.Magic) (Config, error) {
func Load(path string, netMode netmode.Magic, relativePath string) (Config, error) {
configPath := fmt.Sprintf("%s/protocol.%s.yml", path, netMode)
return LoadFile(configPath)
return LoadFile(configPath, relativePath)
}

// LoadFile loads config from the provided path. It also applies backwards compatibility
// fixups if necessary.
func LoadFile(configPath string) (Config, error) {
func LoadFile(configPath string, relativePath string) (Config, error) {
if _, err := os.Stat(configPath); os.IsNotExist(err) {
return Config{}, fmt.Errorf("config '%s' doesn't exist", configPath)
}
Expand All @@ -88,10 +89,31 @@ func LoadFile(configPath string) (Config, error) {
return Config{}, fmt.Errorf("failed to unmarshal config YAML: %w", err)
}

if relativePath != "" {
updateRelativePaths(relativePath, &config)
}

err = config.ProtocolConfiguration.Validate()
if err != nil {
return Config{}, err
}

return config, nil
}

// updateRelativePaths updates relative paths in the config structure based on the provided relative path.
func updateRelativePaths(relativePath string, config *Config) {
updatePath := func(path *string) {
if *path != "" {
*path = filepath.Join(relativePath, *path)
}
}

updatePath(&config.ApplicationConfiguration.LogPath)
updatePath(&config.ApplicationConfiguration.DBConfiguration.BoltDBOptions.FilePath)
updatePath(&config.ApplicationConfiguration.DBConfiguration.LevelDBOptions.DataDirectoryPath)
updatePath(&config.ApplicationConfiguration.Consensus.UnlockWallet.Path)
updatePath(&config.ApplicationConfiguration.P2PNotary.UnlockWallet.Path)
updatePath(&config.ApplicationConfiguration.Oracle.UnlockWallet.Path)
updatePath(&config.ApplicationConfiguration.StateRoot.UnlockWallet.Path)
}
2 changes: 1 addition & 1 deletion pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import (
const testConfigPath = "./testdata/protocol.test.yml"

func TestUnexpectedNativeUpdateHistoryContract(t *testing.T) {
_, err := LoadFile(testConfigPath)
_, err := LoadFile(testConfigPath, "")
require.Error(t, err)
}
6 changes: 3 additions & 3 deletions pkg/config/protocol_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,13 @@ func TestProtocolConfigurationEquals(t *testing.T) {
require.True(t, o.Equals(p))
require.True(t, p.Equals(p))

cfg1, err := LoadFile(filepath.Join("..", "..", "config", "protocol.mainnet.yml"))
cfg1, err := LoadFile(filepath.Join("..", "..", "config", "protocol.mainnet.yml"), "")
require.NoError(t, err)
cfg2, err := LoadFile(filepath.Join("..", "..", "config", "protocol.testnet.yml"))
cfg2, err := LoadFile(filepath.Join("..", "..", "config", "protocol.testnet.yml"), "")
require.NoError(t, err)
require.False(t, cfg1.ProtocolConfiguration.Equals(&cfg2.ProtocolConfiguration))

cfg2, err = LoadFile(filepath.Join("..", "..", "config", "protocol.mainnet.yml"))
cfg2, err = LoadFile(filepath.Join("..", "..", "config", "protocol.mainnet.yml"), "")
require.NoError(t, err)
p = &cfg1.ProtocolConfiguration
o = &cfg2.ProtocolConfiguration
Expand Down
4 changes: 2 additions & 2 deletions pkg/consensus/consensus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ func getTestValidator(i int) (*privateKey, *publicKey) {

func newSingleTestChain(t *testing.T) *core.Blockchain {
configPath := "../../config/protocol.unit_testnet.single.yml"
cfg, err := config.LoadFile(configPath)
cfg, err := config.LoadFile(configPath, "")
require.NoError(t, err, "could not load config")

chain, err := core.NewBlockchain(storage.NewMemoryStore(), cfg.Blockchain(), zaptest.NewLogger(t))
Expand All @@ -553,7 +553,7 @@ func newSingleTestChain(t *testing.T) *core.Blockchain {
}

func newTestChain(t *testing.T, stateRootInHeader bool) *core.Blockchain {
unitTestNetCfg, err := config.Load("../../config", netmode.UnitTestNet)
unitTestNetCfg, err := config.Load("../../config", netmode.UnitTestNet, "")
require.NoError(t, err)
unitTestNetCfg.ProtocolConfiguration.StateRootInHeader = stateRootInHeader

Expand Down
2 changes: 1 addition & 1 deletion pkg/core/blockchain_core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func TestBlockchain_InitWithIncompleteStateJump(t *testing.T) {
require.NoError(t, err)

checkNewBlockchainErr := func(t *testing.T, cfg func(c *config.Config), store storage.Store, errText string) {
unitTestNetCfg, err := config.Load("../../config", testchain.Network())
unitTestNetCfg, err := config.Load("../../config", testchain.Network(), "")
require.NoError(t, err)
cfg(&unitTestNetCfg)
log := zaptest.NewLogger(t)
Expand Down
2 changes: 1 addition & 1 deletion pkg/core/blockchain_neotest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,7 @@ func TestConfigNativeUpdateHistory(t *testing.T) {
var prefixPath = filepath.Join("..", "..", "config")
check := func(t *testing.T, cfgFileSuffix any) {
cfgPath := filepath.Join(prefixPath, fmt.Sprintf("protocol.%s.yml", cfgFileSuffix))
cfg, err := config.LoadFile(cfgPath)
cfg, err := config.LoadFile(cfgPath, "")
require.NoError(t, err, fmt.Errorf("failed to load %s", cfgPath))
natives := native.NewContracts(cfg.ProtocolConfiguration)
assert.Equal(t, len(natives.Contracts),
Expand Down
2 changes: 1 addition & 1 deletion pkg/core/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func initTestChain(t testing.TB, st storage.Store, f func(*config.Config)) *Bloc
}

func initTestChainNoCheck(t testing.TB, st storage.Store, f func(*config.Config)) (*Blockchain, error) {
unitTestNetCfg, err := config.Load("../../config", testchain.Network())
unitTestNetCfg, err := config.Load("../../config", testchain.Network(), "")
require.NoError(t, err)
if f != nil {
f(&unitTestNetCfg)
Expand Down
2 changes: 1 addition & 1 deletion pkg/core/interop/runtime/ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func getSharpTestTx(sender util.Uint160) *transaction.Transaction {
func getSharpTestGenesis(t *testing.T) *block.Block {
const configPath = "../../../../config"

cfg, err := config.Load(configPath, netmode.MainNet)
cfg, err := config.Load(configPath, netmode.MainNet, "")
require.NoError(t, err)
b, err := core.CreateGenesisBlock(cfg.ProtocolConfiguration)
require.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions pkg/core/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestGenesisBlockMainNet(t *testing.T) {
cfg, err := config.Load("../../config", netmode.MainNet)
cfg, err := config.Load("../../config", netmode.MainNet, "")
require.NoError(t, err)

block, err := CreateGenesisBlock(cfg.ProtocolConfiguration)
Expand All @@ -27,7 +27,7 @@ func TestGetConsensusAddressMainNet(t *testing.T) {
consensusScript = "6b123dd8bec718648852bbc78595e3536a058f9f"
)

cfg, err := config.Load("../../config", netmode.MainNet)
cfg, err := config.Load("../../config", netmode.MainNet, "")
require.NoError(t, err)

validators, _, err := validatorsFromConfig(cfg.ProtocolConfiguration)
Expand Down
2 changes: 1 addition & 1 deletion pkg/services/rpcsrv/server_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func getUnitTestChain(t testing.TB, enableOracle bool, enableNotary bool, disabl
func getUnitTestChainWithCustomConfig(t testing.TB, enableOracle bool, enableNotary bool, customCfg func(configuration *config.Config)) (*core.Blockchain, OracleHandler, config.Config, *zap.Logger) {
net := netmode.UnitTestNet
configPath := "../../../config"
cfg, err := config.Load(configPath, net)
cfg, err := config.Load(configPath, net, "")
require.NoError(t, err, "could not load config")
if customCfg != nil {
customCfg(&cfg)
Expand Down
2 changes: 1 addition & 1 deletion scripts/gendump/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func handleError(msg string, err error) {
}

func newChain() (*core.Blockchain, error) {
unitTestNetCfg, err := config.Load("./config", netmode.UnitTestNet)
unitTestNetCfg, err := config.Load("./config", netmode.UnitTestNet, "")
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 9211120

Please sign in to comment.