[#465] settlement: Use unified details format for all asset transfers
Unified format uses transfer type as the first byte and extra details next. List of transfer types used in contracts defined in `details.go`. It includes: - audit settlement, - basic income collection, - basic income distribution. Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
1d68e74636
commit
3e9c578e62
9 changed files with 75 additions and 29 deletions
|
@ -387,13 +387,13 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
||||||
|
|
||||||
// create settlement processor dependencies
|
// create settlement processor dependencies
|
||||||
settlementDeps := &settlementDeps{
|
settlementDeps := &settlementDeps{
|
||||||
|
globalConfig: globalConfig,
|
||||||
log: server.log,
|
log: server.log,
|
||||||
cnrSrc: cnrClient,
|
cnrSrc: cnrClient,
|
||||||
auditClient: server.auditClient,
|
auditClient: server.auditClient,
|
||||||
nmSrc: nmClient,
|
nmSrc: nmClient,
|
||||||
clientCache: clientCache,
|
clientCache: clientCache,
|
||||||
balanceClient: balClient,
|
balanceClient: balClient,
|
||||||
cfg: globalConfig,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auditCalcDeps := &auditSettlementDeps{
|
auditCalcDeps := &auditSettlementDeps{
|
||||||
|
|
|
@ -65,8 +65,9 @@ func (c *Calculator) Calculate(p *CalculatePrm) {
|
||||||
log.Info("calculate audit settlements")
|
log.Info("calculate audit settlements")
|
||||||
|
|
||||||
log.Debug("getting results for the previous epoch")
|
log.Debug("getting results for the previous epoch")
|
||||||
|
prevEpoch := p.Epoch - 1
|
||||||
|
|
||||||
auditResults, err := c.prm.ResultStorage.AuditResultsForEpoch(p.Epoch - 1)
|
auditResults, err := c.prm.ResultStorage.AuditResultsForEpoch(prevEpoch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("could not collect audit results")
|
log.Error("could not collect audit results")
|
||||||
return
|
return
|
||||||
|
@ -99,7 +100,7 @@ func (c *Calculator) Calculate(p *CalculatePrm) {
|
||||||
|
|
||||||
log.Debug("processing transfers")
|
log.Debug("processing transfers")
|
||||||
|
|
||||||
common.TransferAssets(c.prm.Exchanger, table)
|
common.TransferAssets(c.prm.Exchanger, table, common.AuditSettlementDetails(prevEpoch))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Calculator) processResult(ctx *singleResultCtx) {
|
func (c *Calculator) processResult(ctx *singleResultCtx) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ func (inc *IncomeSettlementContext) Collect() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
common.TransferAssets(inc.exchange, txTable)
|
common.TransferAssets(inc.exchange, txTable, common.BasicIncomeCollectionDetails(inc.epoch))
|
||||||
}
|
}
|
||||||
|
|
||||||
// avgEstimation returns estimation value for single container. Right now it
|
// avgEstimation returns estimation value for single container. Right now it
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (inc *IncomeSettlementContext) Distribute() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
common.TransferAssets(inc.exchange, txTable)
|
common.TransferAssets(inc.exchange, txTable, common.BasicIncomeDistributionDetails(inc.epoch))
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizedValue(n, total, limit *big.Int) *big.Int {
|
func normalizedValue(n, total, limit *big.Int) *big.Int {
|
||||||
|
|
33
pkg/innerring/processors/settlement/common/details.go
Normal file
33
pkg/innerring/processors/settlement/common/details.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
auditPrefix = []byte{0x40}
|
||||||
|
basicIncomeCollectionPrefix = []byte{0x41}
|
||||||
|
basicIncomeDistributionPrefix = []byte{0x42}
|
||||||
|
)
|
||||||
|
|
||||||
|
func AuditSettlementDetails(epoch uint64) []byte {
|
||||||
|
return details(auditPrefix, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BasicIncomeCollectionDetails(epoch uint64) []byte {
|
||||||
|
return details(basicIncomeCollectionPrefix, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BasicIncomeDistributionDetails(epoch uint64) []byte {
|
||||||
|
return details(basicIncomeDistributionPrefix, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func details(prefix []byte, epoch uint64) []byte {
|
||||||
|
prefixLen := len(prefix)
|
||||||
|
buf := make([]byte, prefixLen+8)
|
||||||
|
|
||||||
|
copy(buf, prefix)
|
||||||
|
binary.LittleEndian.PutUint64(buf[prefixLen:], epoch)
|
||||||
|
|
||||||
|
return buf
|
||||||
|
}
|
28
pkg/innerring/processors/settlement/common/details_test.go
Normal file
28
pkg/innerring/processors/settlement/common/details_test.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAuditSettlementDetails(t *testing.T) {
|
||||||
|
var n uint64 = 1994 // 0x7CA
|
||||||
|
exp := []byte{0x40, 0xCA, 0x07, 0, 0, 0, 0, 0, 0}
|
||||||
|
got := AuditSettlementDetails(n)
|
||||||
|
require.Equal(t, exp, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBasicIncomeCollectionDetails(t *testing.T) {
|
||||||
|
var n uint64 = 1994 // 0x7CA
|
||||||
|
exp := []byte{0x41, 0xCA, 0x07, 0, 0, 0, 0, 0, 0}
|
||||||
|
got := BasicIncomeCollectionDetails(n)
|
||||||
|
require.Equal(t, exp, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBasicIncomeDistributionDetails(t *testing.T) {
|
||||||
|
var n uint64 = 1994 // 0x7CA
|
||||||
|
exp := []byte{0x42, 0xCA, 0x07, 0, 0, 0, 0, 0, 0}
|
||||||
|
got := BasicIncomeDistributionDetails(n)
|
||||||
|
require.Equal(t, exp, got)
|
||||||
|
}
|
|
@ -50,5 +50,5 @@ type Exchanger interface {
|
||||||
// Must transfer amount of GASe-12 from sender to recipient.
|
// Must transfer amount of GASe-12 from sender to recipient.
|
||||||
//
|
//
|
||||||
// Amount must be positive.
|
// Amount must be positive.
|
||||||
Transfer(sender, recipient *owner.ID, amount *big.Int)
|
Transfer(sender, recipient *owner.ID, amount *big.Int, details []byte)
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ func (t *TransferTable) Iterate(f func(*TransferTx)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TransferAssets(e Exchanger, t *TransferTable) {
|
func TransferAssets(e Exchanger, t *TransferTable, details []byte) {
|
||||||
t.Iterate(func(tx *TransferTx) {
|
t.Iterate(func(tx *TransferTx) {
|
||||||
sign := tx.Amount.Sign()
|
sign := tx.Amount.Sign()
|
||||||
if sign == 0 {
|
if sign == 0 {
|
||||||
|
@ -68,6 +68,6 @@ func TransferAssets(e Exchanger, t *TransferTable) {
|
||||||
tx.Amount.Neg(tx.Amount)
|
tx.Amount.Neg(tx.Amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.Transfer(tx.From, tx.To, tx.Amount)
|
e.Transfer(tx.From, tx.To, tx.Amount, details)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ type globalConfig interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type settlementDeps struct {
|
type settlementDeps struct {
|
||||||
|
globalConfig
|
||||||
|
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
|
|
||||||
cnrSrc container.Source
|
cnrSrc container.Source
|
||||||
|
@ -43,8 +45,6 @@ type settlementDeps struct {
|
||||||
clientCache *ClientCache
|
clientCache *ClientCache
|
||||||
|
|
||||||
balanceClient *balanceClient.Wrapper
|
balanceClient *balanceClient.Wrapper
|
||||||
|
|
||||||
cfg globalConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type auditSettlementDeps struct {
|
type auditSettlementDeps struct {
|
||||||
|
@ -191,16 +191,12 @@ func (s settlementDeps) ResolveKey(ni common.NodeInfo) (*owner.ID, error) {
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
func (s settlementDeps) Transfer(sender, recipient *owner.ID, amount *big.Int, details []byte) {
|
||||||
transferAuditDetails = []byte("settlement-audit")
|
|
||||||
basicIncomeAuditDetails = []byte("settlement-basic-income")
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s settlementDeps) transfer(sender, recipient *owner.ID, amount *big.Int, details []byte) {
|
|
||||||
log := s.log.With(
|
log := s.log.With(
|
||||||
zap.Stringer("sender", sender),
|
zap.Stringer("sender", sender),
|
||||||
zap.Stringer("recipient", recipient),
|
zap.Stringer("recipient", recipient),
|
||||||
zap.Stringer("amount (GASe-12)", amount),
|
zap.Stringer("amount (GASe-12)", amount),
|
||||||
|
zap.String("details", hex.EncodeToString(details)),
|
||||||
)
|
)
|
||||||
|
|
||||||
if !amount.IsInt64() {
|
if !amount.IsInt64() {
|
||||||
|
@ -225,20 +221,8 @@ func (s settlementDeps) transfer(sender, recipient *owner.ID, amount *big.Int, d
|
||||||
log.Debug("transfer transaction for audit was successfully sent")
|
log.Debug("transfer transaction for audit was successfully sent")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a auditSettlementDeps) Transfer(sender, recipient *owner.ID, amount *big.Int) {
|
|
||||||
a.transfer(sender, recipient, amount, transferAuditDetails)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a auditSettlementDeps) AuditFee() (uint64, error) {
|
|
||||||
return a.cfg.AuditFee()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b basicIncomeSettlementDeps) Transfer(sender, recipient *owner.ID, amount *big.Int) {
|
|
||||||
b.transfer(sender, recipient, amount, basicIncomeAuditDetails)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b basicIncomeSettlementDeps) BasicRate() (uint64, error) {
|
func (b basicIncomeSettlementDeps) BasicRate() (uint64, error) {
|
||||||
return b.cfg.BasicIncomeRate()
|
return b.BasicIncomeRate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b basicIncomeSettlementDeps) Estimations(epoch uint64) ([]*wrapper.Estimations, error) {
|
func (b basicIncomeSettlementDeps) Estimations(epoch uint64) ([]*wrapper.Estimations, error) {
|
||||||
|
|
Loading…
Reference in a new issue