forked from evmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
commission.go
129 lines (108 loc) · 4.36 KB
/
commission.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
package types
import (
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type (
// Commission defines a commission parameters for a given validator.
Commission struct {
Rate sdk.Dec `json:"rate"` // the commission rate charged to delegators, as a fraction
MaxRate sdk.Dec `json:"max_rate"` // maximum commission rate which this validator can ever charge, as a fraction
MaxChangeRate sdk.Dec `json:"max_change_rate"` // maximum daily increase of the validator commission, as a fraction
UpdateTime time.Time `json:"update_time"` // the last time the commission rate was changed
}
// CommissionMsg defines a commission message to be used for creating a
// validator.
CommissionMsg struct {
Rate sdk.Dec `json:"rate"` // the commission rate charged to delegators, as a fraction
MaxRate sdk.Dec `json:"max_rate"` // maximum commission rate which validator can ever charge, as a fraction
MaxChangeRate sdk.Dec `json:"max_change_rate"` // maximum daily increase of the validator commission, as a fraction
}
)
// NewCommissionMsg returns an initialized validator commission message.
func NewCommissionMsg(rate, maxRate, maxChangeRate sdk.Dec) CommissionMsg {
return CommissionMsg{
Rate: rate,
MaxRate: maxRate,
MaxChangeRate: maxChangeRate,
}
}
// NewCommission returns an initialized validator commission.
func NewCommission(rate, maxRate, maxChangeRate sdk.Dec) Commission {
return Commission{
Rate: rate,
MaxRate: maxRate,
MaxChangeRate: maxChangeRate,
UpdateTime: time.Unix(0, 0).UTC(),
}
}
// NewCommission returns an initialized validator commission with a specified
// update time which should be the current block BFT time.
func NewCommissionWithTime(rate, maxRate, maxChangeRate sdk.Dec, updatedAt time.Time) Commission {
return Commission{
Rate: rate,
MaxRate: maxRate,
MaxChangeRate: maxChangeRate,
UpdateTime: updatedAt,
}
}
// Equal checks if the given Commission object is equal to the receiving
// Commission object.
func (c Commission) Equal(c2 Commission) bool {
return c.Rate.Equal(c2.Rate) &&
c.MaxRate.Equal(c2.MaxRate) &&
c.MaxChangeRate.Equal(c2.MaxChangeRate) &&
c.UpdateTime.Equal(c2.UpdateTime)
}
// String implements the Stringer interface for a Commission.
func (c Commission) String() string {
return fmt.Sprintf("rate: %s, maxRate: %s, maxChangeRate: %s, updateTime: %s",
c.Rate, c.MaxRate, c.MaxChangeRate, c.UpdateTime,
)
}
// Validate performs basic sanity validation checks of initial commission
// parameters. If validation fails, an SDK error is returned.
func (c Commission) Validate() sdk.Error {
switch {
case c.MaxRate.LT(sdk.ZeroDec()):
// max rate cannot be negative
return ErrCommissionNegative(DefaultCodespace)
case c.MaxRate.GT(sdk.OneDec()):
// max rate cannot be greater than 1
return ErrCommissionHuge(DefaultCodespace)
case c.Rate.LT(sdk.ZeroDec()):
// rate cannot be negative
return ErrCommissionNegative(DefaultCodespace)
case c.Rate.GT(c.MaxRate):
// rate cannot be greater than the max rate
return ErrCommissionGTMaxRate(DefaultCodespace)
case c.MaxChangeRate.LT(sdk.ZeroDec()):
// change rate cannot be negative
return ErrCommissionChangeRateNegative(DefaultCodespace)
case c.MaxChangeRate.GT(c.MaxRate):
// change rate cannot be greater than the max rate
return ErrCommissionChangeRateGTMaxRate(DefaultCodespace)
}
return nil
}
// ValidateNewRate performs basic sanity validation checks of a new commission
// rate. If validation fails, an SDK error is returned.
func (c Commission) ValidateNewRate(newRate sdk.Dec, blockTime time.Time) sdk.Error {
switch {
case blockTime.Sub(c.UpdateTime).Hours() < 24:
// new rate cannot be changed more than once within 24 hours
return ErrCommissionUpdateTime(DefaultCodespace)
case newRate.LT(sdk.ZeroDec()):
// new rate cannot be negative
return ErrCommissionNegative(DefaultCodespace)
case newRate.GT(c.MaxRate):
// new rate cannot be greater than the max rate
return ErrCommissionGTMaxRate(DefaultCodespace)
// TODO: why do we need an absolute value, do we care if the validator decreases their rate rapidly?
case newRate.Sub(c.Rate).Abs().GT(c.MaxChangeRate):
// new rate % points change cannot be greater than the max change rate
return ErrCommissionGTMaxChangeRate(DefaultCodespace)
}
return nil
}