frostfs-node/pkg/innerring/processors/frostfs/processor.go
Evgenii Stratonikov b1614a284d
All checks were successful
Tests and linters / Run gofumpt (push) Successful in 1m26s
Tests and linters / Staticcheck (push) Successful in 3m21s
Vulncheck / Vulncheck (push) Successful in 3m36s
Build / Build Components (push) Successful in 3m58s
Tests and linters / Lint (push) Successful in 4m30s
Pre-commit hooks / Pre-commit (push) Successful in 4m35s
Tests and linters / Tests (push) Successful in 5m15s
Tests and linters / Tests with -race (push) Successful in 5m33s
Tests and linters / gopls check (push) Successful in 5m45s
[#1546] morph/event: Export NotificationHandlerInfo fields
Hiding them achieves nothing, as the struct has no methods and is not
used concurrently.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2024-12-11 07:39:49 +00:00

183 lines
5.5 KiB
Go

package frostfs
import (
"context"
"errors"
"fmt"
"sync"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/metrics"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance"
nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
frostfsEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/frostfs"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
lru "github.com/hashicorp/golang-lru/v2"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/panjf2000/ants/v2"
)
type (
// EpochState is a callback interface for inner ring global state.
EpochState interface {
EpochCounter() uint64
}
// AlphabetState is a callback interface for inner ring global state.
AlphabetState interface {
IsAlphabet(context.Context) bool
}
// PrecisionConverter converts balance amount values.
PrecisionConverter interface {
ToBalancePrecision(int64) int64
}
BalanceClient interface {
Mint(ctx context.Context, p balance.MintPrm) error
Lock(ctx context.Context, p balance.LockPrm) error
Burn(ctx context.Context, p balance.BurnPrm) error
}
NetmapClient interface {
SetConfig(ctx context.Context, p nmClient.SetConfigPrm) error
}
MorphClient interface {
GasBalance() (res int64, err error)
TransferGas(receiver util.Uint160, amount fixedn.Fixed8) error
}
// Processor of events produced by frostfs contract in main net.
Processor struct {
log *logger.Logger
metrics metrics.Register
pool *ants.Pool
frostfsContract util.Uint160
balanceClient BalanceClient
netmapClient NetmapClient
morphClient MorphClient
epochState EpochState
alphabetState AlphabetState
converter PrecisionConverter
mintEmitLock sync.Mutex
mintEmitCache *lru.Cache[string, uint64]
mintEmitThreshold uint64
mintEmitValue fixedn.Fixed8
gasBalanceThreshold int64
}
// Params of the processor constructor.
Params struct {
Log *logger.Logger
Metrics metrics.Register
PoolSize int
FrostFSContract util.Uint160
BalanceClient BalanceClient
NetmapClient NetmapClient
MorphClient MorphClient
EpochState EpochState
AlphabetState AlphabetState
Converter PrecisionConverter
MintEmitCacheSize int
MintEmitThreshold uint64 // in epochs
MintEmitValue fixedn.Fixed8
GasBalanceThreshold int64
}
)
const (
depositNotification = "Deposit"
withdrawNotification = "Withdraw"
chequeNotification = "Cheque"
configNotification = "SetConfig"
)
// New creates frostfs mainnet contract processor instance.
func New(p *Params) (*Processor, error) {
switch {
case p.Log == nil:
return nil, errors.New("ir/frostfs: logger is not set")
case p.MorphClient == nil:
return nil, errors.New("ir/frostfs: neo:morph client is not set")
case p.EpochState == nil:
return nil, errors.New("ir/frostfs: global state is not set")
case p.AlphabetState == nil:
return nil, errors.New("ir/frostfs: global state is not set")
case p.Converter == nil:
return nil, errors.New("ir/frostfs: balance precision converter is not set")
}
pool, err := ants.NewPool(p.PoolSize, ants.WithNonblocking(true))
if err != nil {
return nil, fmt.Errorf("ir/frostfs: can't create worker pool: %w", err)
}
lruCache, err := lru.New[string, uint64](p.MintEmitCacheSize)
if err != nil {
return nil, fmt.Errorf("ir/frostfs: can't create LRU cache for gas emission: %w", err)
}
metricsRegister := p.Metrics
if metricsRegister == nil {
metricsRegister = metrics.DefaultRegister{}
}
return &Processor{
log: p.Log,
metrics: metricsRegister,
pool: pool,
frostfsContract: p.FrostFSContract,
balanceClient: p.BalanceClient,
netmapClient: p.NetmapClient,
morphClient: p.MorphClient,
epochState: p.EpochState,
alphabetState: p.AlphabetState,
converter: p.Converter,
mintEmitCache: lruCache,
mintEmitThreshold: p.MintEmitThreshold,
mintEmitValue: p.MintEmitValue,
gasBalanceThreshold: p.GasBalanceThreshold,
}, nil
}
// ListenerNotificationHandlers for the 'event.Listener' event producer.
func (np *Processor) ListenerNotificationHandlers() []event.NotificationHandlerInfo {
return []event.NotificationHandlerInfo{
{
Contract: np.frostfsContract,
Type: event.TypeFromString(depositNotification),
Parser: frostfsEvent.ParseDeposit,
Handlers: []event.Handler{np.handleDeposit},
},
{
Contract: np.frostfsContract,
Type: event.TypeFromString(withdrawNotification),
Parser: frostfsEvent.ParseWithdraw,
Handlers: []event.Handler{np.handleWithdraw},
},
{
Contract: np.frostfsContract,
Type: event.TypeFromString(chequeNotification),
Parser: frostfsEvent.ParseCheque,
Handlers: []event.Handler{np.handleCheque},
},
{
Contract: np.frostfsContract,
Type: event.TypeFromString(configNotification),
Parser: frostfsEvent.ParseConfig,
Handlers: []event.Handler{np.handleConfig},
},
}
}
// ListenerNotaryParsers for the 'event.Listener' event producer.
func (np *Processor) ListenerNotaryParsers() []event.NotaryParserInfo {
return nil
}
// ListenerNotaryHandlers for the 'event.Listener' event producer.
func (np *Processor) ListenerNotaryHandlers() []event.NotaryHandlerInfo {
return nil
}