[#873] innerring/notary: Change notary deposit logic

IR tries to keep 1:3 proportion of GAS and
notary balances respectively. If that proportion
has been messed(means that notary balance is
lower than required) it sends half of its
GAS balance to the notary service.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2021-10-11 20:09:52 +03:00 committed by Alex Vanin
parent a25bd2112d
commit e5748bfc96
5 changed files with 58 additions and 11 deletions

View file

@ -69,6 +69,7 @@ type (
morphClient *client.Client morphClient *client.Client
mainnetClient *client.Client mainnetClient *client.Client
epochCounter atomic.Uint64 epochCounter atomic.Uint64
epochDuration atomic.Uint64
statusIndex *innerRingIndexer statusIndex *innerRingIndexer
precision precision.Fixed8Converter precision precision.Fixed8Converter
auditClient *auditWrapper.ClientWrapper auditClient *auditWrapper.ClientWrapper
@ -961,7 +962,13 @@ func (s *Server) initConfigFromBlockchain() error {
// get current epoch // get current epoch
epoch, err := s.netmapClient.Epoch() epoch, err := s.netmapClient.Epoch()
if err != nil { if err != nil {
return fmt.Errorf("can't parse epoch: %w", err) return fmt.Errorf("can't read epoch number: %w", err)
}
// get current epoch duration
epochDuration, err := s.netmapClient.EpochDuration()
if err != nil {
return fmt.Errorf("can't read epoch duration: %w", err)
} }
// get balance precision // get balance precision
@ -977,6 +984,7 @@ func (s *Server) initConfigFromBlockchain() error {
} }
s.epochCounter.Store(epoch) s.epochCounter.Store(epoch)
s.epochDuration.Store(epochDuration)
s.precision.SetBalancePrecision(balancePrecision) s.precision.SetBalancePrecision(balancePrecision)
s.log.Debug("read config from blockchain", s.log.Debug("read config from blockchain",

View file

@ -2,8 +2,8 @@ package innerring
import ( import (
"context" "context"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -11,23 +11,43 @@ import (
type ( type (
notaryConfig struct { notaryConfig struct {
amount fixedn.Fixed8 // amount of deposited GAS to notary contract duration uint32 // lifetime of notary deposit in blocks
duration uint32 // lifetime of notary deposit in blocks disabled bool // true if notary disabled on chain
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) { 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( return s.mainnetClient.DepositNotary(
s.mainNotaryConfig.amount, depositAmount,
s.mainNotaryConfig.duration+notaryExtraBlocks, uint32(s.epochDuration.Load())+notaryExtraBlocks,
) )
} }
func (s *Server) depositSideNotary() (tx util.Uint256, err error) { 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.DepositNotary( return s.morphClient.DepositNotary(
s.sideNotaryConfig.amount, depositAmount,
s.sideNotaryConfig.duration+notaryExtraBlocks, uint32(s.epochDuration.Load())+notaryExtraBlocks,
) )
} }
@ -85,10 +105,8 @@ func parseNotaryConfigs(cfg *viper.Viper, withSideNotary, withMainNotary bool) (
} }
main.disabled = !withMainNotary main.disabled = !withMainNotary
main.amount = fixedn.Fixed8(cfg.GetInt64("notary.main.deposit_amount"))
main.duration = cfg.GetUint32("timers.main_notary") main.duration = cfg.GetUint32("timers.main_notary")
side.amount = fixedn.Fixed8(cfg.GetInt64("notary.side.deposit_amount"))
side.duration = cfg.GetUint32("timers.side_notary") side.duration = cfg.GetUint32("timers.side_notary")
return return

View file

@ -16,6 +16,14 @@ func (np *Processor) processNewEpoch(epoch uint64) {
zap.String("error", err.Error())) zap.String("error", err.Error()))
} }
epochDuration, err := np.netmapClient.EpochDuration()
if err != nil {
np.log.Warn("can't get epoch duration",
zap.String("error", err.Error()))
} else {
np.epochState.SetEpochDuration(epochDuration)
}
// get new netmap snapshot // get new netmap snapshot
networkMap, err := np.netmapClient.Snapshot() networkMap, err := np.netmapClient.Snapshot()
if err != nil { if err != nil {

View file

@ -24,6 +24,8 @@ type (
EpochState interface { EpochState interface {
SetEpochCounter(uint64) SetEpochCounter(uint64)
EpochCounter() uint64 EpochCounter() uint64
SetEpochDuration(uint64)
EpochDuration() uint64
} }
// AlphabetState is a callback interface for inner ring global state. // AlphabetState is a callback interface for inner ring global state.

View file

@ -31,6 +31,17 @@ func (s *Server) SetEpochCounter(val uint64) {
s.epochCounter.Store(val) s.epochCounter.Store(val)
} }
// EpochDuration is a getter for a global epoch duration.
func (s *Server) EpochDuration() uint64 {
return s.epochDuration.Load()
}
// SetEpochDuration is a setter for the Netmap processor to update global
// epoch duration.
func (s *Server) SetEpochDuration(val uint64) {
s.epochDuration.Store(val)
}
// IsActive is a getter for a global active flag state. // IsActive is a getter for a global active flag state.
func (s *Server) IsActive() bool { func (s *Server) IsActive() bool {
return s.InnerRingIndex() >= 0 return s.InnerRingIndex() >= 0