Skip to content

Commit

Permalink
cli: add embedded node config
Browse files Browse the repository at this point in the history
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

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
  • Loading branch information
AliceInHunterland committed Jun 27, 2024
1 parent d9d9d00 commit 58256de
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 17 deletions.
2 changes: 1 addition & 1 deletion cli/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
33 changes: 33 additions & 0 deletions config/config_embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Package config contains embedded YAML configuration files for different network modes
// of the Neo N3 blockchain and NeoFS. This includes configurations for the mainnet,
// testnet, and private network environments.
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
55 changes: 39 additions & 16 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -76,22 +78,25 @@ 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)
}
var (
configData []byte
err error
config Config
)

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,
},
},
if _, err = os.Stat(configPath); os.IsNotExist(err) {
if filepath.Dir(configPath) != DefaultConfigPath {
return Config{}, fmt.Errorf("config '%s' doesn't exist", configPath)
}
configData, err = getEmbeddedConfig(configPath)
if err != nil {
return Config{}, err

Check warning on line 93 in pkg/config/config.go

View check run for this annotation

Codecov / codecov/patch

pkg/config/config.go#L91-L93

Added lines #L91 - L93 were not covered by tests
}
} else {
configData, err = os.ReadFile(configPath)
if err != nil {
return Config{}, fmt.Errorf("unable to read config: %w", err)

Check warning on line 98 in pkg/config/config.go

View check run for this annotation

Codecov / codecov/patch

pkg/config/config.go#L98

Added line #L98 was not covered by tests
}
}
decoder := yaml.NewDecoder(bytes.NewReader(configData))
decoder.KnownFields(true)
Expand All @@ -111,6 +116,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.String()):
return config.Mainnet, nil
case fmt.Sprintf("%s/protocol.%s.yml", DefaultConfigPath, netmode.TestNet.String()):
return config.Testnet, nil
case fmt.Sprintf("%s/protocol.%s.yml", DefaultConfigPath, netmode.PrivNet.String()):
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("no embedded config matches path: %s", configPath)

Check warning on line 133 in pkg/config/config.go

View check run for this annotation

Codecov / codecov/patch

pkg/config/config.go#L120-L133

Added lines #L120 - L133 were not covered by tests
}
}

// updateRelativePaths updates relative paths in the config structure based on the provided relative path.
func updateRelativePaths(relativePath string, config *Config) {
updatePath := func(path *string) {
Expand Down
22 changes: 22 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,25 @@ func TestUnknownConfigFields(t *testing.T) {
require.Contains(t, err.Error(), "field UnknownConfigurationField not found in type config.Config")
})
}

func TestLoadFileWithMissingDefaultConfigPath(t *testing.T) {
originalPath := DefaultConfigPath
temporaryPath := filepath.Join(filepath.Dir(originalPath), "missing-config")

if _, err := os.Stat(originalPath); os.IsNotExist(err) {
err = os.MkdirAll(originalPath, os.ModePerm)
require.NoError(t, err)
}

t.Cleanup(func() {
err := os.Rename(temporaryPath, originalPath)
require.NoError(t, err)
})

err := os.Rename(originalPath, temporaryPath)
require.NoError(t, err)

_, err = LoadFile(filepath.Join(DefaultConfigPath, "protocol.privnet.yml"))
require.Error(t, err)
require.Contains(t, err.Error(), "doesn't exist")
}

0 comments on commit 58256de

Please sign in to comment.