-
Notifications
You must be signed in to change notification settings - Fork 0
/
set_allowance.go
140 lines (119 loc) · 4.84 KB
/
set_allowance.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package main
import (
"fmt"
"github.com/Fornaxian/log"
"gitlab.com/NebulousLabs/Sia/node/api/client"
"gitlab.com/NebulousLabs/Sia/types"
)
const (
blocksDay = 144
blocksWeek = blocksDay * 7
blocksYear = uint64(blocksDay * 365.25) // I tried 365.2425 days but it causes problems
blocksMonth = uint64(blocksYear / 12)
)
func adjustAllowance(sia *client.Client, conf Config, scPrice float64) (err error) {
// Get unspent unallocated funds
rg, err := sia.RenterGet()
if err != nil {
return fmt.Errorf("Could not get renter metrics: %w", err)
}
fm := rg.FinancialMetrics
funds := rg.Settings.Allowance.Funds
if funds.Cmp(types.SiacoinPrecision.Mul64(1000)) == -1 {
log.Info("Allowance is below minimum of 1 KS. Defaulting to 1 KS")
funds = types.SiacoinPrecision.Mul64(1000) // Start with 1000 SC
}
spent := fm.ContractFees.
Add(fm.UploadSpending).
Add(fm.DownloadSpending).
Add(fm.StorageSpending)
// Calculate unspent allocated
unspentAllocated := types.ZeroCurrency
if fm.TotalAllocated.Cmp(spent) >= 0 {
unspentAllocated = fm.TotalAllocated.Sub(spent)
}
// Calculate unspent unallocated
unspentUnallocated := types.ZeroCurrency
if fm.Unspent.Cmp(unspentAllocated) >= 0 {
unspentUnallocated = fm.Unspent.Sub(unspentAllocated)
}
var (
// The low bound is the amount of unallocated funds at which the
// allowance will need to be increased. This is currently set to 12.5% of
// the total allowance
lowBound = funds.Div64(8)
// The high bound is the amount of unallocated funds at which the
// allowance will need to be decreased. This is currently set to 50% of
// the total allowance
highBound = funds.Div64(2)
// The adjust margin is the amount of siacoins by which the allowance
// will be adjusted when the allowance is increased or decreased. This
// is currently set to 1/8 of the allowance, or 12.5%
adjustMargin = funds.Div64(8)
)
log.Debug(
"Unallocated lower bound: %s, current: %s, higher bound: %s",
lowBound.HumanString(), unspentUnallocated.HumanString(), highBound.HumanString(),
)
// If the unspent unallocated funds are less than the low bound we increase
// the allowance. If they are more than the high bound we decrease the
// allowance. If they are between the two values we do nothing
if unspentUnallocated.Cmp(lowBound) <= 0 {
funds = funds.Add(adjustMargin)
log.Debug("Funds too low. Increasing to: %s", funds.HumanString())
} else if unspentUnallocated.Cmp(highBound) >= 0 {
// Unallocated funds are more than configured high bound. We need to
// decrease it to save money on fees. Here we lower the allowance by the
// configured adjust margin
funds = funds.Sub(adjustMargin)
log.Debug("Funds too high. Decreasing to: %s", funds.HumanString())
} else {
log.Debug(
"Enough margin left. No need to increase allowance. Funds: %s Unspent unallocated: %s",
funds.HumanString(), unspentUnallocated.HumanString(),
)
return nil
}
fundsSC, _ := funds.Div64(1e12).Float64()
fundsSC /= 1e12
var (
// Calculate allowance based on configured storage price
fundsEUR = fundsSC * scPrice
allowanceMonths = float64(rg.Settings.Allowance.Period) / float64(blocksMonth)
fundsEURPerMonth = fundsEUR / allowanceMonths
expectedStorage = (fundsEURPerMonth / (conf.MaxStoragePriceTBMonth * conf.Redundancy)) * 1e12
expectedUpload = expectedStorage * 0.2
expectedDownload = expectedStorage * 0.2
// Calculate host pricing limits based on configured rates
eur = types.SiacoinPrecision.MulFloat(1 / scPrice)
maxStoragePrice = eur.MulFloat(conf.MaxStoragePriceTBMonth).Div64(1e12).Div64(blocksMonth)
maxUploadPrice = eur.MulFloat(conf.MaxUploadPriceTB).Div64(1e12)
maxDownloadPrice = eur.MulFloat(conf.MaxDownloadPriceTB).Div64(1e12)
// maxCollateral = eur.MulFloat(conf.MaxCollateralTBMonth).Div64(1e12).Div64(blocksMonth)
maxContractPrice = eur.MulFloat(conf.MaxContractFormationPrice)
)
log.Debug(
"SC %.3f, €%.3f, months %.3f, €/month %.3f, storage %v, upload %v, download %v",
fundsSC,
fundsEUR,
allowanceMonths,
fundsEURPerMonth,
FormatData(int64(expectedStorage)),
FormatData(int64(expectedUpload)),
FormatData(int64(expectedDownload)),
)
// Set the allowance using the calculated values
return sia.RenterPostPartialAllowance().
WithExpectedStorage(uint64(expectedStorage)).
WithExpectedUpload(uint64(expectedUpload / float64(rg.Settings.Allowance.Period))).
WithExpectedDownload(uint64(expectedDownload / float64(rg.Settings.Allowance.Period))).
WithMaxStoragePrice(maxStoragePrice).
WithMaxUploadBandwidthPrice(maxUploadPrice).
WithMaxDownloadBandwidthPrice(maxDownloadPrice).
WithMaxContractPrice(maxContractPrice).
WithExpectedRedundancy(conf.Redundancy).
WithPeriod(types.BlockHeight(conf.ContractLength)).
WithRenewWindow(types.BlockHeight(conf.RenewWindow)).
WithHosts(conf.Hosts).
WithFunds(funds).Send()
}