diff --git a/cmd/neofs-ir/defaults.go b/cmd/neofs-ir/defaults.go index 50fc86c9..53bc8519 100644 --- a/cmd/neofs-ir/defaults.go +++ b/cmd/neofs-ir/defaults.go @@ -50,6 +50,7 @@ func defaultConfiguration(cfg *viper.Viper) { cfg.SetDefault("without_mainnet", false) cfg.SetDefault("without_notary", false) + cfg.SetDefault("without_main_notary", false) cfg.SetDefault("morph.endpoint.client", "") cfg.SetDefault("morph.endpoint.notification", "") @@ -75,7 +76,8 @@ func defaultConfiguration(cfg *viper.Viper) { cfg.SetDefault("timers.epoch", "0") cfg.SetDefault("timers.emit", "0") - cfg.SetDefault("timers.notary", "1000") + cfg.SetDefault("timers.main_notary", "1000") + cfg.SetDefault("timers.side_notary", "1000") cfg.SetDefault("timers.stop_estimation.mul", 1) cfg.SetDefault("timers.stop_estimation.div", 1) cfg.SetDefault("timers.collect_basic_income.mul", 1) @@ -83,7 +85,8 @@ func defaultConfiguration(cfg *viper.Viper) { cfg.SetDefault("timers.distribute_basic_income.mul", 1) cfg.SetDefault("timers.distribute_basic_income.div", 1) - cfg.SetDefault("notary.deposit_amount", 1_0000_0000) // 1.0 Fixed8 + cfg.SetDefault("notary.side.deposit_amount", 1_0000_0000) // 1.0 Fixed8 + cfg.SetDefault("notary.main.deposit_amount", 2000_0000) // 0.2 Fixed8 cfg.SetDefault("workers.netmap", "10") cfg.SetDefault("workers.balance", "10") diff --git a/pkg/innerring/blocktimer.go b/pkg/innerring/blocktimer.go index f3e41dde..1a45bf1f 100644 --- a/pkg/innerring/blocktimer.go +++ b/pkg/innerring/blocktimer.go @@ -1,6 +1,8 @@ package innerring import ( + "context" + "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/alphabet" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap" @@ -47,10 +49,13 @@ type ( emitDuration uint32 // in blocks } + depositor func() (util.Uint256, error) + awaiter func(context.Context, util.Uint256) error + notaryDepositArgs struct { l *zap.Logger - depositor func() (util.Uint256, util.Uint256, error) + depositor depositor notaryDuration uint32 // in blocks } @@ -154,7 +159,7 @@ func newNotaryDepositTimer(args *notaryDepositArgs) *timer.BlockTimer { return timer.NewBlockTimer( timer.StaticBlockMeter(args.notaryDuration), func() { - _, _, err := args.depositor() + _, err := args.depositor() if err != nil { args.l.Warn("can't deposit notary contract", zap.String("error", err.Error())) diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 00ec4fa5..6da97722 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -57,10 +57,10 @@ type ( precision precision.Fixed8Converter auditClient *auditWrapper.ClientWrapper - notaryDisabled bool - feeConfig *config.FeeConfig - notaryDepositAmount fixedn.Fixed8 - notaryDuration uint32 + // notary configuration + feeConfig *config.FeeConfig + mainNotaryConfig *notaryConfig + sideNotaryConfig *notaryConfig // internal variables key *ecdsa.PrivateKey @@ -140,17 +140,23 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) error { return err } - if !s.notaryDisabled { - // make an initial deposit to notary contract to enable it - mainTx, sideTx, err := s.depositNotary() + if !s.mainNotaryConfig.disabled { + err = s.initNotary(ctx, + s.depositMainNotary, + s.awaitMainNotaryDeposit, + "waiting to accept main notary deposit", + ) if err != nil { return err } + } - // wait a bit for notary contract deposit - s.log.Info("waiting to accept notary deposit") - - err = s.awaitNotaryDeposit(ctx, mainTx, sideTx) + if !s.sideNotaryConfig.disabled { + err = s.initNotary(ctx, + s.depositSideNotary, + s.awaitSideNotaryDeposit, + "waiting to accept side notary deposit", + ) if err != nil { return err } @@ -237,10 +243,8 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error server := &Server{log: log} // parse notary support - server.notaryDisabled = cfg.GetBool("without_notary") - if server.notaryDisabled { - server.feeConfig = config.NewFeeConfig(cfg) - } + server.feeConfig = config.NewFeeConfig(cfg) + server.mainNotaryConfig, server.sideNotaryConfig = parseNotaryConfigs(cfg) // prepare inner ring node private key server.key, err = crypto.LoadPrivateKey(cfg.GetString("key")) @@ -280,7 +284,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error } // enable notary support in the client - if !server.notaryDisabled { + if !server.sideNotaryConfig.disabled { err = server.morphClient.EnableNotarySupport(server.contracts.proxy) if err != nil { return nil, err @@ -312,7 +316,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error } // enable notary support in the client - if !server.notaryDisabled { + if !server.mainNotaryConfig.disabled { err = server.mainnetClient.EnableNotarySupport( server.contracts.processing, client.WithAlphabetSource(server.morphClient.Committee), @@ -420,7 +424,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error nmSrc: nmClient, clientCache: clientCache, balanceClient: balClient, - notaryDisabled: server.notaryDisabled, + notaryDisabled: server.sideNotaryConfig.disabled, } auditCalcDeps := &auditSettlementDeps{ @@ -470,7 +474,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error Voter: server, MorphClient: server.morphClient, MainnetClient: server.mainnetClient, - NotaryDisabled: server.notaryDisabled, + NotaryDisabled: server.sideNotaryConfig.disabled, FeeProvider: server.feeConfig, }) if err != nil { @@ -507,7 +511,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error ), AlphabetSyncHandler: alphaSync, NodeValidator: locodeValidator, - NotaryDisabled: server.notaryDisabled, + NotaryDisabled: server.sideNotaryConfig.disabled, FeeProvider: server.feeConfig, }) if err != nil { @@ -608,7 +612,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error reputationProcessor, err := reputation.New(&reputation.Params{ Log: log, PoolSize: cfg.GetInt("workers.reputation"), - NotaryDisabled: server.notaryDisabled, + NotaryDisabled: server.sideNotaryConfig.disabled, ReputationContract: server.contracts.reputation, EpochState: server, AlphabetState: server, @@ -628,7 +632,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error // initialize epoch timers server.epochTimer = newEpochTimer(&epochTimerArgs{ l: server.log, - notaryDisabled: server.notaryDisabled, + notaryDisabled: server.sideNotaryConfig.disabled, nm: netmapProcessor, cnrWrapper: cnrClient, epoch: server, @@ -657,18 +661,25 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error server.addBlockTimer(emissionTimer) - if !server.notaryDisabled { - // initialize notary deposit timer - server.notaryDepositAmount = fixedn.Fixed8(cfg.GetInt64("notary.deposit_amount")) - server.notaryDuration = cfg.GetUint32("timers.notary") - - notaryTimer := newNotaryDepositTimer(¬aryDepositArgs{ + // initialize notary timers + if !server.mainNotaryConfig.disabled { + mainNotaryTimer := newNotaryDepositTimer(¬aryDepositArgs{ l: log, - depositor: server.depositNotary, - notaryDuration: server.notaryDuration, + depositor: server.depositMainNotary, + notaryDuration: server.mainNotaryConfig.duration, }) - server.addBlockTimer(notaryTimer) + server.addBlockTimer(mainNotaryTimer) + } + + if !server.sideNotaryConfig.disabled { + sideNotaryTimer := newNotaryDepositTimer(¬aryDepositArgs{ + l: log, + depositor: server.depositSideNotary, + notaryDuration: server.sideNotaryConfig.duration, + }) + + server.addBlockTimer(sideNotaryTimer) } return server, nil @@ -858,51 +869,3 @@ func (s *Server) onlyAlphabetEventHandler(f event.Handler) event.Handler { } } } - -func (s *Server) depositNotary() (mainTx, sideTx util.Uint256, err error) { - mainTx, err = s.mainnetClient.DepositNotary( - s.notaryDepositAmount, - s.notaryDuration+notaryExtraBlocks, - ) - if err != nil { - return - } - - sideTx, err = s.morphClient.DepositNotary( - s.notaryDepositAmount, - s.notaryDuration+notaryExtraBlocks, - ) - - return -} - -func (s *Server) awaitNotaryDeposit(ctx context.Context, mainTx, sideTx util.Uint256) error { - err := awaitNotaryDepositInClient(ctx, s.mainnetClient, mainTx) - if err != nil { - return err - } - - return awaitNotaryDepositInClient(ctx, s.morphClient, sideTx) -} - -func awaitNotaryDepositInClient(ctx context.Context, cli *client.Client, txHash util.Uint256) error { - for i := 0; i < notaryDepositTimeout; i++ { - select { - case <-ctx.Done(): - return nil - default: - } - - ok, err := cli.TxHalt(txHash) - if err == nil { - if ok { - return nil - } - return errDepositFail - } - - cli.Wait(ctx, 1) - } - - return errDepositTimeout -} diff --git a/pkg/innerring/notary.go b/pkg/innerring/notary.go new file mode 100644 index 00000000..146a7570 --- /dev/null +++ b/pkg/innerring/notary.go @@ -0,0 +1,95 @@ +package innerring + +import ( + "context" + + "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neofs-node/pkg/morph/client" + "github.com/spf13/viper" +) + +type ( + notaryConfig struct { + amount fixedn.Fixed8 // amount of deposited GAS to notary contract + duration uint32 // lifetime of notary deposit in blocks + disabled bool // true if notary disabled on chain + } +) + +func (s *Server) depositMainNotary() (tx util.Uint256, err error) { + return s.mainnetClient.DepositNotary( + s.mainNotaryConfig.amount, + s.mainNotaryConfig.duration+notaryExtraBlocks, + ) +} + +func (s *Server) depositSideNotary() (tx util.Uint256, err error) { + return s.morphClient.DepositNotary( + s.sideNotaryConfig.amount, + s.sideNotaryConfig.duration+notaryExtraBlocks, + ) +} + +func (s *Server) awaitMainNotaryDeposit(ctx context.Context, tx util.Uint256) error { + return awaitNotaryDepositInClient(ctx, s.mainnetClient, tx) +} + +func (s *Server) awaitSideNotaryDeposit(ctx context.Context, tx util.Uint256) error { + return awaitNotaryDepositInClient(ctx, s.morphClient, tx) +} + +func (s *Server) initNotary(ctx context.Context, deposit depositor, await awaiter, msg string) error { + tx, err := deposit() + if err != nil { + return err + } + + s.log.Info(msg) + + return await(ctx, tx) +} + +func awaitNotaryDepositInClient(ctx context.Context, cli *client.Client, txHash util.Uint256) error { + for i := 0; i < notaryDepositTimeout; i++ { + select { + case <-ctx.Done(): + return nil + default: + } + + ok, err := cli.TxHalt(txHash) + if err == nil { + if ok { + return nil + } + + return errDepositFail + } + + cli.Wait(ctx, 1) + } + + return errDepositTimeout +} + +func parseNotaryConfigs(cfg *viper.Viper) (main, side *notaryConfig) { + main = new(notaryConfig) + side = new(notaryConfig) + + if cfg.GetBool("without_notary") { + main.disabled = true + side.disabled = true + + return + } + + main.disabled = cfg.GetBool("without_main_notary") + main.amount = fixedn.Fixed8(cfg.GetInt64("notary.main.deposit_amount")) + main.duration = cfg.GetUint32("timers.main_notary") + + side.amount = fixedn.Fixed8(cfg.GetInt64("notary.side.deposit_amount")) + side.duration = cfg.GetUint32("timers.side_notary") + + return +}