2021-02-01 16:17:16 +00:00
|
|
|
package basic
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/big"
|
|
|
|
|
2023-04-12 14:35:10 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
2023-03-07 13:38:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/settlement/common"
|
|
|
|
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
2021-02-01 16:17:16 +00:00
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
bigGB = big.NewInt(1 << 30)
|
|
|
|
bigZero = big.NewInt(0)
|
|
|
|
bigOne = big.NewInt(1)
|
|
|
|
)
|
|
|
|
|
|
|
|
func (inc *IncomeSettlementContext) Collect() {
|
|
|
|
inc.mu.Lock()
|
|
|
|
defer inc.mu.Unlock()
|
|
|
|
|
2021-02-02 11:12:41 +00:00
|
|
|
cachedRate, err := inc.rate.BasicRate()
|
|
|
|
if err != nil {
|
2023-04-12 14:35:10 +00:00
|
|
|
inc.log.Error(logs.BasicCantGetBasicIncomeRate,
|
2021-02-02 11:12:41 +00:00
|
|
|
zap.String("error", err.Error()))
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2021-02-01 16:17:16 +00:00
|
|
|
|
2023-03-20 17:36:07 +00:00
|
|
|
if cachedRate == 0 {
|
|
|
|
inc.noop = true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-01 16:17:16 +00:00
|
|
|
cnrEstimations, err := inc.estimations.Estimations(inc.epoch)
|
|
|
|
if err != nil {
|
2023-04-12 14:35:10 +00:00
|
|
|
inc.log.Error(logs.BasicCantFetchContainerSizeEstimations,
|
2022-06-07 11:06:10 +00:00
|
|
|
zap.Uint64("epoch", inc.epoch),
|
|
|
|
zap.String("error", err.Error()))
|
2021-02-01 16:17:16 +00:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-02 17:39:41 +00:00
|
|
|
txTable := common.NewTransferTable()
|
|
|
|
|
2021-02-01 16:17:16 +00:00
|
|
|
for i := range cnrEstimations {
|
|
|
|
owner, err := inc.container.ContainerInfo(cnrEstimations[i].ContainerID)
|
|
|
|
if err != nil {
|
2023-04-12 14:35:10 +00:00
|
|
|
inc.log.Warn(logs.BasicCantFetchContainerInfo,
|
2021-02-01 16:17:16 +00:00
|
|
|
zap.Uint64("epoch", inc.epoch),
|
2022-05-31 17:00:41 +00:00
|
|
|
zap.Stringer("container_id", cnrEstimations[i].ContainerID),
|
2022-06-07 11:06:10 +00:00
|
|
|
zap.String("error", err.Error()))
|
2021-02-01 16:17:16 +00:00
|
|
|
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
cnrNodes, err := inc.placement.ContainerNodes(inc.epoch, cnrEstimations[i].ContainerID)
|
|
|
|
if err != nil {
|
2023-04-12 14:35:10 +00:00
|
|
|
inc.log.Debug(logs.BasicCantFetchContainerInfo,
|
2021-02-01 16:17:16 +00:00
|
|
|
zap.Uint64("epoch", inc.epoch),
|
2022-05-31 17:00:41 +00:00
|
|
|
zap.Stringer("container_id", cnrEstimations[i].ContainerID),
|
2022-06-07 11:06:10 +00:00
|
|
|
zap.String("error", err.Error()))
|
2021-02-01 16:17:16 +00:00
|
|
|
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
avg := inc.avgEstimation(cnrEstimations[i]) // average container size per node
|
|
|
|
total := calculateBasicSum(avg, cachedRate, len(cnrNodes))
|
|
|
|
|
2021-02-02 17:23:01 +00:00
|
|
|
// fill distribute asset table
|
|
|
|
for i := range cnrNodes {
|
|
|
|
inc.distributeTable.Put(cnrNodes[i].PublicKey(), avg)
|
|
|
|
}
|
|
|
|
|
2021-02-02 17:39:41 +00:00
|
|
|
txTable.Transfer(&common.TransferTx{
|
2021-02-01 16:17:16 +00:00
|
|
|
From: owner.Owner(),
|
2022-05-31 17:00:41 +00:00
|
|
|
To: inc.bankOwner,
|
2021-02-01 16:17:16 +00:00
|
|
|
Amount: total,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-07 12:12:36 +00:00
|
|
|
common.TransferAssets(inc.exchange, txTable, common.BasicIncomeCollectionDetails(inc.epoch))
|
2021-02-01 16:17:16 +00:00
|
|
|
}
|
|
|
|
|
2022-04-21 11:28:05 +00:00
|
|
|
// avgEstimation returns estimation value for a single container. Right now it
|
|
|
|
// simply calculates an average of all announcements, however it can be smarter and
|
|
|
|
// base the result on reputation of the announcers and clever math.
|
2022-01-31 13:34:01 +00:00
|
|
|
func (inc *IncomeSettlementContext) avgEstimation(e *cntClient.Estimations) (avg uint64) {
|
2021-02-01 16:17:16 +00:00
|
|
|
if len(e.Values) == 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range e.Values {
|
|
|
|
avg += e.Values[i].Size
|
|
|
|
}
|
|
|
|
|
|
|
|
return avg / uint64(len(e.Values))
|
|
|
|
}
|
|
|
|
|
|
|
|
func calculateBasicSum(size, rate uint64, ln int) *big.Int {
|
|
|
|
bigRate := big.NewInt(int64(rate))
|
|
|
|
|
|
|
|
total := size * uint64(ln)
|
|
|
|
|
2021-02-03 12:07:37 +00:00
|
|
|
price := big.NewInt(0).SetUint64(total)
|
2021-02-01 16:17:16 +00:00
|
|
|
price.Mul(price, bigRate)
|
|
|
|
price.Div(price, bigGB)
|
|
|
|
|
|
|
|
if price.Cmp(bigZero) == 0 {
|
|
|
|
price.Add(price, bigOne)
|
|
|
|
}
|
|
|
|
|
|
|
|
return price
|
|
|
|
}
|