Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 256 additions & 0 deletions IACP224FeeManager.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"components": [
{
"internalType": "uint256",
"name": "targetGas",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minGasPrice",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeToFillCapacity",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeToDouble",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct IACP224FeeManager.FeeConfig",
"name": "oldFeeConfig",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint256",
"name": "targetGas",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minGasPrice",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeToFillCapacity",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeToDouble",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct IACP224FeeManager.FeeConfig",
"name": "newFeeConfig",
"type": "tuple"
}
],
"name": "FeeConfigUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "role",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "oldRole",
"type": "uint256"
}
],
"name": "RoleSet",
"type": "event"
},
{
"inputs": [],
"name": "getFeeConfig",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "targetGas",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minGasPrice",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeToFillCapacity",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeToDouble",
"type": "uint256"
}
],
"internalType": "struct IACP224FeeManager.FeeConfig",
"name": "config",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getFeeConfigLastChangedAt",
"outputs": [
{
"internalType": "uint256",
"name": "blockNumber",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"name": "readAllowList",
"outputs": [
{
"internalType": "uint256",
"name": "role",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"name": "setAdmin",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"name": "setEnabled",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "targetGas",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minGasPrice",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeToFillCapacity",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeToDouble",
"type": "uint256"
}
],
"internalType": "struct IACP224FeeManager.FeeConfig",
"name": "config",
"type": "tuple"
}
],
"name": "setFeeConfig",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"name": "setManager",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"name": "setNone",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
7 changes: 5 additions & 2 deletions cmd/evm/internal/t8ntool/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,12 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
// Override the default min base fee if it's set in the env
feeConfig.MinBaseFee = env.MinBaseFee
}
acp176Config, err := params.DefaultACP224FeeConfig.ToACP176Config()
if err != nil {
return NewError(ErrorConfig, fmt.Errorf("failed converting ACP224 fee config to ACP176 config: %v", err))
}
configExtra := params.GetExtra(chainConfig)
var err error
env.BaseFee, err = customheader.BaseFee(configExtra, feeConfig, parent, env.Timestamp)
env.BaseFee, err = customheader.BaseFee(configExtra, feeConfig, acp176Config, parent, env.Timestamp)
if err != nil {
return NewError(ErrorConfig, fmt.Errorf("failed calculating base fee: %v", err))
}
Expand Down
85 changes: 85 additions & 0 deletions commontype/fee_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,96 @@ import (
"fmt"
"math/big"

"github.com/ava-labs/avalanchego/vms/components/gas"
"github.com/ava-labs/avalanchego/vms/evm/upgrade/acp176"
"github.com/ava-labs/libevm/common"

"github.com/ava-labs/subnet-evm/utils"
)

type ACP224FeeConfig struct {
TargetGas *big.Int `json:"targetGas,omitempty"`
MinGasPrice *big.Int `json:"minGasPrice,omitempty"`
TimeToFillCapacity *big.Int `json:"timeToFillCapacity,omitempty"`
TimeToDouble *big.Int `json:"timeToDouble,omitempty"`
}

// represents an empty ACP-224 fee config without any field
var EmptyACP224FeeConfig = ACP224FeeConfig{}

