From a9abd84cc4f2f3a84e9152219af99d7c78f44436 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 27 Jun 2024 13:47:18 +0300 Subject: [PATCH] cli: add embedded node config If `config-path` is not passed, default configs are used according to the set network. In VM CLI the default privnet config with InMemory db is used. Close #3450 Close #3459 Signed-off-by: Ekaterina Pavlova --- cli/options/options.go | 2 +- config/config_embed.go | 32 +++++++++++++++++++++++ pkg/config/config.go | 53 ++++++++++++++++++++++++++------------- pkg/config/config_test.go | 22 ++++++++++++++++ 4 files changed, 91 insertions(+), 18 deletions(-) create mode 100644 config/config_embed.go diff --git a/cli/options/options.go b/cli/options/options.go index d53443933..e9504569e 100644 --- a/cli/options/options.go +++ b/cli/options/options.go @@ -201,7 +201,7 @@ func GetConfigFromContext(ctx *cli.Context) (config.Config, error) { if len(configFile) != 0 { return config.LoadFile(configFile, relativePath) } - var configPath = "./config" + var configPath = config.DefaultConfigPath if argCp := ctx.String("config-path"); argCp != "" { configPath = argCp } diff --git a/config/config_embed.go b/config/config_embed.go new file mode 100644 index 000000000..c1f66676f --- /dev/null +++ b/config/config_embed.go @@ -0,0 +1,32 @@ +// Package config contains embedded YAML configuration files for different network modes +// of the Neo N3 blockchain and for NeoFS mainnet and testnet networks. +package config + +import ( + _ "embed" +) + +// MainNet is the Neo N3 mainnet configuration. +// +//go:embed protocol.mainnet.yml +var MainNet []byte + +// TestNet is the Neo N3 testnet configuration. +// +//go:embed protocol.testnet.yml +var TestNet []byte + +// PrivNet is the private network configuration. +// +//go:embed protocol.privnet.yml +var PrivNet []byte + +// MainNetNeoFS is the mainnet NeoFS configuration. +// +//go:embed protocol.mainnet.neofs.yml +var MainNetNeoFS []byte + +// TestNetNeoFS is the testnet NeoFS configuration. +// +//go:embed protocol.testnet.neofs.yml +var TestNetNeoFS []byte diff --git a/pkg/config/config.go b/pkg/config/config.go index 1438ce09d..27b46a2a5 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -6,8 +6,8 @@ import ( "net/http" "os" "path/filepath" - "time" + "github.com/nspcc-dev/neo-go/config" "github.com/nspcc-dev/neo-go/pkg/config/netmode" "gopkg.in/yaml.v3" ) @@ -38,6 +38,8 @@ const ( // DefaultMaxRequestHeaderBytes is the maximum permitted size of the headers // in an HTTP request. DefaultMaxRequestHeaderBytes = http.DefaultMaxHeaderBytes + // DefaultConfigPath is the default path to the config directory. + DefaultConfigPath = "./config" ) // Version is the version of the node, set at the build time. @@ -76,22 +78,21 @@ func Load(path string, netMode netmode.Magic, relativePath ...string) (Config, e // fixups if necessary. If relativePath is not empty, relative paths in the config will // be updated based on the provided relative path. 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) - } - - configData, err := os.ReadFile(configPath) - if err != nil { - return Config{}, fmt.Errorf("unable to read config: %w", err) - } - - config := Config{ - ApplicationConfiguration: ApplicationConfiguration{ - P2P: P2P{ - PingInterval: 30 * time.Second, - PingTimeout: 90 * time.Second, - }, - }, + var ( + configData []byte + err error + config Config + ) + if _, err = os.Stat(configPath); os.IsNotExist(err) { + configData, err = getEmbeddedConfig(configPath) + if err != nil { + return Config{}, err + } + } else { + configData, err = os.ReadFile(configPath) + if err != nil { + return Config{}, fmt.Errorf("unable to read config: %w", err) + } } decoder := yaml.NewDecoder(bytes.NewReader(configData)) decoder.KnownFields(true) @@ -111,6 +112,24 @@ func LoadFile(configPath string, relativePath ...string) (Config, error) { return config, nil } +// getEmbeddedConfig returns the embedded config based on the provided config path. +func getEmbeddedConfig(configPath string) ([]byte, error) { + switch configPath { + case fmt.Sprintf("%s/protocol.%s.yml", DefaultConfigPath, netmode.MainNet): + return config.MainNet, nil + case fmt.Sprintf("%s/protocol.%s.yml", DefaultConfigPath, netmode.TestNet): + return config.TestNet, nil + case fmt.Sprintf("%s/protocol.%s.yml", DefaultConfigPath, netmode.PrivNet): + return config.PrivNet, nil + case fmt.Sprintf("%s/protocol.mainnet.neofs.yml", DefaultConfigPath): + return config.MainNetNeoFS, nil + case fmt.Sprintf("%s/protocol.testnet.neofs.yml", DefaultConfigPath): + return config.TestNetNeoFS, nil + default: + return nil, fmt.Errorf("config '%s' doesn't exist and no matching embedded config was found", configPath) + } +} + // updateRelativePaths updates relative paths in the config structure based on the provided relative path. func updateRelativePaths(relativePath string, config *Config) { updatePath := func(path *string) { diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 7fca30067..da2478921 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -1,12 +1,16 @@ package config import ( + "bytes" + "fmt" "os" "path/filepath" "testing" + "github.com/nspcc-dev/neo-go/config" "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" ) const testConfigPath = "./testdata/protocol.test.yml" @@ -32,3 +36,21 @@ func TestUnknownConfigFields(t *testing.T) { require.Contains(t, err.Error(), "field UnknownConfigurationField not found in type config.Config") }) } + +func TestLoadFileWithMissingDefaultConfigPath(t *testing.T) { + var cfgPrivNet Config + cfg, err := LoadFile(fmt.Sprintf("%s/protocol.%s.yml", DefaultConfigPath, netmode.PrivNet)) + require.Nil(t, err) + decoder := yaml.NewDecoder(bytes.NewReader(config.PrivNet)) + err = decoder.Decode(&cfgPrivNet) + require.NoError(t, err) + require.Equal(t, cfg, cfgPrivNet) + + _, err = LoadFile(fmt.Sprintf("%s/protocol.%s.yml", os.TempDir(), netmode.PrivNet)) + require.Error(t, err) + require.Contains(t, err.Error(), "doesn't exist and no matching embedded config was found") + + _, err = LoadFile(fmt.Sprintf("%s/protocol.%s.yml", DefaultConfigPath, "aaa")) + require.Error(t, err) + require.Contains(t, err.Error(), "doesn't exist and no matching embedded config was found") +}