frostfs-node/pkg/innerring/processors/frostfs/processor.go

191 lines
5.6 KiB
Go
Raw Normal View History

package frostfs
2020-07-24 13:54:03 +00:00
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"
2020-07-24 13:54:03 +00:00
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/panjf2000/ants/v2"
)
type (
// EpochState is a callback interface for inner ring global state.
2020-07-24 13:54:03 +00:00
EpochState interface {
EpochCounter() uint64
}
// AlphabetState is a callback interface for inner ring global state.
AlphabetState interface {
IsAlphabet(context.Context) bool
2020-07-24 13:54:03 +00:00
}
// 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.
2020-07-24 13:54:03 +00:00
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
2020-07-24 13:54:03 +00:00
}
// 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
2020-07-24 13:54:03 +00:00
}
)
const (
depositNotification = "Deposit"
withdrawNotification = "Withdraw"
chequeNotification = "Cheque"
configNotification = "SetConfig"
2020-07-24 13:54:03 +00:00
)
// New creates frostfs mainnet contract processor instance.
2020-07-24 13:54:03 +00:00
func New(p *Params) (*Processor, error) {
switch {
case p.Log == nil:
return nil, errors.New("ir/frostfs: logger is not set")
2020-07-24 13:54:03 +00:00
case p.MorphClient == nil:
return nil, errors.New("ir/frostfs: neo:morph client is not set")
2020-07-24 13:54:03 +00:00
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")
2020-07-24 13:54:03 +00:00
}
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)
2020-07-24 13:54:03 +00:00
}
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{}
}
2020-07-24 13:54:03 +00:00
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,
2020-07-24 13:54:03 +00:00
}, nil
}
// ListenerNotificationHandlers for the 'event.Listener' event producer.
func (np *Processor) ListenerNotificationHandlers() []event.NotificationHandlerInfo {
var (
handlers = make([]event.NotificationHandlerInfo, 0, 6)
h event.NotificationHandlerInfo
)
h.SetScriptHash(np.frostfsContract)
2020-07-24 13:54:03 +00:00
// deposit handler
h.SetType(event.TypeFromString(depositNotification))
h.SetParser(frostfsEvent.ParseDeposit)
h.AddHandler(np.handleDeposit)
handlers = append(handlers, h)
2020-07-24 13:54:03 +00:00
// withdraw handler
h.SetType(event.TypeFromString(withdrawNotification))
h.SetParser(frostfsEvent.ParseWithdraw)
h.AddHandler(np.handleWithdraw)
handlers = append(handlers, h)
2020-07-24 13:54:03 +00:00
// cheque handler
h.SetType(event.TypeFromString(chequeNotification))
h.SetParser(frostfsEvent.ParseCheque)
h.AddHandler(np.handleCheque)
handlers = append(handlers, h)
2020-07-24 13:54:03 +00:00
// config handler
h.SetType(event.TypeFromString(configNotification))
h.SetParser(frostfsEvent.ParseConfig)
h.AddHandler(np.handleConfig)
handlers = append(handlers, h)
2020-07-24 13:54:03 +00:00
return handlers
}
// 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
}