github.com/MetalBlockchain/subnet-evm@v0.4.9/commontype/fee_config.go (about)

     1  // (c) 2019-2022, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package commontype
     5  
     6  import (
     7  	"fmt"
     8  	"math/big"
     9  
    10  	"github.com/MetalBlockchain/subnet-evm/utils"
    11  	"github.com/ethereum/go-ethereum/common"
    12  )
    13  
    14  // FeeConfig specifies the parameters for the dynamic fee algorithm, which determines the gas limit, base fee, and block gas cost of blocks
    15  // on the network.
    16  //
    17  // The dynamic fee algorithm simply increases fees when the network is operating at a utilization level above the target and decreases fees
    18  // when the network is operating at a utilization level below the target.
    19  // This struct is used by params.Config and precompile.FeeConfigManager
    20  // any modification of this struct has direct affect on the precompiled contract
    21  // and changes should be carefully handled in the precompiled contract code.
    22  type FeeConfig struct {
    23  	// GasLimit sets the max amount of gas consumed per block.
    24  	GasLimit *big.Int `json:"gasLimit,omitempty"`
    25  
    26  	// TargetBlockRate sets the target rate of block production in seconds.
    27  	// A target of 2 will target producing a block every 2 seconds.
    28  	TargetBlockRate uint64 `json:"targetBlockRate,omitempty"`
    29  
    30  	// The minimum base fee sets a lower bound on the EIP-1559 base fee of a block.
    31  	// Since the block's base fee sets the minimum gas price for any transaction included in that block, this effectively sets a minimum
    32  	// gas price for any transaction.
    33  	MinBaseFee *big.Int `json:"minBaseFee,omitempty"`
    34  
    35  	// When the dynamic fee algorithm observes that network activity is above/below the [TargetGas], it increases/decreases the base fee proportionally to
    36  	// how far above/below the target actual network activity is.
    37  
    38  	// TargetGas specifies the targeted amount of gas (including block gas cost) to consume within a rolling 10s window.
    39  	TargetGas *big.Int `json:"targetGas,omitempty"`
    40  	// The BaseFeeChangeDenominator divides the difference between actual and target utilization to determine how much to increase/decrease the base fee.
    41  	// This means that a larger denominator indicates a slower changing, stickier base fee, while a lower denominator will allow the base fee to adjust
    42  	// more quickly.
    43  	BaseFeeChangeDenominator *big.Int `json:"baseFeeChangeDenominator,omitempty"`
    44  
    45  	// MinBlockGasCost sets the minimum amount of gas to charge for the production of a block.
    46  	MinBlockGasCost *big.Int `json:"minBlockGasCost,omitempty"`
    47  	// MaxBlockGasCost sets the maximum amount of gas to charge for the production of a block.
    48  	MaxBlockGasCost *big.Int `json:"maxBlockGasCost,omitempty"`
    49  	// BlockGasCostStep determines how much to increase/decrease the block gas cost depending on the amount of time elapsed since the previous block.
    50  	// If the block is produced at the target rate, the block gas cost will stay the same as the block gas cost for the parent block.
    51  	// If it is produced faster/slower, the block gas cost will be increased/decreased by the step value for each second faster/slower than the target
    52  	// block rate accordingly.
    53  	// Note: if the BlockGasCostStep is set to a very large number, it effectively requires block production to go no faster than the TargetBlockRate.
    54  	//
    55  	// Ex: if a block is produced two seconds faster than the target block rate, the block gas cost will increase by 2 * BlockGasCostStep.
    56  	BlockGasCostStep *big.Int `json:"blockGasCostStep,omitempty"`
    57  }
    58  
    59  // represents an empty fee config without any field
    60  var EmptyFeeConfig = FeeConfig{}
    61  
    62  // Verify checks fields of this config to ensure a valid fee configuration is provided.
    63  func (f *FeeConfig) Verify() error {
    64  	switch {
    65  	case f.GasLimit == nil:
    66  		return fmt.Errorf("gasLimit cannot be nil")
    67  	case f.MinBaseFee == nil:
    68  		return fmt.Errorf("minBaseFee cannot be nil")
    69  	case f.TargetGas == nil:
    70  		return fmt.Errorf("targetGas cannot be nil")
    71  	case f.BaseFeeChangeDenominator == nil:
    72  		return fmt.Errorf("baseFeeChangeDenominator cannot be nil")
    73  	case f.MinBlockGasCost == nil:
    74  		return fmt.Errorf("minBlockGasCost cannot be nil")
    75  	case f.MaxBlockGasCost == nil:
    76  		return fmt.Errorf("maxBlockGasCost cannot be nil")
    77  	case f.BlockGasCostStep == nil:
    78  		return fmt.Errorf("blockGasCostStep cannot be nil")
    79  	}
    80  
    81  	switch {
    82  	case f.GasLimit.Cmp(common.Big0) != 1:
    83  		return fmt.Errorf("gasLimit = %d cannot be less than or equal to 0", f.GasLimit)
    84  	case f.TargetBlockRate <= 0:
    85  		return fmt.Errorf("targetBlockRate = %d cannot be less than or equal to 0", f.TargetBlockRate)
    86  	case f.MinBaseFee.Cmp(common.Big0) == -1:
    87  		return fmt.Errorf("minBaseFee = %d cannot be less than 0", f.MinBaseFee)
    88  	case f.TargetGas.Cmp(common.Big0) != 1:
    89  		return fmt.Errorf("targetGas = %d cannot be less than or equal to 0", f.TargetGas)
    90  	case f.BaseFeeChangeDenominator.Cmp(common.Big0) != 1:
    91  		return fmt.Errorf("baseFeeChangeDenominator = %d cannot be less than or equal to 0", f.BaseFeeChangeDenominator)
    92  	case f.MinBlockGasCost.Cmp(common.Big0) == -1:
    93  		return fmt.Errorf("minBlockGasCost = %d cannot be less than 0", f.MinBlockGasCost)
    94  	case f.MinBlockGasCost.Cmp(f.MaxBlockGasCost) == 1:
    95  		return fmt.Errorf("minBlockGasCost = %d cannot be greater than maxBlockGasCost = %d", f.MinBlockGasCost, f.MaxBlockGasCost)
    96  	case f.BlockGasCostStep.Cmp(common.Big0) == -1:
    97  		return fmt.Errorf("blockGasCostStep = %d cannot be less than 0", f.BlockGasCostStep)
    98  	}
    99  	return f.checkByteLens()
   100  }
   101  
   102  // Equal checks if given [other] is same with this FeeConfig.
   103  func (f *FeeConfig) Equal(other *FeeConfig) bool {
   104  	if other == nil {
   105  		return false
   106  	}
   107  
   108  	return utils.BigNumEqual(f.GasLimit, other.GasLimit) &&
   109  		f.TargetBlockRate == other.TargetBlockRate &&
   110  		utils.BigNumEqual(f.MinBaseFee, other.MinBaseFee) &&
   111  		utils.BigNumEqual(f.TargetGas, other.TargetGas) &&
   112  		utils.BigNumEqual(f.BaseFeeChangeDenominator, other.BaseFeeChangeDenominator) &&
   113  		utils.BigNumEqual(f.MinBlockGasCost, other.MinBlockGasCost) &&
   114  		utils.BigNumEqual(f.MaxBlockGasCost, other.MaxBlockGasCost) &&
   115  		utils.BigNumEqual(f.BlockGasCostStep, other.BlockGasCostStep)
   116  }
   117  
   118  // checkByteLens checks byte lengths against common.HashLen (32 bytes) and returns error
   119  func (f *FeeConfig) checkByteLens() error {
   120  	if isBiggerThanHashLen(f.GasLimit) {
   121  		return fmt.Errorf("gasLimit exceeds %d bytes", common.HashLength)
   122  	}
   123  	if isBiggerThanHashLen(new(big.Int).SetUint64(f.TargetBlockRate)) {
   124  		return fmt.Errorf("targetBlockRate exceeds %d bytes", common.HashLength)
   125  	}
   126  	if isBiggerThanHashLen(f.MinBaseFee) {
   127  		return fmt.Errorf("minBaseFee exceeds %d bytes", common.HashLength)
   128  	}
   129  	if isBiggerThanHashLen(f.TargetGas) {
   130  		return fmt.Errorf("targetGas exceeds %d bytes", common.HashLength)
   131  	}
   132  	if isBiggerThanHashLen(f.BaseFeeChangeDenominator) {
   133  		return fmt.Errorf("baseFeeChangeDenominator exceeds %d bytes", common.HashLength)
   134  	}
   135  	if isBiggerThanHashLen(f.MinBlockGasCost) {
   136  		return fmt.Errorf("minBlockGasCost exceeds %d bytes", common.HashLength)
   137  	}
   138  	if isBiggerThanHashLen(f.MaxBlockGasCost) {
   139  		return fmt.Errorf("maxBlockGasCost exceeds %d bytes", common.HashLength)
   140  	}
   141  	if isBiggerThanHashLen(f.BlockGasCostStep) {
   142  		return fmt.Errorf("blockGasCostStep exceeds %d bytes", common.HashLength)
   143  	}
   144  	return nil
   145  }
   146  
   147  func isBiggerThanHashLen(bigint *big.Int) bool {
   148  	buf := bigint.Bytes()
   149  	isBigger := len(buf) > common.HashLength
   150  	return isBigger
   151  }