/
subsidy.go
84 lines (71 loc) · 2.84 KB
/
subsidy.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
// Copyright (c) 2015-2019 The Eacred developers
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package txhelpers
import (
"sync"
"github.com/Eacred/eacrd/blockchain/standalone"
"github.com/Eacred/eacrd/chaincfg"
)
// ultimateSubsidies stores ultimate subsidy values computed by UltimateSubsidy.
var ultimateSubsidies sync.Map
// UltimateSubsidy computes the total subsidy over the entire subsidy
// distribution period of the network.
func UltimateSubsidy(params *chaincfg.Params) int64 {
// Check previously computed ultimate subsidies.
result, ok := ultimateSubsidies.Load(params)
if ok {
return result.(int64)
}
votesPerBlock := params.VotesPerBlock()
stakeValidationHeight := params.StakeValidationBeginHeight()
reductionInterval := params.SubsidyReductionIntervalBlocks()
subsidyCache := standalone.NewSubsidyCache(params)
subsidySum := func(height int64) int64 {
work := subsidyCache.CalcWorkSubsidy(height, votesPerBlock)
vote := subsidyCache.CalcStakeVoteSubsidy(height) * int64(votesPerBlock)
treasury := subsidyCache.CalcTreasurySubsidy(height, votesPerBlock)
return work + vote + treasury
}
totalSubsidy := params.BlockOneSubsidy()
for i := int64(0); ; i++ {
// The first interval contains a few special cases:
// 1) Block 0 does not produce any subsidy
// 2) Block 1 consists of a special initial coin distribution
// 3) Votes do not produce subsidy until voting begins
if i == 0 {
// Account for the block up to the point voting begins ignoring the
// first two special blocks.
subsidyCalcHeight := int64(2)
nonVotingBlocks := stakeValidationHeight - subsidyCalcHeight
totalSubsidy += subsidySum(subsidyCalcHeight) * nonVotingBlocks
// Account for the blocks remaining in the interval once voting
// begins.
subsidyCalcHeight = stakeValidationHeight
votingBlocks := reductionInterval - subsidyCalcHeight
totalSubsidy += subsidySum(subsidyCalcHeight) * votingBlocks
continue
}
// Account for the all other reduction intervals until all subsidy has
// been produced.
subsidyCalcHeight := i * reductionInterval
sum := subsidySum(subsidyCalcHeight)
if sum == 0 {
break
}
totalSubsidy += sum * reductionInterval
}
// Update the ultimate subsidy store.
ultimateSubsidies.Store(params, totalSubsidy)
return totalSubsidy
}
// RewardsAtBlock computes the PoW, PoS (per vote), and project fund subsidies
// at for the specified block index, assuming a certain number of votes.
func RewardsAtBlock(blockIdx int64, votes uint16, p *chaincfg.Params) (work, stake, tax int64) {
subsidyCache := standalone.NewSubsidyCache(p)
work = subsidyCache.CalcWorkSubsidy(blockIdx, votes)
stake = subsidyCache.CalcStakeVoteSubsidy(blockIdx)
tax = subsidyCache.CalcTreasurySubsidy(blockIdx, votes)
return
}