feat(mempool): support direct insert tx via app mempool#2119
Conversation
Under mempool.type=app, route eth_sendRawTransaction/sendTransaction/etherbase straight into the app mempool via ethermint's MempoolTxInserter (crypto-org-chain/ethermint#1016) instead of BroadcastTx -> CheckTx. EVM RPC now gets a correct synchronous ABCI response and back-pressure (CodeTypeRetry on capacity), sharing one admission path with p2p gossip. - Manager: extract shared admit(); InsertTxHandler becomes a thin adapter; add Manager.InsertTx returning code+codespace+log for the RPC caller. - App: add InsertMempoolTx + MempoolInsertEnabled. The ethermint server gates registration on MempoolInsertEnabled(), so the default flood mempool keeps the unchanged BroadcastTx submission path. - Bump ethermint pin to the gated-interface follow-up. Addresses PR #2091 review r3361761130 (divergent RPC vs gossip admission).
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds direct RPC-based EVM transaction insertion into the app mempool by refactoring ChangesEVM direct mempool insertion
Receipt RPC argument formatting
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@claude review |
|
Claude finished @JayT106's task in 2m 33s —— View job PR #2119 Review
SummaryGood, well-scoped PR. The refactor is clean — extracting Issues FoundMedium — Nil-safety gap in
|
Address PR #2119 review: InsertMempoolTx relied on ethermint gating the call on MempoolInsertEnabled(), a cross-repo contract. Add a nil guard returning ErrNotSupported (matching the other mempoolManager call sites) so a stray call returns a code instead of panicking. Add wrapped-capacity and flood-gate tests.
… uint32 casts - gomod2nix.toml still pinned the pre-#1003 ethermint, so the Nix build failed with 'undefined: ethermintserver.MempoolTxInserter'. Regenerate to match the go.mod pin (#1016, b8b15b3); also pulls the new transitive deps. - Drop unnecessary uint32(abci.CodeTypeOK) conversions flagged by unconvert.
The ethermint bump changes GetBlockReceipts param from BlockNumber to BlockNumberOrHash. BlockNumber accepted a plain decimal int (cast.ToUint64 fallback on missing 0x prefix); BlockNumberOrHash does not, so the raw int arg now returns an error and the response has no 'result'. Pass hex().
|
please rework on the comment in this PR, they are too verbose |
…ia nil response InsertMempoolTx now returns (nil, nil) when mempool.type != app, so ethermint falls back to BroadcastTx — no separate predicate gating registration. Re-pin ethermint to the matching single-method MempoolTxInserter interface.
done! |
|
update pin once ethermint got merged. |
…nserter Ethermint moved the app-mempool contracts into a new appmempool package and dropped the package-global inserter registration (stack #1016+#1019+#1011). - Bump ethermint pin to 562fa2a2 (go.mod, go.sum, gomod2nix.toml). - Repoint root.go interface assertion: server.MempoolTxInserter -> appmempool.Inserter. App.InsertMempoolTx signature is unchanged, so ethermint StartJSONRPC casts it automatically; no app wiring change.
Address review: App.InsertMempoolTx no longer constructs the sdk.TxResponse. Manager.InsertTx now returns *sdk.TxResponse; App is a thin delegate (nil-decline gate + forward), keeping mempool response logic in the mempool package.
The InsertMempoolTx method now lives on the mempool Manager, which satisfies ethermint's appmempool.Inserter directly. App implements the new InserterProvider (MempoolInserter), returning the manager or nil under flood mode. This keeps all mempool response logic in the mempool package and removes the (nil,nil) decline sentinel from app.go. Repin ethermint to 2ae3aaf8 (adds appmempool.InserterProvider).
|
Claude finished @JayT106's task in 4m 11s —— View job PR #2119 Review
SummaryClean, well-scoped PR. The Issues FoundMinor — No compile-time assertion for
|
BaseApp.RunTx accepts nil sdk.Tx and falls back to txBytes; cacheTx is a no-op without encCache, so passing nil is safe.
# Conflicts: # CHANGELOG.md # app/mempool/manager.go
Pull request was closed
* feat(mempool): submit EVM RPC txs via app-mempool direct insert Under mempool.type=app, route eth_sendRawTransaction/sendTransaction/etherbase straight into the app mempool via ethermint's MempoolTxInserter (crypto-org-chain/ethermint#1016) instead of BroadcastTx -> CheckTx. EVM RPC now gets a correct synchronous ABCI response and back-pressure (CodeTypeRetry on capacity), sharing one admission path with p2p gossip. - Manager: extract shared admit(); InsertTxHandler becomes a thin adapter; add Manager.InsertTx returning code+codespace+log for the RPC caller. - App: add InsertMempoolTx + MempoolInsertEnabled. The ethermint server gates registration on MempoolInsertEnabled(), so the default flood mempool keeps the unchanged BroadcastTx submission path. - Bump ethermint pin to the gated-interface follow-up. Addresses PR #2091 review r3361761130 (divergent RPC vs gossip admission). * chore(changelog): fill PR number #2119 * chore(changelog): align #2119 entry to PR title * style(mempool): tighten InsertMempoolTx/admit comments * fix(app): guard InsertMempoolTx against nil mempool manager Address PR #2119 review: InsertMempoolTx relied on ethermint gating the call on MempoolInsertEnabled(), a cross-repo contract. Add a nil guard returning ErrNotSupported (matching the other mempoolManager call sites) so a stray call returns a code instead of panicking. Add wrapped-capacity and flood-gate tests. * fix(ci): regenerate gomod2nix.toml for ethermint pin + drop redundant uint32 casts - gomod2nix.toml still pinned the pre-#1003 ethermint, so the Nix build failed with 'undefined: ethermintserver.MempoolTxInserter'. Regenerate to match the go.mod pin (#1016, b8b15b3); also pulls the new transitive deps. - Drop unnecessary uint32(abci.CodeTypeOK) conversions flagged by unconvert. * test(integration): pass hex block number to eth_getBlockReceipts The ethermint bump changes GetBlockReceipts param from BlockNumber to BlockNumberOrHash. BlockNumber accepted a plain decimal int (cast.ToUint64 fallback on missing 0x prefix); BlockNumberOrHash does not, so the raw int arg now returns an error and the response has no 'result'. Pass hex(). * docs(mempool): tighten insert-tx comments, align changelog wording * refactor(mempool): drop MempoolInsertEnabled, decline direct insert via nil response InsertMempoolTx now returns (nil, nil) when mempool.type != app, so ethermint falls back to BroadcastTx — no separate predicate gating registration. Re-pin ethermint to the matching single-method MempoolTxInserter interface. * remove wordy comments * chore(deps): repin ethermint to appmempool refactor; use appmempool.Inserter Ethermint moved the app-mempool contracts into a new appmempool package and dropped the package-global inserter registration (stack #1016+#1019+#1011). - Bump ethermint pin to 562fa2a2 (go.mod, go.sum, gomod2nix.toml). - Repoint root.go interface assertion: server.MempoolTxInserter -> appmempool.Inserter. App.InsertMempoolTx signature is unchanged, so ethermint StartJSONRPC casts it automatically; no app wiring change. * refactor(mempool): move InsertTx response build into Manager Address review: App.InsertMempoolTx no longer constructs the sdk.TxResponse. Manager.InsertTx now returns *sdk.TxResponse; App is a thin delegate (nil-decline gate + forward), keeping mempool response logic in the mempool package. * refactor(mempool): expose inserter via appmempool.InserterProvider The InsertMempoolTx method now lives on the mempool Manager, which satisfies ethermint's appmempool.Inserter directly. App implements the new InserterProvider (MempoolInserter), returning the manager or nil under flood mode. This keeps all mempool response logic in the mempool package and removes the (nil,nil) decline sentinel from app.go. Repin ethermint to 2ae3aaf8 (adds appmempool.InserterProvider). * chore(deps): repin ethermint to #1016 head (1389b15f) #2119 depends only on appmempool.Inserter/InserterProvider, which live in ethermint #1016. Pin directly to that PR head instead of the full sig-preverifier stack tip. Inserter API unchanged, so no cronos code change. * test(mempool): isolate tamper-reject case; tighten inserter comments - admission_test: tamper a fresh account so the forged-From rejection isn't confounded by nonce/check-state from the prior accepted tx (CodeRabbit r3483469252). - app.go / root.go: trim MempoolInserter / InserterProvider comments to the design decision (avoid BaseApp.InsertTx clash). * chore(deps): repin ethermint #1016; adapt to MempoolClient interface PR #1016 replaced appmempool.Inserter/InserterProvider with MempoolClient (InsertTx + PendingTxs) and MempoolClientProvider. - repin ethermint to d61c063f (PR head); regen gomod2nix.toml - Manager: InsertMempoolTx -> InsertTx; add PendingTxs (nil; app mempool holds generic sdk.Tx, not decoded MsgEthereumTx) - App: MempoolInserter() -> MempoolClient() via MempoolClientProvider (promoted BaseApp.InsertTx still blocks direct MempoolClient impl) * fix(lint): gci import formatting in app/app.go and app/mempool/manager.go - Remove extra blank line in app/app.go import section (line 52) - Reorder imports in app/mempool/manager.go to follow gci section rules: standard → default → cosmossdk.io → github.com/cosmos/cosmos-sdk * chore(deps): repin ethermint #1016 head (66efb289) Picks up main merge into the PR branch (go-metrics 0.5.4 -> 0.6.0). appmempool.MempoolClient interface unchanged; no code change. Regenerate gomod2nix.toml. * refactor: move MempoolClientProvider assertion to app.go Compile-time assert lives next to *App and its MempoolClient method; drop the now-unused appmempool import from root.go. * chore(deps): repin ethermint #1016 head (2f1ceeab) MempoolClientProvider removed; pass MempoolClient explicitly. Adapt: - Remove MempoolClientProvider compile-time assertion in app/app.go - Manager.PendingTxs() return type: []*MsgEthereumTx → []sdk.Tx (drops evmtypes dep) * docs(mempool): note nil-tx path is intentional when encCache disabled BaseApp.RunTx accepts nil sdk.Tx and falls back to txBytes; cacheTx is a no-op without encCache, so passing nil is safe. * refactor(mempool): trim verbose comments on InsertTx/PendingTxs * chore(deps): repin ethermint #1016 head (6f932cde) * feat(mempool): back txpool RPC with app mempool PendingTxs Repin ethermint to PR #1019 head (stacked on #1016), which wires the txpool RPC namespace (content/inspect/status/contentFrom) to MempoolClient.PendingTxs. Implement Manager.PendingTxs: lock-free PoolSnapshot scan returning pooled EVM messages; skips non-EVM/multi-message txs; nil mpool reports none. * docs(changelog): add #2127 txpool RPC PendingTxs entry * fix(mempool): address PendingTxs review nits - Rename PoolSnapshot telemetry label recheck→pool; snapshot is now called from both recheck and txpool RPC paths so the label was misleading - Drop over-eager capacity hint in PendingTxs; EVM:non-EVM ratio unknown - Add missing blank line in manager_test.go (gofmt / CI lint fix) * test(mempool): integration tests for txpool RPC namespace Covers txpool_content, txpool_inspect, txpool_status, txpool_contentFrom: - shape tests (always pass): verify endpoints respond with {pending,queued} - test_txpool_pending_tx_visible: submit tx, query pool immediately, assert tx appears in all four endpoints; @flaky(3) for reap_interval race. * refactor(test): simplify txpool shape tests; add inspect xfail guard Extract _assert_pool_dict_shape to deduplicate the 3 identical dict-shape assertions. Add missing pytest.xfail guard for inspect_sender None case (timing race path identified in code review). * fix(lint): black format + wrap long lines in txpool tests * fix(test): enable txpool JSON-RPC namespace for app-mempool suite default.jsonnet's api list omits txpool, overriding ethermint's default namespace set. mempool_app.jsonnet never restored it, so all txpool_* RPC calls in test_app_mempool.py hit an unregistered namespace and returned no "result" key. * chore(deps): repin ethermint #1034 head (de2396e91b19) github.com/crypto-org-chain/ethermint v0.22.1-0.20260707200522-de2396e91b19 * fix(test): move txpool api override to app-config in mempool_app.jsonnet json-rpc lives under app-config in pystarport's schema, not config (config maps to config.toml; app-config maps to app.toml). The previous override nested json-rpc under config, so it silently patched an unused config.toml section instead of app.toml, and the txpool namespace was never actually enabled on the running node. * chore(deps): repin ethermint #1051 head (ea6791fbb8f0) Ethermint's MempoolClient interface gained CountTx() for O(1) txpool_status. Add Manager.CountTx() to satisfy it. * test(mempool): cover Manager.CountTx unit + integration Add TestManagerCountTx (nil mpool -> 0, populated pool -> exact count) and tighten test_txpool_pending_tx_visible's status assertion from a loose >= 1 to a before/after delta, so it actually verifies CountTx() counted the submitted tx instead of just "something is pending". * fix(nix): bump go_1_25 overlay pin to 1.25.11 go.mod's go directive moved to 1.25.11 (ethermint #1051 repin), but the nix overlay still pinned go1.25.9 and CI has no network access to fetch the newer toolchain on demand. Every nix-based build/integration job failed with "toolchain not available". Bump the overlay's version and source hash to match. * fix(ci): bump stale go-version 1.25.9 pins to 1.25.11 lint.yml, codeql-analysis.yml, and sims.yml each hardcode actions/setup-go's go-version separately from the nix toolchain. go.mod now requires go >= 1.25.11 (bumped by the ethermint #1051 repin), so these jobs failed with GOTOOLCHAIN=local: toolchain not available. * fix(testground): bump golang base image 1.25.9 -> 1.25.11 Same toolchain mismatch as the CI workflows: go.mod requires go >= 1.25.11 since the ethermint #1051 repin.
Under
mempool.type=app, EVM RPC txs now insert straight into the app mempool instead of going throughBroadcastTx -> CheckTx(which returns an empty response and spawns a goroutine per tx). Uses ethermint'sappmempool.MempoolClient(crypto-org-chain/ethermint#1016).Why:
eth_sendRawTransaction,eth_sendTransaction, and etherbase, plus back-pressure (CodeTypeRetrywhen full).Changes:
Manager: extractadmit();InsertTxHandlerbecomes a thin adapter over it; addManager.InsertTx(RPC path) andPendingTxs(txpool stub — app mempool holds genericsdk.Tx, not decodedMsgEthereumTx, so it reports none).App.MempoolClient(): returns theManager, or nil under flood mode so ethermint falls back toBroadcastTx. Method on*Appavoids a clash with the promotedBaseApp.InsertTx.Depends on crypto-org-chain/ethermint#1016.