diff --git a/cmd/frostfs-node/morph.go b/cmd/frostfs-node/morph.go index 1b148095b..b025f63ef 100644 --- a/cmd/frostfs-node/morph.go +++ b/cmd/frostfs-node/morph.go @@ -48,6 +48,7 @@ func initMorphComponents(ctx context.Context, c *cfg) { }), client.WithSwitchInterval(morphconfig.SwitchInterval(c.appCfg)), client.WithMorphCacheMetrics(c.metricsCollector.MorphCacheMetrics()), + client.WithCompatibilityMode(c.cmode), ) if err != nil { c.log.Info(logs.FrostFSNodeFailedToCreateNeoRPCClient, diff --git a/pkg/innerring/initialization.go b/pkg/innerring/initialization.go index 1a4174289..783888b3d 100644 --- a/pkg/innerring/initialization.go +++ b/pkg/innerring/initialization.go @@ -462,6 +462,7 @@ func (s *Server) initMorph(ctx context.Context, cfg *viper.Viper, errChan chan<- name: morphPrefix, from: fromSideChainBlock, morphCacheMetric: s.irMetrics.MorphCacheMetrics(), + cmode: s.cmode, } // create morph client diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 11d43f845..3cc203558 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -115,6 +115,7 @@ type ( sgn *transaction.Signer from uint32 // block height morphCacheMetric metrics.MorphCacheMetrics + cmode *atomic.Bool } ) @@ -488,6 +489,7 @@ func createClient(ctx context.Context, p *chainParams, errChan chan<- error) (*c }), client.WithSwitchInterval(p.cfg.GetDuration(p.name+".switch_interval")), client.WithMorphCacheMetrics(p.morphCacheMetric), + client.WithCompatibilityMode(p.cmode), ) } diff --git a/pkg/morph/client/constructor.go b/pkg/morph/client/constructor.go index 50a9572d4..956ebfb31 100644 --- a/pkg/morph/client/constructor.go +++ b/pkg/morph/client/constructor.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "sync/atomic" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" @@ -48,6 +49,8 @@ type cfg struct { switchInterval time.Duration morphCacheMetrics metrics.MorphCacheMetrics + + cmode *atomic.Bool } const ( @@ -311,3 +314,11 @@ func WithMorphCacheMetrics(morphCacheMetrics metrics.MorphCacheMetrics) Option { c.morphCacheMetrics = morphCacheMetrics } } + +// WithCompatibilityMode indicates that Client is working in compatibility mode +// in this mode we need to keep backward compatibility with services with previous version. +func WithCompatibilityMode(cmode *atomic.Bool) Option { + return func(c *cfg) { + c.cmode = cmode + } +} diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index 1665fec1d..564384a3d 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -566,14 +566,19 @@ func (c *Client) notaryCosigners(invokedByAlpha bool, ir []*keys.PublicKey, comm } s := make([]actor.SignerAccount, 2, 3) // Proxy contract that will pay for the execution. + // Do not change this: + // We must be able to call NNS contract indirectly from the Container contract. + // Thus, CalledByEntry is not sufficient. + // In future we may restrict this to all the usecases we have. + scopes := transaction.Global + if c.cfg.cmode != nil && c.cfg.cmode.Load() { + // Set it to None to keep ability to send notary requests during upgrade + scopes = transaction.None + } s[0] = actor.SignerAccount{ Signer: transaction.Signer{ Account: c.notary.proxy, - // Do not change this: - // We must be able to call NNS contract indirectly from the Container contract. - // Thus, CalledByEntry is not sufficient. - // In future we may restrict this to all the usecases we have. - Scopes: transaction.Global, + Scopes: scopes, }, Account: notary.FakeContractAccount(c.notary.proxy), }