Skip to content

Commit d38db0e

Browse files
vladjdktechnicallytyAlex | Interchain Labsalmk-devEric-Warehime
authored
(feat):Appside Mempool (cosmos#387)
* wip * wip: iterator * nil check * wip: selectby * add todo * pointer * pointer 2 * remove impl, type assertions * add txpool locally * change statedb types to interface * fix tests * scaffold app setup * Add initial tests to ExtMempool * real priority nonce mempool + fixes * improve test for wrong denom ordering * move initialization to mempool * ok * Nonce gap tx test * revert * bloom parsing dumb * redundant * ignore this dir for markdown linting * Cleanup + Test SelectBy * implement blockchain * update systemtest test tag * add subscription * fix tests * wiring and bug fixes and todos and etc * wip * fix * WIP on vlad/mempool * Auto stash before checking out "origin/vlad/mempool" * rpc no error * clean up logging * verification * Add broadcasting * add retries to tx results * feature: Add txpool namespace stubs ahead of app-side mempool implementation (cosmos#344) * add txpool implementation stubs * update interface * fix lint --------- Co-authored-by: Alex | Interchain Labs <alex@interchainlabs.io> * txpool endpoint * wip refactor * do not allow block 1 submission * fix some tests * fix more tests * fix last remaining evmd test * add second registry for testing * wip: integration tests * wip: functional tests time to add more test cases * fix tests and chain * demo ready todo: fix removals * fix removals (out of gas errors should be skipped) * add gas to config * attempt to fix flakes * strict equalities * FIXED FLAKES * reformat tests into original structure * nonce gap tests * add demo test and fix prev system case * remove done todos and the other mempool * add instructions to remove mempool * remove mocks * lint fixes * review test cases * add some more test cases * fix scripts * add more backoff for testing * remove logs from simplesends * fix systest CI * skip test for now see if main one works * Update .markdownlintignore Co-authored-by: Alex | Interchain Labs <alex@interchainlabs.io> * Update evmd/tests/integration/create_app.go Co-authored-by: Eric Warehime <eric.warehime@gmail.com> * Refactor: Rename 'nonce' to 'accountNonce' in IncrementNonce function * refactor app.go imports * extract atest to constant * fix nonce name test * use actual release * evmd use release tag * refactor ctx -> getCtxCallback * rename errors2 and types2 to sdkerrors and sdktypes * group vars in mempool init * privatize newBlockchain * enhance mempool init readability on nil checks * move txPool checks to right after initialization * use errors.Is for nonce gap errors in rpc * group vars * Update tests/systemtests/.gitignore * refactor iterator to make it more readable * refactor iterator to make it more readable * rename blocked -> queued and runnable -> pending * explain some questionable naming choices * add some status constants * add logging * move custom endblocker to vm * fix rpc error compare * fix system tests * lints * fixed from main merge * rename mempool to experimental * Auto-fix markdown lint issues * we tidy * overflow comment * add changelog entry * Update evmd/app.go Co-authored-by: Hyunwoo Lee <124245155+zsystm@users.noreply.github.com> * remove comment * initialize txpool unconditionally * sort by effective gas tips instead of fees on cosmos * lints * small test cleanup --------- Co-authored-by: Tyler <48813565+technicallyty@users.noreply.github.com> Co-authored-by: Alex | Interchain Labs <alex@interchainlabs.io> Co-authored-by: Abdul Malek <me@almk.dev> Co-authored-by: Eric Warehime <eric.warehime@gmail.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Hyunwoo Lee <124245155+zsystm@users.noreply.github.com>
1 parent 04d23e5 commit d38db0e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+10726
-72
lines changed

.github/workflows/system-test.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ jobs:
2424
with:
2525
go-version: "1.22"
2626
check-latest: true
27+
- name: Install Foundry (forge/cast/anvil)
28+
uses: foundry-rs/foundry-toolchain@v1
29+
with:
30+
version: stable
2731
- uses: actions/checkout@v4
2832
- uses: technote-space/get-diff-action@v6.1.2
2933
with:

.golangci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ linters:
9393
text: 'ST1001:'
9494
paths:
9595
- x/vm/core
96+
- mempool/txpool
97+
- mempool/miner
9698
- third_party$
9799
- builtin$
98100
- examples$
@@ -121,6 +123,8 @@ formatters:
121123
generated: lax
122124
paths:
123125
- x/vm/core
126+
- mempool/txpool
127+
- mempool/miner
124128
- third_party$
125129
- builtin$
126130
- examples$

.markdownlintignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
tests/systemtests/Counter
1+
tests/systemtests/Counter

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
- [\#389](https://github.com/cosmos/evm/pull/389) Post-audit security fixes (batch 3)
4040
- [\#392](https://github.com/cosmos/evm/pull/392) Post-audit security fixes (batch 5)
4141
- [\#398](https://github.com/cosmos/evm/pull/398) Post-audit security fixes (batch 4)
42+
- [\#387](https://github.com/cosmos/evm/pull/387) (Experimental) EVM-compatible appside mempool
4243

4344
### FEATURES
4445

ante/evm/09_increment_sequence.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"math"
55

66
anteinterfaces "github.com/cosmos/evm/ante/interfaces"
7+
"github.com/cosmos/evm/mempool"
78

89
errorsmod "cosmossdk.io/errors"
910

@@ -18,28 +19,34 @@ func IncrementNonce(
1819
account sdk.AccountI,
1920
txNonce uint64,
2021
) error {
21-
nonce := account.GetSequence()
22-
// we merged the nonce verification to nonce increment, so when tx includes multiple messages
22+
accountNonce := account.GetSequence()
23+
// we merged the accountNonce verification to accountNonce increment, so when tx includes multiple messages
2324
// with same sender, they'll be accepted.
24-
if txNonce != nonce {
25+
if txNonce != accountNonce {
26+
if txNonce > accountNonce {
27+
return errorsmod.Wrapf(
28+
mempool.ErrNonceGap,
29+
"tx nonce: %d, account accountNonce: %d", txNonce, accountNonce,
30+
)
31+
}
2532
return errorsmod.Wrapf(
2633
errortypes.ErrInvalidSequence,
27-
"invalid nonce; got %d, expected %d", txNonce, nonce,
34+
"invalid nonce; got %d, expected %d", txNonce, accountNonce,
2835
)
2936
}
3037

3138
// EIP-2681 / state safety: refuse to overflow beyond 2^64-1.
32-
if nonce == math.MaxUint64 {
39+
if accountNonce == math.MaxUint64 {
3340
return errorsmod.Wrap(
3441
errortypes.ErrInvalidSequence,
3542
"nonce overflow: increment beyond 2^64-1 violates EIP-2681",
3643
)
3744
}
3845

39-
nonce++
46+
accountNonce++
4047

41-
if err := account.SetSequence(nonce); err != nil {
42-
return errorsmod.Wrapf(err, "failed to set sequence to %d", nonce)
48+
if err := account.SetSequence(accountNonce); err != nil {
49+
return errorsmod.Wrapf(err, "failed to set sequence to %d", accountNonce)
4350
}
4451

4552
accountKeeper.SetAccount(ctx, account)

evmd/app.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
evmconfig "github.com/cosmos/evm/config"
2222
evmosencoding "github.com/cosmos/evm/encoding"
2323
"github.com/cosmos/evm/evmd/ante"
24+
evmmempool "github.com/cosmos/evm/mempool"
2425
srvflags "github.com/cosmos/evm/server/flags"
2526
cosmosevmtypes "github.com/cosmos/evm/types"
2627
"github.com/cosmos/evm/x/erc20"
@@ -88,6 +89,7 @@ import (
8889
servertypes "github.com/cosmos/cosmos-sdk/server/types"
8990
testdata_pulsar "github.com/cosmos/cosmos-sdk/testutil/testdata/testpb"
9091
sdk "github.com/cosmos/cosmos-sdk/types"
92+
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
9193
"github.com/cosmos/cosmos-sdk/types/module"
9294
"github.com/cosmos/cosmos-sdk/types/msgservice"
9395
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
@@ -161,6 +163,7 @@ type EVMD struct {
161163
appCodec codec.Codec
162164
interfaceRegistry types.InterfaceRegistry
163165
txConfig client.TxConfig
166+
clientCtx client.Context
164167

165168
pendingTxListeners []evmante.PendingTxListener
166169

@@ -194,6 +197,7 @@ type EVMD struct {
194197
EVMKeeper *evmkeeper.Keeper
195198
Erc20Keeper erc20keeper.Keeper
196199
PreciseBankKeeper precisebankkeeper.Keeper
200+
EVMMempool *evmmempool.ExperimentalEVMMempool
197201

198202
// the module manager
199203
ModuleManager *module.Manager
@@ -232,7 +236,7 @@ func NewExampleApp(
232236
// Example:
233237
//
234238
// bApp := baseapp.NewBaseApp(...)
235-
// nonceMempool := mempool.NewSenderNonceMempool()
239+
// nonceMempool := evmmempool.NewSenderNonceMempool()
236240
// abciPropHandler := NewDefaultProposalHandler(nonceMempool, bApp)
237241
//
238242
// bApp.SetMempool(nonceMempool)
@@ -439,7 +443,7 @@ func NewExampleApp(
439443

440444
app.GovKeeper = *govKeeper.SetHooks(
441445
govtypes.NewMultiGovHooks(
442-
// register the governance hooks
446+
// register the governance hooks
443447
),
444448
)
445449

@@ -757,6 +761,31 @@ func NewExampleApp(
757761

758762
app.setAnteHandler(app.txConfig, maxGasWanted)
759763

764+
// set the EVM priority nonce mempool
765+
// If you wish to use the noop mempool, remove this codeblock
766+
if evmtypes.GetChainConfig() != nil {
767+
// TODO: Get the actual block gas limit from consensus parameters
768+
mempoolConfig := &evmmempool.EVMMempoolConfig{
769+
AnteHandler: app.GetAnteHandler(),
770+
BlockGasLimit: 100_000_000,
771+
}
772+
773+
evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
774+
app.EVMMempool = evmMempool
775+
776+
// Set the global mempool for RPC access
777+
if err := evmmempool.SetGlobalEVMMempool(evmMempool); err != nil {
778+
panic(err)
779+
}
780+
app.SetMempool(evmMempool)
781+
checkTxHandler := evmmempool.NewCheckTxHandler(evmMempool)
782+
app.SetCheckTxHandler(checkTxHandler)
783+
784+
abciProposalHandler := baseapp.NewDefaultProposalHandler(evmMempool, app)
785+
abciProposalHandler.SetSignerExtractionAdapter(evmmempool.NewEthSignerExtractionAdapter(sdkmempool.NewDefaultSignerExtractionAdapter()))
786+
app.SetPrepareProposal(abciProposalHandler.PrepareProposalHandler())
787+
}
788+
760789
// In v0.46, the SDK introduces _postHandlers_. PostHandlers are like
761790
// antehandlers, but are run _after_ the `runMsgs` execution. They are also
762791
// defined as a chain, and have the same signature as antehandlers.
@@ -1103,6 +1132,10 @@ func (app *EVMD) SetTransferKeeper(transferKeeper transferkeeper.Keeper) {
11031132
app.TransferKeeper = transferKeeper
11041133
}
11051134

1135+
func (app *EVMD) GetMempool() sdkmempool.ExtMempool {
1136+
return app.EVMMempool
1137+
}
1138+
11061139
func (app *EVMD) GetAnteHandler() sdk.AnteHandler {
11071140
return app.BaseApp.AnteHandler()
11081141
}
@@ -1112,6 +1145,10 @@ func (app *EVMD) GetTxConfig() client.TxConfig {
11121145
return app.txConfig
11131146
}
11141147

1148+
func (app *EVMD) SetClientCtx(clientCtx client.Context) {
1149+
app.clientCtx = clientCtx
1150+
}
1151+
11151152
// AutoCliOpts returns the autocli options for the app.
11161153
func (app *EVMD) AutoCliOpts() autocli.AppOptions {
11171154
modules := make(map[string]appmodule.AppModule, 0)

evmd/cmd/evmd/cmd/root.go

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,10 @@ import (
3535
"github.com/cosmos/cosmos-sdk/client/pruning"
3636
"github.com/cosmos/cosmos-sdk/client/rpc"
3737
"github.com/cosmos/cosmos-sdk/client/snapshot"
38-
"github.com/cosmos/cosmos-sdk/server"
3938
sdkserver "github.com/cosmos/cosmos-sdk/server"
4039
servertypes "github.com/cosmos/cosmos-sdk/server/types"
4140
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
4241
sdk "github.com/cosmos/cosmos-sdk/types"
43-
"github.com/cosmos/cosmos-sdk/types/mempool"
4442
sdktestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
4543
"github.com/cosmos/cosmos-sdk/types/tx/signing"
4644
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
@@ -318,25 +316,6 @@ func newApp(
318316
baseapp.SetChainID(chainID),
319317
}
320318

321-
// Set up the required mempool and ABCI proposal handlers for Cosmos EVM
322-
baseappOptions = append(baseappOptions, func(app *baseapp.BaseApp) {
323-
var mpool mempool.Mempool
324-
if maxTxs := cast.ToInt(appOpts.Get(server.FlagMempoolMaxTxs)); maxTxs >= 0 {
325-
// Setup Mempool and Proposal Handlers
326-
mpool = mempool.NewPriorityMempool(mempool.PriorityNonceMempoolConfig[int64]{
327-
TxPriority: mempool.NewDefaultTxPriority(),
328-
SignerExtractor: evmd.NewEthSignerExtractionAdapter(mempool.NewDefaultSignerExtractionAdapter()),
329-
MaxTx: maxTxs,
330-
})
331-
} else {
332-
mpool = mempool.NoOpMempool{}
333-
}
334-
app.SetMempool(mpool)
335-
handler := baseapp.NewDefaultProposalHandler(mpool, app)
336-
app.SetPrepareProposal(handler.PrepareProposalHandler())
337-
app.SetProcessProposal(handler.ProcessProposalHandler())
338-
})
339-
340319
return evmd.NewExampleApp(
341320
logger, db, traceStore, true,
342321
appOpts,

evmd/cmd/evmd/cmd/testnet.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ var (
6565
unsafeStartValidatorFn UnsafeStartValidatorCmdCreator
6666
)
6767

68+
const TEST_DENOM = "atest"
69+
6870
var mnemonics = []string{
6971
"copper push brief egg scan entry inform record adjust fossil boss egg comic alien upon aspect dry avoid interest fury window hint race symptom",
7072
"maximum display century economy unlock van census kite error heart snow filter midnight usage egg venture cash kick motor survey drastic edge muffin visual",
@@ -384,7 +386,7 @@ func initTestnetFiles(
384386
accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction)
385387
accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction)
386388
coins := sdk.Coins{
387-
sdk.NewCoin("atest", accTokens),
389+
sdk.NewCoin(TEST_DENOM, accTokens),
388390
sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens),
389391
}
390392

@@ -462,7 +464,7 @@ func addExtraAccounts(kb keyring.Keyring, algo keyring.SignatureAlgo) ([]banktyp
462464
accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction)
463465
accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction)
464466
coins := sdk.Coins{
465-
sdk.NewCoin("atest", accTokens),
467+
sdk.NewCoin(TEST_DENOM, accTokens),
466468
sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens),
467469
}
468470
coins = coins.Sort()

evmd/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ require (
3131
github.com/stretchr/testify v1.10.0
3232
golang.org/x/sync v0.16.0
3333
google.golang.org/grpc v1.74.2
34-
google.golang.org/protobuf v1.36.7
3534
)
3635

3736
require (
@@ -263,6 +262,7 @@ require (
263262
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
264263
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
265264
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
265+
google.golang.org/protobuf v1.36.7 // indirect
266266
gopkg.in/yaml.v2 v2.4.0 // indirect
267267
gopkg.in/yaml.v3 v3.0.1 // indirect
268268
gotest.tools/v3 v3.5.2 // indirect

evmd/tests/integration/create_app.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,20 @@ import (
2121
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
2222
)
2323

24-
// CreateEvmd creates an evmos app
24+
// CreateEvmd creates an evm app for regular integration tests (non-mempool)
25+
// This version uses a noop mempool to avoid state issues during transaction processing
2526
func CreateEvmd(chainID string, evmChainID uint64, customBaseAppOptions ...func(*baseapp.BaseApp)) evm.EvmApp {
2627
defaultNodeHome, err := clienthelpers.GetNodeHomeDirectory(".evmd")
2728
if err != nil {
2829
panic(err)
2930
}
30-
// create evmos app
31+
3132
db := dbm.NewMemDB()
3233
logger := log.NewNopLogger()
3334
loadLatest := true
3435
appOptions := simutils.NewAppOptionsWithFlagHome(defaultNodeHome)
35-
baseAppOptions := append(customBaseAppOptions, baseapp.SetChainID(chainID)) //nolint:gocritic
36+
37+
baseAppOptions := append(customBaseAppOptions, baseapp.SetChainID(chainID))
3638

3739
return evmd.NewExampleApp(
3840
logger,

0 commit comments

Comments
 (0)