storj/storagenode/payouts/estimatedpayouts/estimatedpayouts.go

111 lines
4.0 KiB
Go
Raw Normal View History

// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package estimatedpayouts
import (
"math"
"time"
"storj.io/storj/private/date"
)
// EstimatedPayout contains usage and estimated payouts data for current and previous months.
type EstimatedPayout struct {
CurrentMonth PayoutMonthly `json:"currentMonth"`
PreviousMonth PayoutMonthly `json:"previousMonth"`
CurrentMonthExpectations int64 `json:"currentMonthExpectations"`
}
// PayoutMonthly contains usage and estimated payouts date.
type PayoutMonthly struct {
EgressBandwidth int64 `json:"egressBandwidth"`
EgressBandwidthPayout float64 `json:"egressBandwidthPayout"`
EgressRepairAudit int64 `json:"egressRepairAudit"`
EgressRepairAuditPayout float64 `json:"egressRepairAuditPayout"`
DiskSpace float64 `json:"diskSpace"`
DiskSpacePayout float64 `json:"diskSpacePayout"`
HeldRate float64 `json:"heldRate"`
Payout float64 `json:"payout"`
Held float64 `json:"held"`
}
// SetEgressBandwidthPayout counts egress bandwidth payouts for PayoutMonthly object.
func (pm *PayoutMonthly) SetEgressBandwidthPayout(egressPrice int64) {
amount := float64(pm.EgressBandwidth*egressPrice) / math.Pow10(12)
pm.EgressBandwidthPayout += RoundFloat(amount)
}
// SetEgressRepairAuditPayout counts audit and repair payouts for PayoutMonthly object.
func (pm *PayoutMonthly) SetEgressRepairAuditPayout(auditRepairPrice int64) {
amount := float64(pm.EgressRepairAudit*auditRepairPrice) / math.Pow10(12)
pm.EgressRepairAuditPayout += RoundFloat(amount)
}
// SetDiskSpacePayout counts disk space payouts for PayoutMonthly object.
func (pm *PayoutMonthly) SetDiskSpacePayout(diskSpacePrice int64) {
amount := pm.DiskSpace * float64(diskSpacePrice) / math.Pow10(12)
pm.DiskSpacePayout += RoundFloat(amount)
}
// SetHeldAmount counts held amount for PayoutMonthly object.
func (pm *PayoutMonthly) SetHeldAmount() {
amount := (pm.DiskSpacePayout + pm.EgressBandwidthPayout + pm.EgressRepairAuditPayout) * pm.HeldRate / 100
pm.Held = amount
}
// SetPayout counts payouts amount for PayoutMonthly object.
func (pm *PayoutMonthly) SetPayout() {
amount := pm.DiskSpacePayout + pm.EgressBandwidthPayout + pm.EgressRepairAuditPayout - pm.Held
pm.Payout = RoundFloat(amount)
}
// Add sums payout monthly data.
func (pm *PayoutMonthly) Add(monthly PayoutMonthly) {
pm.Payout += monthly.Payout
pm.EgressRepairAuditPayout += monthly.EgressRepairAuditPayout
pm.DiskSpacePayout += monthly.DiskSpacePayout
pm.DiskSpace += monthly.DiskSpace
pm.EgressBandwidth += monthly.EgressBandwidth
pm.EgressBandwidthPayout += monthly.EgressBandwidthPayout
pm.EgressRepairAudit += monthly.EgressRepairAudit
pm.Held += monthly.Held
}
// RoundFloat rounds float value till 2 signs after dot.
func RoundFloat(value float64) float64 {
return math.Round(value*100) / 100
}
// Set set's estimated payout with current/previous PayoutMonthly's data and current month expectations.
func (estimatedPayout *EstimatedPayout) Set(current, previous PayoutMonthly, now, joinedAt time.Time) {
estimatedPayout.CurrentMonth = current
estimatedPayout.PreviousMonth = previous
daysPerMonth := float64(date.UTCEndOfMonth(now).Day())
daysSinceJoined := now.Sub(joinedAt).Hours() / 24
if daysSinceJoined < 1 {
daysSinceJoined = 1
}
if daysSinceJoined >= float64(now.Day()) {
daysPast := float64(now.Day()) - 1
if daysPast < 1 {
daysPast = 1
}
payoutPerDay := estimatedPayout.CurrentMonth.Payout / daysPast
estimatedPayout.CurrentMonthExpectations += int64(payoutPerDay * daysPerMonth)
return
}
estimatedPayout.CurrentMonthExpectations += int64(estimatedPayout.CurrentMonth.Payout / math.Round(daysSinceJoined) * daysPerMonth)
}
// Add adds estimate into the receiver.
func (estimatedPayout *EstimatedPayout) Add(other EstimatedPayout) {
estimatedPayout.CurrentMonth.Add(other.CurrentMonth)
estimatedPayout.PreviousMonth.Add(other.PreviousMonth)
estimatedPayout.CurrentMonthExpectations += other.CurrentMonthExpectations
}