mirror of
https://github.com/luxfi/evmgpu.git
synced 2026-10-30 16:57:11 +00:00
261 lines
7.6 KiB
Go
261 lines
7.6 KiB
Go
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package header
|
|
|
|
import (
|
|
"math/big"
|
|
"testing"
|
|
|
|
"github.com/luxfi/evmgpu/commontype"
|
|
"github.com/luxfi/evmgpu/params/extras"
|
|
"github.com/luxfi/evmgpu/plugin/evm/upgrade/feewindow"
|
|
"github.com/luxfi/evmgpu/utils"
|
|
"github.com/luxfi/geth/common"
|
|
"github.com/luxfi/geth/core/types"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const (
|
|
maxBaseFee = 225 * utils.GWei
|
|
)
|
|
|
|
func TestBaseFee(t *testing.T) {
|
|
t.Run("normal", func(t *testing.T) {
|
|
BaseFeeTest(t, testFeeConfig)
|
|
})
|
|
t.Run("double", func(t *testing.T) {
|
|
BaseFeeTest(t, testFeeConfigDouble)
|
|
})
|
|
}
|
|
|
|
func BaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) {
|
|
tests := []struct {
|
|
name string
|
|
upgrades extras.NetworkUpgrades
|
|
parent *types.Header
|
|
timestamp uint64
|
|
want *big.Int
|
|
wantErr error
|
|
}{
|
|
{
|
|
name: "pre_chain_evm",
|
|
upgrades: extras.TestPreEVMChainConfig.NetworkUpgrades,
|
|
want: nil,
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "chain_evm_first_block",
|
|
upgrades: extras.NetworkUpgrades{
|
|
EVMTimestamp: utils.NewUint64(1),
|
|
},
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
},
|
|
timestamp: 1,
|
|
want: big.NewInt(feeConfig.MinBaseFee.Int64()),
|
|
},
|
|
{
|
|
name: "chain_evm_genesis_block",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(0),
|
|
},
|
|
want: big.NewInt(feeConfig.MinBaseFee.Int64()),
|
|
},
|
|
{
|
|
name: "chain_evm_invalid_fee_window",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
},
|
|
wantErr: feewindow.ErrWindowInsufficientLength,
|
|
},
|
|
{
|
|
name: "chain_evm_invalid_timestamp",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
Time: 1,
|
|
Extra: (&feewindow.Window{}).Bytes(),
|
|
},
|
|
timestamp: 0,
|
|
wantErr: errInvalidTimestamp,
|
|
},
|
|
{
|
|
name: "chain_evm_no_change",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
GasUsed: feeConfig.TargetGas.Uint64(),
|
|
Time: 1,
|
|
Extra: (&feewindow.Window{}).Bytes(),
|
|
BaseFee: big.NewInt(feeConfig.MinBaseFee.Int64() + 1),
|
|
},
|
|
timestamp: 1,
|
|
want: big.NewInt(feeConfig.MinBaseFee.Int64() + 1),
|
|
},
|
|
{
|
|
name: "chain_evm_small_decrease",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
Extra: (&feewindow.Window{}).Bytes(),
|
|
BaseFee: big.NewInt(maxBaseFee),
|
|
},
|
|
timestamp: 1,
|
|
want: func() *big.Int {
|
|
var (
|
|
gasTarget = feeConfig.TargetGas.Int64()
|
|
gasUsed = int64(0)
|
|
amountUnderTarget = gasTarget - gasUsed
|
|
parentBaseFee = int64(maxBaseFee)
|
|
smoothingFactor = feeConfig.BaseFeeChangeDenominator.Int64()
|
|
baseFeeFractionUnderTarget = amountUnderTarget * parentBaseFee / gasTarget
|
|
delta = baseFeeFractionUnderTarget / smoothingFactor
|
|
baseFee = parentBaseFee - delta
|
|
)
|
|
return big.NewInt(baseFee)
|
|
}(),
|
|
},
|
|
{
|
|
name: "chain_evm_large_decrease",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
Extra: (&feewindow.Window{}).Bytes(),
|
|
BaseFee: big.NewInt(maxBaseFee),
|
|
},
|
|
timestamp: 2 * feewindow.WindowLen,
|
|
want: func() *big.Int {
|
|
var (
|
|
gasTarget = feeConfig.TargetGas.Int64()
|
|
gasUsed = int64(0)
|
|
amountUnderTarget = gasTarget - gasUsed
|
|
parentBaseFee = int64(maxBaseFee)
|
|
smoothingFactor = feeConfig.BaseFeeChangeDenominator.Int64()
|
|
baseFeeFractionUnderTarget = amountUnderTarget * parentBaseFee / gasTarget
|
|
windowsElapsed = int64(2)
|
|
delta = windowsElapsed * baseFeeFractionUnderTarget / smoothingFactor
|
|
baseFee = parentBaseFee - delta
|
|
)
|
|
return big.NewInt(baseFee)
|
|
}(),
|
|
},
|
|
{
|
|
name: "chain_evm_increase",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
GasUsed: 2 * feeConfig.TargetGas.Uint64(),
|
|
Extra: (&feewindow.Window{}).Bytes(),
|
|
BaseFee: big.NewInt(feeConfig.MinBaseFee.Int64()),
|
|
},
|
|
timestamp: 1,
|
|
want: func() *big.Int {
|
|
var (
|
|
gasTarget = feeConfig.TargetGas.Int64()
|
|
gasUsed = 2 * gasTarget
|
|
amountOverTarget = gasUsed - gasTarget
|
|
parentBaseFee = feeConfig.MinBaseFee.Int64()
|
|
smoothingFactor = feeConfig.BaseFeeChangeDenominator.Int64()
|
|
baseFeeFractionOverTarget = amountOverTarget * parentBaseFee / gasTarget
|
|
delta = baseFeeFractionOverTarget / smoothingFactor
|
|
baseFee = parentBaseFee + delta
|
|
)
|
|
return big.NewInt(baseFee)
|
|
}(),
|
|
},
|
|
{
|
|
name: "chain_evm_big_1_not_modified",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
GasUsed: 1,
|
|
Extra: (&feewindow.Window{}).Bytes(),
|
|
BaseFee: big.NewInt(1),
|
|
},
|
|
timestamp: 2 * feewindow.WindowLen,
|
|
want: big.NewInt(feeConfig.MinBaseFee.Int64()),
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
config := &extras.ChainConfig{
|
|
NetworkUpgrades: test.upgrades,
|
|
}
|
|
got, err := BaseFee(config, feeConfig, test.parent, test.timestamp)
|
|
require.ErrorIs(err, test.wantErr)
|
|
require.Equal(test.want, got)
|
|
|
|
// Verify that [common.Big1] is not modified by [BaseFee].
|
|
require.Equal(big.NewInt(1), common.Big1)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEstimateNextBaseFee(t *testing.T) {
|
|
t.Run("normal", func(t *testing.T) {
|
|
EstimateNextBaseFeeTest(t, testFeeConfig)
|
|
})
|
|
t.Run("double", func(t *testing.T) {
|
|
EstimateNextBaseFeeTest(t, testFeeConfigDouble)
|
|
})
|
|
}
|
|
|
|
func EstimateNextBaseFeeTest(t *testing.T, feeConfig commontype.FeeConfig) {
|
|
testBaseFee := uint64(225 * utils.GWei)
|
|
nilUpgrade := extras.NetworkUpgrades{}
|
|
tests := []struct {
|
|
name string
|
|
upgrades extras.NetworkUpgrades
|
|
parent *types.Header
|
|
timestamp uint64
|
|
want *big.Int
|
|
wantErr error
|
|
}{
|
|
{
|
|
name: "activated",
|
|
upgrades: extras.TestEVMChainConfig.NetworkUpgrades,
|
|
parent: &types.Header{
|
|
Number: big.NewInt(1),
|
|
Extra: (&feewindow.Window{}).Bytes(),
|
|
BaseFee: new(big.Int).SetUint64(testBaseFee),
|
|
},
|
|
timestamp: 1,
|
|
want: func() *big.Int {
|
|
var (
|
|
gasTarget = feeConfig.TargetGas.Uint64()
|
|
gasUsed = uint64(0)
|
|
amountUnderTarget = gasTarget - gasUsed
|
|
parentBaseFee = testBaseFee
|
|
smoothingFactor = feeConfig.BaseFeeChangeDenominator.Uint64()
|
|
baseFeeFractionUnderTarget = amountUnderTarget * parentBaseFee / gasTarget
|
|
delta = baseFeeFractionUnderTarget / smoothingFactor
|
|
baseFee = parentBaseFee - delta
|
|
)
|
|
return new(big.Int).SetUint64(baseFee)
|
|
}(),
|
|
},
|
|
{
|
|
name: "not_scheduled",
|
|
upgrades: nilUpgrade,
|
|
wantErr: errEstimateBaseFeeWithoutActivation,
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
config := &extras.ChainConfig{
|
|
NetworkUpgrades: test.upgrades,
|
|
}
|
|
got, err := EstimateNextBaseFee(config, feeConfig, test.parent, test.timestamp)
|
|
require.ErrorIs(err, test.wantErr)
|
|
require.Equal(test.want, got)
|
|
})
|
|
}
|
|
}
|