Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting eip 1559 fee params #3

Merged
merged 5 commits into from
May 1, 2024
Merged
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
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 @@ -231,7 +231,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 @@ -431,7 +431,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 }
mycodecrafting marked this conversation as resolved.
Show resolved Hide resolved
}
},
"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 @@ -1025,7 +1025,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
if w.chainConfig.IsLondon(header.Number) {
header.BaseFee = eip1559.CalcBaseFee(w.chainConfig, parent)
if !w.chainConfig.IsLondon(parent.Number) {
parentGasLimit := parent.GasLimit * w.chainConfig.ElasticityMultiplier()
parentGasLimit := parent.GasLimit * w.chainConfig.ElasticityMultiplier(parent.Number.Uint64())
header.GasLimit = core.CalcGasLimit(parentGasLimit, w.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 @@ -345,6 +347,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 @@ -366,6 +369,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)
Copy link
Contributor

@noot noot Apr 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this actually work? or do you have to set each field within c manually? can you test this? i remember this not working when i wrote go before

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya it works. I made a test script and it worked. I can add a few tests tho, prob not a bad idea.

return nil
}

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

Expand Down Expand Up @@ -742,12 +809,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
Loading