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  }