1 package consensusreward
7 "github.com/vapor/consensus"
8 "github.com/vapor/errors"
9 "github.com/vapor/toolbar/apinode"
10 "github.com/vapor/toolbar/common"
11 "github.com/vapor/toolbar/consensusreward/config"
14 const standbyNodesRewardForConsensusCycle = 7610350076 // 400000000000000 / (365 * 24 * 60 / (500 * 1200 / 1000 / 60))
16 type StandbyNodeReward struct {
19 xpubRewards map[string]uint64
24 func NewStandbyNodeReward(cfg *config.Config, startHeight, endHeight uint64) *StandbyNodeReward {
25 return &StandbyNodeReward{
27 node: apinode.NewNode(cfg.NodeIP),
28 xpubRewards: make(map[string]uint64),
29 startHeight: startHeight,
34 func (s *StandbyNodeReward) getStandbyNodeReward(height uint64) error {
36 voteInfos, err := s.node.GetVoteByHeight(height)
38 return errors.Wrapf(err, "get alternative node reward")
41 voteInfos = common.CalcStandByNodes(voteInfos)
42 totalVoteNum := uint64(0)
43 for _, voteInfo := range voteInfos {
44 totalVoteNum += voteInfo.VoteNum
47 total := big.NewInt(0).SetUint64(totalVoteNum)
48 for _, voteInfo := range voteInfos {
49 amount := big.NewInt(0).SetUint64(standbyNodesRewardForConsensusCycle)
50 voteNum := big.NewInt(0).SetUint64(voteInfo.VoteNum)
51 s.xpubRewards[voteInfo.Vote] += amount.Mul(amount, voteNum).Div(amount, total).Uint64()
56 func (s *StandbyNodeReward) Settlement() error {
57 for height := s.startHeight + consensus.ActiveNetParams.RoundVoteBlockNums; height <= s.endHeight; height += consensus.ActiveNetParams.RoundVoteBlockNums {
58 if err := s.getStandbyNodeReward(height - consensus.ActiveNetParams.RoundVoteBlockNums); err != nil {
62 rewards := map[string]uint64{}
63 for _, item := range s.cfg.RewardConf.Node {
64 if reward, ok := s.xpubRewards[item.XPub]; ok {
65 rewards[item.Address] = reward
69 if len(rewards) == 0 {
72 return s.node.BatchSendBTM(s.cfg.RewardConf.AccountID, s.cfg.RewardConf.Password, rewards)