github.com/DxChainNetwork/dxc@v0.8.1-0.20220824085222-1162e304b6e7/consensus/dpos/systemcontract/base.go (about)

     1  package systemcontract
     2  
     3  import (
     4  	"errors"
     5  	"github.com/DxChainNetwork/dxc/accounts/abi"
     6  	"github.com/DxChainNetwork/dxc/common"
     7  	"github.com/DxChainNetwork/dxc/consensus/dpos/vmcaller"
     8  	"github.com/DxChainNetwork/dxc/core"
     9  	"github.com/DxChainNetwork/dxc/core/state"
    10  	"github.com/DxChainNetwork/dxc/core/types"
    11  	"github.com/DxChainNetwork/dxc/log"
    12  	"github.com/DxChainNetwork/dxc/params"
    13  	"math"
    14  	"math/big"
    15  )
    16  
    17  type Base struct {
    18  	abi          abi.ABI
    19  	contractAddr common.Address
    20  }
    21  
    22  // NewBase return Base contract instance
    23  func NewBase() *Base {
    24  	return &Base{
    25  		abi:          abiMap[ValidatorsContractName],
    26  		contractAddr: ValidatorsContractAddr,
    27  	}
    28  }
    29  
    30  func (b *Base) GetBaseInfos(statedb *state.StateDB, header *types.Header, chainContext core.ChainContext, config *params.ChainConfig) (map[string]interface{}, error) {
    31  	baseInfos := map[string]interface{}{}
    32  
    33  	uint256Methods := []string{"BLOCK_SECONDS", "EPOCH_BLOCKS", "MIN_DEPOSIT",
    34  		"MAX_VALIDATORS_COUNT", "MAX_VALIDATOR_DETAIL_LENGTH", "MAX_VALIDATOR_NAME_LENGTH", "MAX_PUNISH_COUNT",
    35  		"RATE_SET_LOCK_EPOCHS", "VALIDATOR_UNSTAKE_LOCK_EPOCHS", "PROPOSAL_DURATION_EPOCHS",
    36  		"VALIDATOR_REWARD_LOCK_EPOCHS", "VOTE_CANCEL_EPOCHS", "TOTAL_DEPOSIT_LV1",
    37  		"TOTAL_DEPOSIT_LV2", "TOTAL_DEPOSIT_LV3", "TOTAL_DEPOSIT_LV4", "TOTAL_DEPOSIT_LV5",
    38  		"REWARD_DEPOSIT_UNDER_LV1", "REWARD_DEPOSIT_FROM_LV1_TO_LV2", "REWARD_DEPOSIT_FROM_LV2_TO_LV3",
    39  		"REWARD_DEPOSIT_FROM_LV3_TO_LV4", "REWARD_DEPOSIT_FROM_LV4_TO_LV5", "REWARD_DEPOSIT_OVER_LV5",
    40  		"MAX_VALIDATOR_COUNT_LV1", "MAX_VALIDATOR_COUNT_LV2", "MAX_VALIDATOR_COUNT_LV3", "MAX_VALIDATOR_COUNT_LV4",
    41  		"MIN_LEVEL_VALIDATOR_COUNT", "MEDIUM_LEVEL_VALIDATOR_COUNT", "MAX_LEVEL_VALIDATOR_COUNT", "SAFE_MULTIPLIER"}
    42  
    43  	uin8Methods := []string{"MIN_RATE", "MAX_RATE"}
    44  
    45  	addressMethods := []string{"BLACK_HOLE_ADDRESS"}
    46  
    47  	for i := 0; i < len(uint256Methods); i++ {
    48  		method := uint256Methods[i]
    49  		data, err := b.abi.Pack(method)
    50  
    51  		if err != nil {
    52  			log.Error("can't pack Base contract method", "method", method)
    53  			return map[string]interface{}{}, err
    54  		}
    55  
    56  		msg := vmcaller.NewLegacyMessage(header.Coinbase, &b.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false)
    57  		result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config)
    58  		if err != nil {
    59  			log.Error("GetBaseInfos result", "error", err)
    60  			return map[string]interface{}{}, err
    61  		}
    62  
    63  		//unpack data
    64  		ret, err := b.abi.Unpack(method, result)
    65  		if err != nil {
    66  			log.Error("GetBaseInfos Unpack", "error", err, "result", result)
    67  			return map[string]interface{}{}, err
    68  		}
    69  		info, ok := ret[0].(*big.Int)
    70  		if !ok {
    71  			return map[string]interface{}{}, errors.New("invalid minRate format")
    72  		}
    73  		baseInfos[method] = info
    74  	}
    75  
    76  	for i := 0; i < len(uin8Methods); i++ {
    77  		method := uin8Methods[i]
    78  		data, err := b.abi.Pack(method)
    79  
    80  		if err != nil {
    81  			log.Error("can't pack Base contract method", "method", method)
    82  			return map[string]interface{}{}, err
    83  		}
    84  
    85  		msg := vmcaller.NewLegacyMessage(header.Coinbase, &b.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false)
    86  		result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config)
    87  		if err != nil {
    88  			log.Error("GetBaseInfos result", "error", err)
    89  			return map[string]interface{}{}, err
    90  		}
    91  
    92  		//unpack data
    93  		ret, err := b.abi.Unpack(method, result)
    94  		if err != nil {
    95  			log.Error("GetBaseInfos Unpack", "error", err, "result", result)
    96  			return map[string]interface{}{}, err
    97  		}
    98  		info, ok := ret[0].(uint8)
    99  		if !ok {
   100  			return map[string]interface{}{}, errors.New("invalid minRate format")
   101  		}
   102  		baseInfos[method] = info
   103  	}
   104  
   105  	for i := 0; i < len(addressMethods); i++ {
   106  		method := addressMethods[i]
   107  		data, err := b.abi.Pack(method)
   108  
   109  		if err != nil {
   110  			log.Error("can't pack Base contract method", "method", method)
   111  			return map[string]interface{}{}, err
   112  		}
   113  
   114  		msg := vmcaller.NewLegacyMessage(header.Coinbase, &b.contractAddr, 0, new(big.Int), math.MaxUint64, new(big.Int), data, false)
   115  		result, err := vmcaller.ExecuteMsg(msg, statedb, header, chainContext, config)
   116  		if err != nil {
   117  			log.Error("GetBaseInfos result", "error", err)
   118  			return map[string]interface{}{}, err
   119  		}
   120  
   121  		//unpack data
   122  		ret, err := b.abi.Unpack(method, result)
   123  		if err != nil {
   124  			log.Error("GetBaseInfos Unpack", "error", err, "result", result)
   125  			return map[string]interface{}{}, err
   126  		}
   127  		info, ok := ret[0].(common.Address)
   128  		if !ok {
   129  			return map[string]interface{}{}, errors.New("invalid minRate format")
   130  		}
   131  		baseInfos[method] = info
   132  	}
   133  
   134  	return baseInfos, nil
   135  }