Skip to content

Commit

Permalink
node: rename morph config section to fschain
Browse files Browse the repository at this point in the history
Rename the `morph` section in the code, config and examples to `fschain`.
Maintain compatibility for the transition and warn if `morph` is used.
Migrate data for deprecated DB key to new.

Refs #3021.

Signed-off-by: Andrey Butusov <[email protected]>
  • Loading branch information
End-rey committed Nov 26, 2024
1 parent 4e34161 commit 2ad8a8d
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 82 deletions.
56 changes: 40 additions & 16 deletions cmd/neofs-node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import (
engineconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine"
shardconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine/shard"
fstreeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine/shard/blobstor/fstree"
fschainconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/fschain"
loggerconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/logger"
morphconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/morph"
nodeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/node"
objectconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/object"
policerconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/policer"
Expand Down Expand Up @@ -110,7 +110,7 @@ type applicationConfiguration struct {
objectBatchSize uint32
}

morph struct {
fsChain struct {
endpoints []string
dialTimeout time.Duration
cacheTTL time.Duration
Expand Down Expand Up @@ -166,13 +166,13 @@ func (a *applicationConfiguration) readConfig(c *config.Config) error {
a.engine.isIgnoreUninitedShards = engineconfig.IgnoreUninitedShards(c)
a.engine.objectPutRetryDeadline = engineconfig.ObjectPutRetryDeadline(c)

// Morph
// FS chain

a.morph.endpoints = morphconfig.Endpoints(c)
a.morph.dialTimeout = morphconfig.DialTimeout(c)
a.morph.cacheTTL = morphconfig.CacheTTL(c)
a.morph.reconnectionRetriesNumber = morphconfig.ReconnectionRetriesNumber(c)
a.morph.reconnectionRetriesDelay = morphconfig.ReconnectionRetriesDelay(c)
a.fsChain.endpoints = fschainconfig.Endpoints(c)
a.fsChain.dialTimeout = fschainconfig.DialTimeout(c)
a.fsChain.cacheTTL = fschainconfig.CacheTTL(c)
a.fsChain.reconnectionRetriesNumber = fschainconfig.ReconnectionRetriesNumber(c)
a.fsChain.reconnectionRetriesDelay = fschainconfig.ReconnectionRetriesDelay(c)

// Contracts

Expand Down Expand Up @@ -522,7 +522,10 @@ type cfgReputation struct {
localTrustCtrl *trustcontroller.Controller
}

var persistateFSChainLastBlockKey = []byte("fs_chain_last_processed_block")
var (
persistateFSChainLastBlockKey = []byte("fs_chain_last_processed_block")
persistateDeprecatedSidechainLastBlockKey = []byte("side_chain_last_processed_block")
)

func initCfg(appCfg *config.Config) *cfg {
c := &cfg{}
Expand Down Expand Up @@ -649,6 +652,12 @@ func initCfg(appCfg *config.Config) *cfg {

c.veryLastClosers = make(map[string]func())

// warning if there is morph section

if c.cfgReader.Value("morph") != nil {
c.log.Warn("config section 'morph' is deprecated, use 'fschain'")
}

c.onShutdown(c.clientCache.CloseAll) // clean up connections
c.onShutdown(c.bgClientCache.CloseAll) // clean up connections
c.onShutdown(c.putClientCache.CloseAll) // clean up connections
Expand All @@ -660,22 +669,37 @@ func initCfg(appCfg *config.Config) *cfg {
func initBasics(c *cfg, key *keys.PrivateKey, stateStorage *state.PersistentStorage) basics {
b := basics{}

addresses := c.applicationConfiguration.morph.endpoints
addresses := c.applicationConfiguration.fsChain.endpoints

fromDeprectedSidechanBlock, err := stateStorage.UInt32(persistateDeprecatedSidechainLastBlockKey)
if err != nil {
fromDeprectedSidechanBlock = 0
}
fromFSChainBlock, err := stateStorage.UInt32(persistateFSChainLastBlockKey)
if err != nil {
fromFSChainBlock = 0
c.log.Warn("can't get last processed FS chain block number", zap.Error(err))
}

// migration for deprecated DB key
if fromFSChainBlock == 0 && fromDeprectedSidechanBlock != fromFSChainBlock {
fromFSChainBlock = fromDeprectedSidechanBlock
err = stateStorage.SetUInt32(persistateFSChainLastBlockKey, fromFSChainBlock)
if err != nil {
c.log.Warn("can't update persistent state",
zap.String("chain", "FS"),
zap.Uint32("block_index", fromFSChainBlock))
}
}

cli, err := client.New(key,
client.WithContext(c.internals.ctx),
client.WithDialTimeout(c.applicationConfiguration.morph.dialTimeout),
client.WithDialTimeout(c.applicationConfiguration.fsChain.dialTimeout),
client.WithLogger(c.log),
client.WithAutoFSChainScope(),
client.WithEndpoints(addresses),
client.WithReconnectionRetries(c.applicationConfiguration.morph.reconnectionRetriesNumber),
client.WithReconnectionsDelay(c.applicationConfiguration.morph.reconnectionRetriesDelay),
client.WithReconnectionRetries(c.applicationConfiguration.fsChain.reconnectionRetriesNumber),
client.WithReconnectionsDelay(c.applicationConfiguration.fsChain.reconnectionRetriesDelay),
client.WithConnSwitchCallback(func() {
err = c.restartMorph()
if err != nil {
Expand Down Expand Up @@ -709,12 +733,12 @@ func initBasics(c *cfg, key *keys.PrivateKey, stateStorage *state.PersistentStor
nmWrap, err := nmClient.NewFromMorph(cli, b.netmapSH, 0)
fatalOnErr(err)

ttl := c.applicationConfiguration.morph.cacheTTL
ttl := c.applicationConfiguration.fsChain.cacheTTL
if ttl == 0 {
msPerBlock, err := cli.MsPerBlock()
fatalOnErr(err)
ttl = time.Duration(msPerBlock) * time.Millisecond
c.log.Debug("morph.cache_ttl fetched from network", zap.Duration("value", ttl))
c.log.Debug("fschain.cache_ttl fetched from network", zap.Duration("value", ttl))
}

var netmapSource netmapCore.Source
Expand Down Expand Up @@ -918,7 +942,7 @@ func (c *cfg) configWatcher(ctx context.Context) {

// Morph

c.cli.Reload(client.WithEndpoints(c.morph.endpoints))
c.cli.Reload(client.WithEndpoints(c.fsChain.endpoints))

// Node

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package morphconfig
package fschainconfig

import (
"fmt"
Expand All @@ -8,9 +8,10 @@ import (
)

const (
subsection = "morph"
subsection = "fschain"
deprecatedMorphSubsection = "morph"

// DialTimeoutDefault is a default dial timeout of morph chain client connection.
// DialTimeoutDefault is a default dial timeout of FS chain client connection.
DialTimeoutDefault = time.Minute

// CacheTTLDefault is a default value for cached values TTL.
Expand All @@ -24,65 +25,90 @@ const (
)

// Endpoints returns list of the values of "endpoints" config parameter
// from "morph" section.
// from "fschain" section (primary) or from "morph" section.
//
// Throws panic if list is empty.
func Endpoints(c *config.Config) []string {
endpoints := config.StringSliceSafe(c.Sub(subsection), "endpoints")
if len(endpoints) == 0 {
panic(fmt.Errorf("no morph chain RPC endpoints, see `morph.endpoints` section"))
morphEndpoints := config.StringSliceSafe(c.Sub(deprecatedMorphSubsection), "endpoints")

if len(endpoints) == 0 && len(morphEndpoints) == 0 {
panic(fmt.Errorf("no FS chain RPC endpoints, see `fschain.endpoints` section"))
}
if len(endpoints) > 0 {
return endpoints
}
return endpoints
return morphEndpoints
}

// DialTimeout returns the value of "dial_timeout" config parameter
// from "morph" section.
// from "fschain" section (primary) or from "morph" section.
//
// Returns DialTimeoutDefault if the value is not positive duration.
func DialTimeout(c *config.Config) time.Duration {
v := config.DurationSafe(c.Sub(subsection), "dial_timeout")
morphV := config.DurationSafe(c.Sub(deprecatedMorphSubsection), "dial_timeout")

if v > 0 {
return v
}
if morphV > 0 {
return morphV
}

return DialTimeoutDefault
}

// CacheTTL returns the value of "cache_ttl" config parameter
// from "morph" section.
// from "fschain" section (primary) or from "morph" section.
//
// Returns CacheTTLDefault if value is zero or invalid. Supports negative durations.
func CacheTTL(c *config.Config) time.Duration {
res := config.DurationSafe(c.Sub(subsection), "cache_ttl")
morphRes := config.DurationSafe(c.Sub(deprecatedMorphSubsection), "cache_ttl")

if res != 0 {
return res
}
if morphRes != 0 {
return morphRes
}

return CacheTTLDefault
}

// ReconnectionRetriesNumber returns the value of "reconnections_number" config
// parameter from "morph" section.
// parameter from "fschain" section (primary) or from "morph" section.
//
// Returns 0 if value is not specified.
func ReconnectionRetriesNumber(c *config.Config) int {
res := config.Int(c.Sub(subsection), "reconnections_number")
morphRes := config.Int(c.Sub(deprecatedMorphSubsection), "reconnections_number")

if res != 0 {
return int(res)
}
if morphRes != 0 {
return int(morphRes)
}

return ReconnectionRetriesNumberDefault
}

// ReconnectionRetriesDelay returns the value of "reconnections_delay" config
// parameter from "morph" section.
// parameter from "fschain" section (primary) or from "morph" section.
//
// Returns 0 if value is not specified.
func ReconnectionRetriesDelay(c *config.Config) time.Duration {
res := config.DurationSafe(c.Sub(subsection), "reconnections_delay")
morphRes := config.DurationSafe(c.Sub(deprecatedMorphSubsection), "reconnections_delay")

if res != 0 {
return res
}
if morphRes != 0 {
return morphRes
}

return ReconnectionRetriesDelayDefault
}
70 changes: 70 additions & 0 deletions cmd/neofs-node/config/fschain/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package fschainconfig_test

import (
"os"
"path/filepath"
"testing"
"time"

"github.com/nspcc-dev/neofs-node/cmd/neofs-node/config"
fschainconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/fschain"
configtest "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/test"
"github.com/stretchr/testify/require"
)

func TestFSChainSection(t *testing.T) {
t.Run("defaults", func(t *testing.T) {
empty := configtest.EmptyConfig()

require.Panics(t, func() { fschainconfig.Endpoints(empty) })
require.Equal(t, fschainconfig.DialTimeoutDefault, fschainconfig.DialTimeout(empty))
require.Equal(t, fschainconfig.CacheTTLDefault, fschainconfig.CacheTTL(empty))
require.Equal(t, 5, fschainconfig.ReconnectionRetriesNumber(empty))
require.Equal(t, 5*time.Second, fschainconfig.ReconnectionRetriesDelay(empty))
})

const path = "../../../../config/example/node"

rpcs := []string{"wss://rpc1.morph.fs.neo.org:40341/ws", "wss://rpc2.morph.fs.neo.org:40341/ws"}

var fileConfigTest = func(c *config.Config) {
require.Equal(t, rpcs, fschainconfig.Endpoints(c))
require.Equal(t, 30*time.Second, fschainconfig.DialTimeout(c))
require.Equal(t, 15*time.Second, fschainconfig.CacheTTL(c))
require.Equal(t, 6, fschainconfig.ReconnectionRetriesNumber(c))
require.Equal(t, 6*time.Second, fschainconfig.ReconnectionRetriesDelay(c))
}

configtest.ForEachFileType(path, fileConfigTest)

t.Run("ENV", func(t *testing.T) {
configtest.ForEnvFileType(path, fileConfigTest)
})

t.Run("compatibility with morph section", func(t *testing.T) {
data := []byte(`
morph:
dial_timeout: 30s
cache_ttl: 15s
reconnections_number: 6
reconnections_delay: 6s
endpoints:
- wss://rpc1.morph.fs.neo.org:40341/ws
- wss://rpc2.morph.fs.neo.org:40341/ws
`)

morphPath := filepath.Join(t.TempDir(), "morph.yaml")
require.NoError(t, os.WriteFile(morphPath, data, 0o640))

var p config.Prm

os.Clearenv()

c := config.New(p,
config.WithConfigFile(morphPath),
config.WithValidate(false),
)

fileConfigTest(c)
})
}
8 changes: 8 additions & 0 deletions cmd/neofs-node/config/internal/validate/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ type valideConfig struct {
Endpoints []string `mapstructure:"endpoints"`
} `mapstructure:"morph"`

FSChain struct {
DialTimeout time.Duration `mapstructure:"dial_timeout"`
CacheTTL time.Duration `mapstructure:"cache_ttl"`
ReconnectionsNumber int `mapstructure:"reconnections_number"`
ReconnectionsDelay time.Duration `mapstructure:"reconnections_delay"`
Endpoints []string `mapstructure:"endpoints"`
} `mapstructure:"fschain"`

APIClient struct {
DialTimeout time.Duration `mapstructure:"dial_timeout"`
StreamTimeout time.Duration `mapstructure:"stream_timeout"`
Expand Down
41 changes: 0 additions & 41 deletions cmd/neofs-node/config/morph/config_test.go

This file was deleted.

12 changes: 6 additions & 6 deletions config/example/node.env
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ NEOFS_CONTRACTS_NETMAP=0cce9e948dca43a6b592efe59ddb4ecb89bdd9ca
NEOFS_CONTRACTS_REPUTATION=441995f631c1da2b133462b71859494a5cd45e90
NEOFS_CONTRACTS_PROXY=ad7c6b55b737b696e5c82c85445040964a03e97f

# Morph chain section
NEOFS_MORPH_DIAL_TIMEOUT=30s
NEOFS_MORPH_CACHE_TTL=15s
NEOFS_MORPH_RECONNECTIONS_NUMBER=6
NEOFS_MORPH_RECONNECTIONS_DELAY=6s
NEOFS_MORPH_ENDPOINTS="wss://rpc1.morph.fs.neo.org:40341/ws wss://rpc2.morph.fs.neo.org:40341/ws"
# FS chain section
NEOFS_FSCHAIN_DIAL_TIMEOUT=30s
NEOFS_FSCHAIN_CACHE_TTL=15s
NEOFS_FSCHAIN_RECONNECTIONS_NUMBER=6
NEOFS_FSCHAIN_RECONNECTIONS_DELAY=6s
NEOFS_FSCHAIN_ENDPOINTS="wss://rpc1.morph.fs.neo.org:40341/ws wss://rpc2.morph.fs.neo.org:40341/ws"

# API Client section
NEOFS_APICLIENT_DIAL_TIMEOUT=15s
Expand Down
Loading

0 comments on commit 2ad8a8d

Please sign in to comment.