package innerring import ( "context" "fmt" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event" "github.com/nspcc-dev/neo-go/pkg/util" "go.uber.org/zap" ) type ( notaryConfig struct { disabled bool // true if notary disabled on chain } ) const ( // gasMultiplier defines how many times more the notary // balance must be compared to the GAS balance of the IR: // notaryBalance = GASBalance * gasMultiplier. gasMultiplier = 3 // gasDivisor defines what part of GAS balance (1/gasDivisor) // should be transferred to the notary service. gasDivisor = 2 ) func (s *Server) depositMainNotary() (tx util.Uint256, err error) { depositAmount, err := client.CalculateNotaryDepositAmount(s.mainnetClient, gasMultiplier, gasDivisor) if err != nil { return util.Uint256{}, fmt.Errorf("could not calculate main notary deposit amount: %w", err) } return s.mainnetClient.DepositNotary( depositAmount, uint32(s.epochDuration.Load())+notaryExtraBlocks, ) } func (s *Server) depositSideNotary() (tx util.Uint256, err error) { depositAmount, err := client.CalculateNotaryDepositAmount(s.morphClient, gasMultiplier, gasDivisor) if err != nil { return util.Uint256{}, fmt.Errorf("could not calculate side notary deposit amount: %w", err) } return s.morphClient.DepositEndlessNotary(depositAmount) } func (s *Server) notaryHandler(_ event.Event) { if !s.mainNotaryConfig.disabled { _, err := s.depositMainNotary() if err != nil { s.log.Error(context.Background(), logs.InnerringCantMakeNotaryDepositInMainChain, zap.Error(err)) } } if _, err := s.depositSideNotary(); err != nil { s.log.Error(context.Background(), logs.InnerringCantMakeNotaryDepositInSideChain, zap.Error(err)) } } 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 } if tx.Equals(util.Uint256{}) { // non-error deposit with an empty TX hash means // that the deposit has already been made; no // need to wait it. s.log.Info(ctx, logs.InnerringNotaryDepositHasAlreadyBeenMade) return nil } s.log.Info(ctx, msg) return await(ctx, tx) } func awaitNotaryDepositInClient(ctx context.Context, cli *client.Client, txHash util.Uint256) error { for range notaryDepositTimeout { select { case <-ctx.Done(): return ctx.Err() default: } ok, err := cli.TxHalt(txHash) if err == nil { if ok { return nil } return errDepositFail } _ = cli.Wait(ctx, 1) } return errDepositTimeout } func notaryConfigs(withMainNotary bool) (main *notaryConfig) { main = new(notaryConfig) main.disabled = !withMainNotary return }