forked from TrueCloudLab/frostfs-node
[#708] innerring: Synchronize initial epoch tick
When Inner Ring node starts, it should sync nearest epoch tick event based on the block of the latest epoch. Otherwise epoch ticking can be stopped, because ballots or notary transactions are valid for limited period of time. Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
67b3682348
commit
62efa3f098
1 changed files with 51 additions and 7 deletions
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/reputation"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement"
|
||||
auditSettlement "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement/audit"
|
||||
timerEvent "github.com/nspcc-dev/neofs-node/pkg/innerring/timers"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
auditWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/audit/wrapper"
|
||||
balanceWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance/wrapper"
|
||||
|
@ -79,10 +80,14 @@ type (
|
|||
sideNotaryConfig *notaryConfig
|
||||
|
||||
// internal variables
|
||||
key *keys.PrivateKey
|
||||
pubKey []byte
|
||||
contracts *contracts
|
||||
predefinedValidators keys.PublicKeys
|
||||
key *keys.PrivateKey
|
||||
pubKey []byte
|
||||
contracts *contracts
|
||||
predefinedValidators keys.PublicKeys
|
||||
initialEpochTickDelta uint32
|
||||
|
||||
// runtime processors
|
||||
netmapProcessor *netmap.Processor
|
||||
|
||||
workers []func(context.Context)
|
||||
|
||||
|
@ -201,6 +206,14 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) (err error) {
|
|||
zap.String("error", err.Error()))
|
||||
}
|
||||
|
||||
// tick initial epoch
|
||||
initialEpochTicker := timer.NewOneTickTimer(
|
||||
timer.StaticBlockMeter(s.initialEpochTickDelta),
|
||||
func() {
|
||||
s.netmapProcessor.HandleNewEpochTick(timerEvent.NewEpochTick{})
|
||||
})
|
||||
s.addBlockTimer(initialEpochTicker)
|
||||
|
||||
morphErr := make(chan error)
|
||||
mainnnetErr := make(chan error)
|
||||
|
||||
|
@ -564,7 +577,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
|||
}
|
||||
|
||||
// create netmap processor
|
||||
netmapProcessor, err := netmap.New(&netmap.Params{
|
||||
server.netmapProcessor, err = netmap.New(&netmap.Params{
|
||||
Log: log,
|
||||
PoolSize: cfg.GetInt("workers.netmap"),
|
||||
NetmapContract: server.contracts.netmap,
|
||||
|
@ -591,7 +604,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
err = bindMorphProcessor(netmapProcessor, server)
|
||||
err = bindMorphProcessor(server.netmapProcessor, server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -708,7 +721,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
|||
// initialize epoch timers
|
||||
server.epochTimer = newEpochTimer(&epochTimerArgs{
|
||||
l: server.log,
|
||||
nm: netmapProcessor,
|
||||
nm: server.netmapProcessor,
|
||||
cnrWrapper: cnrClient,
|
||||
epoch: server,
|
||||
epochDuration: globalConfig.EpochDuration,
|
||||
|
@ -966,6 +979,12 @@ func (s *Server) initConfigFromBlockchain() error {
|
|||
return fmt.Errorf("can't read balance contract precision: %w", err)
|
||||
}
|
||||
|
||||
// get next epoch delta tick
|
||||
s.initialEpochTickDelta, err = s.nextEpochBlockDelta()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.epochCounter.Store(epoch)
|
||||
s.precision.SetBalancePrecision(balancePrecision)
|
||||
|
||||
|
@ -974,11 +993,36 @@ func (s *Server) initConfigFromBlockchain() error {
|
|||
zap.Bool("alphabet", s.IsAlphabet()),
|
||||
zap.Uint64("epoch", epoch),
|
||||
zap.Uint32("precision", balancePrecision),
|
||||
zap.Uint32("init_epoch_tick_delta", s.initialEpochTickDelta),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) nextEpochBlockDelta() (uint32, error) {
|
||||
epochBlock, err := s.netmapClient.LastEpochBlock()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't read last epoch block: %w", err)
|
||||
}
|
||||
|
||||
blockHeight, err := s.morphClient.BlockCount()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't get side chain height: %w", err)
|
||||
}
|
||||
|
||||
epochDuration, err := s.netmapClient.EpochDuration()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't get epoch duration: %w", err)
|
||||
}
|
||||
|
||||
delta := uint32(epochDuration) + epochBlock
|
||||
if delta < blockHeight {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return delta - blockHeight, nil
|
||||
}
|
||||
|
||||
// onlyActiveHandler wrapper around event handler that executes it
|
||||
// only if inner ring node state is active.
|
||||
func (s *Server) onlyActiveEventHandler(f event.Handler) event.Handler {
|
||||
|
|
Loading…
Reference in a new issue