update suggestion gas price

This commit is contained in:
Solovyov1796 2025-02-13 02:19:08 +08:00
parent e54d5ba99a
commit 4d95fd5f30
6 changed files with 13 additions and 152 deletions

View File

@ -2,10 +2,7 @@ package app
import (
"fmt"
"math/big"
"sort"
"github.com/0glabs/0g-chain/chaincfg"
"github.com/cockroachdb/errors"
abci "github.com/cometbft/cometbft/abci/types"
gethtypes "github.com/ethereum/go-ethereum/core/types"
@ -16,8 +13,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
const gasPriceSuggestionBlockNum int64 = 5
type (
// GasTx defines the contract that a transaction with a gas limit must implement.
GasTx interface {
@ -35,29 +30,17 @@ type (
// DefaultProposalHandler defines the default ABCI PrepareProposal and
// ProcessProposal handlers.
DefaultProposalHandler struct {
mempool mempool.Mempool
txVerifier ProposalTxVerifier
txSelector TxSelector
feemarketKeeper FeeMarketKeeper
}
FeeMarketKeeper interface {
SetSuggestionGasPrice(ctx sdk.Context, gas *big.Int)
}
txnInfo struct {
gasPrice *big.Int
gasLimit uint64
nonce uint64
sender string
mempool mempool.Mempool
txVerifier ProposalTxVerifier
txSelector TxSelector
}
)
func NewDefaultProposalHandler(mp mempool.Mempool, txVerifier ProposalTxVerifier, feemarketKeeper FeeMarketKeeper) *DefaultProposalHandler {
func NewDefaultProposalHandler(mp mempool.Mempool, txVerifier ProposalTxVerifier) *DefaultProposalHandler {
return &DefaultProposalHandler{
mempool: mp,
txVerifier: txVerifier,
txSelector: NewDefaultTxSelector(),
feemarketKeeper: feemarketKeeper,
mempool: mp,
txVerifier: txVerifier,
txSelector: NewDefaultTxSelector(),
}
}
@ -114,14 +97,11 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan
return abci.ResponsePrepareProposal{Txs: h.txSelector.SelectedTxs()}
}
txnInfoMap := make(map[string][]*txnInfo, h.mempool.CountTx())
iterator := h.mempool.Select(ctx, req.Txs)
selectedTxsSignersSeqs := make(map[string]uint64)
var selectedTxsNums int
for iterator != nil {
memTx := iterator.Tx()
sigs, err := memTx.(signing.SigVerifiableTx).GetSignaturesV2()
if err != nil {
panic(fmt.Errorf("failed to get signatures: %w", err))
@ -154,42 +134,10 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan
txSignersSeqs[signer] = nonce
}
}
if _, exists := txnInfoMap[signer]; !exists {
txnInfoMap[signer] = make([]*txnInfo, 0, 128)
}
txnInfoMap[signer] = append(txnInfoMap[signer], &txnInfo{
gasPrice: ethTx.GasPrice(),
gasLimit: ethTx.Gas(),
nonce: nonce,
sender: signer,
})
}
}
}
} else {
// ignore multisig case now
fee := memTx.(sdk.Fee)
if len(sigs) == 1 {
signer := sdk.AccAddress(sigs[0].PubKey.Address()).String()
if _, exists := txnInfoMap[signer]; !exists {
txnInfoMap[signer] = make([]*txnInfo, 0, 16)
}
evmGasPrice, err := utilCosmosDemonGasPriceToEvmDemonGasPrice(fee.GetAmount())
if err == nil {
txnInfoMap[signer] = append(txnInfoMap[signer], &txnInfo{
gasPrice: evmGasPrice,
gasLimit: utilCosmosDemonGasLimitToEvmDemonGasLimit(fee.GetGas()),
nonce: sigs[0].Sequence,
sender: signer,
})
}
}
for _, sig := range sigs {
signer := sdk.AccAddress(sig.PubKey.Address()).String()
seq, ok := selectedTxsSignersSeqs[signer]
@ -250,65 +198,6 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan
iterator = iterator.Next()
}
if len(txnInfoMap) == 0 {
h.feemarketKeeper.SetSuggestionGasPrice(ctx, big.NewInt(0))
} else {
senderCnt := 0
txnCnt := 0
for sender := range txnInfoMap {
sort.Slice(txnInfoMap[sender], func(i, j int) bool {
return txnInfoMap[sender][i].nonce < txnInfoMap[sender][j].nonce
})
txnCnt += len(txnInfoMap[sender])
senderCnt++
}
remaing := gasPriceSuggestionBlockNum * int64(maxBlockGas)
var lastProcessedTx *txnInfo
for remaing > 0 && len(txnInfoMap) > 0 {
// Find the highest gas price among the first transaction of each account
var highestGasPrice *big.Int
var selectedSender string
// Compare first transaction (lowest nonce) from each account
for sender, txns := range txnInfoMap {
if len(txns) == 0 {
delete(txnInfoMap, sender)
continue
}
// First tx has lowest nonce due to earlier sorting
if highestGasPrice == nil || txns[0].gasPrice.Cmp(highestGasPrice) > 0 {
highestGasPrice = txns[0].gasPrice
selectedSender = sender
}
}
if selectedSender == "" {
break
}
// Process the selected transaction
selectedTx := txnInfoMap[selectedSender][0]
remaing -= int64(selectedTx.gasLimit)
lastProcessedTx = selectedTx
// Remove processed transaction
txnInfoMap[selectedSender] = txnInfoMap[selectedSender][1:]
if len(txnInfoMap[selectedSender]) == 0 {
delete(txnInfoMap, selectedSender)
}
}
if lastProcessedTx != nil && remaing <= 0 {
h.feemarketKeeper.SetSuggestionGasPrice(ctx, lastProcessedTx.gasPrice)
} else {
h.feemarketKeeper.SetSuggestionGasPrice(ctx, big.NewInt(0))
}
}
return abci.ResponsePrepareProposal{Txs: h.txSelector.SelectedTxs()}
}
}
@ -447,22 +336,3 @@ func (ts *defaultTxSelector) SelectTxForProposal(maxTxBytes, maxBlockGas uint64,
// check if we've reached capacity; if so, we cannot select any more transactions
return ts.totalTxBytes >= maxTxBytes || (maxBlockGas > 0 && (ts.totalTxGas >= maxBlockGas))
}
func utilCosmosDemonGasPriceToEvmDemonGasPrice(gasGroup sdk.Coins) (*big.Int, error) {
gasPrice := big.NewInt(0)
for _, coin := range gasGroup {
if coin.Denom == chaincfg.GasDenom {
thisGasPrice := big.NewInt(0).SetUint64(coin.Amount.Uint64())
thisGasPrice = thisGasPrice.Mul(thisGasPrice, big.NewInt(0).SetInt64(chaincfg.GasDenomConversionMultiplier))
gasPrice = gasPrice.Add(gasPrice, thisGasPrice)
} else {
return big.NewInt(0), fmt.Errorf("invalid denom: %s", coin.Denom)
}
}
return gasPrice, nil
}
func utilCosmosDemonGasLimitToEvmDemonGasLimit(gasLimit uint64) uint64 {
return gasLimit * chaincfg.GasDenomConversionMultiplier
}

