Skip to content

Commit

Permalink
init fee market in endblock (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidterpay authored Nov 15, 2023
1 parent ab21b71 commit bab1579
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 48 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
cosmossdk.io/core v0.11.0
cosmossdk.io/depinject v1.0.0-alpha.4
cosmossdk.io/log v1.2.1
cosmossdk.io/math v1.1.3-rc.1
github.com/client9/misspell v0.3.4
github.com/cometbft/cometbft v0.37.2
github.com/cometbft/cometbft-db v0.8.0
Expand Down Expand Up @@ -35,7 +36,6 @@ require (
cloud.google.com/go/iam v1.1.4 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
cosmossdk.io/errors v1.0.0 // indirect
cosmossdk.io/math v1.1.3-rc.1 // indirect
cosmossdk.io/tools/rosetta v0.2.1 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/4meepo/tagalign v1.3.3 // indirect
Expand Down
13 changes: 7 additions & 6 deletions x/feemarket/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// BeginBlock returns a beginblocker for the x/feemarket module.
func (k *Keeper) BeginBlock(ctx sdk.Context) ([]abci.ValidatorUpdate, error) {
return []abci.ValidatorUpdate{}, nil
}

// EndBlock returns an endblocker for the x/feemarket module.
// EndBlock returns an endblocker for the x/feemarket module. The endblocker
// is responsible for updating the state of the fee market based on the
// AIMD learning rate adjustment algorithm.
func (k *Keeper) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
if err := k.UpdateFeeMarket(ctx); err != nil {
panic(err)
}

return []abci.ValidatorUpdate{}
}
54 changes: 27 additions & 27 deletions x/feemarket/keeper/feemarket.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,16 @@
package keeper

import (
"encoding/json"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// ------------------- Fee Market Updates ------------------- //

// Init initializes the fee market (in InitGenesis).
func (k *Keeper) Init(_ sdk.Context) error {
// TODO initialize fee market state with params

return nil
}

// Export exports the fee market (in ExportGenesis).
func (k *Keeper) Export(_ sdk.Context) (json.RawMessage, error) {
// TODO export state from fee market state

return nil, nil
}

// BeginBlocker allows the fee market to be updated
// after every block. This will be added to the BeginBlock chain.
func (k *Keeper) BeginBlocker(_ sdk.Context) error {
return nil
}

// EndBlocker allows the fee market to be updated
// after every block. This will be added to the EndBlock chain.
func (k *Keeper) EndBlocker(ctx sdk.Context) error {
// UpdateFeeMarket updates the base fee and learning rate based on the
// AIMD learning rate adjustment algorithm. Note that if the fee market
// is disabled, this function will return without updating the fee market.
// This is executed in EndBlock which allows the next block's base fee to
// be readily available for wallets to estimate gas prices.
func (k *Keeper) UpdateFeeMarket(ctx sdk.Context) error {
params, err := k.GetParams(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -71,3 +51,23 @@ func (k *Keeper) EndBlocker(ctx sdk.Context) error {
state.IncrementHeight()
return k.SetState(ctx, state)
}

// GetBaseFee returns the base fee from the fee market state.
func (k *Keeper) GetBaseFee(ctx sdk.Context) (math.Int, error) {
state, err := k.GetState(ctx)
if err != nil {
return math.Int{}, err
}

return state.BaseFee, nil
}

// GetLearningRate returns the learning rate from the fee market state.
func (k *Keeper) GetLearningRate(ctx sdk.Context) (math.LegacyDec, error) {
state, err := k.GetState(ctx)
if err != nil {
return math.LegacyDec{}, err
}

return state.LearningRate, nil
}
49 changes: 49 additions & 0 deletions x/feemarket/keeper/feemarket_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package keeper_test

import (
"github.com/skip-mev/feemarket/x/feemarket/types"
)

func (s *KeeperTestSuite) TestUpdateFeeMarket() {
// TODO: add tests.
}

func (s *KeeperTestSuite) TestGetBaseFee() {
s.Run("can retrieve base fee with default eip-1559", func() {
gs := types.DefaultGenesisState()
s.feemarketKeeper.InitGenesis(s.ctx, *gs)

fee, err := s.feemarketKeeper.GetBaseFee(s.ctx)
s.Require().NoError(err)
s.Require().Equal(fee, gs.State.BaseFee)
})

s.Run("can retrieve base fee with aimd eip-1559", func() {
gs := types.DefaultAIMDGenesisState()
s.feemarketKeeper.InitGenesis(s.ctx, *gs)

fee, err := s.feemarketKeeper.GetBaseFee(s.ctx)
s.Require().NoError(err)
s.Require().Equal(fee, gs.State.BaseFee)
})
}

func (s *KeeperTestSuite) TestGetLearningRate() {
s.Run("can retrieve learning rate with default eip-1559", func() {
gs := types.DefaultGenesisState()
s.feemarketKeeper.InitGenesis(s.ctx, *gs)

lr, err := s.feemarketKeeper.GetLearningRate(s.ctx)
s.Require().NoError(err)
s.Require().Equal(lr, gs.State.LearningRate)
})

s.Run("can retrieve learning rate with aimd eip-1559", func() {
gs := types.DefaultAIMDGenesisState()
s.feemarketKeeper.InitGenesis(s.ctx, *gs)

lr, err := s.feemarketKeeper.GetLearningRate(s.ctx)
s.Require().NoError(err)
s.Require().Equal(lr, gs.State.LearningRate)
})
}
30 changes: 22 additions & 8 deletions x/feemarket/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,29 @@ import (

// InitGenesis initializes the feemarket module's state from a given genesis state.
func (k *Keeper) InitGenesis(ctx sdk.Context, gs types.GenesisState) {
if err := gs.Params.ValidateBasic(); err != nil {
if err := gs.ValidateBasic(); err != nil {
panic(err)
}

// Set the feemarket module's parameters.
// Ensure that state and fee market match required configurations.
if gs.Params.MaxBlockUtilization != gs.State.MaxBlockUtilization {
panic("genesis state and parameters do not match for max block utilization")
}

if gs.Params.TargetBlockUtilization != gs.State.TargetBlockUtilization {
panic("genesis state and parameters do not match for target block utilization")
}

if gs.Params.Window != uint64(len(gs.State.Window)) {
panic("genesis state and parameters do not match for window")
}

// Initialize the fee market state and parameters.
if err := k.SetParams(ctx, gs.Params); err != nil {
panic(err)
}

if err := k.Init(ctx); err != nil {
if err := k.SetState(ctx, gs.State); err != nil {
panic(err)
}
}
Expand All @@ -30,10 +43,11 @@ func (k *Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
panic(err)
}

// TODO get state

state := types.DefaultGenesisState()
state.Params = params
// Get the feemarket module's state.
state, err := k.GetState(ctx)
if err != nil {
panic(err)
}

return state // TODO Return full state
return types.NewGenesisState(params, state)
}
67 changes: 66 additions & 1 deletion x/feemarket/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,70 @@ func (s *KeeperTestSuite) TestInitGenesis() {
})
})

// TODO test further
s.Run("default AIMD genesis should not panic", func() {
s.Require().NotPanics(func() {
s.feemarketKeeper.InitGenesis(s.ctx, *types.DefaultAIMDGenesisState())
})
})

s.Run("bad genesis state should panic", func() {
gs := types.DefaultGenesisState()
gs.Params.Window = 0
s.Require().Panics(func() {
s.feemarketKeeper.InitGenesis(s.ctx, *gs)
})
})

s.Run("mismatch in params and state for window should panic", func() {
gs := types.DefaultAIMDGenesisState()
gs.Params.Window = 1

s.Require().Panics(func() {
s.feemarketKeeper.InitGenesis(s.ctx, *gs)
})
})

s.Run("mismatch in params and state for target utilization should panic", func() {
gs := types.DefaultAIMDGenesisState()
gs.Params.TargetBlockUtilization = 1

s.Require().Panics(func() {
s.feemarketKeeper.InitGenesis(s.ctx, *gs)
})
})

s.Run("mismatch in params and state for max utilization should panic", func() {
gs := types.DefaultAIMDGenesisState()
gs.Params.MaxBlockUtilization = 1

s.Require().Panics(func() {
s.feemarketKeeper.InitGenesis(s.ctx, *gs)
})
})
}

func (s *KeeperTestSuite) TestExportGenesis() {
s.Run("export genesis should not panic for default eip-1559", func() {
gs := types.DefaultGenesisState()
s.feemarketKeeper.InitGenesis(s.ctx, *gs)

var exportedGenesis *types.GenesisState
s.Require().NotPanics(func() {
exportedGenesis = s.feemarketKeeper.ExportGenesis(s.ctx)
})

s.Require().Equal(gs, exportedGenesis)
})

s.Run("export genesis should not panic for default AIMD eip-1559", func() {
gs := types.DefaultAIMDGenesisState()
s.feemarketKeeper.InitGenesis(s.ctx, *gs)

var exportedGenesis *types.GenesisState
s.Require().NotPanics(func() {
exportedGenesis = s.feemarketKeeper.ExportGenesis(s.ctx)
})

s.Require().Equal(gs, exportedGenesis)
})
}
5 changes: 0 additions & 5 deletions x/feemarket/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,6 @@ func NewAppModule(cdc codec.Codec, k keeper.Keeper) AppModule {
}
}

// BeginBlock returns a beginblocker for the x/feemarket module.
func (am AppModule) BeginBlock(ctx sdk.Context) ([]abci.ValidatorUpdate, error) {
return am.k.BeginBlock(ctx)
}

// EndBlock returns an endblocker for the x/feemarket module.
func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
return am.k.EndBlock(ctx, req)
Expand Down

0 comments on commit bab1579

Please sign in to comment.