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 }