diff --git a/app/app.go b/app/app.go index 95001bc030..eecebe3c20 100644 --- a/app/app.go +++ b/app/app.go @@ -647,6 +647,10 @@ func NewOKExChainApp( app.SetEvmSysContractAddressHandler(NewEvmSysContractAddressHandler(app.EvmKeeper)) app.SetEvmWatcherCollector(app.EvmKeeper.Watcher.Collect) + gpoConfig := gasprice.NewGPOConfig(appconfig.GetOecConfig().GetDynamicGpWeight(), appconfig.GetOecConfig().GetDynamicGpCheckBlocks()) + app.gpo = gasprice.NewOracle(gpoConfig) + app.SetUpdateGPOHandler(updateGPOHandler(app.gpo)) + if loadLatest { err := app.LoadLatestVersion(app.keys[bam.MainStoreKey]) if err != nil { @@ -669,10 +673,6 @@ func NewOKExChainApp( enableAnalyzer := sm.DeliverTxsExecMode(viper.GetInt(sm.FlagDeliverTxsExecMode)) == sm.DeliverTxsExecModeSerial trace.EnableAnalyzer(enableAnalyzer) - if appconfig.GetOecConfig().GetDynamicGpMode() != types.CloseMode { - gpoConfig := gasprice.NewGPOConfig(appconfig.GetOecConfig().GetDynamicGpWeight(), appconfig.GetOecConfig().GetDynamicGpCheckBlocks()) - app.gpo = gasprice.NewOracle(gpoConfig) - } return app } @@ -705,7 +705,7 @@ func (app *OKExChainApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBloc // EndBlocker updates every end block func (app *OKExChainApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - if appconfig.GetOecConfig().GetDynamicGpMode() != types.CloseMode { + if appconfig.GetOecConfig().GetDynamicGpMode() != types.MinimalGpMode { currentBlockGPsCopy := app.gpo.CurrentBlockGPs.Copy() _ = app.gpo.BlockGPQueue.Push(currentBlockGPsCopy) GlobalGp = app.gpo.RecommendGP() diff --git a/app/app_abci.go b/app/app_abci.go index b7449b8798..3e32af70a7 100644 --- a/app/app_abci.go +++ b/app/app_abci.go @@ -5,11 +5,8 @@ import ( "time" appconfig "github.com/okex/exchain/app/config" - "github.com/okex/exchain/app/types" - sdk "github.com/okex/exchain/libs/cosmos-sdk/types" "github.com/okex/exchain/libs/system/trace" abci "github.com/okex/exchain/libs/tendermint/abci/types" - "github.com/okex/exchain/x/evm" "github.com/okex/exchain/x/wasm/watcher" ) @@ -26,14 +23,6 @@ func (app *OKExChainApp) DeliverTx(req abci.RequestDeliverTx) (res abci.Response resp := app.BaseApp.DeliverTx(req) - if appconfig.GetOecConfig().GetDynamicGpMode() != types.CloseMode { - tx, err := evm.TxDecoder(app.marshal)(req.Tx) - if err == nil { - //optimize get tx gas price can not get value from verifySign method - app.gpo.CurrentBlockGPs.Update(tx.GetGasPrice(), uint64(resp.GasUsed)) - } - } - return resp } @@ -46,18 +35,6 @@ func (app *OKExChainApp) DeliverRealTx(req abci.TxEssentials) (res abci.Response resp := app.BaseApp.DeliverRealTx(req) app.EvmKeeper.Watcher.RecordTxAndFailedReceipt(req, &resp, app.GetTxDecoder()) - var err error - if appconfig.GetOecConfig().GetDynamicGpMode() != types.CloseMode { - tx, _ := req.(sdk.Tx) - if tx == nil { - tx, err = evm.TxDecoder(app.Codec())(req.GetRaw()) - } - if err == nil { - //optimize get tx gas price can not get value from verifySign method - app.gpo.CurrentBlockGPs.Update(tx.GetGasPrice(), uint64(resp.GasUsed)) - } - } - return resp } diff --git a/app/app_parallel.go b/app/app_parallel.go index 41cdc79b4f..5428070b77 100644 --- a/app/app_parallel.go +++ b/app/app_parallel.go @@ -5,6 +5,8 @@ import ( "sort" "strings" + appconfig "github.com/okex/exchain/app/config" + "github.com/okex/exchain/app/gasprice" ethermint "github.com/okex/exchain/app/types" sdk "github.com/okex/exchain/libs/cosmos-sdk/types" "github.com/okex/exchain/libs/cosmos-sdk/x/auth" @@ -145,3 +147,13 @@ func groupByAddrAndSortFeeSplits(txFeesplit []*sdk.FeeSplitInfo) (feesplits map[ return } + +func updateGPOHandler(gpo *gasprice.Oracle) sdk.UpdateGPOHandler { + return func(dynamicGpInfos []sdk.DynamicGasInfo) { + if appconfig.GetOecConfig().GetDynamicGpMode() != ethermint.MinimalGpMode { + for _, dgi := range dynamicGpInfos { + gpo.CurrentBlockGPs.Update(dgi.GetGP(), dgi.GetGU()) + } + } + } +} diff --git a/app/app_test.go b/app/app_test.go index 0bd8002243..df2c609a93 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -1,8 +1,14 @@ package app import ( + "math/big" + "os" + "testing" + ethcommon "github.com/ethereum/go-ethereum/common" ethcrypto "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/suite" + "github.com/okex/exchain/app/crypto/ethsecp256k1" cosmossdk "github.com/okex/exchain/libs/cosmos-sdk/types" authclient "github.com/okex/exchain/libs/cosmos-sdk/x/auth/client/utils" @@ -10,10 +16,6 @@ import ( tendertypes "github.com/okex/exchain/libs/tendermint/types" "github.com/okex/exchain/x/distribution/keeper" evmtypes "github.com/okex/exchain/x/evm/types" - "github.com/stretchr/testify/suite" - "math/big" - "os" - "testing" "github.com/okex/exchain/libs/cosmos-sdk/x/upgrade" "github.com/okex/exchain/x/dex" diff --git a/app/gasprice/gasprice_test.go b/app/gasprice/gasprice_test.go deleted file mode 100644 index 8a28f04965..0000000000 --- a/app/gasprice/gasprice_test.go +++ /dev/null @@ -1,411 +0,0 @@ -package gasprice - -import ( - "fmt" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/params" - "github.com/stretchr/testify/require" - - appconfig "github.com/okex/exchain/app/config" - "github.com/okex/exchain/app/types" -) - -func TestOracle_RecommendGP(t *testing.T) { - t.Run("case 1: mainnet case", func(t *testing.T) { - // Case 1 reproduces the problem of GP increase when the OKC's block height is 13527188 - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(1) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - - blockPGs13527188 := types.NewSingleBlockGPs() - blockPGs13527188.Update(big.NewInt(10*params.GWei), 35) - blockPGs13527188.Update(big.NewInt(10*params.GWei), 35) - blockPGs13527188.Update(big.NewInt(params.GWei/10), 35) - - blockPGs13527187 := types.NewSingleBlockGPs() - blockPGs13527187.Update(big.NewInt(params.GWei/10), 35) - blockPGs13527187.Update(big.NewInt(params.GWei/10), 35) - - blockPGs13527186 := types.NewSingleBlockGPs() - blockPGs13527186.Update(big.NewInt(params.GWei/10), 35) - blockPGs13527186.Update(big.NewInt(params.GWei/10), 35) - - blockPGs13527185 := types.NewSingleBlockGPs() - blockPGs13527185.Update(big.NewInt(params.GWei/10+params.GWei/1000), 35) - blockPGs13527185.Update(big.NewInt(params.GWei/10), 35) - blockPGs13527185.Update(big.NewInt(params.GWei/10), 35) - - blockPGs13527184 := types.NewSingleBlockGPs() - blockPGs13527184.Update(big.NewInt(params.GWei*3/10), 35) - blockPGs13527184.Update(big.NewInt(params.GWei*3/10), 35) - blockPGs13527184.Update(big.NewInt(params.GWei*3/10), 35) - blockPGs13527184.Update(big.NewInt(params.GWei/10), 35) - blockPGs13527184.Update(big.NewInt(params.GWei/10), 35) - blockPGs13527184.Update(big.NewInt(params.GWei/10), 35) - - gpo.BlockGPQueue.Push(blockPGs13527184) - gpo.BlockGPQueue.Push(blockPGs13527185) - gpo.BlockGPQueue.Push(blockPGs13527186) - gpo.BlockGPQueue.Push(blockPGs13527187) - gpo.BlockGPQueue.Push(blockPGs13527188) - - testRecommendGP = gpo.RecommendGP() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - //testRecommendGP == 0.1GWei - }) - t.Run("case 2: not full tx, not full gasUsed, maxGasUsed configured, mode 1", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(1) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - delta := int64(200000) - gpNum := 200 - - for blockNum := 1; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(delta + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 3500) - delta-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) - t.Run("case 3: not full tx, not full gasUsed, maxGasUsed unconfigured, mode 0", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(-1) - appconfig.GetOecConfig().SetDynamicGpMode(0) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - coefficient := int64(200000) - gpNum := 200 - - for blockNum := 1; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 3500) // chain is uncongested - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) - t.Run("case 4: not full tx, not full gasUsed, maxGasUsed unconfigured, mode 1", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(-1) - appconfig.GetOecConfig().SetDynamicGpMode(1) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - coefficient := int64(200000) - gpNum := 200 - - for blockNum := 1; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 3500) - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) - - t.Run("case 5: not full tx, full gasUsed, gp surge, mode 0", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(200) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(0) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - coefficient := int64(200000) - gpNum := 180 - - for blockNum := 1; blockNum <= 5; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 6000) // chain is congested - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - for blockNum := 5; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum/2; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 6000) // chain is congested - coefficient-- - } - for i := gpNum / 2; i < gpNum; i++ { - gp := big.NewInt((coefficient + params.GWei) * 100) - gpo.CurrentBlockGPs.Update(gp, 6000) - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) - t.Run("case 6: not full tx, full gasUsed, gp surge, mode 1", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(1) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - coefficient := int64(200000) - gpNum := 200 - - for blockNum := 1; blockNum <= 5; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 4500) // chain is congested - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - for blockNum := 5; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum/2; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 4500) // chain is congested - coefficient-- - } - for i := gpNum / 2; i < gpNum; i++ { - gp := big.NewInt((coefficient + params.GWei) * 100) - gpo.CurrentBlockGPs.Update(gp, 4500) // chain is congested - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) - t.Run("case 7: full tx, not full gasUsed, gp surge, mode 0", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(0) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - coefficient := int64(200000) - gpNum := 300 - for blockNum := 1; blockNum <= 5; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 450) // chain is congested - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - for blockNum := 5; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum/2; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 450) // chain is congested - coefficient-- - } - for i := gpNum / 2; i < gpNum; i++ { - gp := big.NewInt((coefficient + params.GWei) * 100) - gpo.CurrentBlockGPs.Update(gp, 450) // chain is congested - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) - t.Run("case 8: full tx, not full gasUsed, gp surge, mode 1", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(1) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - coefficient := int64(200000) - gpNum := 300 - for blockNum := 1; blockNum <= 5; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 450) // chain is congested - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - for blockNum := 5; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum/2; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 450) - coefficient-- - } - for i := gpNum / 2; i < gpNum; i++ { - gp := big.NewInt((coefficient + params.GWei) * 100) - gpo.CurrentBlockGPs.Update(gp, 450) - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) - t.Run("case 9: not full tx, full gasUsed, gp decrease, mode 0", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(0) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - coefficient := int64(200000) - gpNum := 200 - - for blockNum := 1; blockNum <= 5; blockNum++ { - for i := 0; i < gpNum/2; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 6000) - coefficient-- - } - for i := gpNum / 2; i < gpNum; i++ { - gp := big.NewInt((coefficient + params.GWei) * 100) - gpo.CurrentBlockGPs.Update(gp, 6000) - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - for blockNum := 5; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 6000) - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) - t.Run("case 10: not full tx, full gasUsed, gp decrease, mode 1", func(t *testing.T) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(1) - config := NewGPOConfig(80, 5) - var testRecommendGP *big.Int - gpo := NewOracle(config) - coefficient := int64(200000) - gpNum := 200 - - for blockNum := 1; blockNum <= 5; blockNum++ { - for i := 0; i < gpNum/2; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 6000) - coefficient-- - } - for i := gpNum / 2; i < gpNum; i++ { - gp := big.NewInt((coefficient + params.GWei) * 100) - gpo.CurrentBlockGPs.Update(gp, 6000) - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - for blockNum := 5; blockNum <= 10; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 6000) - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - testRecommendGP = gpo.RecommendGP() - gpo.CurrentBlockGPs.Clear() - require.NotNil(t, testRecommendGP) - fmt.Println(testRecommendGP) - } - }) -} - -func BenchmarkRecommendGP(b *testing.B) { - appconfig.GetOecConfig().SetDynamicGpMaxTxNum(300) - appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(1000000) - appconfig.GetOecConfig().SetDynamicGpMode(0) - config := NewGPOConfig(80, 6) - gpo := NewOracle(config) - coefficient := int64(2000000) - gpNum := 300 - for blockNum := 1; blockNum <= 20; blockNum++ { - for i := 0; i < gpNum; i++ { - gp := big.NewInt(coefficient + params.GWei) - gpo.CurrentBlockGPs.Update(gp, 6000) - coefficient-- - } - cp := gpo.CurrentBlockGPs.Copy() - gpo.BlockGPQueue.Push(cp) - gpo.CurrentBlockGPs.Clear() - } - - b.ResetTimer() - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = gpo.RecommendGP() - } -} diff --git a/app/gasprice_test.go b/app/gasprice_test.go new file mode 100644 index 0000000000..8cab7bff48 --- /dev/null +++ b/app/gasprice_test.go @@ -0,0 +1,280 @@ +package app + +import ( + "math/big" + "testing" + + ethcommon "github.com/ethereum/go-ethereum/common" + ethcrypto "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/suite" + + appconfig "github.com/okex/exchain/app/config" + "github.com/okex/exchain/app/crypto/ethsecp256k1" + "github.com/okex/exchain/libs/cosmos-sdk/codec" + cosmossdk "github.com/okex/exchain/libs/cosmos-sdk/types" + authclient "github.com/okex/exchain/libs/cosmos-sdk/x/auth/client/utils" + abcitypes "github.com/okex/exchain/libs/tendermint/abci/types" + "github.com/okex/exchain/libs/tendermint/global" + tendertypes "github.com/okex/exchain/libs/tendermint/types" + evmtypes "github.com/okex/exchain/x/evm/types" +) + +var ( + txCoin100000 = cosmossdk.NewInt64Coin(cosmossdk.DefaultBondDenom, 100000) + nonce = uint64(0) + txNumPerBlock = 200 +) + +type FakeBlockRecommendGPTestSuite struct { + suite.Suite + app *OKExChainApp + codec *codec.Codec + + evmSenderPrivKey ethsecp256k1.PrivKey + evmContractAddress ethcommon.Address +} + +func (suite *FakeBlockRecommendGPTestSuite) SetupTest() { + suite.app = Setup(checkTx, WithChainId(cosmosChainId)) + suite.codec = suite.app.Codec() + params := evmtypes.DefaultParams() + params.EnableCreate = true + params.EnableCall = true + suite.app.EvmKeeper.SetParams(suite.Ctx(), params) + + suite.evmSenderPrivKey, _ = ethsecp256k1.GenerateKey() + suite.evmContractAddress = ethcrypto.CreateAddress(ethcommon.HexToAddress(suite.evmSenderPrivKey.PubKey().Address().String()), 0) + accountEvm := suite.app.AccountKeeper.NewAccountWithAddress(suite.Ctx(), suite.evmSenderPrivKey.PubKey().Address().Bytes()) + accountEvm.SetAccountNumber(accountNum) + accountEvm.SetCoins(cosmossdk.NewCoins(txCoin100000)) + suite.app.AccountKeeper.SetAccount(suite.Ctx(), accountEvm) +} + +func (suite *FakeBlockRecommendGPTestSuite) Ctx() cosmossdk.Context { + return suite.app.BaseApp.GetDeliverStateCtx() +} + +func (suite *FakeBlockRecommendGPTestSuite) beginFakeBlock(height int64) { + tendertypes.UnittestOnlySetMilestoneVenusHeight(height - 1) + global.SetGlobalHeight(height - 1) + suite.app.BeginBlocker(suite.Ctx(), abcitypes.RequestBeginBlock{Header: abcitypes.Header{Height: height}}) +} + +func (suite *FakeBlockRecommendGPTestSuite) endFakeBlock(recommendGp string) { + suite.app.EndBlocker(suite.Ctx(), abcitypes.RequestEndBlock{}) + ctx := suite.Ctx() + suite.Require().True(recommendGp == GlobalGp.String(), "recommend gas price expect %s, but %s ", recommendGp, GlobalGp.String()) + //fmt.Println("GlobalGp: ", GlobalGp) + suite.Require().False(ctx.BlockGasMeter().IsPastLimit()) + suite.Require().False(ctx.BlockGasMeter().IsOutOfGas()) +} + +func generateEvmTxs(totalTxNum int, baseGP int64, gpOffset *int64, decreaseGP bool, needMultiple bool) []*evmtypes.MsgEthereumTx { + //Create evm contract - Owner.sol + bytecode := ethcommon.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032") + txs := make([]*evmtypes.MsgEthereumTx, 0) + for txCount := 0; txCount < totalTxNum/2; txCount++ { + curTxGp := baseGP + *gpOffset + if !decreaseGP { + *gpOffset++ + } else { + *gpOffset-- + } + tx := evmtypes.NewMsgEthereumTx(nonce, nil, evmAmountZero, evmGasLimit, big.NewInt(curTxGp), bytecode) + + txs = append(txs, tx) + nonce++ + } + multiple := int64(1) + if needMultiple { + multiple = 100 + } + for txCount := totalTxNum / 2; txCount < totalTxNum; txCount++ { + curTxGp := (baseGP + *gpOffset) * multiple + if !decreaseGP { + *gpOffset++ + } else { + *gpOffset-- + } + tx := evmtypes.NewMsgEthereumTx(nonce, nil, evmAmountZero, evmGasLimit, big.NewInt(curTxGp), bytecode) + + txs = append(txs, tx) + nonce++ + } + return txs +} + +func (suite *FakeBlockRecommendGPTestSuite) TestRecommendGP() { + testCases := []struct { + title string + // build txs for one block + buildTxs func(int, int64, *int64, bool, bool) []*evmtypes.MsgEthereumTx + + gpMaxTxNum int64 + gpMaxGasUsed int64 + gpMode int + + expectedTotalGU []int64 + expectedRecommendGp []string + blocks int + + needMultiple bool + gpDecrease bool + }{ + { + title: "congestion, gp increase, higher gp mode", + buildTxs: generateEvmTxs, + gpMaxTxNum: 300, + gpMaxGasUsed: 1000000, + gpMode: 0, + expectedTotalGU: []int64{46329800, 46329800, 46329800, 46329800, 46329800}, + expectedRecommendGp: []string{"100200099", "100200299", "100200499", "100200699", "100200899"}, + blocks: 5, + needMultiple: false, + }, + { + title: "congestion, gp decrease, higher gp mode", + buildTxs: generateEvmTxs, + gpMaxTxNum: 300, + gpMaxGasUsed: 1000000, + gpMode: 0, + expectedTotalGU: []int64{46329800, 46329800, 46329800, 46329800, 46329800}, + expectedRecommendGp: []string{"100199900", "100199700", "100199500", "100199300", "100199100"}, + blocks: 5, + needMultiple: false, + gpDecrease: true, + }, + { + title: "congestion, gp increase, normal mode", + buildTxs: generateEvmTxs, + gpMaxTxNum: 300, + gpMaxGasUsed: 1000000, + gpMode: 1, + expectedTotalGU: []int64{46329800, 46329800, 46329800, 46329800, 46329800}, + expectedRecommendGp: []string{"100200000", "100200200", "100200400", "100200600", "100200800"}, + blocks: 5, + needMultiple: false, + }, + { + title: "no congestion, gp increase, higher gp mode", + buildTxs: generateEvmTxs, + gpMaxTxNum: 300, + gpMaxGasUsed: 60000000, + gpMode: 0, + expectedTotalGU: []int64{46329800, 46329800, 46329800, 46329800, 46329800}, + expectedRecommendGp: []string{"100200000", "100200200", "100200400", "100200600", "100200800"}, + blocks: 5, + needMultiple: false, + }, + { + title: "no congestion, gp increase, gp multiple, higher gp mode", + buildTxs: generateEvmTxs, + gpMaxTxNum: 300, + gpMaxGasUsed: 60000000, + gpMode: 0, + expectedTotalGU: []int64{46329800, 46329800, 46329800, 46329800, 46329800}, + expectedRecommendGp: []string{"100200000", "100200200", "100200400", "100200600", "100200800"}, + blocks: 5, + needMultiple: true, + }, + { + title: "congestion, gp increase, gp multiple, higher gp mode", + buildTxs: generateEvmTxs, + gpMaxTxNum: 300, + gpMaxGasUsed: 1000000, + gpMode: 0, + expectedTotalGU: []int64{46329800, 46329800, 46329800, 46329800, 46329800}, + expectedRecommendGp: []string{"5060109900", "5060120000", "5060130100", "5060140200", "5060150300"}, + blocks: 5, + needMultiple: true, + }, + { + title: "congestion, gp decrease, gp multiple, higher gp mode", + buildTxs: generateEvmTxs, + gpMaxTxNum: 300, + gpMaxGasUsed: 1000000, + gpMode: 0, + expectedTotalGU: []int64{46329800, 46329800, 46329800, 46329800, 46329800}, + expectedRecommendGp: []string{"5060094901", "5060084801", "5060074701", "5060064601", "5060054501"}, + blocks: 5, + needMultiple: true, + gpDecrease: true, + }, + { + title: "congestion, gp increase, gp multiple, normal mode", + buildTxs: generateEvmTxs, + gpMaxTxNum: 300, + gpMaxGasUsed: 1000000, + gpMode: 1, + expectedTotalGU: []int64{46329800, 46329800, 46329800, 46329800, 46329800}, + expectedRecommendGp: []string{"100200000", "100200200", "100200400", "100200600", "100200800"}, + blocks: 5, + needMultiple: true, + }, + } + + suite.SetupTest() + for _, tc := range testCases { + + appconfig.GetOecConfig().SetDynamicGpMaxTxNum(tc.gpMaxTxNum) + appconfig.GetOecConfig().SetDynamicGpMaxGasUsed(tc.gpMaxGasUsed) + appconfig.GetOecConfig().SetDynamicGpMode(tc.gpMode) + + // tx serial + gpOffset := int64(200000) + baseGP := int64(params.GWei / 10) + height := int64(2) + for i := 0; i < tc.blocks; i++ { + totalGasUsed := int64(0) + suite.beginFakeBlock(height) + suite.Run(tc.title+", tx serial", func() { + txs := tc.buildTxs(txNumPerBlock, baseGP, &gpOffset, tc.gpDecrease, tc.needMultiple) + for _, tx := range txs { + tx.Sign(evmChainID, suite.evmSenderPrivKey.ToECDSA()) + txBytes, err := authclient.GetTxEncoder(nil, authclient.WithEthereumTx())(tx) + suite.Require().NoError(err) + txReal := suite.app.PreDeliverRealTx(txBytes) + suite.Require().NotNil(txReal) + resp := suite.app.DeliverRealTx(txReal) + totalGasUsed += resp.GasUsed + } + }) + //fmt.Println("totalGasUsed: ", totalGasUsed) + suite.Require().True(totalGasUsed == tc.expectedTotalGU[i], "block gas expect %d, but %d ", tc.expectedTotalGU, totalGasUsed) + suite.endFakeBlock(tc.expectedRecommendGp[i]) + height++ + } + + // tx parallel + gpOffset = int64(200000) + baseGP = int64(params.GWei / 10) + height = int64(2) + for i := 0; i < tc.blocks; i++ { + totalGasUsed := int64(0) + suite.beginFakeBlock(height) + suite.Run(tc.title+", tx parallel", func() { + txs := tc.buildTxs(txNumPerBlock, baseGP, &gpOffset, tc.gpDecrease, tc.needMultiple) + txsBytes := make([][]byte, 0) + for _, tx := range txs { + tx.Sign(evmChainID, suite.evmSenderPrivKey.ToECDSA()) + txBytes, err := authclient.GetTxEncoder(nil, authclient.WithEthereumTx())(tx) + suite.Require().NoError(err) + txsBytes = append(txsBytes, txBytes) + } + resps := suite.app.ParallelTxs(txsBytes, false) + for _, resp := range resps { + totalGasUsed += resp.GasUsed + } + }) + //fmt.Println("totalGasUsed: ", totalGasUsed) + suite.Require().True(totalGasUsed == tc.expectedTotalGU[i], "block gas expect %d, but %d ", tc.expectedTotalGU, totalGasUsed) + suite.endFakeBlock(tc.expectedRecommendGp[i]) + height++ + } + } +} + +func TestFakeBlockRecommendGPSuite(t *testing.T) { + suite.Run(t, new(FakeBlockRecommendGPTestSuite)) +} diff --git a/app/node_mode.go b/app/node_mode.go index 5b6a07f0c8..f430ea7495 100644 --- a/app/node_mode.go +++ b/app/node_mode.go @@ -71,7 +71,7 @@ func setRpcConfig(ctx *server.Context) { func setValidatorConfig(ctx *server.Context) { viper.SetDefault(abcitypes.FlagDisableABCIQueryMutex, true) - viper.SetDefault(appconfig.FlagDynamicGpMode, types.CloseMode) + viper.SetDefault(appconfig.FlagDynamicGpMode, types.MinimalGpMode) viper.SetDefault(iavl.FlagIavlEnableAsyncCommit, true) viper.SetDefault(store.FlagIavlCacheSize, 10000000) viper.SetDefault(server.FlagPruning, "everything") @@ -80,8 +80,9 @@ func setValidatorConfig(ctx *server.Context) { viper.SetDefault(appconfig.FlagMaxGasUsedPerBlock, 120000000) viper.SetDefault(mempool.FlagEnablePendingPool, false) + ctx.Logger.Info(fmt.Sprintf("Set --%s=%v\n--%s=%v\n--%s=%v\n--%s=%v\n--%s=%v\n--%s=%v\n--%s=%v\n--%s=%v\n--%s=%v by validator node mode", - abcitypes.FlagDisableABCIQueryMutex, true, appconfig.FlagDynamicGpMode, types.CloseMode, iavl.FlagIavlEnableAsyncCommit, true, + abcitypes.FlagDisableABCIQueryMutex, true, appconfig.FlagDynamicGpMode, types.MinimalGpMode, iavl.FlagIavlEnableAsyncCommit, true, store.FlagIavlCacheSize, 10000000, server.FlagPruning, "everything", evmtypes.FlagEnableBloomFilter, false, watcher.FlagFastQuery, false, appconfig.FlagMaxGasUsedPerBlock, 120000000, mempool.FlagEnablePendingPool, false)) diff --git a/app/rpc/namespaces/eth/api.go b/app/rpc/namespaces/eth/api.go index df20fe048d..4f20387d65 100644 --- a/app/rpc/namespaces/eth/api.go +++ b/app/rpc/namespaces/eth/api.go @@ -252,7 +252,7 @@ func (api *PublicEthereumAPI) GasPrice() *hexutil.Big { monitor := monitor.GetMonitor("eth_gasPrice", api.logger, api.Metrics).OnBegin() defer monitor.OnEnd() - if appconfig.GetOecConfig().GetDynamicGpMode() != types.CloseMode { + if appconfig.GetOecConfig().GetDynamicGpMode() != types.MinimalGpMode { price := new(big.Int).Set(app.GlobalGp) if price.Cmp((*big.Int)(api.gasPrice)) == -1 { price.Set((*big.Int)(api.gasPrice)) diff --git a/app/types/gasprice.go b/app/types/gasprice.go index 4b7450adba..d7e633d19d 100644 --- a/app/types/gasprice.go +++ b/app/types/gasprice.go @@ -11,7 +11,7 @@ const ( CongestionHigherGpMode = 0 NormalGpMode = 1 - CloseMode = 2 + MinimalGpMode = 2 NoGasUsedCap = -1 ) @@ -53,8 +53,7 @@ func (bgp *SingleBlockGPs) AddSampledGP(gp *big.Int) { } func (bgp *SingleBlockGPs) Update(gp *big.Int, gas uint64) { - gpCopy := new(big.Int).Set(gp) - bgp.all = append(bgp.all, gpCopy) + bgp.all = append(bgp.all, gp) bgp.gasUsed += gas } diff --git a/cmd/client/flags.go b/cmd/client/flags.go index 7ff9ef6110..eb2912647e 100644 --- a/cmd/client/flags.go +++ b/cmd/client/flags.go @@ -64,7 +64,7 @@ func RegisterAppFlag(cmd *cobra.Command) { cmd.Flags().Int(config.FlagDynamicGpWeight, 80, "The recommended weight of dynamic gas price [1,100])") cmd.Flags().Int(config.FlagDynamicGpCheckBlocks, 5, "The recommended number of blocks checked of dynamic gas price [1,100])") cmd.Flags().Int(config.FlagDynamicGpCoefficient, 1, "Adjustment coefficient of dynamic gas price [1,100])") - cmd.Flags().Int(config.FlagDynamicGpMode, types.CongestionHigherGpMode, "Dynamic gas price mode (0: higher price|1: normal|2: close) is used to manage flags") + cmd.Flags().Int(config.FlagDynamicGpMode, types.MinimalGpMode, "Dynamic gas price mode (0: higher price|1: normal price|2: minimal price) is used to manage flags") cmd.Flags().Bool(config.FlagEnableHasBlockPartMsg, false, "Enable peer to broadcast HasBlockPartMessage") cmd.Flags().Bool(eth.FlagEnableMultiCall, false, "Enable node to support the eth_multiCall RPC API") diff --git a/libs/cosmos-sdk/baseapp/baseapp.go b/libs/cosmos-sdk/baseapp/baseapp.go index 97a06995d1..77596b0714 100644 --- a/libs/cosmos-sdk/baseapp/baseapp.go +++ b/libs/cosmos-sdk/baseapp/baseapp.go @@ -12,6 +12,8 @@ import ( "time" "github.com/gogo/protobuf/proto" + "github.com/spf13/viper" + "github.com/okex/exchain/libs/cosmos-sdk/codec/types" "github.com/okex/exchain/libs/cosmos-sdk/store" "github.com/okex/exchain/libs/cosmos-sdk/store/mpt" @@ -29,7 +31,6 @@ import ( ctypes "github.com/okex/exchain/libs/tendermint/rpc/core/types" tmtypes "github.com/okex/exchain/libs/tendermint/types" dbm "github.com/okex/exchain/libs/tm-db" - "github.com/spf13/viper" ) const ( @@ -153,6 +154,7 @@ type BaseApp struct { // nolint: maligned getTxFeeAndFromHandler sdk.GetTxFeeAndFromHandler getTxFeeHandler sdk.GetTxFeeHandler + updateGPOHandler sdk.UpdateGPOHandler // volatile states: // // checkState is set on InitChain and reset on Commit diff --git a/libs/cosmos-sdk/baseapp/baseapp_parallel.go b/libs/cosmos-sdk/baseapp/baseapp_parallel.go index 1f6408b877..16f09be17c 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_parallel.go +++ b/libs/cosmos-sdk/baseapp/baseapp_parallel.go @@ -6,12 +6,13 @@ import ( "sync" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/spf13/viper" + "github.com/okex/exchain/libs/cosmos-sdk/store/types" sdk "github.com/okex/exchain/libs/cosmos-sdk/types" sdkerrors "github.com/okex/exchain/libs/cosmos-sdk/types/errors" abci "github.com/okex/exchain/libs/tendermint/abci/types" sm "github.com/okex/exchain/libs/tendermint/state" - "github.com/spf13/viper" ) var ( @@ -57,6 +58,7 @@ func (app *BaseApp) getExtraDataByTxs(txs [][]byte) { } if tx != nil { app.blockDataCache.SetTx(txBytes, tx) + para.dynamicGpInfos[index].SetGP(tx.GetGasPrice()) } coin, isEvm, s, toAddr, _ := app.getTxFeeAndFromHandler(app.getContextForTx(runTxModeDeliver, txBytes), tx) @@ -343,6 +345,10 @@ func (app *BaseApp) endParallelTxs() [][]byte { resp[index] = txRes.resp watchers[index] = txRes.watcher txs[index] = app.parallelTxManage.extraTxsInfo[index].stdTx + + // int64 -> uint64 may not be safe + app.parallelTxManage.dynamicGpInfos[index].SetGU(uint64(txRes.resp.GasUsed)) + if txRes.FeeSpiltInfo.HasFee { app.FeeSplitCollector = append(app.FeeSplitCollector, txRes.FeeSpiltInfo) } @@ -350,6 +356,9 @@ func (app *BaseApp) endParallelTxs() [][]byte { } app.watcherCollector(watchers...) app.parallelTxManage.clear() + + app.updateGPOHandler(app.parallelTxManage.dynamicGpInfos) + return app.logFix(txs, logIndex, hasEnterEvmTx, errs, resp) } @@ -635,6 +644,8 @@ type parallelTxManager struct { blockMultiStores *cacheMultiStoreList chainMultiStores *cacheMultiStoreList + + dynamicGpInfos []sdk.DynamicGasInfo } func newParallelTxManager() *parallelTxManager { @@ -745,6 +756,7 @@ func (f *parallelTxManager) clear() { func (f *parallelTxManager) init() { txSize := f.txSize + f.dynamicGpInfos = make([]sdk.DynamicGasInfo, txSize) f.txResultCollector.init(txSize) f.finalResult = make([]*executeResult, txSize) diff --git a/libs/cosmos-sdk/baseapp/baseapp_runtx.go b/libs/cosmos-sdk/baseapp/baseapp_runtx.go index ad3b8196e7..035f0e0ca4 100644 --- a/libs/cosmos-sdk/baseapp/baseapp_runtx.go +++ b/libs/cosmos-sdk/baseapp/baseapp_runtx.go @@ -4,9 +4,10 @@ import ( "fmt" "runtime/debug" - "github.com/okex/exchain/libs/system/trace" "github.com/pkg/errors" + "github.com/okex/exchain/libs/system/trace" + sdk "github.com/okex/exchain/libs/cosmos-sdk/types" sdkerrors "github.com/okex/exchain/libs/cosmos-sdk/types/errors" abci "github.com/okex/exchain/libs/tendermint/abci/types" @@ -305,6 +306,8 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx return sdkerrors.ResponseDeliverTx(err, info.gInfo.GasWanted, info.gInfo.GasUsed, app.trace) } + app.updateGPOHandler([]sdk.DynamicGasInfo{sdk.NewDynamicGasInfo(realTx.GetGasPrice(), info.gInfo.GasUsed)}) + return abci.ResponseDeliverTx{ GasWanted: int64(info.gInfo.GasWanted), // TODO: Should type accept unsigned ints? GasUsed: int64(info.gInfo.GasUsed), // TODO: Should type accept unsigned ints? @@ -357,6 +360,9 @@ func (app *BaseApp) DeliverRealTx(txes abci.TxEssentials) abci.ResponseDeliverTx if err != nil { return sdkerrors.ResponseDeliverTx(err, info.gInfo.GasWanted, info.gInfo.GasUsed, app.trace) } + + app.updateGPOHandler([]sdk.DynamicGasInfo{sdk.NewDynamicGasInfo(realTx.GetGasPrice(), info.gInfo.GasUsed)}) + return abci.ResponseDeliverTx{ GasWanted: int64(info.gInfo.GasWanted), // TODO: Should type accept unsigned ints? GasUsed: int64(info.gInfo.GasUsed), // TODO: Should type accept unsigned ints? diff --git a/libs/cosmos-sdk/baseapp/options.go b/libs/cosmos-sdk/baseapp/options.go index 39d0fc76df..04ecdde22d 100644 --- a/libs/cosmos-sdk/baseapp/options.go +++ b/libs/cosmos-sdk/baseapp/options.go @@ -222,3 +222,10 @@ func (app *BaseApp) SetGetTxFeeHandler(handler sdk.GetTxFeeHandler) { func (app *BaseApp) SetTmClient(client client.Client) { app.tmClient = client } + +func (app *BaseApp) SetUpdateGPOHandler(handler sdk.UpdateGPOHandler) { + if app.sealed { + panic("SetUpdateGPOHandler() on sealed BaseApp") + } + app.updateGPOHandler = handler +} diff --git a/libs/cosmos-sdk/types/gasprice.go b/libs/cosmos-sdk/types/gasprice.go new file mode 100644 index 0000000000..241a0097d6 --- /dev/null +++ b/libs/cosmos-sdk/types/gasprice.go @@ -0,0 +1,42 @@ +package types + +import "math/big" + +type DynamicGasInfo struct { + // gas price + gp *big.Int + // gas used + gu uint64 +} + +func NewDynamicGasInfo(gp *big.Int, gu uint64) DynamicGasInfo { + return DynamicGasInfo{ + gp: new(big.Int).Set(gp), + gu: gu, + } +} + +func NewEmptyDynamicGasInfo() DynamicGasInfo { + return DynamicGasInfo{ + gp: big.NewInt(0), + gu: 0, + } +} + +func (info DynamicGasInfo) GetGP() *big.Int { + return info.gp +} + +func (info *DynamicGasInfo) SetGP(gp *big.Int) { + // deep copy + gpCopy := new(big.Int).Set(gp) + info.gp = gpCopy +} + +func (info DynamicGasInfo) GetGU() uint64 { + return info.gu +} + +func (info *DynamicGasInfo) SetGU(gu uint64) { + info.gu = gu +} diff --git a/libs/cosmos-sdk/types/handler.go b/libs/cosmos-sdk/types/handler.go index 54f455635c..0894c94bc7 100644 --- a/libs/cosmos-sdk/types/handler.go +++ b/libs/cosmos-sdk/types/handler.go @@ -27,7 +27,7 @@ type LogFix func(tx []Tx, logIndex []int, hasEnterEvmTx []bool, errs []error, re type UpdateFeeSplitHandler func(txHash common.Hash, addr AccAddress, fee Coins, isDelete bool) type GetTxFeeAndFromHandler func(ctx Context, tx Tx) (Coins, bool, string, string, error) type GetTxFeeHandler func(tx Tx) Coins - +type UpdateGPOHandler func(dynamicGpInfos []DynamicGasInfo) type CustomizeOnStop func(ctx Context) error type MptCommitHandler func(ctx Context)