frostfs-node/pkg/innerring/audit.go
Alex Vanin 6848a816f9 [#355] innerring: Refactor block timer constructors
This small refactoring adds `blocktimer.go` file with
all timer related function and constructors. This way
we can create all timers in one place (at the end of
innerring.Server constructor).

To do that we had to move timer reset into global
server state so it can be accessed by netmap
processor.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
2021-01-29 11:23:37 +03:00

204 lines
4.9 KiB
Go

package innerring
import (
"context"
"math/big"
auditAPI "github.com/nspcc-dev/neofs-api-go/pkg/audit"
containerAPI "github.com/nspcc-dev/neofs-api-go/pkg/container"
netmapAPI "github.com/nspcc-dev/neofs-api-go/pkg/netmap"
"github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/pkg/storagegroup"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement/audit"
auditClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/audit/wrapper"
balanceClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance/wrapper"
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
"github.com/pkg/errors"
"go.uber.org/zap"
)
type auditSettlementDeps struct {
log *logger.Logger
cnrSrc container.Source
auditClient *auditClient.ClientWrapper
nmSrc netmap.Source
clientCache *ClientCache
balanceClient *balanceClient.Wrapper
}
type auditSettlementCalculator audit.Calculator
type containerWrapper containerAPI.Container
type nodeInfoWrapper struct {
ni *netmapAPI.Node
}
type sgWrapper storagegroup.StorageGroup
func (s *sgWrapper) Size() uint64 {
return (*storagegroup.StorageGroup)(s).ValidationDataSize()
}
func (n nodeInfoWrapper) PublicKey() []byte {
return n.ni.PublicKey()
}
func (n nodeInfoWrapper) Price() *big.Int {
return big.NewInt(int64(n.ni.Price))
}
func (c *containerWrapper) Owner() *owner.ID {
return (*containerAPI.Container)(c).OwnerID()
}
func (a auditSettlementDeps) AuditResultsForEpoch(epoch uint64) ([]*auditAPI.Result, error) {
idList, err := a.auditClient.ListAuditResultIDByEpoch(epoch)
if err != nil {
return nil, errors.Wrap(err, "could not list audit results in sidechain")
}
res := make([]*auditAPI.Result, 0, len(idList))
for i := range idList {
r, err := a.auditClient.GetAuditResult(idList[i])
if err != nil {
return nil, errors.Wrap(err, "could not get audit result")
}
res = append(res, r)
}
return res, nil
}
func (a auditSettlementDeps) ContainerInfo(cid *containerAPI.ID) (audit.ContainerInfo, error) {
cnr, err := a.cnrSrc.Get(cid)
if err != nil {
return nil, errors.Wrap(err, "could not get container from storage")
}
return (*containerWrapper)(cnr), nil
}
func (a auditSettlementDeps) buildContainer(e uint64, cid *containerAPI.ID) (netmapAPI.ContainerNodes, *netmapAPI.Netmap, error) {
var (
nm *netmapAPI.Netmap
err error
)
if e > 0 {
nm, err = a.nmSrc.GetNetMapByEpoch(e)
} else {
nm, err = netmap.GetLatestNetworkMap(a.nmSrc)
}
if err != nil {
return nil, nil, errors.Wrap(err, "could not get network map from storage")
}
cnr, err := a.cnrSrc.Get(cid)
if err != nil {
return nil, nil, errors.Wrap(err, "could not get container from sidechain")
}
cn, err := nm.GetContainerNodes(
cnr.PlacementPolicy(),
cid.ToV2().GetValue(), // may be replace pivot calculation to neofs-api-go
)
if err != nil {
return nil, nil, errors.Wrap(err, "could not calculate container nodes")
}
return cn, nm, nil
}
func (a auditSettlementDeps) ContainerNodes(e uint64, cid *containerAPI.ID) ([]audit.NodeInfo, error) {
cn, _, err := a.buildContainer(e, cid)
if err != nil {
return nil, err
}
ns := cn.Flatten()
res := make([]audit.NodeInfo, 0, len(ns))
for i := range ns {
res = append(res, &nodeInfoWrapper{
ni: ns[i],
})
}
return res, nil
}
func (a auditSettlementDeps) SGInfo(addr *object.Address) (audit.SGInfo, error) {
cn, nm, err := a.buildContainer(0, addr.ContainerID())
if err != nil {
return nil, err
}
sg, err := a.clientCache.getSG(context.Background(), addr, nm, cn)
if err != nil {
return nil, err
}
return (*sgWrapper)(sg), nil
}
func (a auditSettlementDeps) ResolveKey(ni audit.NodeInfo) (*owner.ID, error) {
w, err := owner.NEO3WalletFromPublicKey(crypto.UnmarshalPublicKey(ni.PublicKey()))
if err != nil {
return nil, err
}
id := owner.NewID()
id.SetNeo3Wallet(w)
return id, nil
}
var transferAuditDetails = []byte("settlement-audit")
func (a auditSettlementDeps) Transfer(sender, recipient *owner.ID, amount *big.Int) {
log := a.log.With(
zap.Stringer("sender", sender),
zap.Stringer("recipient", recipient),
zap.Stringer("amount (GASe-12)", amount),
)
if !amount.IsInt64() {
a.log.Error("amount can not be represented as an int64")
return
}
if err := a.balanceClient.TransferX(balanceClient.TransferPrm{
Amount: amount.Int64(),
From: sender,
To: recipient,
Details: transferAuditDetails,
}); err != nil {
log.Error("could not send transfer transaction for audit",
zap.String("error", err.Error()),
)
return
}
log.Debug("transfer transaction for audit was successfully sent")
}
func (s *auditSettlementCalculator) ProcessAuditSettlements(epoch uint64) {
(*audit.Calculator)(s).Calculate(&audit.CalculatePrm{
Epoch: epoch,
})
}