diff --git a/cmd/neofs-node/config/morph/config.go b/cmd/neofs-node/config/morph/config.go
index 565699b15..782b941e2 100644
--- a/cmd/neofs-node/config/morph/config.go
+++ b/cmd/neofs-node/config/morph/config.go
@@ -22,6 +22,9 @@ const (
// CacheTTLDefault is a default value for cached values TTL.
// It is 0, because actual default depends on block time.
CacheTTLDefault = time.Duration(0)
+
+ // SwitchIntervalDefault is a default Neo RPCs switch interval.
+ SwitchIntervalDefault = 2 * time.Minute
)
// RPCEndpoint returns list of the values of "rpc_endpoint" config parameter
@@ -81,3 +84,16 @@ func CacheTTL(c *config.Config) time.Duration {
return CacheTTLDefault
}
+
+// SwitchInterval returns the value of "switch_interval" config parameter
+// from "morph" section.
+//
+// Returns SwitchIntervalDefault if value is not positive duration.
+func SwitchInterval(c *config.Config) time.Duration {
+ res := config.DurationSafe(c.Sub(subsection), "switch_interval")
+ if res != 0 {
+ return res
+ }
+
+ return SwitchIntervalDefault
+}
diff --git a/cmd/neofs-node/config/morph/config_test.go b/cmd/neofs-node/config/morph/config_test.go
index 24bdf24a8..78f528e80 100644
--- a/cmd/neofs-node/config/morph/config_test.go
+++ b/cmd/neofs-node/config/morph/config_test.go
@@ -18,6 +18,7 @@ func TestMorphSection(t *testing.T) {
require.Panics(t, func() { morphconfig.RPCEndpoint(empty) })
require.Equal(t, morphconfig.DialTimeoutDefault, morphconfig.DialTimeout(empty))
require.Equal(t, morphconfig.CacheTTLDefault, morphconfig.CacheTTL(empty))
+ require.Equal(t, morphconfig.SwitchIntervalDefault, morphconfig.SwitchInterval(empty))
})
const path = "../../../../config/example/node"
@@ -33,6 +34,7 @@ func TestMorphSection(t *testing.T) {
require.Equal(t, rpcs, morphconfig.RPCEndpoint(c))
require.Equal(t, 30*time.Second, morphconfig.DialTimeout(c))
require.Equal(t, 15*time.Second, morphconfig.CacheTTL(c))
+ require.Equal(t, 3*time.Minute, morphconfig.SwitchInterval(c))
}
configtest.ForEachFileType(path, fileConfigTest)
diff --git a/cmd/neofs-node/morph.go b/cmd/neofs-node/morph.go
index b38260b0a..4ceee9e3f 100644
--- a/cmd/neofs-node/morph.go
+++ b/cmd/neofs-node/morph.go
@@ -51,6 +51,7 @@ func initMorphComponents(c *cfg) {
client.WithConnLostCallback(func() {
c.internalErr <- errors.New("morph connection has been lost")
}),
+ client.WithSwitchInterval(morphconfig.SwitchInterval(c.appCfg)),
)
if err != nil {
c.log.Info("failed to create neo RPC client",
diff --git a/config/example/node.env b/config/example/node.env
index 0b259365f..e7c9cfab4 100644
--- a/config/example/node.env
+++ b/config/example/node.env
@@ -62,6 +62,7 @@ NEOFS_CONTRACTS_PROXY=ad7c6b55b737b696e5c82c85445040964a03e97f
# Morph chain section
NEOFS_MORPH_DIAL_TIMEOUT=30s
NEOFS_MORPH_CACHE_TTL=15s
+NEOFS_MORPH_SWITCH_INTERVAL=3m
NEOFS_MORPH_RPC_ENDPOINT_0_ADDRESS="wss://rpc1.morph.fs.neo.org:40341/ws"
NEOFS_MORPH_RPC_ENDPOINT_0_PRIORITY=0
NEOFS_MORPH_RPC_ENDPOINT_1_ADDRESS="wss://rpc2.morph.fs.neo.org:40341/ws"
diff --git a/config/example/node.json b/config/example/node.json
index c098e8f6d..fa35fa275 100644
--- a/config/example/node.json
+++ b/config/example/node.json
@@ -100,6 +100,7 @@
"morph": {
"dial_timeout": "30s",
"cache_ttl": "15s",
+ "switch_interval": "3m",
"rpc_endpoint": [
{
"address": "wss://rpc1.morph.fs.neo.org:40341/ws",
diff --git a/config/example/node.yaml b/config/example/node.yaml
index 9ae9d82ce..36b77af79 100644
--- a/config/example/node.yaml
+++ b/config/example/node.yaml
@@ -82,8 +82,9 @@ contracts: # side chain NEOFS contract script hashes; optional, override values
morph:
dial_timeout: 30s # timeout for side chain NEO RPC client connection
cache_ttl: 15s # Sidechain cache TTL value (min interval between similar calls). Negative value disables caching.
- # Default value: block time. It is recommended to have this value less or equal to block time.
- # Cached entities: containers, container lists, eACL tables.
+ # Default value: block time. It is recommended to have this value less or equal to block time.
+ # Cached entities: containers, container lists, eACL tables.
+ switch_interval: 3m # interval b/w RPC switch attempts if the node is connected not to the highest priority node
rpc_endpoint: # side chain NEO RPC endpoints; are shuffled and used one by one until the first success
- address: wss://rpc1.morph.fs.neo.org:40341/ws
priority: 0
diff --git a/docs/storage-node-configuration.md b/docs/storage-node-configuration.md
index 00650dc81..51785e981 100644
--- a/docs/storage-node-configuration.md
+++ b/docs/storage-node-configuration.md
@@ -137,13 +137,15 @@ morph:
priority: 1
- address: wss://rpc2.morph.fs.neo.org:40341/ws
priority: 2
+ switch_interval: 2m
```
-| Parameter | Type | Default value | Description |
-|----------------|-----------------------------------------------------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `dial_timeout` | `duration` | `5s` | Timeout for dialing connections to N3 RPCs. |
-| `cache_ttl` | `duration` | Morph block time | Sidechain cache TTL value (min interval between similar calls).
Negative value disables caching.
Cached entities: containers, container lists, eACL tables. |
-| `rpc_endpoint` | list of [endpoint descriptions](#rpc_endpoint-subsection) | | Array of endpoint descriptions. |
+| Parameter | Type | Default value | Description |
+|-------------------|-----------------------------------------------------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `dial_timeout` | `duration` | `5s` | Timeout for dialing connections to N3 RPCs. |
+| `cache_ttl` | `duration` | Morph block time | Sidechain cache TTL value (min interval between similar calls).
Negative value disables caching.
Cached entities: containers, container lists, eACL tables. |
+| `rpc_endpoint` | list of [endpoint descriptions](#rpc_endpoint-subsection) | | Array of endpoint descriptions. |
+| `switch_interval` | `duration` | `2m` | Time interval between the attempts to connect to the highest priority RPC node if the connection is not established yet. |
## `rpc_endpoint` subsection
| Parameter | Type | Default value | Description |
diff --git a/pkg/morph/client/constructor.go b/pkg/morph/client/constructor.go
index 8db9ff523..378e28735 100644
--- a/pkg/morph/client/constructor.go
+++ b/pkg/morph/client/constructor.go
@@ -49,9 +49,8 @@ type cfg struct {
}
const (
- defaultDialTimeout = 5 * time.Second
- defaultWaitInterval = 500 * time.Millisecond
- defaultSwitchInterval = 2 * time.Minute
+ defaultDialTimeout = 5 * time.Second
+ defaultWaitInterval = 500 * time.Millisecond
)
func defaultConfig() *cfg {
@@ -63,7 +62,6 @@ func defaultConfig() *cfg {
signer: &transaction.Signer{
Scopes: transaction.Global,
},
- switchInterval: defaultSwitchInterval,
}
}
diff --git a/pkg/morph/client/multi.go b/pkg/morph/client/multi.go
index 8d9e0bd5b..d72c0794c 100644
--- a/pkg/morph/client/multi.go
+++ b/pkg/morph/client/multi.go
@@ -65,7 +65,7 @@ func (c *Client) switchRPC() bool {
c.rpcActor = act
c.gasToken = gas
- if !c.switchIsActive.Load() &&
+ if c.cfg.switchInterval != 0 && !c.switchIsActive.Load() &&
c.endpoints.list[c.endpoints.curr].Priority != c.endpoints.list[0].Priority {
c.switchIsActive.Store(true)
go c.switchToMostPrioritized()