forked from TrueCloudLab/frostfs-node
122 lines
3 KiB
Go
122 lines
3 KiB
Go
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() (util.Uint256, 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)
|
|
}
|
|
|
|
tx, _, err := s.morphClient.DepositEndlessNotary(depositAmount)
|
|
return tx, err
|
|
}
|
|
|
|
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
|
|
}
|