func (f *ACP224FeeConfig) Verify() error {
switch {
case f.TargetGas == nil:
return errors.New("targetGas cannot be nil")
case f.MinGasPrice == nil:
return errors.New("minGasPrice cannot be nil")
case f.TimeToFillCapacity == nil:
return errors.New("timeToFillCapacity cannot be nil")
case f.TimeToDouble == nil:
return errors.New("timeToDouble cannot be nil")
}

switch {
case f.TargetGas.Cmp(common.Big0) != 1:
return fmt.Errorf("targetGas = %d cannot be less than or equal to 0", f.TargetGas)
case f.MinGasPrice.Cmp(common.Big0) != 1:
return fmt.Errorf("minGasPrice = %d cannot be less than or equal to 0", f.MinGasPrice)
case f.TimeToFillCapacity.Cmp(common.Big0) == -1:
return fmt.Errorf("timeToFillCapacity = %d cannot be less than 0", f.TimeToFillCapacity)
case f.TimeToDouble.Cmp(common.Big0) == -1:
return fmt.Errorf("timeToDouble = %d cannot be less than 0", f.TimeToDouble)
}

switch {
case f.TimeToFillCapacity.Cmp(big.NewInt(acp176.MaxTimeToFillCapacity)) == 1:
return fmt.Errorf("timeToFillCapacity = %d cannot be greater than %d", f.TimeToFillCapacity, acp176.MaxTimeToFillCapacity)
case f.TimeToDouble.Cmp(big.NewInt(acp176.MaxTimeToDouble)) == 1:
return fmt.Errorf("timeToDouble = %d cannot be greater than %d", f.TimeToDouble, acp176.MaxTimeToDouble)
}
return f.checkByteLens()
}

func (f *ACP224FeeConfig) Equal(other *ACP224FeeConfig) bool {
if other == nil {
return false
}

return utils.BigNumEqual(f.TargetGas, other.TargetGas) &&
utils.BigNumEqual(f.MinGasPrice, other.MinGasPrice) &&
utils.BigNumEqual(f.TimeToFillCapacity, other.TimeToFillCapacity) &&
utils.BigNumEqual(f.TimeToDouble, other.TimeToDouble)
}

func (f *ACP224FeeConfig) ToACP176Config() (acp176.Config, error) {
if err := f.Verify(); err != nil {
return acp176.Config{}, err
}

config := acp176.Config{
MinGasPrice: gas.Price(f.MinGasPrice.Uint64()),
TimeToFillCapacity: gas.Gas(f.TimeToFillCapacity.Uint64()),
TimeToDouble: f.TimeToDouble.Uint64(),
}
return config, config.Verify()
}

// checkByteLens checks byte lengths against common.HashLen (32 bytes) and returns error
func (f *ACP224FeeConfig) checkByteLens() error {
if isBiggerThanHashLen(f.TargetGas) {
return fmt.Errorf("targetGas exceeds %d bytes", common.HashLength)
}
if isBiggerThanHashLen(f.MinGasPrice) {
return fmt.Errorf("minGasPrice exceeds %d bytes", common.HashLength)
}
if isBiggerThanHashLen(f.TimeToFillCapacity) {
return fmt.Errorf("timeToFillCapacity exceeds %d bytes", common.HashLength)
}
if isBiggerThanHashLen(f.TimeToDouble) {
return fmt.Errorf("timeToDouble exceeds %d bytes", common.HashLength)
}
return nil
}

// FeeConfig specifies the parameters for the dynamic fee algorithm, which determines the gas limit, base fee, and block gas cost of blocks
// on the network.
//
Expand Down
7 changes: 7 additions & 0 deletions commontype/test_fee_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ var ValidTestFeeConfig = FeeConfig{
MaxBlockGasCost: big.NewInt(1_000_000),
BlockGasCostStep: big.NewInt(200_000),
}

var ValidTestACP224FeeConfig = ACP224FeeConfig{
TargetGas: big.NewInt(15_000_000),
MinGasPrice: big.NewInt(1),
TimeToFillCapacity: big.NewInt(5),
TimeToDouble: big.NewInt(60),
}
3 changes: 3 additions & 0 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ type ChainHeaderReader interface {
// GetFeeConfigAt retrieves the fee config and last changed block number at block header.
GetFeeConfigAt(parent *types.Header) (commontype.FeeConfig, *big.Int, error)

// GetACP224FeeConfigAt retrieves the ACP224 fee config and last changed block number at block header.
GetACP224FeeConfigAt(parent *types.Header) (commontype.ACP224FeeConfig, *big.Int, error)

// GetCoinbaseAt retrieves the configured coinbase address at [parent].
// If fee recipients are allowed, returns true in the second return value and a predefined address in the first value.
GetCoinbaseAt(parent *types.Header) (common.Address, bool, error)
Expand Down
Loading
Loading