View File

@ -62,7 +62,6 @@ func TestAppAnteHandler_AuthorizedMempool(t *testing.T) {
encodingConfig,
baseapp.SetChainID(app.TestChainId),
),
nil,
),
}

View File

@ -313,7 +313,6 @@ func NewApp(
encodingConfig chainparams.EncodingConfig,
options Options,
bApp *baseapp.BaseApp,
setAbciProposalHandler func(feemarketKeeper FeeMarketKeeper) sdk.PrepareProposalHandler,
) *App {
appCodec := encodingConfig.Marshaler
legacyAmino := encodingConfig.Amino
@ -490,6 +489,7 @@ func NewApp(
keys[feemarkettypes.StoreKey],
tkeys[feemarkettypes.TransientKey],
feemarketSubspace,
bApp.Mempool(),
)
app.evmutilKeeper = evmutilkeeper.NewKeeper(
@ -902,10 +902,6 @@ func NewApp(
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
if setAbciProposalHandler != nil {
abciProposalHandler := setAbciProposalHandler(app.feeMarketKeeper)
bApp.SetPrepareProposal(abciProposalHandler)
}
// load store
if !options.SkipLoadLatest {
if err := app.LoadLatestVersion(); err != nil {

View File

@ -38,7 +38,6 @@ func TestNewApp(t *testing.T) {
MakeEncodingConfig(),
baseapp.SetChainID(TestChainId),
),
nil,
)
}
@ -56,7 +55,6 @@ func TestExport(t *testing.T) {
MakeEncodingConfig(),
baseapp.SetChainID(TestChainId),
),
nil,
)
genesisState := GenesisStateWithSingleValidator(&TestApp{App: *app}, NewDefaultGenesisState())

View File

@ -96,7 +96,7 @@ func NewTestAppFromSealed() TestApp {
bApp := NewBaseApp(log.NewNopLogger(), db, encCfg, baseapp.SetChainID(TestChainId))
app := NewApp(
chaincfg.DefaultNodeHome, nil,
encCfg, DefaultOptions, bApp, nil,
encCfg, DefaultOptions, bApp,
)
return TestApp{App: *app}
}

View File

@ -126,6 +126,8 @@ func (ac appCreator) newApp(
baseapp.SetMempool(mempool),
)
bApp.SetTxEncoder(ac.encodingConfig.TxConfig.TxEncoder())
abciProposalHandler := app.NewDefaultProposalHandler(mempool, bApp)
bApp.SetPrepareProposal(abciProposalHandler.PrepareProposalHandler())
newApp := app.NewApp(
homeDir, traceStore, ac.encodingConfig,
@ -140,10 +142,6 @@ func (ac appCreator) newApp(
EVMMaxGasWanted: cast.ToUint64(appOpts.Get(ethermintflags.EVMMaxTxGasWanted)),
},
bApp,
func(k app.FeeMarketKeeper) sdk.PrepareProposalHandler {
abciProposalHandler := app.NewDefaultProposalHandler(mempool, bApp, k)
return abciProposalHandler.PrepareProposalHandler()
},
)
return newApp
@ -172,14 +170,14 @@ func (ac appCreator) appExport(
var tempApp *app.App
if height != -1 {
bApp := app.NewBaseApp(logger, db, ac.encodingConfig)
tempApp = app.NewApp(homePath, traceStore, ac.encodingConfig, options, bApp, nil)
tempApp = app.NewApp(homePath, traceStore, ac.encodingConfig, options, bApp)
if err := tempApp.LoadHeight(height); err != nil {
return servertypes.ExportedApp{}, err
}
} else {
bApp := app.NewBaseApp(logger, db, ac.encodingConfig)
tempApp = app.NewApp(homePath, traceStore, ac.encodingConfig, options, bApp, nil)
tempApp = app.NewApp(homePath, traceStore, ac.encodingConfig, options, bApp)
}
return tempApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
}