-
Notifications
You must be signed in to change notification settings - Fork 95
/
mana.go
85 lines (76 loc) · 3.99 KB
/
mana.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
package iotago
import (
"github.com/iotaledger/hive.go/core/safemath"
"github.com/iotaledger/hive.go/ierrors"
"github.com/iotaledger/hive.go/lo"
)
// Mana Structure defines the parameters used in mana calculations.
type ManaParameters struct {
// BitsCount is the number of bits used to represent Mana.
BitsCount uint8 `serix:""`
// GenerationRate is the amount of potential Mana generated by 1 microIOTA in 1 slot multiplied by 2^GenerationRateExponent.
GenerationRate uint8 `serix:""`
// GenerationRateExponent is the scaling of GenerationRate expressed as an exponent of 2.
// The actual generation rate of Mana is given by GenerationRate * 2^(-GenerationRateExponent).
GenerationRateExponent uint8 `serix:""`
// DecayFactors is a lookup table of epoch diff to mana decay factor (slice index 0 = 1 epoch).
// The actual decay factor is given by DecayFactors[epochDiff] * 2^(-DecayFactorsExponent).
DecayFactors []uint32 `serix:",lenPrefix=uint16"`
// DecayFactorsExponent is the scaling of DecayFactors expressed as an exponent of 2.
DecayFactorsExponent uint8 `serix:""`
// DecayFactorEpochsSum is an integer approximation of the sum of decay over epochs.
DecayFactorEpochsSum uint32 `serix:""`
// DecayFactorEpochsSumExponent is the scaling of DecayFactorEpochsSum expressed as an exponent of 2.
DecayFactorEpochsSumExponent uint8 `serix:""`
// AnnualDecayFactorPercentage is the decay factor for 1 year.
AnnualDecayFactorPercentage uint8 `serix:""`
}
func (m ManaParameters) Equals(other ManaParameters) bool {
return m.BitsCount == other.BitsCount &&
m.GenerationRate == other.GenerationRate &&
m.GenerationRateExponent == other.GenerationRateExponent &&
lo.Equal(m.DecayFactors, other.DecayFactors) &&
m.DecayFactorsExponent == other.DecayFactorsExponent &&
m.DecayFactorEpochsSum == other.DecayFactorEpochsSum &&
m.DecayFactorEpochsSumExponent == other.DecayFactorEpochsSumExponent &&
m.AnnualDecayFactorPercentage == other.AnnualDecayFactorPercentage
}
type RewardsParameters struct {
// ProfitMarginExponent is used for shift operation for calculation of profit margin.
ProfitMarginExponent uint8 `serix:""`
// BootstrappingDuration is the length, in epochs, of the bootstrapping phase, (approx 3 years).
BootstrappingDuration EpochIndex `serix:""`
// RewardToGenerationRatio is the ratio of the final rewards rate to the generation rate of Mana.
RewardToGenerationRatio uint8 `serix:""`
// InitialTargetRewardsRate is the rate of Mana rewards at the start of the bootstrapping phase.
InitialTargetRewardsRate Mana `serix:""`
// FinalTargetRewardsRate is the rate of Mana rewards after the bootstrapping phase.
FinalTargetRewardsRate Mana `serix:""`
// PoolCoefficientExponent is the exponent used for shifting operation in the pool rewards calculations.
PoolCoefficientExponent uint8 `serix:""`
// The number of epochs for which rewards are retained.
RetentionPeriod uint16 `serix:""`
}
func (r RewardsParameters) Equals(other RewardsParameters) bool {
return r.ProfitMarginExponent == other.ProfitMarginExponent &&
r.BootstrappingDuration == other.BootstrappingDuration &&
r.RewardToGenerationRatio == other.RewardToGenerationRatio &&
r.InitialTargetRewardsRate == other.InitialTargetRewardsRate &&
r.FinalTargetRewardsRate == other.FinalTargetRewardsRate &&
r.PoolCoefficientExponent == other.PoolCoefficientExponent &&
r.RetentionPeriod == other.RetentionPeriod
}
func (r RewardsParameters) TargetReward(epoch EpochIndex, api API) (Mana, error) {
if epoch > r.BootstrappingDuration {
return api.ProtocolParameters().RewardsParameters().FinalTargetRewardsRate, nil
}
// Rewards start at epoch 0.
decayedInitialReward, err := api.ManaDecayProvider().DecayManaByEpochs(api.ProtocolParameters().RewardsParameters().InitialTargetRewardsRate, 0, epoch)
if err != nil {
return 0, ierrors.Wrap(err, "failed to calculate decayed initial reward")
}
return decayedInitialReward, nil
}
func ManaCost(rmc Mana, workScore WorkScore) (Mana, error) {
return safemath.SafeMul(rmc, Mana(workScore))
}