Skip to content

Commit

Permalink
Allow setting eip 1559 fee params (#3)
Browse files Browse the repository at this point in the history
Adds a per block height config to set some EIP1559 fee params
(elasticity and denominator) + adds a min base fee parameter.
  • Loading branch information
bharath-123 committed May 29, 2024
1 parent 8a2d76b commit d66918d
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 10 deletions.
15 changes: 10 additions & 5 deletions consensus/misc/eip1559/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade
// Verify that the gas limit remains within allowed bounds
parentGasLimit := parent.GasLimit
if !config.IsLondon(parent.Number) {
parentGasLimit = parent.GasLimit * config.ElasticityMultiplier()
parentGasLimit = parent.GasLimit * config.ElasticityMultiplier(parent.Number.Uint64())
}
if err := misc.VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil {
return err
Expand All @@ -60,7 +60,7 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
return new(big.Int).SetUint64(params.InitialBaseFee)
}

parentGasTarget := parent.GasLimit / config.ElasticityMultiplier()
parentGasTarget := parent.GasLimit / config.ElasticityMultiplier(parent.Number.Uint64()+1)
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
if parent.GasUsed == parentGasTarget {
return new(big.Int).Set(parent.BaseFee)
Expand All @@ -77,7 +77,7 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
num.SetUint64(parent.GasUsed - parentGasTarget)
num.Mul(num, parent.BaseFee)
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator(parent.Number.Uint64()+1)))
baseFeeDelta := math.BigMax(num, common.Big1)

return num.Add(parent.BaseFee, baseFeeDelta)
Expand All @@ -87,9 +87,14 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
num.SetUint64(parentGasTarget - parent.GasUsed)
num.Mul(num, parent.BaseFee)
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator(parent.Number.Uint64()+1)))
baseFee := num.Sub(parent.BaseFee, num)

return math.BigMax(baseFee, common.Big0)
lowerBound := common.Big0
if config.AstriaEIP1559Params != nil {
lowerBound = config.AstriaEIP1559Params.MinBaseFeeAt(parent.Number.Uint64() + 1)
}

return math.BigMax(baseFee, lowerBound)
}
}
4 changes: 2 additions & 2 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func (b *BlockGen) AddUncle(h *types.Header) {
if b.cm.config.IsLondon(h.Number) {
h.BaseFee = eip1559.CalcBaseFee(b.cm.config, parent)
if !b.cm.config.IsLondon(parent.Number) {
parentGasLimit := parent.GasLimit * b.cm.config.ElasticityMultiplier()
parentGasLimit := parent.GasLimit * b.cm.config.ElasticityMultiplier(parent.Number.Uint64())
h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
}
}
Expand Down Expand Up @@ -540,7 +540,7 @@ func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engi
if cm.config.IsLondon(header.Number) {
header.BaseFee = eip1559.CalcBaseFee(cm.config, parent.Header())
if !cm.config.IsLondon(parent.Number()) {
parentGasLimit := parent.GasLimit() * cm.config.ElasticityMultiplier()
parentGasLimit := parent.GasLimit() * cm.config.ElasticityMultiplier(parent.Number().Uint64())
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
}
}
Expand Down
3 changes: 3 additions & 0 deletions genesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
],
"astriaFeeCollectors": {
"1": "0xaC21B97d35Bf75A7dAb16f35b111a50e78A72F30"
},
"astriaEIP1559Params": {
"1": { "minBaseFee": 0, "elasticityMultiplier": 2, "BaseFeeChangeDenominator": 8 }
}
},
"difficulty": "10000000",
Expand Down
2 changes: 1 addition & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (miner *Miner) prepareWork(genParams *generateParams) (*environment, error)
if miner.chainConfig.IsLondon(header.Number) {
header.BaseFee = eip1559.CalcBaseFee(miner.chainConfig, parent)
if !miner.chainConfig.IsLondon(parent.Number) {
parentGasLimit := parent.GasLimit * miner.chainConfig.ElasticityMultiplier()
parentGasLimit := parent.GasLimit * miner.chainConfig.ElasticityMultiplier(parent.Number.Uint64())
header.GasLimit = core.CalcGasLimit(parentGasLimit, miner.config.GasCeil)
}
}
Expand Down
97 changes: 97 additions & 0 deletions params/astria_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package params

import (
"encoding/json"
"math/big"
"reflect"
"testing"

"github.com/ethereum/go-ethereum/common"
)

