OSDN Git Service

update
[bytom/vapor.git] / toolbar / consensusreward / consensusreward.go
1 package consensusreward
2
3 import (
4         "fmt"
5         "math/big"
6
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"
12 )
13
14 const standbyNodesRewardForConsensusCycle = 7610350076 // 400000000000000 / (365 * 24 * 60 / (500 * 1200 / 1000 / 60))
15
16 type StandbyNodeReward struct {
17         cfg         *config.Config
18         node        *apinode.Node
19         xpubRewards map[string]uint64
20         startHeight uint64
21         endHeight   uint64
22 }
23
24 func NewStandbyNodeReward(cfg *config.Config, startHeight, endHeight uint64) *StandbyNodeReward {
25         return &StandbyNodeReward{
26                 cfg:         cfg,
27                 node:        apinode.NewNode(cfg.NodeIP),
28                 xpubRewards: make(map[string]uint64),
29                 startHeight: startHeight,
30                 endHeight:   endHeight,
31         }
32 }
33
34 func (s *StandbyNodeReward) getStandbyNodeReward(height uint64) error {
35         fmt.Println(height)
36         voteInfos, err := s.node.GetVoteByHeight(height)
37         if err != nil {
38                 return errors.Wrapf(err, "get alternative node reward")
39         }
40
41         voteInfos = common.CalcStandByNodes(voteInfos)
42         totalVoteNum := uint64(0)
43         for _, voteInfo := range voteInfos {
44                 totalVoteNum += voteInfo.VoteNum
45         }
46
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()
52         }
53         return nil
54 }
55
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 {
59                         return err
60                 }
61         }
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
66                 }
67         }
68
69         if len(rewards) == 0 {
70                 return nil
71         }
72         return s.node.BatchSendBTM(s.cfg.RewardConf.AccountID, s.cfg.RewardConf.Password, rewards)
73 }