From 93d39841a11361717ce792e215f4975e726df351 Mon Sep 17 00:00:00 2001 From: hyeonLewis Date: Thu, 27 Jun 2024 17:48:11 +0900 Subject: [PATCH] Return zero tip cap if next baseFee is lower bound --- node/cn/gasprice/gasprice.go | 22 +++++++++++++----- node/cn/gasprice/gasprice_test.go | 38 +++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/node/cn/gasprice/gasprice.go b/node/cn/gasprice/gasprice.go index 2e62a6eb7..b70d6594c 100644 --- a/node/cn/gasprice/gasprice.go +++ b/node/cn/gasprice/gasprice.go @@ -30,6 +30,7 @@ import ( lru "github.com/hashicorp/golang-lru" "github.com/klaytn/klaytn/blockchain/types" "github.com/klaytn/klaytn/common" + "github.com/klaytn/klaytn/consensus/misc" "github.com/klaytn/klaytn/networks/rpc" "github.com/klaytn/klaytn/params" "golang.org/x/exp/slices" @@ -143,11 +144,11 @@ func NewOracle(backend OracleBackend, config Config, txPool TxPool, governance G // // The suggested prices needs to match the requirements. // -// | Fork | SuggestPrice (for gasPrice and maxFeePerGas) | SuggestTipCap (for maxPriorityFeePerGas) | -// |------------------ |------------------------------------------------------------ |----------------------------------------- | -// | Before Magma | Fixed UnitPrice | Fixed UnitPrice | -// | After Magma | BaseFee * 2 | Zero | -// | After Kaia | BaseFee + SuggestTipCap | 60% percentile of last 20 blocks | +// | Fork | SuggestPrice (for gasPrice and maxFeePerGas) | SuggestTipCap (for maxPriorityFeePerGas) | +// |------------------ |------------------------------------------------------------ |-------------------------------------------------------------------------------------- | +// | Before Magma | Fixed UnitPrice | Fixed UnitPrice | +// | After Magma | BaseFee * 2 | Zero | +// | After Kaia | BaseFee + SuggestTipCap | Zero if nextBaseFee is lower bound, 60% percentile of last 20 blocks otherwise. | // SuggestPrice returns the recommended gas price. // This value is intended to be used as gasPrice or maxFeePerGas. @@ -188,8 +189,17 @@ func (gpo *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) { nextNum := new(big.Int).Add(gpo.backend.CurrentBlock().Number(), common.Big1) if gpo.backend.ChainConfig().IsKaiaForkEnabled(nextNum) { // After Kaia, return using fee history. - // By default config, this will return 60% percentile of last 20 blocks + // If the next baseFee is lower bound, return 0. + // Otherwise, by default config, this will return 60% percentile of last 20 blocks // See node/cn/config.go for the default config. + pset, err := gpo.gov.EffectiveParams(nextNum.Uint64()) + if pset != nil && err == nil { + header := gpo.backend.CurrentBlock().Header() + nextBaseFee := misc.NextMagmaBlockBaseFee(header, pset.ToKIP71Config()) + if nextBaseFee.Cmp(big.NewInt(int64(pset.LowerBoundBaseFee()))) <= 0 { + return common.Big0, nil + } + } return gpo.suggestTipCapUsingFeeHistory(ctx) } else if gpo.backend.ChainConfig().IsMagmaForkEnabled(nextNum) { // After Magma, return zero diff --git a/node/cn/gasprice/gasprice_test.go b/node/cn/gasprice/gasprice_test.go index bfec07680..a5e58d7a8 100644 --- a/node/cn/gasprice/gasprice_test.go +++ b/node/cn/gasprice/gasprice_test.go @@ -233,6 +233,12 @@ func TestGasPrice_SuggestPrice(t *testing.T) { assert.Nil(t, err) } +type MockGov struct{} + +func (m *MockGov) EffectiveParams(bn uint64) (*params.GovParamSet, error) { + return nil, nil +} + func TestSuggestTipCap(t *testing.T) { config := Config{ Blocks: 3, @@ -246,22 +252,40 @@ func TestSuggestTipCap(t *testing.T) { magmaBlock *big.Int // Magma fork block number kaiaBlock *big.Int // Kaia fork block number expect *big.Int // Expected gasprice suggestion + isBusy bool // Whether the network is busy }{ - {nil, nil, big.NewInt(1)}, // If not Magma forked, should return unitPrice (which is 1 for test) + /// Not busy network + {nil, nil, big.NewInt(1), false}, // If not Magma forked, should return unitPrice (which is 1 for test) + + {big.NewInt(0), nil, common.Big0, false}, // After Magma fork and before Kaia fork, should return 0 - {big.NewInt(0), nil, common.Big0}, // After Magma fork and before Kaia fork, should return 0 + // After Kaia fork + // Expected gas tip is 0 since the next base fee is lower bound + {big.NewInt(0), big.NewInt(0), big.NewInt(params.Gkei * int64(0)), false}, // Fork point in genesis + {big.NewInt(1), big.NewInt(1), big.NewInt(params.Gkei * int64(0)), false}, // Fork point in first block + {big.NewInt(32), big.NewInt(32), big.NewInt(params.Gkei * int64(0)), false}, // Fork point in last block + {big.NewInt(33), big.NewInt(33), big.NewInt(params.Gkei * int64(0)), false}, // Fork point in the future + + /// Busy network + {nil, nil, big.NewInt(1), true}, // If not Magma forked, should return unitPrice (which is 1 for test) + + {big.NewInt(0), nil, common.Big0, true}, // After Magma fork and before Kaia fork, should return 0 // After Kaia fork - {big.NewInt(0), big.NewInt(0), big.NewInt(params.Gkei * int64(30))}, // Fork point in genesis - {big.NewInt(1), big.NewInt(1), big.NewInt(params.Gkei * int64(30))}, // Fork point in first block - {big.NewInt(32), big.NewInt(32), big.NewInt(params.Gkei * int64(30))}, // Fork point in last block - {big.NewInt(33), big.NewInt(33), big.NewInt(params.Gkei * int64(30))}, // Fork point in the future + {big.NewInt(0), big.NewInt(0), big.NewInt(params.Gkei * int64(30)), true}, // Fork point in genesis + {big.NewInt(1), big.NewInt(1), big.NewInt(params.Gkei * int64(30)), true}, // Fork point in first block + {big.NewInt(32), big.NewInt(32), big.NewInt(params.Gkei * int64(30)), true}, // Fork point in last block + {big.NewInt(33), big.NewInt(33), big.NewInt(params.Gkei * int64(30)), true}, // Fork point in the future } for _, c := range cases { testBackend, testGov := newTestBackend(t, c.magmaBlock, c.kaiaBlock) chainConfig := testBackend.ChainConfig() txPool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, chainConfig, testBackend.chain) - oracle := NewOracle(testBackend, config, txPool, testGov) + gov := testGov + if c.isBusy { + gov = &MockGov{} + } + oracle := NewOracle(testBackend, config, txPool, gov) // The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G got, err := oracle.SuggestTipCap(context.Background())