func TestAstriaEIP1559Params(t *testing.T) {
jsonBuf := []byte(`{
"1":{ "minBaseFee": 45000000000, "elasticityMultiplier": 4, "baseFeeChangeDenominator": 100 },
"101":{ "minBaseFee": 120000000, "elasticityMultiplier": 11, "baseFeeChangeDenominator": 250 },
"15":{ "minBaseFee": 15000000000, "elasticityMultiplier": 5, "baseFeeChangeDenominator": 50 }
}`)

var eip1559Params AstriaEIP1559Params
err := json.Unmarshal(jsonBuf, &eip1559Params)
if err != nil {
t.Errorf("unexpected err %v", err)
}

expected := AstriaEIP1559Params{
heights: map[uint64]AstriaEIP1559Param{
1: {MinBaseFee: 45000000000, ElasticityMultiplier: 4, BaseFeeChangeDenominator: 100},
101: {MinBaseFee: 120000000, ElasticityMultiplier: 11, BaseFeeChangeDenominator: 250},
15: {MinBaseFee: 15000000000, ElasticityMultiplier: 5, BaseFeeChangeDenominator: 50},
},
orderedHeights: []uint64{101, 15, 1},
}

if !reflect.DeepEqual(eip1559Params, expected) {
t.Errorf("expected %v, got %v", expected, eip1559Params)
}

minBaseTests := map[uint64]*big.Int{
0: common.Big0,
1: big.NewInt(45000000000),
2: big.NewInt(45000000000),
14: big.NewInt(45000000000),
15: big.NewInt(15000000000),
16: big.NewInt(15000000000),
50: big.NewInt(15000000000),
100: big.NewInt(15000000000),
101: big.NewInt(120000000),
102: big.NewInt(120000000),
123456: big.NewInt(120000000),
}

for height, expected := range minBaseTests {
if got := eip1559Params.MinBaseFeeAt(height); got.Cmp(expected) != 0 {
t.Errorf("MinBaseFeeAt(%d): expected %v, got %v", height, expected, got)
}
}

elasticityMultiplierTests := map[uint64]uint64{
0: DefaultElasticityMultiplier,
1: 4,
2: 4,
14: 4,
15: 5,
16: 5,
50: 5,
100: 5,
101: 11,
102: 11,
123456: 11,
}

for height, expected := range elasticityMultiplierTests {
if got := eip1559Params.ElasticityMultiplierAt(height); got != expected {
t.Errorf("ElasticityMultiplierAt(%d): expected %v, got %v", height, expected, got)
}
}

baseFeeChangeDenominatorTests := map[uint64]uint64{
0: DefaultBaseFeeChangeDenominator,
1: 100,
2: 100,
14: 100,
15: 50,
16: 50,
50: 50,
100: 50,
101: 250,
102: 250,
123456: 250,
}

for height, expected := range baseFeeChangeDenominatorTests {
if got := eip1559Params.BaseFeeChangeDenominatorAt(height); got != expected {
t.Errorf("BaseFeeChangeDenominatorAt(%d): expected %v, got %v", height, expected, got)
}
}
}
77 changes: 75 additions & 2 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package params

import (
"encoding/json"
"fmt"
"math/big"
"sort"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -382,6 +384,7 @@ type ChainConfig struct {
AstriaCelestiaHeightVariance uint32 `json:"astriaCelestiaHeightVariance,omitempty"`
AstriaBridgeAddressConfigs []AstriaBridgeAddressConfig `json:"astriaBridgeAddresses,omitempty"`
AstriaFeeCollectors map[uint32]common.Address `json:"astriaFeeCollectors"`
AstriaEIP1559Params *AstriaEIP1559Params `json:"astriaEIP1559Params,omitempty"`
}

func (c *ChainConfig) AstriaExtraData() []byte {
Expand All @@ -403,6 +406,70 @@ func (c *ChainConfig) AstriaExtraData() []byte {
return extra
}

type AstriaEIP1559Param struct {
MinBaseFee uint64 `json:"minBaseFee"`
ElasticityMultiplier uint64 `json:"elasticityMultiplier"`
BaseFeeChangeDenominator uint64 `json:"baseFeeChangeDenominator"`
}

type AstriaEIP1559Params struct {
heights map[uint64]AstriaEIP1559Param
orderedHeights []uint64
}

func NewAstriaEIP1559Params(heights map[uint64]AstriaEIP1559Param) *AstriaEIP1559Params {
orderedHeights := []uint64{}
for k := range heights {
orderedHeights = append(orderedHeights, k)
}
sort.Slice(orderedHeights, func(i, j int) bool { return orderedHeights[i] > orderedHeights[j] })

return &AstriaEIP1559Params{
heights: heights,
orderedHeights: orderedHeights,
}
}

func (c *AstriaEIP1559Params) MinBaseFeeAt(height uint64) *big.Int {
for _, h := range c.orderedHeights {
if height >= h {
return big.NewInt(0).SetUint64(c.heights[h].MinBaseFee)
}
}
return common.Big0
}

func (c *AstriaEIP1559Params) ElasticityMultiplierAt(height uint64) uint64 {
for _, h := range c.orderedHeights {
if height >= h {
return c.heights[h].ElasticityMultiplier
}
}
return DefaultElasticityMultiplier
}

func (c *AstriaEIP1559Params) BaseFeeChangeDenominatorAt(height uint64) uint64 {
for _, h := range c.orderedHeights {
if height >= h {
return c.heights[h].BaseFeeChangeDenominator
}
}
return DefaultBaseFeeChangeDenominator
}

func (c AstriaEIP1559Params) MarshalJSON() ([]byte, error) {
return json.Marshal(c.heights)
}

func (c *AstriaEIP1559Params) UnmarshalJSON(data []byte) error {
var heights map[uint64]AstriaEIP1559Param
if err := json.Unmarshal(data, &heights); err != nil {
return err
}
*c = *NewAstriaEIP1559Params(heights)
return nil
}

// EthashConfig is the consensus engine configs for proof-of-work based sealing.
type EthashConfig struct{}

Expand Down Expand Up @@ -779,12 +846,18 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int,
}

// BaseFeeChangeDenominator bounds the amount the base fee can change between blocks.
func (c *ChainConfig) BaseFeeChangeDenominator() uint64 {
func (c *ChainConfig) BaseFeeChangeDenominator(height uint64) uint64 {
if c.AstriaEIP1559Params != nil {
return c.AstriaEIP1559Params.BaseFeeChangeDenominatorAt(height)
}
return DefaultBaseFeeChangeDenominator
}

// ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have.
func (c *ChainConfig) ElasticityMultiplier() uint64 {
func (c *ChainConfig) ElasticityMultiplier(height uint64) uint64 {
if c.AstriaEIP1559Params != nil {
return c.AstriaEIP1559Params.ElasticityMultiplierAt(height)
}
return DefaultElasticityMultiplier
}

Expand Down

0 comments on commit d66918d

Please sign in to comment.