Skip to content

Commit

Permalink
Base Fee Floor (Fixed amount) (#235)
Browse files Browse the repository at this point in the history
* Base Fee Floor

* Improve config description
  • Loading branch information
gastonponti authored Sep 23, 2024
1 parent af4532b commit 84a6afd
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 2 deletions.
10 changes: 9 additions & 1 deletion consensus/misc/eip1559/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,15 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade

// CalcBaseFee calculates the basefee of the header.
// The time belongs to the new block to check if Canyon is activted or not
func CalcBaseFee(config *params.ChainConfig, parent *types.Header, time uint64) *big.Int {
// **Notice** that the return value is catched by the deferred function which can change the return value
func CalcBaseFee(config *params.ChainConfig, parent *types.Header, time uint64) (response *big.Int) {
defer func() {
// If the base fee response is below the floor, intercept the return and return the floor instead.
if config.Celo != nil {
response = math.BigMax(response, new(big.Int).SetUint64(config.Celo.EIP1559BaseFeeFloor))
}
}()

// If this is the cel2 transition block and the parent block has a base fee
// then use that.
if config.Cel2Time != nil && *config.Cel2Time == time && parent.BaseFee != nil {
Expand Down
53 changes: 53 additions & 0 deletions consensus/misc/eip1559/eip1559_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ func opConfig() *params.ChainConfig {
return config
}

func celoConfig() *params.ChainConfig {
config := copyConfig(params.TestChainConfig)
ct := uint64(10)
config.Cel2Time = &ct
config.Celo = &params.CeloConfig{EIP1559BaseFeeFloor: params.InitialBaseFee}

return config
}

// TestBlockGasLimits tests the gasLimit checks for blocks both across
// the EIP-1559 boundary and post-1559 blocks
func TestBlockGasLimits(t *testing.T) {
Expand Down Expand Up @@ -176,3 +185,47 @@ func TestCalcBaseFeeOptimism(t *testing.T) {
}
}
}

// TestCalcBaseFeeCeloFloor assumes all blocks are 1559-blocks
func TestCalcBaseFeeCeloFloor(t *testing.T) {
config := celoConfig()
tests := []struct {
parentBaseFee int64
parentGasLimit uint64
parentGasUsed uint64
expectedBaseFee int64
}{
{params.InitialBaseFee, 20000000, 10000000, params.InitialBaseFee}, // usage == target
{params.InitialBaseFee, 20000000, 7000000, params.InitialBaseFee}, // usage below target
{params.InitialBaseFee, 20000000, 11000000, 1012500000}, // usage above target
}
for i, test := range tests {
parent := &types.Header{
Number: common.Big32,
GasLimit: test.parentGasLimit,
GasUsed: test.parentGasUsed,
BaseFee: big.NewInt(test.parentBaseFee),
Time: *config.Cel2Time,
}
if have, want := CalcBaseFee(config, parent, parent.Time+2), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 {
t.Errorf("test %d: have %d want %d, ", i, have, want)
}
}
}

// TestCalcBaseFeeCeloBlockActivation tests the base fee calculation for the celo block activation, mantaining the same base fee as the parent block
func TestCalcBaseFeeCeloBlockActivation(t *testing.T) {
config := celoConfig()
// Before activation
// usage above target
parent := &types.Header{
Number: common.Big32,
GasLimit: 20000000,
GasUsed: 15000000,
BaseFee: big.NewInt(params.InitialBaseFee * 3),
Time: *config.Cel2Time - 2,
}
if have, want := CalcBaseFee(config, parent, parent.Time+2), big.NewInt(params.InitialBaseFee*3); have.Cmp(want) != 0 {
t.Errorf("have %d want %d, ", have, want)
}
}
20 changes: 19 additions & 1 deletion params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ type ChainConfig struct {

// Optimism config, nil if not active
Optimism *OptimismConfig `json:"optimism,omitempty"`
// Celo config, nil if not active
Celo *CeloConfig `json:"celo,omitempty"`
}

// EthashConfig is the consensus engine configs for proof-of-work based sealing.
Expand Down Expand Up @@ -488,7 +490,21 @@ type OptimismConfig struct {

// String implements the stringer interface, returning the optimism fee config details.
func (o *OptimismConfig) String() string {
return "optimism"
denominatorCanyonStr := "nil"
if o.EIP1559DenominatorCanyon != nil {
denominatorCanyonStr = fmt.Sprintf("%d", *o.EIP1559DenominatorCanyon)
}
return fmt.Sprintf("optimism(eip1559Elasticity: %d, eip1559Denominator: %d, eip1559DenominatorCanyon: %s)",
o.EIP1559Elasticity, o.EIP1559Denominator, denominatorCanyonStr)
}

type CeloConfig struct {
EIP1559BaseFeeFloor uint64 `json:"eip1559BaseFeeFloor"`
}

// String implements the stringer interface, returning the celo config details.
func (o *CeloConfig) String() string {
return fmt.Sprintf("celo(eip1559BaseFeeFloor: %d)", o.EIP1559BaseFeeFloor)
}

// Description returns a human-readable description of ChainConfig.
Expand All @@ -504,6 +520,8 @@ func (c *ChainConfig) Description() string {
switch {
case c.Optimism != nil:
banner += "Consensus: Optimism\n"
banner += fmt.Sprintf(" - %s\n", c.Optimism)
banner += fmt.Sprintf(" - %s\n", c.Celo)
case c.Ethash != nil:
if c.TerminalTotalDifficulty == nil {
banner += "Consensus: Ethash (proof-of-work)\n"
Expand Down

0 comments on commit 84a6afd

Please sign in to comment.