Skip to content

Conversation

mmsqe
Copy link
Contributor

@mmsqe mmsqe commented Sep 11, 2025

upstream the fix for gas wanted

Summary by CodeRabbit

  • New Features
    • Transactions now carry explicit gas values through mempool and proposal processing, enabling accurate block gas accounting and fairer selection under gas limits.
    • Gas-aware insertion and selection supported across mempool variants, aligning proposal preparation and processing with returned gas wanted.
  • Documentation
    • Changelog updated to note mempool now respects gas wanted from the ante handler.
  • Tests
    • Mocks and tests updated to use gas-aware APIs and wrappers.

yihuang and others added 2 commits September 11, 2025 09:33
* Problem: mempool don't respect gas wanted returned by ante handler

Solution:
- support custom gas wanted in mempool

* Update CHANGELOG.md

Signed-off-by: yihuang <huang@crypto.com>

* cleanup

* cleanup

* fix priorityIndex

* fix process proposal

* fix lint

* fix lint

---------

Signed-off-by: yihuang <huang@crypto.com>

Problem: mempool.GasTx interface is not reused (cosmos#536)

* Problem: redundant mutex for InsertWithGasWanted

cfg of PriorityNonceMempool remains unchanged once assigned, so no lock is required

* make mocks

* cleanup

* keep order of check MaxTx
Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

📝 Walkthrough

Walkthrough

Propagates gasWanted from ante handling through mempool and proposal flows. Updates ProposalTxVerifier and TxSelector signatures to carry gasWanted, refactors BaseApp’s ProcessProposalVerifyTx and CheckTx insertion, introduces a mempool.Tx wrapper with gasWanted, and updates mempool interfaces, iterators, and implementations (noop, priority_nonce, sender_nonce) along with tests. Adds CHANGELOG note.

Changes

Cohort / File(s) Summary of changes
Changelog
CHANGELOG.md
Added Unreleased note: mempool respects gas wanted returned by ante handler.
BaseApp proposal flow
baseapp/abci_utils.go, baseapp/baseapp.go
Thread gasWanted through PrepareProposal and ProcessProposal. ProposalTxVerifier.ProcessProposalVerifyTx now returns (sdk.Tx, uint64, error). Tx selection uses gasWanted. CheckTx inserts via InsertWithGasWanted. Accumulate gas via returned gasWanted.
BaseApp test mocks
baseapp/testutil/mock/mocks.go
Updated gomock signatures: ProcessProposalVerifyTx returns gasWanted; TxSelector.SelectTxForProposal accepts gasWanted; recorder updated accordingly.
Mempool interfaces & core test & noop
types/mempool/mempool.go, types/mempool/mempool_test.go, types/mempool/noop.go
Introduced mempool.Tx{Tx, GasWanted}, NewMempoolTx, GasTx. Mempool adds InsertWithGasWanted, CountTx, Remove. ExtMempool.SelectBy and Iterator.Tx() now use wrapper Tx. NoOpMempool implements new methods and updated callback types. Tests adjusted to unwrap iterator.Tx().Tx.
Priority nonce mempool
types/mempool/priority_nonce.go, types/mempool/priority_nonce_test.go
Store wrapper Tx instead of raw sdk.Tx. Added InsertWithGasWanted; Insert now derives gas via GasTx and delegates. Iterator Tx() returns wrapper. SelectBy callback now func(Tx) bool. Tests updated to access memTx.Tx.
Sender nonce mempool
types/mempool/sender_nonce.go, types/mempool/sender_nonce_property_test.go
Added gas-aware insertion InsertWithGasWanted; Insert delegates after deriving gas via GasTx. Storage uses wrapper Tx. Iterator Tx() and SelectBy use wrapper. Iteration unwraps via .Tx. Tests updated to unwrap for assertions.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Proposer
  participant BaseApp
  participant Mempool
  participant TxSelector
  participant ProposalTxVerifier as TxVerifier
  participant Ante as AnteHandler

  Proposer->>BaseApp: PrepareProposal
  BaseApp->>Mempool: SelectBy(ctx, txs, callback(memTx))
  activate Mempool
  loop For each memTx
    Mempool-->>BaseApp: memTx (Tx + GasWanted)
    BaseApp->>TxVerifier: PrepareProposalVerifyTx(memTx.Tx)
    TxVerifier-->>BaseApp: ok/error
    alt ok
      BaseApp->>TxSelector: SelectTxForProposal(..., memTx.Tx, txBz, memTx.GasWanted)
      TxSelector-->>BaseApp: include?
      alt include
        BaseApp-->>Mempool: (continue)
      else skip
      end
    else invalid
      BaseApp-->>Mempool: (continue)
    end
  end
  deactivate Mempool
  BaseApp-->>Proposer: Proposal with selected txs
Loading
sequenceDiagram
  autonumber
  actor Validator
  participant BaseApp
  participant TxVerifier as ProposalTxVerifier
  participant Ante as AnteHandler

  Validator->>BaseApp: ProcessProposal(txs)
  Note over BaseApp: maxBlockGas check
  loop For each txBz
    BaseApp->>TxVerifier: ProcessProposalVerifyTx(txBz)
    activate TxVerifier
    TxVerifier->>BaseApp: (sdk.Tx, gasWanted, err)
    deactivate TxVerifier
    alt err
      BaseApp-->>Validator: REJECT
    else ok
      BaseApp->>BaseApp: totalTxGas += gasWanted (if maxBlockGas>0)
      alt totalTxGas > maxBlockGas
        BaseApp-->>Validator: REJECT
      end
    end
  end
  BaseApp-->>Validator: ACCEPT
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title succinctly and accurately describes the primary change — updating the mempool to respect the gas-wanted value returned by the ante handler — and directly matches the mempool and gas-propagation changes in the diff.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title is concise and accurately captures the primary change: making the mempool respect the gas wanted value returned by the ante handler. It uses a conventional scope ("mempool") and clearly describes the behavioral change without extraneous details. The title is specific enough for teammates scanning history and does not use vague terms like "misc" or "stuff".
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
types/mempool/priority_nonce.go (1)

182-193: Fix potential nil-deref in NextSenderTx.

If the sender index exists but is empty, cursor will be nil and this panics.

 func (mp *PriorityNonceMempool[C]) NextSenderTx(sender string) sdk.Tx {
   senderIndex, ok := mp.senderIndices[sender]
   if !ok {
     return nil
   }

   cursor := senderIndex.Front()
-  return cursor.Value.(Tx).Tx
+  if cursor == nil {
+    return nil
+  }
+  return cursor.Value.(Tx).Tx
 }
types/mempool/sender_nonce.go (1)

106-117: Fix potential nil-deref in NextSenderTx.

Empty per-sender list yields nil cursor; guard it.

 func (snm *SenderNonceMempool) NextSenderTx(sender string) sdk.Tx {
   senderIndex, ok := snm.senders[sender]
   if !ok {
     return nil
   }

   cursor := senderIndex.Front()
-  return cursor.Value.(Tx).Tx
+  if cursor == nil {
+    return nil
+  }
+  return cursor.Value.(Tx).Tx
 }
🧹 Nitpick comments (11)
types/mempool/mempool_test.go (1)

142-145: Unwrap via helper to decouple tests from wrapper field layout

Accessing .Tx directly ties tests to the struct field name. Prefer a small helper to improve resilience if the wrapper evolves. Functionally identical.

-        txs = append(txs, iterator.Tx().Tx)
+        txs = append(txs, unwrapTx(iterator.Tx()))

Add once in this test file:

// unwrapTx returns the underlying sdk.Tx from the mempool wrapper.
func unwrapTx(t mempool.Tx) sdk.Tx { return t.Tx }
types/mempool/sender_nonce_property_test.go (1)

95-103: Same unwrapping helper to avoid direct field access in tests

Mirror the helper approach to reduce coupling to the wrapper’s field name.

-        tx := iterator.Tx()
-        txs = append(txs, tx.Tx.(testTx))
+        tx := iterator.Tx()
+        txs = append(txs, unwrapTx(tx).(testTx))

Add once in this test file if not shared:

func unwrapTx(t mempool.Tx) sdk.Tx { return t.Tx }
types/mempool/noop.go (1)

19-24: No-op additions look good; add compile-time check for Mempool too

You already assert ExtMempool conformance. Add Mempool as well to catch drift if interfaces change.

Add near the existing assertion:

var _ Mempool = (*NoOpMempool)(nil)
types/mempool/mempool.go (3)

10-20: Add brief GoDoc to clarify wrapper semantics.

Document that GasWanted is the ante-derived value (when available) or implementation-derived default.

Apply:

 type Tx struct {
-	Tx        sdk.Tx
-	GasWanted uint64
+	// Tx is the original SDK transaction.
+	Tx        sdk.Tx
+	// GasWanted is the gas value to be respected by selection logic (e.g., from ante).
+	// Implementations MAY derive this from tx if not provided via InsertWithGasWanted.
+	GasWanted uint64
 }
 
-func NewMempoolTx(tx sdk.Tx, gasWanted uint64) Tx {
+// NewMempoolTx wraps an sdk.Tx with its gasWanted value for mempool iteration/selection.
+func NewMempoolTx(tx sdk.Tx, gasWanted uint64) Tx {

22-24: Clarify how GasTx is used by Insert implementations.

State that Insert may populate GasWanted by checking this interface when InsertWithGasWanted isn’t used.

Apply:

 type GasTx interface {
-	GetGas() uint64
+	// GetGas returns the gas wanted for the transaction.
+	GetGas() uint64
 }

31-33: Document InsertWithGasWanted override behavior.

Make it explicit that this bypasses interface-based derivation.

Apply:

-	// Insert with a custom gas wanted value
+	// Insert with a custom gasWanted value.
+	// Implementations MUST use this gasWanted value as authoritative for the inserted tx.
 	InsertWithGasWanted(context.Context, sdk.Tx, uint64) error
types/mempool/priority_nonce.go (2)

213-214: Avoid duplicate lookups in senderIndex.Get(key).

Cache the element to prevent two map/skiplist traversals and simplify formatting.

-    if mp.cfg.TxReplacement != nil && !mp.cfg.TxReplacement(oldScore.priority, priority, senderIndex.Get(key).Value.(Tx).Tx, tx) {
+    oldEl := senderIndex.Get(key)
+    oldTx := oldEl.Value.(Tx).Tx
+    if mp.cfg.TxReplacement != nil && !mp.cfg.TxReplacement(oldScore.priority, priority, oldTx, tx) {
       return fmt.Errorf(
         "tx doesn't fit the replacement rule, oldPriority: %v, newPriority: %v, oldTx: %v, newTx: %v",
         oldScore.priority,
         priority,
-        senderIndex.Get(key).Value.(Tx).Tx,
+        oldTx,
         tx,
       )
     }

Also applies to: 251-259


283-290: Name consistency: use gasWanted, not gasLimit.

This wrapper derives gas from GasTx. Rename local var for clarity and consistency with InsertWithGasWanted.

 func (mp *PriorityNonceMempool[C]) Insert(ctx context.Context, tx sdk.Tx) error {
-  var gasLimit uint64
+  var gasWanted uint64
   if gasTx, ok := tx.(GasTx); ok {
-    gasLimit = gasTx.GetGas()
+    gasWanted = gasTx.GetGas()
   }
-  return mp.InsertWithGasWanted(ctx, tx, gasLimit)
+  return mp.InsertWithGasWanted(ctx, tx, gasWanted)
 }
types/mempool/sender_nonce.go (2)

119-129: Good: gas-aware insertion path; minor naming nit.

Functionality is correct; consider renaming gasLimit -> gasWanted for consistency with the rest of the API and PR intent.

-func (snm *SenderNonceMempool) InsertWithGasWanted(_ context.Context, tx sdk.Tx, gasLimit uint64) error {
+func (snm *SenderNonceMempool) InsertWithGasWanted(_ context.Context, tx sdk.Tx, gasWanted uint64) error {
@@
-  memTx := NewMempoolTx(tx, gasLimit)
+  memTx := NewMempoolTx(tx, gasWanted)
@@
-  senderTxs.Set(nonce, memTx)
+  senderTxs.Set(nonce, memTx)

Also applies to: 131-132, 154-155


162-169: Name consistency in wrapper Insert.

Rename local variable to gasWanted for clarity.

 func (snm *SenderNonceMempool) Insert(ctx context.Context, tx sdk.Tx) error {
-  var gasLimit uint64
+  var gasWanted uint64
   if gasTx, ok := tx.(GasTx); ok {
-    gasLimit = gasTx.GetGas()
+    gasWanted = gasTx.GetGas()
   }
-  return snm.InsertWithGasWanted(ctx, tx, gasLimit)
+  return snm.InsertWithGasWanted(ctx, tx, gasWanted)
 }
baseapp/abci_utils.go (1)

506-507: Nit: parameter name.

The parameter named memTx is actually an sdk.Tx; consider renaming to tx for clarity.

-func (ts *defaultTxSelector) SelectTxForProposal(_ context.Context, maxTxBytes, maxBlockGas uint64, memTx sdk.Tx, txBz []byte, gasWanted uint64) bool {
+func (ts *defaultTxSelector) SelectTxForProposal(_ context.Context, maxTxBytes, maxBlockGas uint64, tx sdk.Tx, txBz []byte, gasWanted uint64) bool {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between c2f3bfd and 4cd29a5.

📒 Files selected for processing (11)
  • CHANGELOG.md (1 hunks)
  • baseapp/abci_utils.go (7 hunks)
  • baseapp/baseapp.go (2 hunks)
  • baseapp/testutil/mock/mocks.go (2 hunks)
  • types/mempool/mempool.go (4 hunks)
  • types/mempool/mempool_test.go (1 hunks)
  • types/mempool/noop.go (1 hunks)
  • types/mempool/priority_nonce.go (7 hunks)
  • types/mempool/priority_nonce_test.go (4 hunks)
  • types/mempool/sender_nonce.go (5 hunks)
  • types/mempool/sender_nonce_property_test.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: test-system
  • GitHub Check: test-system-legacy
  • GitHub Check: tests (01)
  • GitHub Check: tests (03)
  • GitHub Check: tests (00)
  • GitHub Check: tests (02)
  • GitHub Check: Check up to date mocks
  • GitHub Check: test-e2e
  • GitHub Check: test-sim-nondeterminism
  • GitHub Check: test-integration
  • GitHub Check: build (amd64)
  • GitHub Check: build (arm64)
  • GitHub Check: Analyze
  • GitHub Check: golangci-lint
  • GitHub Check: Gosec
  • GitHub Check: dependency-review
  • GitHub Check: Summary
🔇 Additional comments (21)
baseapp/baseapp.go (2)

875-880: LGTM: mempool insertion now carries gasWanted

Switching to InsertWithGasWanted on CheckTx correctly threads ante-derived gasWanted into the mempool.


1071-1082: LGTM — ProcessProposalVerifyTx now returns gasWanted; callers & mocks updated

rg output shows the interface, call site handling gasWanted, and mock implementation updated (no other references found).

types/mempool/priority_nonce_test.go (4)

391-391: Iterator now returns wrapper mempool.Tx — access pattern looks correct.

Using iterator.Tx().Tx.(testTx) aligns with the new wrapper. No issues.


467-469: SelectBy callback updated to accept mempool.Tx — usage is correct.

Unwrapping via memTx.Tx.(testTx) is consistent with the new API.


938-938: Tx replacement test assertion updated for wrapper — OK.

Comparing against iter.Tx().Tx matches the new iterator contract.


973-973: Final iterator assertion updated for wrapper — OK.

Accessing iter.Tx().Tx for equality is correct.

baseapp/testutil/mock/mocks.go (4)

138-145: Mock return signature extended to include gasWanted — implementation matches interface.

Return indexes and types (types.Tx, uint64, error) are correct.


220-231: TxSelector mock updated to accept gasWanted — signature and recorder are consistent.

Parameter threading (ctx, maxTxBytes, maxBlockGas, memTx, txBz, gasWanted) is correct.


148-151: No action required — callers already handle the extra return value.
Only invocation found: baseapp/abci_utils.go:417 — _, gasWanted, err := h.txVerifier.ProcessProposalVerifyTx(txBytes).


220-231: Confirm gomock expectations include gasWanted in SelectTxForProposal

Mocks were regenerated (baseapp/testutil/mock/mocks.go:219–231) and callers pass gasWanted (baseapp/abci_utils.go:284,345); no gomock EXPECT(...).SelectTxForProposal(...) usages were found — verify and update any tests/stubs to include the new gasWanted argument (or use gomock.Any()/matchers).

types/mempool/mempool.go (2)

53-54: ExtMempool SelectBy callback type updated to wrapper Tx — OK.

Matches the new iterator return type; enables passing gasWanted to selectors.


75-86: SelectBy helper preserves fallback behavior — OK.

Wrapper callback is propagated; fallback remains not thread-safe as documented.

types/mempool/priority_nonce.go (3)

195-205: Good: gas-aware insertion entry point.

Renamed/added InsertWithGasWanted aligns with the new gasWanted flow.


355-357: Iterator now returns mempool.Tx.

API shift looks consistent; downstream selection uses the wrapper.


390-398: SelectBy callback type change acknowledged.

Signature updates to func(Tx) bool match the wrapper-based iteration.

types/mempool/sender_nonce.go (1)

211-219: Iterator and SelectBy now operate on mempool.Tx.

Changes are coherent with the wrapper storage.

Also applies to: 304-306

baseapp/abci_utils.go (5)

279-285: No-op path: uses gas from tx when available.

Good fallback for non-mempool selection; consistent with new TxSelector signature.


417-427: ProcessProposal gas accounting uses ante-returned gasWanted.

This matches PR intent; guards maxBlockGas strictly.


205-207: Resolved — ProcessProposalVerifyTx now returns (sdk.Tx, uint64, error).
Search shows updated signatures/usages in baseapp/abci_utils.go, baseapp/baseapp.go and baseapp/testutil/mock/mocks.go; no old two-value implementations were found.


481-483: Breaking change: TxSelector.SelectTxForProposal signature now includes gasWanted — add migration note

Custom TxSelector implementations and tests must be updated to accept and handle the new gasWanted (uint64) parameter; add an UPGRADE/MIGRATION note calling out this breaking change.

Locations: baseapp/abci_utils.go — interface (lines 481–483) and default implementation (lines 506–527); baseapp/testutil/mock/mocks.go — mock (lines ~220–230).


299-346: PrepareProposal mempool path wired to memTx.GasWanted — CheckTx passes ante GasMeter limit

Confirmed: baseapp.runTx sets gasWanted = ctx.GasMeter().Limit() after the AnteHandler and calls app.mempool.InsertWithGasWanted(ctx, tx, gasWanted) on CheckTx (baseapp/baseapp.go:858,876). PrepareProposal selection reads memTx.GasWanted (baseapp/abci_utils.go; mempool types). Ensure your AnteHandler sets the GasMeter (e.g., include SetUpContextDecorator or call ctx.WithGasMeter(NewGasMeter(tx.GetGas()))) so InsertWithGasWanted receives the intended non-zero GasWanted; mempool Insert wrappers also pass tx.GetGas when used directly (types/mempool/sender_nonce.go:168, priority_nonce.go:289).

Comment on lines +65 to 66
Tx() Tx
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Iterator.Tx now returns wrapper Tx — breaking change: verify all usages are updated.

Audit for code still asserting sdk.Tx directly from Iterator.Tx().

Run:

Expected: call sites use iter.Tx().Tx (or equivalent) after this change.


🏁 Script executed:

#!/bin/bash
# Find Iterator.Tx() usages and spot unwraps expecting sdk.Tx.
rg -nP --type=go -C3 '\.Tx\(\)\s*[\),]'  # method call contexts
rg -nP --type=go -C3 '\.Tx\(\)\.'        # chained member access implying wrapper usage
rg -nP --type=go -C3 '=\s*iter\.Tx\(\)'  # direct assignment patterns

Length of output: 3411


Iterator.Tx now returns wrapper Tx — update all call sites that still treat it as sdk.Tx

Call sites still passing/assigning iter.Tx() must unwrap (.Tx) or accept the wrapper:

  • types/mempool/mempool.go:83 — for iter != nil && callback(iter.Tx()) {
  • types/mempool/sender_nonce.go:216 — for iter != nil && callback(iter.Tx()) {
  • types/mempool/priority_nonce.go:395 — for iter != nil && callback(iter.Tx()) {

Tests already access the inner Tx in several places (e.g., types/mempool/mempool_test.go:142; types/mempool/priority_nonce_test.go:391, 938, 973) — ensure expectations/ assertions match the wrapper change.

🤖 Prompt for AI Agents
In types/mempool/mempool.go around lines 65-66 the interface method Tx() now
returns the wrapper type Tx instead of sdk.Tx; update all call sites that still
treat iter.Tx() as sdk.Tx to either unwrap the inner sdk.Tx via iter.Tx.Tx or
change the consumer to accept the wrapper type. Specifically, modify the three
call sites (types/mempool/mempool.go:83, types/mempool/sender_nonce.go:216,
types/mempool/priority_nonce.go:395) to call callback(iter.Tx().Tx) if callback
expects sdk.Tx, or change the callback signature to accept the wrapper; also
update tests that inspect the inner transaction (e.g.,
types/mempool/mempool_test.go:142; types/mempool/priority_nonce_test.go:391,
938, 973) to access the inner sdk.Tx through the wrapper before making
assertions.

@aljo242
Copy link
Contributor

aljo242 commented Sep 11, 2025

@mmsqe looks like there are some CI issues

@mmsqe
Copy link
Contributor Author

mmsqe commented Sep 12, 2025

@mmsqe looks like there are some CI issues

Seems got github rate limited.

@aljo242
Copy link
Contributor

aljo242 commented Sep 12, 2025

@mmsqe we should note that this is an API breaking change - is there any way to make this non-api breaking?

@mmsqe
Copy link
Contributor Author

mmsqe commented Sep 12, 2025

@mmsqe we should note that this is an API breaking change - is there any way to make this non-api breaking?

seems inevitable, since we can't add property in sdk.Tx which is an interface, we need to save GasWanted in mempool.Tx.

@technicallyty technicallyty self-requested a review September 12, 2025 16:07
@technicallyty
Copy link
Contributor

i will have a look here next week

@technicallyty technicallyty changed the title feat(mempool): respect gas wanted returned by ante handler feat(mempool)!: respect gas wanted returned by ante handler Sep 17, 2025
ProposalTxVerifier interface {
PrepareProposalVerifyTx(tx sdk.Tx) ([]byte, error)
ProcessProposalVerifyTx(txBz []byte) (sdk.Tx, error)
ProcessProposalVerifyTx(txBz []byte) (sdk.Tx, uint64, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint64 is a bit ambiguous, maybe a named return or comment to help the developer understand the variable

// returned if the transaction cannot be decoded. <Tx, nil> will be returned if
// the transaction is valid, otherwise <Tx, err> will be returned.
func (app *BaseApp) ProcessProposalVerifyTx(txBz []byte) (sdk.Tx, error) {
func (app *BaseApp) ProcessProposalVerifyTx(txBz []byte) (sdk.Tx, uint64, error) {
Copy link
Contributor

@technicallyty technicallyty Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here and comments need to updated above too

Comment on lines 31 to 33
// Insert with a custom gas wanted value
InsertWithGasWanted(context.Context, sdk.Tx, uint64) error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain why this extra method is needed? i think the reason is here:

err = app.mempool.InsertWithGasWanted(ctx, tx, gasWanted)
but im not sure i fully understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we need to fill mempoolTx with gasWanted from gas meter when runTx

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the difference between the tx.Gas() vs the gasWanted from the meter here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think of removing this method and instead adding an argument to Insert such as:

type InsertOption struct {
   GasWanted uint64
}

type Mempool interface {
    // ....
    Insert(context.Context, sdk.Tx, InsertOption) error
}

this way, if more is needed in the future, it will be nonbreaking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are cases that tx.Gas() is different from gasWanted returned from context GasMeter() and we need to override with it. I think we keep Insert mainly for the tests.

Comment on lines 22 to 24
type GasTx interface {
GetGas() uint64
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this should be defined with the other tx interfaces: types/tx_msg.go?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this interface is mainly used in mempool

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think even if it is only used here, i would prefer to house all Tx interfaces in one place

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants