#36393 wallet: enforce max_tx_weight for preset inputs

ReviewabilityReviewsAgreementSize
#36393 gjija wallet: enforce max_tx_weight for preset inputsReady0 (+1)Strong5 + 14 tests
  • Enforce caller-specified max_tx_weight when preset inputs fully cover a wallet transaction
  • Prevents RPC calls like fundrawtransaction from generating transactions heavier than requested
  • Ready for review, with no known blockers or invalidating changes
  • Substantive support with no open objections
  • Verified fix by reproducing max_tx_weight behavior with legacy inputs and functional tests (jcastros)
  • Verified fix by testing transactions with preset inputs and outputs (vicjuma)
  • Resolved question on whether to enforce TRUC child limits now or in a follow-up (jcastros)
  • 5 lines added or modified outside tests
  • 14 lines added or modified in tests
  • 3 lines removed in total
  • 2 files, 1 commits
Wallet#40 of 92
P3 · bug fix
  • P3 because it fixes a bug where explicit weight limits were ignored when coin selection was bypassed
  • Affects users funding transactions with preset inputs who rely on max_tx_weight constraints
  • Ranking pass: Moved up: an explicitly requested constraint being silently ignored is a bug, ranked with the other P3 bug fixes.
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Enforces caller-specified `max_tx_weight` during wallet transaction creation when preset inputs already cover the payment amount. Previously, bypassing coin selection left only the default `MAX_STANDARD_TX_WEIGHT` ceiling in the final guard of `CreateTransactionInternal`.

Problem: When preset inputs fully fund a transaction, coin selection is bypassed along with its weight constraints. The final transaction weight check compared against the 400,000 WU standard network limit rather than the caller's requested `max_tx_weight`, allowing RPC methods like `fundrawtransaction` to output transactions heavier than requested.

Evidence of importance:

  • Author reproduced the issue using 10 legacy inputs and `max_tx_weight=4000`: funding succeeded with a 6,168 WU transaction instead of returning an error, under both `add_inputs=false` and `add_inputs=true` (PR description).

Risk of a mistake: medium (wallet). A bug in wallet transaction weight checking could inadvertently reject valid funding attempts or throw an unhandled exception during transaction construction.

Changed since the previous assessment: Unchanged in approach; likely updated comments or rebased since the previous revision.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • reviewer: re-review after author addressed comment nits 2026-10-19

Agreement

Strong

substantive support, no open objection (jcastros, vicjuma)

Thread notes: The author pushed a comment-only update addressing vicjuma's code comment nits.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
jcastros (contributor)question, scopewhether the final check should enforce the 1000 vbyte TRUC limit for preset inputs or leave it for a follow-upanswered · author replied that TRUC child-limit fix should be handled in a follow-upansweredyes2026-10-03: 'Should this final check enforce that cap as well, or do you want it as a follow-up?'
Status from: 2026-10-04: gjija: 'I’d keep the TRUC child-limit fix as a follow-up, since it reproduces on the parent too.'

Support:

  • jcastros (contributor) (ACK, 2026-10-03) [both]: tested reproduction of max_tx_weight behavior with legacy inputs and verified wallet_fundrawtransaction.py fails without the fix and passes with it
  • vicjuma (contributor) (Concept ACK, 2026-10-16) [both: src/wallet/spend.cpp, test/functional/wallet_fundrawtransaction.py]: tested with ~830 weighted transactions (2 P2WPKH inputs + 1 P2WPKH output) and confirmed it works as expected

Participants:

  • jcastros (contributor, support, 1 statements 2026-10-03 to 2026-10-03): tested and ACKed; asked about TRUC child-limit scope which author answered
  • vicjuma (contributor, support, 3 statements 2026-10-16 to 2026-10-16): Concept ACK with testing; left minor nits on comments

Files

14 lines under test/bench/ci.

  • test/functional/wallet_fundrawtransaction.py +14/-0
  • src/wallet/spend.cpp +5/-3

Card

The short text the ranking pass compares across PRs.

Wallet transaction funding (`fundrawtransaction`) fails to enforce custom `max_tx_weight` limits when preset inputs alone satisfy the target amount. Because coin selection exits early, the wallet's final weight check previously verified against the standard 400,000 WU network limit instead of the user-provided maximum. This change checks against the configured maximum weight in the final guard and adds regression tests.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-21T01:17, confidence high, input hash 84134898cbad910a
thread read through 2026-10-19 (8 statements), head 37f3c7da4e
labels: Wallet

Categories

Wallet

P3 · bug fix (ranking pass: Moved up: an explicitly requested constraint being silently ignored is a bug, ranked with the other P3 bug fixes.)

Fixes a bug where caller-specified `max_tx_weight` is ignored during wallet transaction creation when preset inputs fully cover the transaction amount. In `CreateTransactionInternal`, bypassing coin selection fell back to checking against `MAX_STANDARD_TX_WEIGHT` (400,000 WU) instead of the caller's parameter, allowing RPCs like `fundrawtransaction` to output transactions exceeding requested weight limits.

Membership: Landed in src/wallet/spend.cpp and labeled Wallet, modifying transaction creation weight validation.

Factors: security/stability 0, bug 1, performance 0, user value 1, leverage 0