From e5748bfc967756e994fa54ae13c7fa74d02f7cbe Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Mon, 11 Oct 2021 20:09:52 +0300 Subject: [PATCH] [#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 --- pkg/innerring/innerring.go | 10 ++++- pkg/innerring/notary.go | 38 ++++++++++++++----- .../processors/netmap/process_epoch.go | 8 ++++ pkg/innerring/processors/netmap/processor.go | 2 + pkg/innerring/state.go | 11 ++++++ 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index deb37a240..ae2e695bb 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -69,6 +69,7 @@ type ( morphClient *client.Client mainnetClient *client.Client epochCounter atomic.Uint64 + epochDuration atomic.Uint64 statusIndex *innerRingIndexer precision precision.Fixed8Converter auditClient *auditWrapper.ClientWrapper @@ -961,7 +962,13 @@ func (s *Server) initConfigFromBlockchain() error { // get current epoch epoch, err := s.netmapClient.Epoch() 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 @@ -977,6 +984,7 @@ func (s *Server) initConfigFromBlockchain() error { } s.epochCounter.Store(epoch) + s.epochDuration.Store(epochDuration) s.precision.SetBalancePrecision(balancePrecision) s.log.Debug("read config from blockchain", diff --git a/pkg/innerring/notary.go b/pkg/innerring/notary.go index 6c5468253..f43a302d2 100644 --- a/pkg/innerring/notary.go +++ b/pkg/innerring/notary.go @@ -2,8 +2,8 @@ package innerring import ( "context" + "fmt" - "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" @@ -11,23 +11,43 @@ import ( 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 + duration uint32 // lifetime of notary deposit in blocks + 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( - s.mainNotaryConfig.amount, - s.mainNotaryConfig.duration+notaryExtraBlocks, + 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.DepositNotary( - s.sideNotaryConfig.amount, - s.sideNotaryConfig.duration+notaryExtraBlocks, + depositAmount, + uint32(s.epochDuration.Load())+notaryExtraBlocks, ) } @@ -85,10 +105,8 @@ func parseNotaryConfigs(cfg *viper.Viper, withSideNotary, withMainNotary bool) ( } main.disabled = !withMainNotary - 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 diff --git a/pkg/innerring/processors/netmap/process_epoch.go b/pkg/innerring/processors/netmap/process_epoch.go index 1a94542f5..9854936a1 100644 --- a/pkg/innerring/processors/netmap/process_epoch.go +++ b/pkg/innerring/processors/netmap/process_epoch.go @@ -16,6 +16,14 @@ func (np *Processor) processNewEpoch(epoch uint64) { 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 networkMap, err := np.netmapClient.Snapshot() if err != nil { diff --git a/pkg/innerring/processors/netmap/processor.go b/pkg/innerring/processors/netmap/processor.go index a8f090d76..c4e7bd848 100644 --- a/pkg/innerring/processors/netmap/processor.go +++ b/pkg/innerring/processors/netmap/processor.go @@ -24,6 +24,8 @@ type ( EpochState interface { SetEpochCounter(uint64) EpochCounter() uint64 + SetEpochDuration(uint64) + EpochDuration() uint64 } // AlphabetState is a callback interface for inner ring global state. diff --git a/pkg/innerring/state.go b/pkg/innerring/state.go index e0750f032..368de8051 100644 --- a/pkg/innerring/state.go +++ b/pkg/innerring/state.go @@ -31,6 +31,17 @@ func (s *Server) SetEpochCounter(val uint64) { 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. func (s *Server) IsActive() bool { return s.InnerRingIndex() >= 0