Skip to content

Commit 04ce2e1

Browse files
almk-devvladjdkaljo242
authored
refactor(config): Expose mempool configuration flags and move mempool app configuration to helper (#698)
* move tests to remove circular dependency * remove ante2 * wip: move all config files out of evmd * wip: add todos * reset config to fix test * fix evmd tests by adding resets to the evmappoptions * remove testutil/config constants consolidates these constants into one file in /config * fix eips test the test was using a duplicate eips multiplier value instead of the global one moved to config * remove all configs except for genesis from testutil/config and consolidate into /config * changelogchangelogchangelogchangelogchangelog * lints * wip: removing app options (tests failing) app options is removed from new app creation. however, we're getting a recovered panic on *restarting* the chain due to prepareproposal running before preblocker: +0x120\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).PrepareProposal.func1()\n\tgithub.com/cosmos/[email protected]/baseapp/abci.go:433 +0x38\npanic({0x1061c8160?, 0x10912faa0?})\n\truntime/panic.go:783 +0x120\ngithub.com/cosmos/evm/x/vm/types.GetEVMCoinDecimals(...)\n\tgithub.com/cosmos/[email protected]/x/vm/types/denom_config.go:61\ngithub.com/cosmos/evm/x/vm/types.ConvertAmountTo18DecimalsLegacy(...)\n\tgithub.com/cosmos/[email protected]/x/vm/types/scaling.go:17\ngithub.com/cosmos/evm/x/vm/wrappers.FeeMarketWrapper.GetBaseFee({{_, _}}, {{0x10698a810, 0x109225540}, {0x1069b51c0, 0x14001f4c200}, {{0x0, 0x0}, {0x16dc0f689, 0x4}, ...}, ...})\n\tgithub.com/cosmos/[email protected]/x/vm/wrappers/feemarket.go:38 +0x68\ngithub.com/cosmos/evm/x/vm/keeper.Keeper.GetBaseFee({{0x1069b4890, 0x14001eddeb0}, {0x10695e0b0, 0x14003560450}, {0x10695e240, 0x14003560490}, 0x140035637a0, {0x1400189d3e0, 0x14, 0x20}, ...}, ...)\n\tgithub.com/cosmos/[email protected]/x/vm/keeper/keeper.go:355 +0xe4\ngithub.com/cosmos/evm/mempool.(*ExperimentalEVMMempool).getIterators(0x14003cbd180, {0x10698a848?, 0x14002c39c08?}, {0x109225540, 0x0, 0x0})\n\tgithub.com/cosmos/[email protected]/mempool/mempool.go:439 +0x20c\ngithub.com/cosmos/evm/mempool.(*ExperimentalEVMMempool).SelectBy(0x14003cbd180, {0x10698a848?, 0x14002c39c08?}, {0x109225540?, 0x14000085ce8?, 0x104cce034?}, 0x140044cd540)\n\tgithub.com/cosmos/[email protected]/mempool/mempool.go:370 +0xe0\ngithub.com/cosmos/cosmos-sdk/types/mempool.SelectBy({0x10698a848?, 0x14002c39c08?}, {0x10698b108?, 0x14003cbd180?}, {0x109225540?, 0x0?, 0x0?}, 0x140044cd540)\n\tgithub.com/cosmos/[email protected]/types/mempool/mempool.go:58 +0xa0\ngithub.com/cosmos/evm/evmd.NewExampleApp.(*DefaultProposalHandler).PrepareProposalHandler.func3({{0x10698a810, 0x109225540}, {0x1069b51c0, 0x14001f4c200}, {{0x0, 0x0}, {0x16dc0f689, 0x4}, 0xd, {0x3507e5b0, ...}, ...}, ...}, ...)\n\tgithub.com/cosmos/[email protected]/baseapp/abci_utils.go:294 +0x250\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).PrepareProposal(0x14002d32488, 0x140015f42c0)\n\tgithub.com/cosmos/[email protected]/baseapp/abci.go:439 * begin storing coin info in the vm keeper storage the mempool needed the global variable, but that wasn't set, so we set it in the vm keeper storage and use it from there in the mempool everything else still uses the global variable, but we now have a foundation to move it over to the state storage * remove debugging artifact * artifact removal 2 * fix unit tests * wip: fix ibc testing * delete all evmappoptions from tests * fix ibc precompile integration test balance getters we were getting the 6 decimal balance when we were operating in 18-balance territory. now that we have a separation in the ibc tests, we should check balances accordingly * fix all evmd tests * fix precisebank keeper test * fix smore tests * lol * add upgrade handler * lints * changelog * Fix imports, add upgrade for non-18-decimal chains, and add migration guide * fix system test * Update docs/migrations/v0.4.0_to_v0.5.0_UNRELEASED.md Co-authored-by: Abdul Malek <[email protected]> * fix monodecorator test * Remove test* denoms and replace with default* * extract var * match vars * remove chain config from configurator * undo uint8 change * comment fixes * Auto stash before merge of "vlad/remove-app-options" and "origin/main" * set chain config in vm integ tests * lint * fix error on test * fix denoms for ibc chain * add mempool config helper * Revert "fix denoms for ibc chain" This reverts commit cbbaa44. * add mempool config helper * use app options chain id instead of passing param * lints * revert make race * add changelog * expore legacy fields * use default config * add mempool config helper * add changelog * expore legacy fields * use default config * fix tests * clean up config creator * get rid of obvious comments * fix lint * add bindings * unbounded txs * add max txs flag binding * set to int * add mempool config to docs * max-txs param in eip tests --------- Co-authored-by: Vlad <[email protected]> Co-authored-by: Alex | Cosmos Labs <[email protected]>
1 parent 83a8ad8 commit 04ce2e1

File tree

12 files changed

+334
-25
lines changed

12 files changed

+334
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
### IMPROVEMENTS
2727

28+
- [\#698](https://github.com/cosmos/evm/pull/698) Expose mempool configuration flags and move mempool configuration in app.go to helper
2829
- [\#538](https://github.com/cosmos/evm/pull/538) Optimize `eth_estimateGas` gRPC path: short-circuit plain transfers, add optimistic gas bound based on `MaxUsedGas`.
2930
- [\#513](https://github.com/cosmos/evm/pull/513) Replace `TestEncodingConfig` with production `EncodingConfig` in encoding package to remove test dependencies from production code.
3031
- [\#467](https://github.com/cosmos/evm/pull/467) Replace GlobalEVMMempool by passing to JSONRPC on initiate.

config/server_app_options.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/holiman/uint256"
88
"github.com/spf13/cast"
99

10+
"github.com/cosmos/evm/mempool/txpool/legacypool"
1011
srvflags "github.com/cosmos/evm/server/flags"
1112

1213
"cosmossdk.io/log"
@@ -21,6 +22,11 @@ import (
2122
// GetBlockGasLimit reads the genesis json file using AppGenesisFromFile
2223
// to extract the consensus block gas limit before InitChain is called.
2324
func GetBlockGasLimit(appOpts servertypes.AppOptions, logger log.Logger) uint64 {
25+
if appOpts == nil {
26+
logger.Error("app options is nil, using zero block gas limit")
27+
return math.MaxUint64
28+
}
29+
2430
homeDir := cast.ToString(appOpts.Get(flags.FlagHome))
2531
if homeDir == "" {
2632
logger.Error("home directory not found in app options, using zero block gas limit")
@@ -69,6 +75,11 @@ func GetBlockGasLimit(appOpts servertypes.AppOptions, logger log.Logger) uint64
6975
// This is currently not used, but is kept in case this is useful for the mempool,
7076
// in addition to the min tip flag
7177
func GetMinGasPrices(appOpts servertypes.AppOptions, logger log.Logger) sdk.DecCoins {
78+
if appOpts == nil {
79+
logger.Error("app options is nil, using empty DecCoins")
80+
return sdk.DecCoins{}
81+
}
82+
7283
minGasPricesStr := cast.ToString(appOpts.Get(sdkserver.FlagMinGasPrices))
7384
minGasPrices, err := sdk.ParseDecCoins(minGasPricesStr)
7485
if err != nil {
@@ -82,6 +93,11 @@ func GetMinGasPrices(appOpts servertypes.AppOptions, logger log.Logger) sdk.DecC
8293
// GetMinTip reads the min tip from the app options, set from app.toml
8394
// This field is also known as the minimum priority fee
8495
func GetMinTip(appOpts servertypes.AppOptions, logger log.Logger) *uint256.Int {
96+
if appOpts == nil {
97+
logger.Error("app options is nil, using zero min tip")
98+
return nil
99+
}
100+
85101
minTipUint64 := cast.ToUint64(appOpts.Get(srvflags.EVMMinTip))
86102
minTip := uint256.NewInt(minTipUint64)
87103

@@ -92,3 +108,46 @@ func GetMinTip(appOpts servertypes.AppOptions, logger log.Logger) *uint256.Int {
92108
logger.Error("invalid min tip value in app.toml or flag, falling back to nil", "min_tip", minTipUint64)
93109
return nil
94110
}
111+
112+
// GetLegacyPoolConfig reads the legacy pool configuration from appOpts and overrides
113+
// default values with values from app.toml if they exist and are non-zero.
114+
func GetLegacyPoolConfig(appOpts servertypes.AppOptions, logger log.Logger) *legacypool.Config {
115+
if appOpts == nil {
116+
logger.Error("app options is nil, using default mempool config")
117+
return &legacypool.DefaultConfig
118+
}
119+
120+
legacyConfig := legacypool.DefaultConfig
121+
if priceLimit := cast.ToUint64(appOpts.Get(srvflags.EVMMempoolPriceLimit)); priceLimit != 0 {
122+
legacyConfig.PriceLimit = priceLimit
123+
}
124+
if priceBump := cast.ToUint64(appOpts.Get(srvflags.EVMMempoolPriceBump)); priceBump != 0 {
125+
legacyConfig.PriceBump = priceBump
126+
}
127+
if accountSlots := cast.ToUint64(appOpts.Get(srvflags.EVMMempoolAccountSlots)); accountSlots != 0 {
128+
legacyConfig.AccountSlots = accountSlots
129+
}
130+
if globalSlots := cast.ToUint64(appOpts.Get(srvflags.EVMMempoolGlobalSlots)); globalSlots != 0 {
131+
legacyConfig.GlobalSlots = globalSlots
132+
}
133+
if accountQueue := cast.ToUint64(appOpts.Get(srvflags.EVMMempoolAccountQueue)); accountQueue != 0 {
134+
legacyConfig.AccountQueue = accountQueue
135+
}
136+
if globalQueue := cast.ToUint64(appOpts.Get(srvflags.EVMMempoolGlobalQueue)); globalQueue != 0 {
137+
legacyConfig.GlobalQueue = globalQueue
138+
}
139+
if lifetime := cast.ToDuration(appOpts.Get(srvflags.EVMMempoolLifetime)); lifetime != 0 {
140+
legacyConfig.Lifetime = lifetime
141+
}
142+
143+
return &legacyConfig
144+
}
145+
146+
func GetCosmosPoolMaxTx(appOpts servertypes.AppOptions, logger log.Logger) int {
147+
if appOpts == nil {
148+
logger.Error("app options is nil, using default cosmos pool max tx of -1 (no-op)")
149+
return 0
150+
}
151+
152+
return cast.ToInt(appOpts.Get(sdkserver.FlagMempoolMaxTxs))
153+
}

docs/migrations/v0.4.0_to_v0.5.0_UNRELEASED.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,79 @@ mempoolConfig.CosmosPoolConfig = &cosmosCfg
135135
mempoolConfig.BroadCastTxFn = func(txs []*ethtypes.Transaction) error { return nil }
136136
```
137137

138+
#### New Configuration Options
139+
140+
PR [#698](https://github.com/cosmos/evm/pull/698) adds new configuration options for the EVM mempool that can be set via `app.toml` or CLI flags. These options allow fine-tuning of the EVM legacy pool behavior.
141+
142+
##### Configuration via `app.toml`
143+
144+
The following mempool configuration options are now available in `app.toml` under the `[evm.mempool]` section:
145+
146+
```toml
147+
[evm.mempool]
148+
# PriceLimit is the minimum gas price to enforce for acceptance into the pool (in wei)
149+
price-limit = 1
150+
151+
# PriceBump is the minimum price bump percentage to replace an already existing transaction (nonce)
152+
price-bump = 10
153+
154+
# AccountSlots is the number of executable transaction slots guaranteed per account
155+
account-slots = 16
156+
157+
# GlobalSlots is the maximum number of executable transaction slots for all accounts
158+
global-slots = 5120
159+
160+
# AccountQueue is the maximum number of non-executable transaction slots permitted per account
161+
account-queue = 64
162+
163+
# GlobalQueue is the maximum number of non-executable transaction slots for all accounts
164+
global-queue = 1024
165+
166+
# Lifetime is the maximum amount of time non-executable transaction are queued
167+
lifetime = "3h0m0s"
168+
```
169+
170+
##### Configuration via CLI Flags
171+
172+
These options can also be set via CLI flags:
173+
174+
- `--evm.mempool.price-limit` (default: 1)
175+
- `--evm.mempool.price-bump` (default: 10)
176+
- `--evm.mempool.account-slots` (default: 16)
177+
- `--evm.mempool.global-slots` (default: 5120)
178+
- `--evm.mempool.account-queue` (default: 64)
179+
- `--evm.mempool.global-queue` (default: 1024)
180+
- `--evm.mempool.lifetime` (default: 3h0m0s)
181+
182+
##### Cosmos Mempool Max Transactions
183+
184+
A new flag `--mempool.max-txs` allows limiting the maximum number of transactions in the Cosmos mempool. Set to 0 or -1 for unbounded (default: 0).
185+
186+
##### Simplified Mempool Setup
187+
188+
The mempool configuration can now be handled by a helper function. If you prefer to use the configuration from `app.toml` and CLI flags, you can refactor your mempool setup:
189+
190+
```go
191+
// Before: Manual configuration in app.go
192+
mempoolConfig := &evmmempool.EVMMempoolConfig{
193+
AnteHandler: app.GetAnteHandler(),
194+
BlockGasLimit: blockGasLimit,
195+
MinTip: minTip,
196+
}
197+
evmMempool := evmmempool.NewExperimentalEVMMempool(
198+
app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper,
199+
app.txConfig, app.clientCtx, mempoolConfig,
200+
)
201+
202+
// After: Using helper function (optional)
203+
// See evmd/mempool.go for reference implementation
204+
if err := app.configureEVMMempool(appOpts, logger); err != nil {
205+
panic(fmt.Sprintf("failed to configure EVM mempool: %s", err.Error()))
206+
}
207+
```
208+
209+
The helper function reads configuration from `appOpts` and applies defaults where needed. Note that `NewExperimentalEVMMempool` now takes an additional `cosmosPoolMaxTx` parameter.
210+
138211
### Default Precompiles
139212

140213
Default precompiles have been moved to `/evm/precompiles/types/defaults.go` and the function name was
@@ -175,6 +248,18 @@ and moves them to state or genesis.
175248
It is critical to remove any use of EvmAppOptions as calling the configurator will panic the chain
176249
at runtime during startup.
177250

251+
#### EVM Chain ID
252+
253+
The EVM chain ID is now retrieved directly from `appOpts` instead of being passed as a parameter. In `app.go`, the chain ID is obtained using:
254+
255+
```go
256+
evmChainID := cast.ToUint64(appOpts.Get(srvflags.EVMChainID))
257+
```
258+
259+
See `evmd/app.go:216` for the reference implementation.
260+
261+
#### Function Signature Changes
262+
178263
In `app.go`, remove evmChainID and evmAppOptions from the NewApp signature.
179264

180265
```diff

evmd/app.go

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -717,29 +717,9 @@ func NewExampleApp(
717717
app.setAnteHandler(app.txConfig, maxGasWanted)
718718

719719
// set the EVM priority nonce mempool
720-
// If you wish to use the noop mempool, remove this codeblock
721-
if evmtypes.GetChainConfig() != nil {
722-
// Get the block gas limit from genesis file
723-
blockGasLimit := evmconfig.GetBlockGasLimit(appOpts, logger)
724-
// Get GetMinTip from app.toml or cli flag configuration
725-
mipTip := evmconfig.GetMinTip(appOpts, logger)
726-
727-
mempoolConfig := &evmmempool.EVMMempoolConfig{
728-
AnteHandler: app.GetAnteHandler(),
729-
BlockGasLimit: blockGasLimit,
730-
MinTip: mipTip,
731-
}
732-
733-
evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
734-
app.EVMMempool = evmMempool
735-
736-
app.SetMempool(evmMempool)
737-
checkTxHandler := evmmempool.NewCheckTxHandler(evmMempool)
738-
app.SetCheckTxHandler(checkTxHandler)
739-
740-
abciProposalHandler := baseapp.NewDefaultProposalHandler(evmMempool, app)
741-
abciProposalHandler.SetSignerExtractionAdapter(evmmempool.NewEthSignerExtractionAdapter(sdkmempool.NewDefaultSignerExtractionAdapter()))
742-
app.SetPrepareProposal(abciProposalHandler.PrepareProposalHandler())
720+
// if you wish to use the noop mempool, remove this codeblock
721+
if err := app.configureEVMMempool(appOpts, logger); err != nil {
722+
panic(fmt.Sprintf("failed to configure EVM mempool: %s", err.Error()))
743723
}
744724

745725
// In v0.46, the SDK introduces _postHandlers_. PostHandlers are like

evmd/mempool.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package evmd
2+
3+
import (
4+
"fmt"
5+
6+
"cosmossdk.io/log"
7+
8+
"github.com/cosmos/cosmos-sdk/baseapp"
9+
servertypes "github.com/cosmos/cosmos-sdk/server/types"
10+
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
11+
12+
evmconfig "github.com/cosmos/evm/config"
13+
evmmempool "github.com/cosmos/evm/mempool"
14+
evmtypes "github.com/cosmos/evm/x/vm/types"
15+
)
16+
17+
// configureEVMMempool sets up the EVM mempool and related handlers using viper configuration.
18+
func (app *EVMD) configureEVMMempool(appOpts servertypes.AppOptions, logger log.Logger) error {
19+
if evmtypes.GetChainConfig() == nil {
20+
logger.Debug("evm chain config is not set, skipping mempool configuration")
21+
return nil
22+
}
23+
24+
mempoolConfig, err := app.createMempoolConfig(appOpts, logger)
25+
if err != nil {
26+
return fmt.Errorf("failed to get mempool config: %w", err)
27+
}
28+
cosmosPoolMaxTx := evmconfig.GetCosmosPoolMaxTx(appOpts, logger)
29+
30+
evmMempool := evmmempool.NewExperimentalEVMMempool(
31+
app.CreateQueryContext,
32+
logger,
33+
app.EVMKeeper,
34+
app.FeeMarketKeeper,
35+
app.txConfig,
36+
app.clientCtx,
37+
mempoolConfig,
38+
cosmosPoolMaxTx,
39+
)
40+
app.EVMMempool = evmMempool
41+
app.SetMempool(evmMempool)
42+
checkTxHandler := evmmempool.NewCheckTxHandler(evmMempool)
43+
app.SetCheckTxHandler(checkTxHandler)
44+
45+
abciProposalHandler := baseapp.NewDefaultProposalHandler(evmMempool, app)
46+
abciProposalHandler.SetSignerExtractionAdapter(
47+
evmmempool.NewEthSignerExtractionAdapter(
48+
sdkmempool.NewDefaultSignerExtractionAdapter(),
49+
),
50+
)
51+
app.SetPrepareProposal(abciProposalHandler.PrepareProposalHandler())
52+
53+
return nil
54+
}
55+
56+
// createMempoolConfig creates a new EVMMempoolConfig with the default configuration
57+
// and overrides it with values from appOpts if they exist and are non-zero.
58+
func (app *EVMD) createMempoolConfig(appOpts servertypes.AppOptions, logger log.Logger) (*evmmempool.EVMMempoolConfig, error) {
59+
return &evmmempool.EVMMempoolConfig{
60+
AnteHandler: app.GetAnteHandler(),
61+
LegacyPoolConfig: evmconfig.GetLegacyPoolConfig(appOpts, logger),
62+
BlockGasLimit: evmconfig.GetBlockGasLimit(appOpts, logger),
63+
MinTip: evmconfig.GetMinTip(appOpts, logger),
64+
}, nil
65+
}

mempool/mempool.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,16 @@ type EVMMempoolConfig struct {
8282
// It initializes both EVM and Cosmos transaction pools, sets up blockchain interfaces,
8383
// and configures fee-based prioritization. The config parameter allows customization
8484
// of pools and verification functions, with sensible defaults created if not provided.
85-
func NewExperimentalEVMMempool(getCtxCallback func(height int64, prove bool) (sdk.Context, error), logger log.Logger, vmKeeper VMKeeperI, feeMarketKeeper FeeMarketKeeperI, txConfig client.TxConfig, clientCtx client.Context, config *EVMMempoolConfig) *ExperimentalEVMMempool {
85+
func NewExperimentalEVMMempool(
86+
getCtxCallback func(height int64, prove bool) (sdk.Context, error),
87+
logger log.Logger,
88+
vmKeeper VMKeeperI,
89+
feeMarketKeeper FeeMarketKeeperI,
90+
txConfig client.TxConfig,
91+
clientCtx client.Context,
92+
config *EVMMempoolConfig,
93+
cosmosPoolMaxTx int,
94+
) *ExperimentalEVMMempool {
8695
var (
8796
cosmosPool sdkmempool.ExtMempool
8897
blockchain *Blockchain
@@ -137,6 +146,7 @@ func NewExperimentalEVMMempool(getCtxCallback func(height int64, prove bool) (sd
137146
panic("tx pool should contain only legacypool")
138147
}
139148

149+
// TODO: move this logic to evmd.createMempoolConfig and set the max tx there
140150
// Create Cosmos Mempool from configuration
141151
cosmosPoolConfig := config.CosmosPoolConfig
142152
if cosmosPoolConfig == nil {
@@ -166,6 +176,7 @@ func NewExperimentalEVMMempool(getCtxCallback func(height int64, prove bool) (sd
166176
cosmosPoolConfig = &defaultConfig
167177
}
168178

179+
cosmosPoolConfig.MaxTx = cosmosPoolMaxTx
169180
cosmosPool = sdkmempool.NewPriorityMempool(*cosmosPoolConfig)
170181

171182
evmMempool := &ExperimentalEVMMempool{

0 commit comments

Comments
 (0)