github.com/amazechain/amc@v0.1.3/internal/consensus/apos/consensus.go (about) 1 package apos 2 3 import ( 4 "github.com/amazechain/amc/common/block" 5 "github.com/amazechain/amc/common/math" 6 "github.com/amazechain/amc/common/types" 7 "github.com/amazechain/amc/internal/consensus" 8 "github.com/amazechain/amc/log" 9 "github.com/amazechain/amc/modules/state" 10 "github.com/amazechain/amc/params" 11 "github.com/holiman/uint256" 12 "sort" 13 ) 14 15 func AccumulateRewards(r *Reward, number *uint256.Int, chain consensus.ChainHeaderReader) (map[types.Address]*uint256.Int, map[types.Address]*uint256.Int, error) { 16 17 rewardMap := make(map[types.Address]*uint256.Int, 0) 18 unpayMap := make(map[types.Address]*uint256.Int, 0) 19 20 endNumber := new(uint256.Int).Sub(number, r.rewardEpoch) 21 //calculate last batch but this one 22 currentNr := number.Clone() 23 currentNr.SubUint64(currentNr, 1) 24 25 depositeMap := map[types.Address]struct { 26 reward *uint256.Int 27 maxReward *uint256.Int 28 }{} 29 for currentNr.Cmp(endNumber) >= 0 { 30 block, err := chain.GetBlockByNumber(currentNr) 31 if nil != err { 32 return nil, nil, err 33 } 34 35 verifiers := block.Body().Verifier() 36 for _, verifier := range verifiers { 37 _, ok := depositeMap[verifier.Address] 38 if !ok { 39 low, max := chain.GetDepositInfo(verifier.Address) 40 if low == nil || max == nil { 41 continue 42 } 43 depositeMap[verifier.Address] = struct { 44 reward *uint256.Int 45 maxReward *uint256.Int 46 }{reward: low, maxReward: max} 47 48 log.Debug("account deposite infos", "addr", verifier.Address, "perblock", low, "perepoch", max) 49 } 50 51 addrReward, ok := rewardMap[verifier.Address] 52 if !ok { 53 addrReward = uint256.NewInt(0) 54 } 55 56 rewardMap[verifier.Address] = math.Min256(addrReward.Add(addrReward, depositeMap[verifier.Address].reward), depositeMap[verifier.Address].maxReward.Clone()) 57 } 58 59 currentNr.SubUint64(currentNr, 1) 60 } 61 62 for addr, amount := range rewardMap { 63 var payAmount, unpayAmount *uint256.Int 64 65 lastSedi, err := chain.GetAccountRewardUnpaid(addr) 66 if err != nil { 67 log.Debug("build reward Big map get account reward error,err=", err) 68 return nil, nil, err 69 } 70 if lastSedi != nil { 71 amount.Add(amount, lastSedi) 72 } 73 74 if amount.Cmp(r.rewardLimit) >= 0 { 75 payAmount = amount.Clone() 76 unpayAmount = uint256.NewInt(0) 77 } else { 78 payAmount = uint256.NewInt(0) 79 unpayAmount = amount.Clone() 80 } 81 82 rewardMap[addr] = payAmount 83 unpayMap[addr] = unpayAmount 84 } 85 86 //log.Debug("buildrewards maps", "rewardMap", rewardMap, "rewardmap len", len(rewardMap), "issetreward", setRewards) 87 // 88 //if setRewards { 89 // if err := r.setRewardByEpochPaid(tx, epoch, rewardMap); err != nil { 90 // return nil, err 91 // } 92 //} 93 94 return rewardMap, unpayMap, nil 95 } 96 97 func doReward(chainConf *params.ChainConfig, state *state.IntraBlockState, header *block.Header, chain consensus.ChainHeaderReader) ([]*block.Reward, map[types.Address]*uint256.Int, error) { 98 beijing, _ := uint256.FromBig(chainConf.BeijingBlock) 99 number := header.Number64() 100 var rewards block.Rewards 101 var upayMap map[types.Address]*uint256.Int 102 103 if chainConf.IsBeijing(number.Uint64()) && new(uint256.Int).Mod(new(uint256.Int).Sub(number, beijing), uint256.NewInt(chainConf.Apos.RewardEpoch)). 104 Cmp(uint256.NewInt(0)) == 0 { 105 r := newReward(chainConf) 106 var ( 107 err error 108 payMap map[types.Address]*uint256.Int 109 ) 110 payMap, upayMap, err = AccumulateRewards(r, number, chain) 111 if nil != err { 112 return nil, nil, err 113 } 114 for addr, value := range payMap { 115 if value.Cmp(uint256.NewInt(0)) > 0 { 116 if !state.Exist(addr) { 117 state.CreateAccount(addr, false) 118 } 119 120 log.Info("🔨 set account reward", "addr", addr, "amount", value.Uint64(), "blockNr", header.Number.Uint64()) 121 state.AddBalance(addr, value) 122 rewards = append(rewards, &block.Reward{ 123 Address: addr, 124 Amount: value, 125 }) 126 } 127 } 128 if !isWrongStateRootBlockNumber(header.Number64()) { 129 state.SoftFinalise() 130 } 131 sort.Sort(rewards) 132 } 133 return rewards, upayMap, nil 134 } 135 136 func isWrongStateRootBlockNumber(blockNr *uint256.Int) bool { 137 switch blockNr.Uint64() { 138 case 1288400, 1299200, 1310000, 1320800, 1331600, 1342400, 1353200, 1364000, 1374800, 1385600, 1396400, 1407200, 1418000, 1428800, 1439600, 1450400: 139 return true 140 default: 141 return false 142 } 143 }