Remove container estimation code #1475
13 changed files with 9 additions and 499 deletions
|
@ -17,8 +17,6 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
InnerringNonalphabetModeDoNotStopContainerEstimations = "non-alphabet mode, do not stop container estimations"
|
||||
InnerringCantStopEpochEstimation = "can't stop epoch estimation"
|
||||
InnerringCantMakeNotaryDepositInMainChain = "can't make notary deposit in main chain"
|
||||
InnerringCantMakeNotaryDepositInSideChain = "can't make notary deposit in side chain"
|
||||
InnerringNotaryDepositHasAlreadyBeenMade = "notary deposit has already been made"
|
||||
|
@ -343,7 +341,6 @@ const (
|
|||
NetmapCantGetTransactionHeight = "can't get transaction height"
|
||||
NetmapCantResetEpochTimer = "can't reset epoch timer"
|
||||
NetmapCantGetNetmapSnapshotToPerformCleanup = "can't get netmap snapshot to perform cleanup"
|
||||
NetmapCantStartContainerSizeEstimation = "can't start container size estimation"
|
||||
NetmapNonAlphabetModeIgnoreNewEpochTick = "non alphabet mode, ignore new epoch tick"
|
||||
NetmapNextEpoch = "next epoch"
|
||||
NetmapCantInvokeNetmapNewEpoch = "can't invoke netmap.NewEpoch"
|
||||
|
|
|
@ -3,14 +3,10 @@ package innerring
|
|||
import (
|
||||
"context"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/alphabet"
|
||||
timerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/timers"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/timer"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -19,28 +15,12 @@ type (
|
|||
EpochDuration() uint64
|
||||
}
|
||||
|
||||
alphaState interface {
|
||||
IsAlphabet() bool
|
||||
}
|
||||
|
||||
newEpochHandler func()
|
||||
|
||||
containerEstimationStopper interface {
|
||||
StopEstimation(p container.StopEstimationPrm) error
|
||||
}
|
||||
|
||||
epochTimerArgs struct {
|
||||
l *logger.Logger
|
||||
|
||||
alphabetState alphaState
|
||||
|
||||
newEpochHandlers []newEpochHandler
|
||||
|
||||
cnrWrapper containerEstimationStopper // to invoke stop container estimation
|
||||
epoch epochState // to specify which epoch to stop, and epoch duration
|
||||
|
||||
stopEstimationDMul uint32 // X: X/Y of epoch in blocks
|
||||
stopEstimationDDiv uint32 // Y: X/Y of epoch in blocks
|
||||
epoch epochState // to specify which epoch to stop, and epoch duration
|
||||
}
|
||||
|
||||
emitTimerArgs struct {
|
||||
|
@ -74,7 +54,7 @@ func (s *Server) tickTimers(h uint32) {
|
|||
}
|
||||
|
||||
func newEpochTimer(args *epochTimerArgs) *timer.BlockTimer {
|
||||
epochTimer := timer.NewBlockTimer(
|
||||
return timer.NewBlockTimer(
|
||||
func() (uint32, error) {
|
||||
return uint32(args.epoch.EpochDuration()), nil
|
||||
},
|
||||
|
@ -84,35 +64,6 @@ func newEpochTimer(args *epochTimerArgs) *timer.BlockTimer {
|
|||
}
|
||||
},
|
||||
)
|
||||
|
||||
// sub-timer for epoch timer to tick stop container estimation events at
|
||||
// some block in epoch
|
||||
epochTimer.OnDelta(
|
||||
args.stopEstimationDMul,
|
||||
args.stopEstimationDDiv,
|
||||
func() {
|
||||
if !args.alphabetState.IsAlphabet() {
|
||||
args.l.Debug(logs.InnerringNonalphabetModeDoNotStopContainerEstimations)
|
||||
return
|
||||
}
|
||||
|
||||
epochN := args.epoch.EpochCounter()
|
||||
if epochN == 0 { // estimates are invalid in genesis epoch
|
||||
return
|
||||
}
|
||||
|
||||
prm := container.StopEstimationPrm{}
|
||||
prm.SetEpoch(epochN - 1)
|
||||
|
||||
err := args.cnrWrapper.StopEstimation(prm)
|
||||
if err != nil {
|
||||
args.l.Warn(logs.InnerringCantStopEpochEstimation,
|
||||
zap.Uint64("epoch", epochN),
|
||||
zap.String("error", err.Error()))
|
||||
}
|
||||
})
|
||||
|
||||
return epochTimer
|
||||
}
|
||||
|
||||
func newEmissionTimer(args *emitTimerArgs) *timer.BlockTimer {
|
||||
|
|
|
@ -3,29 +3,20 @@ package innerring
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEpochTimer(t *testing.T) {
|
||||
t.Parallel()
|
||||
alphaState := &testAlphabetState{isAlphabet: true}
|
||||
neh := &testNewEpochHandler{}
|
||||
cnrStopper := &testContainerEstStopper{}
|
||||
epochState := &testEpochState{
|
||||
counter: 99,
|
||||
duration: 10,
|
||||
}
|
||||
|
||||
args := &epochTimerArgs{
|
||||
l: test.NewLogger(t),
|
||||
alphabetState: alphaState,
|
||||
newEpochHandlers: []newEpochHandler{neh.Handle},
|
||||
cnrWrapper: cnrStopper,
|
||||
epoch: epochState,
|
||||
stopEstimationDMul: 2,
|
||||
stopEstimationDDiv: 10,
|
||||
newEpochHandlers: []newEpochHandler{neh.Handle},
|
||||
epoch: epochState,
|
||||
}
|
||||
et := newEpochTimer(args)
|
||||
err := et.Reset()
|
||||
|
@ -33,63 +24,43 @@ func TestEpochTimer(t *testing.T) {
|
|||
|
||||
et.Tick(100)
|
||||
require.Equal(t, 0, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 0, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
et.Tick(101)
|
||||
require.Equal(t, 0, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
et.Tick(102)
|
||||
require.Equal(t, 0, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
et.Tick(103)
|
||||
require.Equal(t, 0, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
var h uint32
|
||||
for h = 104; h < 109; h++ {
|
||||
et.Tick(h)
|
||||
require.Equal(t, 0, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls")
|
||||
}
|
||||
|
||||
et.Tick(109)
|
||||
require.Equal(t, 1, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
et.Tick(110)
|
||||
require.Equal(t, 1, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 1, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
et.Tick(111)
|
||||
require.Equal(t, 1, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
et.Tick(112)
|
||||
require.Equal(t, 1, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
et.Tick(113)
|
||||
require.Equal(t, 1, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls")
|
||||
|
||||
for h = 114; h < 119; h++ {
|
||||
et.Tick(h)
|
||||
require.Equal(t, 1, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls")
|
||||
}
|
||||
et.Tick(120)
|
||||
require.Equal(t, 2, neh.called, "invalid new epoch handler calls")
|
||||
require.Equal(t, 2, cnrStopper.called, "invalid container stop handler calls")
|
||||
}
|
||||
|
||||
type testAlphabetState struct {
|
||||
isAlphabet bool
|
||||
}
|
||||
|
||||
func (s *testAlphabetState) IsAlphabet() bool {
|
||||
return s.isAlphabet
|
||||
}
|
||||
|
||||
type testNewEpochHandler struct {
|
||||
|
@ -100,15 +71,6 @@ func (h *testNewEpochHandler) Handle() {
|
|||
h.called++
|
||||
}
|
||||
|
||||
type testContainerEstStopper struct {
|
||||
called int
|
||||
}
|
||||
|
||||
func (s *testContainerEstStopper) StopEstimation(_ container.StopEstimationPrm) error {
|
||||
s.called++
|
||||
return nil
|
||||
}
|
||||
|
||||
type testEpochState struct {
|
||||
counter uint64
|
||||
duration uint64
|
||||
|
|
|
@ -36,7 +36,6 @@ import (
|
|||
)
|
||||
|
||||
func (s *Server) initNetmapProcessor(cfg *viper.Viper,
|
||||
cnrClient *container.Client,
|
||||
alphaSync event.Handler,
|
||||
) error {
|
||||
locodeValidator, err := s.newLocodeValidator(cfg)
|
||||
|
@ -59,7 +58,6 @@ func (s *Server) initNetmapProcessor(cfg *viper.Viper,
|
|||
AlphabetState: s,
|
||||
CleanupEnabled: cfg.GetBool("netmap_cleaner.enabled"),
|
||||
CleanupThreshold: cfg.GetUint64("netmap_cleaner.threshold"),
|
||||
ContainerWrapper: cnrClient,
|
||||
NotaryDepositHandler: s.onlyAlphabetEventHandler(
|
||||
s.notaryHandler,
|
||||
),
|
||||
|
@ -198,15 +196,10 @@ func (s *Server) createIRFetcher() irFetcher {
|
|||
return irf
|
||||
}
|
||||
|
||||
func (s *Server) initTimers(cfg *viper.Viper, morphClients *serverMorphClients) {
|
||||
func (s *Server) initTimers(cfg *viper.Viper) {
|
||||
s.epochTimer = newEpochTimer(&epochTimerArgs{
|
||||
l: s.log,
|
||||
alphabetState: s,
|
||||
newEpochHandlers: s.newEpochTickHandlers(),
|
||||
cnrWrapper: morphClients.CnrClient,
|
||||
epoch: s,
|
||||
stopEstimationDMul: cfg.GetUint32("timers.stop_estimation.mul"),
|
||||
stopEstimationDDiv: cfg.GetUint32("timers.stop_estimation.div"),
|
||||
newEpochHandlers: s.newEpochTickHandlers(),
|
||||
epoch: s,
|
||||
})
|
||||
|
||||
s.addBlockTimer(s.epochTimer)
|
||||
|
@ -425,7 +418,7 @@ func (s *Server) initProcessors(cfg *viper.Viper, morphClients *serverMorphClien
|
|||
return err
|
||||
}
|
||||
|
||||
err = s.initNetmapProcessor(cfg, morphClients.CnrClient, alphaSync)
|
||||
err = s.initNetmapProcessor(cfg, alphaSync)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -405,7 +405,7 @@ func New(ctx context.Context, log *logger.Logger, cfg *viper.Viper, errChan chan
|
|||
return nil, err
|
||||
}
|
||||
|
||||
server.initTimers(cfg, morphClients)
|
||||
server.initTimers(cfg)
|
||||
|
||||
err = server.initGRPCServer(cfg, log, audit)
|
||||
if err != nil {
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
netmapContract "git.frostfs.info/TrueCloudLab/frostfs-contract/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/governance"
|
||||
timerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/timers"
|
||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
netmapclient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
netmapEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/netmap"
|
||||
|
@ -68,7 +67,6 @@ func TestNewEpoch(t *testing.T) {
|
|||
duration: 10,
|
||||
}
|
||||
r := &testEpochResetter{}
|
||||
cc := &testContainerClient{}
|
||||
nc := &testNetmapClient{
|
||||
epochDuration: 20,
|
||||
txHeights: map[util.Uint256]uint32{
|
||||
|
@ -82,7 +80,6 @@ func TestNewEpoch(t *testing.T) {
|
|||
p.NotaryDepositHandler = eh.Handle
|
||||
p.AlphabetSyncHandler = eh.Handle
|
||||
p.NetmapClient = nc
|
||||
p.ContainerWrapper = cc
|
||||
p.EpochTimer = r
|
||||
p.EpochState = es
|
||||
})
|
||||
|
@ -103,11 +100,6 @@ func TestNewEpoch(t *testing.T) {
|
|||
require.Equal(t, ev.Num, es.counter, "invalid epoch counter")
|
||||
require.EqualValues(t, []uint32{nc.txHeights[ev.Hash]}, r.timers, "invalid epoch timer resets")
|
||||
|
||||
var expEstimation cntClient.StartEstimationPrm
|
||||
expEstimation.SetEpoch(ev.Num - 1)
|
||||
expEstimation.SetHash(ev.Hash)
|
||||
require.EqualValues(t, []cntClient.StartEstimationPrm{expEstimation}, cc.estimations, "invalid estimations")
|
||||
|
||||
require.EqualValues(t, []event.Event{
|
||||
governance.NewSyncEvent(ev.TxHash()),
|
||||
ev,
|
||||
|
@ -274,7 +266,6 @@ func newTestProc(t *testing.T, nonDefault func(p *Params)) (*Processor, error) {
|
|||
as := &testAlphabetState{
|
||||
isAlphabet: true,
|
||||
}
|
||||
cc := &testContainerClient{}
|
||||
nc := &testNetmapClient{}
|
||||
eh := &testEventHandler{}
|
||||
|
||||
|
@ -288,7 +279,6 @@ func newTestProc(t *testing.T, nonDefault func(p *Params)) (*Processor, error) {
|
|||
EpochState: es,
|
||||
EpochTimer: r,
|
||||
AlphabetState: as,
|
||||
ContainerWrapper: cc,
|
||||
NetmapClient: nc,
|
||||
NotaryDepositHandler: eh.Handle,
|
||||
AlphabetSyncHandler: eh.Handle,
|
||||
|
@ -354,15 +344,6 @@ func (s *testAlphabetState) IsAlphabet() bool {
|
|||
return s.isAlphabet
|
||||
}
|
||||
|
||||
type testContainerClient struct {
|
||||
estimations []cntClient.StartEstimationPrm
|
||||
}
|
||||
|
||||
func (c *testContainerClient) StartEstimation(p cntClient.StartEstimationPrm) error {
|
||||
c.estimations = append(c.estimations, p)
|
||||
return nil
|
||||
}
|
||||
|
||||
type notaryInvoke struct {
|
||||
contract util.Uint160
|
||||
fee fixedn.Fixed8
|
||||
|
|
|
@ -3,7 +3,6 @@ package netmap
|
|||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/governance"
|
||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
netmapEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/netmap"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -44,20 +43,6 @@ func (np *Processor) processNewEpoch(ev netmapEvent.NewEpoch) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
prm := cntClient.StartEstimationPrm{}
|
||||
|
||||
prm.SetEpoch(epoch - 1)
|
||||
prm.SetHash(ev.TxHash())
|
||||
|
||||
if epoch > 0 && np.alphabetState.IsAlphabet() { // estimates are invalid in genesis epoch
|
||||
err = np.containerWrp.StartEstimation(prm)
|
||||
if err != nil {
|
||||
np.log.Warn(logs.NetmapCantStartContainerSizeEstimation,
|
||||
zap.Uint64("epoch", epoch),
|
||||
zap.String("error", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
np.netmapSnapshot.update(*networkMap, epoch)
|
||||
np.handleCleanupTick(netmapCleanupTick{epoch: epoch, txHash: ev.TxHash()})
|
||||
np.handleAlphabetSync(governance.NewSyncEvent(ev.TxHash()))
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/metrics"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/netmap/nodevalidation/state"
|
||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
netmapEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||
|
@ -65,10 +64,6 @@ type (
|
|||
MorphNotarySignAndInvokeTX(mainTx *transaction.Transaction) error
|
||||
}
|
||||
|
||||
ContainerClient interface {
|
||||
StartEstimation(p cntClient.StartEstimationPrm) error
|
||||
}
|
||||
|
||||
// Processor of events produced by network map contract
|
||||
// and new epoch ticker, because it is related to contract.
|
||||
Processor struct {
|
||||
|
@ -80,7 +75,6 @@ type (
|
|||
alphabetState AlphabetState
|
||||
|
||||
netmapClient Client
|
||||
containerWrp ContainerClient
|
||||
|
||||
netmapSnapshot cleanupTable
|
||||
|
||||
|
@ -103,7 +97,6 @@ type (
|
|||
AlphabetState AlphabetState
|
||||
CleanupEnabled bool
|
||||
CleanupThreshold uint64 // in epochs
|
||||
ContainerWrapper ContainerClient
|
||||
|
||||
AlphabetSyncHandler event.Handler
|
||||
NotaryDepositHandler event.Handler
|
||||
|
@ -133,8 +126,6 @@ func New(p *Params) (*Processor, error) {
|
|||
return nil, errors.New("ir/netmap: alphabet sync handler is not set")
|
||||
case p.NotaryDepositHandler == nil:
|
||||
return nil, errors.New("ir/netmap: notary deposit handler is not set")
|
||||
case p.ContainerWrapper == nil:
|
||||
return nil, errors.New("ir/netmap: container contract wrapper is not set")
|
||||
case p.NodeValidator == nil:
|
||||
return nil, errors.New("ir/netmap: node validator is not set")
|
||||
case p.NodeStateSettings == nil:
|
||||
|
@ -161,7 +152,6 @@ func New(p *Params) (*Processor, error) {
|
|||
epochState: p.EpochState,
|
||||
alphabetState: p.AlphabetState,
|
||||
netmapClient: p.NetmapClient,
|
||||
containerWrp: p.ContainerWrapper,
|
||||
netmapSnapshot: newCleanupTable(p.CleanupEnabled, p.CleanupThreshold),
|
||||
|
||||
handleAlphabetSync: p.AlphabetSyncHandler,
|
||||
|
|
|
@ -30,12 +30,6 @@ const (
|
|||
eaclMethod = "eACL"
|
||||
deletionInfoMethod = "deletionInfo"
|
||||
|
||||
startEstimationMethod = "startContainerEstimation"
|
||||
stopEstimationMethod = "stopContainerEstimation"
|
||||
|
||||
listSizesMethod = "listContainerSizes"
|
||||
getSizeMethod = "getContainerSize"
|
||||
|
||||
// putNamedMethod is method name for container put with an alias. It is exported to provide custom fee.
|
||||
putNamedMethod = "putNamed"
|
||||
)
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// StartEstimationPrm groups parameters of StartEstimation operation.
|
||||
type StartEstimationPrm struct {
|
||||
commonEstimationPrm
|
||||
}
|
||||
|
||||
// StopEstimationPrm groups parameters of StopEstimation operation.
|
||||
type StopEstimationPrm struct {
|
||||
commonEstimationPrm
|
||||
}
|
||||
|
||||
type commonEstimationPrm struct {
|
||||
epoch uint64
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetEpoch sets epoch.
|
||||
func (p *commonEstimationPrm) SetEpoch(epoch uint64) {
|
||||
p.epoch = epoch
|
||||
}
|
||||
|
||||
// StartEstimation votes to produce start estimation notification.
|
||||
func (c *Client) StartEstimation(p StartEstimationPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
prm.SetMethod(startEstimationMethod)
|
||||
prm.SetArgs(p.epoch)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
if _, err := c.client.Invoke(prm); err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", startEstimationMethod, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StopEstimation votes to produce stop estimation notification.
|
||||
func (c *Client) StopEstimation(p StopEstimationPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
prm.SetMethod(stopEstimationMethod)
|
||||
prm.SetArgs(p.epoch)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
if _, err := c.client.Invoke(prm); err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", stopEstimationMethod, err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v2refs "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
// EstimationID is an identity of container load estimation inside Container contract.
|
||||
type EstimationID []byte
|
||||
|
||||
// ListLoadEstimationsByEpoch returns a list of container load estimations for to the specified epoch.
|
||||
// The list is composed through Container contract call.
|
||||
func (c *Client) ListLoadEstimationsByEpoch(epoch uint64) ([]EstimationID, error) {
|
||||
invokePrm := client.TestInvokePrm{}
|
||||
invokePrm.SetMethod(listSizesMethod)
|
||||
invokePrm.SetArgs(epoch)
|
||||
|
||||
prms, err := c.client.TestInvoke(invokePrm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w", listSizesMethod, err)
|
||||
} else if ln := len(prms); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d", listSizesMethod, ln)
|
||||
}
|
||||
|
||||
prms, err = client.ArrayFromStackItem(prms[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", listSizesMethod, err)
|
||||
}
|
||||
|
||||
res := make([]EstimationID, 0, len(prms))
|
||||
for i := range prms {
|
||||
id, err := client.BytesFromStackItem(prms[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get ID byte array from stack item (%s): %w", listSizesMethod, err)
|
||||
}
|
||||
|
||||
res = append(res, id)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Estimation is a structure of single container load estimation
|
||||
// reported by storage node.
|
||||
type Estimation struct {
|
||||
Size uint64
|
||||
|
||||
Reporter []byte
|
||||
}
|
||||
|
||||
// Estimations is a structure of grouped container load estimation inside Container contract.
|
||||
type Estimations struct {
|
||||
ContainerID cid.ID
|
||||
|
||||
Values []Estimation
|
||||
}
|
||||
|
||||
// GetUsedSpaceEstimations returns a list of container load estimations by ID.
|
||||
// The list is composed through Container contract call.
|
||||
func (c *Client) GetUsedSpaceEstimations(id EstimationID) (*Estimations, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(getSizeMethod)
|
||||
prm.SetArgs([]byte(id))
|
||||
|
||||
prms, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w", getSizeMethod, err)
|
||||
} else if ln := len(prms); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d", getSizeMethod, ln)
|
||||
}
|
||||
|
||||
prms, err = client.ArrayFromStackItem(prms[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get stack items of estimation fields from stack item (%s): %w", getSizeMethod, err)
|
||||
} else if ln := len(prms); ln != 2 {
|
||||
return nil, fmt.Errorf("unexpected stack item count of estimations fields (%s)", getSizeMethod)
|
||||
}
|
||||
|
||||
rawCnr, err := client.BytesFromStackItem(prms[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get container ID byte array from stack item (%s): %w", getSizeMethod, err)
|
||||
}
|
||||
|
||||
prms, err = client.ArrayFromStackItem(prms[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get estimation list array from stack item (%s): %w", getSizeMethod, err)
|
||||
}
|
||||
|
||||
var cnr cid.ID
|
||||
|
||||
err = cnr.Decode(rawCnr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode container ID: %w", err)
|
||||
}
|
||||
|
||||
v2 := new(v2refs.ContainerID)
|
||||
v2.SetValue(rawCnr)
|
||||
res := &Estimations{
|
||||
ContainerID: cnr,
|
||||
Values: make([]Estimation, 0, len(prms)),
|
||||
}
|
||||
|
||||
for i := range prms {
|
||||
arr, err := client.ArrayFromStackItem(prms[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get estimation struct from stack item (%s): %w", getSizeMethod, err)
|
||||
} else if ln := len(arr); ln != 2 {
|
||||
return nil, fmt.Errorf("unexpected stack item count of estimation fields (%s)", getSizeMethod)
|
||||
}
|
||||
|
||||
reporter, err := client.BytesFromStackItem(arr[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get reporter byte array from stack item (%s): %w", getSizeMethod, err)
|
||||
}
|
||||
|
||||
sz, err := client.IntFromStackItem(arr[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get estimation size from stack item (%s): %w", getSizeMethod, err)
|
||||
}
|
||||
|
||||
res.Values = append(res.Values, Estimation{
|
||||
Reporter: reporter,
|
||||
Size: uint64(sz),
|
||||
})
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"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/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
// StartEstimation structure of container.StartEstimation notification from
|
||||
// morph chain.
|
||||
type StartEstimation struct {
|
||||
epoch uint64
|
||||
}
|
||||
|
||||
// StopEstimation structure of container.StopEstimation notification from
|
||||
// morph chain.
|
||||
type StopEstimation struct {
|
||||
epoch uint64
|
||||
}
|
||||
|
||||
// MorphEvent implements Neo:Morph Event interface.
|
||||
func (StartEstimation) MorphEvent() {}
|
||||
|
||||
// MorphEvent implements Neo:Morph Event interface.
|
||||
func (StopEstimation) MorphEvent() {}
|
||||
|
||||
// Epoch returns epoch value for which to start container size estimation.
|
||||
func (s StartEstimation) Epoch() uint64 { return s.epoch }
|
||||
|
||||
// Epoch returns epoch value for which to stop container size estimation.
|
||||
func (s StopEstimation) Epoch() uint64 { return s.epoch }
|
||||
|
||||
// ParseStartEstimation from notification into container event structure.
|
||||
func ParseStartEstimation(e *state.ContainedNotificationEvent) (event.Event, error) {
|
||||
params, err := event.ParseStackArray(e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse stack items from notify event: %w", err)
|
||||
}
|
||||
|
||||
epoch, err := parseEstimation(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return StartEstimation{epoch: epoch}, nil
|
||||
}
|
||||
|
||||
// ParseStopEstimation from notification into container event structure.
|
||||
func ParseStopEstimation(e *state.ContainedNotificationEvent) (event.Event, error) {
|
||||
params, err := event.ParseStackArray(e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse stack items from notify event: %w", err)
|
||||
}
|
||||
|
||||
epoch, err := parseEstimation(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return StopEstimation{epoch: epoch}, nil
|
||||
}
|
||||
|
||||
func parseEstimation(params []stackitem.Item) (uint64, error) {
|
||||
if ln := len(params); ln != 1 {
|
||||
return 0, event.WrongNumberOfParameters(1, ln)
|
||||
}
|
||||
|
||||
// parse container
|
||||
epoch, err := client.IntFromStackItem(params[0])
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not get estimation epoch: %w", err)
|
||||
}
|
||||
|
||||
return uint64(epoch), nil
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStartEstimation(t *testing.T) {
|
||||
var epochNum uint64 = 100
|
||||
epochItem := stackitem.NewBigInteger(new(big.Int).SetUint64(epochNum))
|
||||
|
||||
t.Run("wrong number of parameters", func(t *testing.T) {
|
||||
prms := []stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
stackitem.NewMap(),
|
||||
}
|
||||
|
||||
_, err := ParseStartEstimation(createNotifyEventFromItems(prms))
|
||||
require.EqualError(t, err, event.WrongNumberOfParameters(1, len(prms)).Error())
|
||||
})
|
||||
|
||||
t.Run("wrong estimation parameter", func(t *testing.T) {
|
||||
_, err := ParseStartEstimation(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("correct behavior", func(t *testing.T) {
|
||||
ev, err := ParseStartEstimation(createNotifyEventFromItems([]stackitem.Item{
|
||||
epochItem,
|
||||
}))
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, StartEstimation{
|
||||
epochNum,
|
||||
}, ev)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStopEstimation(t *testing.T) {
|
||||
var epochNum uint64 = 100
|
||||
epochItem := stackitem.NewBigInteger(new(big.Int).SetUint64(epochNum))
|
||||
|
||||
t.Run("wrong number of parameters", func(t *testing.T) {
|
||||
prms := []stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
stackitem.NewMap(),
|
||||
}
|
||||
|
||||
_, err := ParseStopEstimation(createNotifyEventFromItems(prms))
|
||||
require.EqualError(t, err, event.WrongNumberOfParameters(1, len(prms)).Error())
|
||||
})
|
||||
|
||||
t.Run("wrong estimation parameter", func(t *testing.T) {
|
||||
_, err := ParseStopEstimation(createNotifyEventFromItems([]stackitem.Item{
|
||||
stackitem.NewMap(),
|
||||
}))
|
||||
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("correct behavior", func(t *testing.T) {
|
||||
ev, err := ParseStopEstimation(createNotifyEventFromItems([]stackitem.Item{
|
||||
epochItem,
|
||||
}))
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, StopEstimation{
|
||||
epochNum,
|
||||
}, ev)
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue