github.com/DxChainNetwork/dxc@v0.8.1-0.20220824085222-1162e304b6e7/consensus/dpos/systemcontract/system_rewards.go (about) 1 package systemcontract 2 3 import ( 4 "github.com/DxChainNetwork/dxc/accounts/abi" 5 "github.com/DxChainNetwork/dxc/common" 6 "github.com/DxChainNetwork/dxc/consensus/dpos/vmcaller" 7 "github.com/DxChainNetwork/dxc/core" 8 "github.com/DxChainNetwork/dxc/core/state" 9 "github.com/DxChainNetwork/dxc/core/types" 10 "github.com/DxChainNetwork/dxc/log" 11 "github.com/DxChainNetwork/dxc/params" 12 "math" 13 "math/big" 14 ) 15 16 type SystemRewards struct { 17 abi abi.ABI 18 contractAddr common.Address 19 } 20 21 // EpochInfo struct `epoch` in SystemRewards contract 22 type EpochInfo struct { 23 BlockReward *big.Int 24 Tvl *big.Int 25 ValidatorCount *big.Int 26 EffictiveValCount *big.Int 27 } 28 29 type Reward struct { 30 ValidatorReward *big.Int 31 DelegatorsReward *big.Int 32 Rate uint8 33 } 34 35 type SysRewardsInfo struct { 36 Epochs []*big.Int 37 ValidatorRewards []*big.Int 38 DelegatorsRewards []*big.Int 39 Rates []uint8 40 PendingReward *big.Int 41 FrozenReward *big.Int 42 RewardPerVote *big.Int 43 } 44 45 type Punish struct { 46 Count *big.Int 47 PunishBlocks []*big.Int 48 KickoutBlocks []*big.Int 49 BurnRewards []*big.Int 50 } 51 52 // NewSystemRewards return SystemRewards contract instance 53 func NewSystemRewards() *SystemRewards { 54 return &SystemRewards{ 55 abi: abiMap[SystemRewardsContractName], 56 contractAddr: SystemRewardsContractAddr, 57 } 58 } 59 60 // GetEpochInfo return epoch info 61 func (s *SystemRewards) GetEpochInfo(statedb *state.StateDB, header *types.Header, chainContext core.ChainContext, config *params.ChainConfig, epoch *big.Int) (*EpochInfo, error) { 62 method := "epochs" 63 64 data, err := s.abi.Pack(method, epoch) 65 if err != nil { 66 log.Error("can't pack SystemRewards contract method", "method", method) 67 return &EpochInfo{}, err 68 } 69 msg := vmcaller.NewLegacyMessage(header.Coinbase, &s.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false) 70 result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config) 71 if err != nil { 72 log.Error("SystemRewards contract execute error", "method", method, "error", err) 73 return &EpochInfo{}, err 74 } 75 epochInfo := &EpochInfo{} 76 err = s.abi.UnpackIntoInterface(epochInfo, method, result) 77 if err != nil { 78 log.Error("SystemRewards contract Unpack error", "method", method, "error", err, "result", result) 79 return &EpochInfo{}, err 80 } 81 82 return epochInfo, nil 83 } 84 85 // KickoutInfo return kickout addresses in epoch 86 func (s *SystemRewards) KickoutInfo(statedb *state.StateDB, header *types.Header, chainContext core.ChainContext, config *params.ChainConfig, epoch *big.Int) ([]common.Address, error) { 87 method := "kickoutInfo" 88 89 data, err := s.abi.Pack(method, epoch) 90 if err != nil { 91 log.Error("can't pack SystemRewards contract method", "method", method) 92 return []common.Address{}, err 93 } 94 msg := vmcaller.NewLegacyMessage(header.Coinbase, &s.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false) 95 result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config) 96 if err != nil { 97 log.Error("SystemRewards contract execute error", "method", method, "error", err) 98 return []common.Address{}, err 99 } 100 101 ret, err := s.abi.Unpack(method, result) 102 if err != nil { 103 log.Error("SystemRewards contract Unpack error", "method", method, "error", err, "result", result) 104 return []common.Address{}, err 105 } 106 107 vals, ok := ret[0].([]common.Address) 108 if !ok { 109 log.Error("SystemRewards contract format result error", "method", method, "error", err) 110 return []common.Address{}, err 111 } 112 113 return vals, nil 114 } 115 116 // GetValRewardInfoByEpoch return the address and the epoch reward info 117 func (s *SystemRewards) GetValRewardInfoByEpoch(statedb *state.StateDB, header *types.Header, chainContext core.ChainContext, config *params.ChainConfig, addr common.Address, epoch *big.Int) (*Reward, error) { 118 method := "validatorEpochRewardInfo" 119 120 data, err := s.abi.Pack(method, addr, epoch) 121 if err != nil { 122 log.Error("can't pack SystemRewards contract method", "method", method) 123 return &Reward{}, err 124 } 125 msg := vmcaller.NewLegacyMessage(header.Coinbase, &s.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false) 126 result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config) 127 if err != nil { 128 log.Error("SystemRewards contract execute error", "method", method, "error", err) 129 return &Reward{}, err 130 } 131 rewards := &Reward{} 132 err = s.abi.UnpackIntoInterface(rewards, method, result) 133 if err != nil { 134 log.Error("SystemRewards contract Unpack error", "method", method, "error", err, "result", result) 135 return &Reward{}, err 136 } 137 138 return rewards, nil 139 } 140 141 // PendingValidatorReward return the address reward 142 func (s *SystemRewards) PendingValidatorReward(statedb *state.StateDB, header *types.Header, chainContext core.ChainContext, config *params.ChainConfig, addr common.Address) (*big.Int, *big.Int, error) { 143 method := "pendingValidatorReward" 144 data, err := s.abi.Pack(method, addr) 145 if err != nil { 146 log.Error("can't pack SystemRewards contract method", "method", method) 147 return big.NewInt(0), big.NewInt(0), err 148 } 149 msg := vmcaller.NewLegacyMessage(header.Coinbase, &s.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false) 150 result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config) 151 if err != nil { 152 log.Error("SystemRewards contract execute error", "method", method, "error", err) 153 return big.NewInt(0), big.NewInt(0), err 154 } 155 ret, err := s.abi.Unpack(method, result) 156 if err != nil { 157 log.Error("SystemRewards contract Unpack error", "method", method, "error", err, "result", result) 158 return big.NewInt(0), big.NewInt(0), err 159 } 160 avaliable, ok := ret[0].(*big.Int) 161 if !ok { 162 log.Error("SystemRewards contract format result error", "method", method, "error", err) 163 return big.NewInt(0), big.NewInt(0), err 164 } 165 frozen, ok := ret[1].(*big.Int) 166 if !ok { 167 log.Error("SystemRewards contract format result error", "method", method, "error", err) 168 return big.NewInt(0), big.NewInt(0), err 169 } 170 return avaliable, frozen, nil 171 } 172 173 // ValidatorRewardsInfo return the address sys rewards 174 func (s *SystemRewards) ValidatorRewardsInfo(statedb *state.StateDB, header *types.Header, chainContext core.ChainContext, config *params.ChainConfig, addr common.Address) (*SysRewardsInfo, error) { 175 method := "validatorRewardsInfo" 176 177 data, err := s.abi.Pack(method, addr) 178 if err != nil { 179 log.Error("can't pack SystemRewards contract method", "method", method) 180 return &SysRewardsInfo{}, err 181 } 182 msg := vmcaller.NewLegacyMessage(header.Coinbase, &s.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false) 183 result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config) 184 if err != nil { 185 log.Error("SystemRewards contract execute error", "method", method, "error", err) 186 return &SysRewardsInfo{}, err 187 } 188 rewardInfo := &SysRewardsInfo{} 189 err = s.abi.UnpackIntoInterface(rewardInfo, method, result) 190 if err != nil { 191 log.Error("SystemRewards contract Unpack error", "method", method, "error", err, "result", result) 192 return &SysRewardsInfo{}, err 193 } 194 195 return rewardInfo, nil 196 } 197 198 // PunishInfo punishInfo function of systemRewards contract 199 func (s *SystemRewards) PunishInfo(statedb *state.StateDB, header *types.Header, chainContext core.ChainContext, config *params.ChainConfig, addr common.Address, epoch *big.Int) (*Punish, error) { 200 method := "punishInfo" 201 202 data, err := s.abi.Pack(method, addr, epoch) 203 if err != nil { 204 log.Error("can't pack SystemRewards contract method", "method", method) 205 return &Punish{}, err 206 } 207 msg := vmcaller.NewLegacyMessage(header.Coinbase, &s.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false) 208 result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config) 209 if err != nil { 210 log.Error("SystemRewards contract execute error", "method", method, "error", err) 211 return &Punish{}, err 212 } 213 punish := &Punish{} 214 err = s.abi.UnpackIntoInterface(punish, method, result) 215 log.Info("punish", "rst", punish) 216 if err != nil { 217 log.Error("SystemRewards contract Unpack error", "method", method, "error", err, "result", result) 218 return &Punish{}, err 219 } 220 221 return punish, nil 222 }