#36597 wallet: return broadcast errors from CommitTransaction
| Reviewability | Reviews | Agreement | Size | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| #36597 wallet: return broadcast errors from CommitTransaction | Waiting on author | 0 | Positive | 150 + 110 tests | ||||||
|
|
|
|
| ||||||
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
Updates wallet commit and transaction broadcast interfaces to return an `Expected<void, TransactionBroadcastError>` instead of `void` or error codes with separate output strings. Introduces `TransactionBroadcastError` pairing a `TransactionError` code with an untranslated message, removes `TransactionError::OK`, and adds a `SUBMISSION_SKIPPED` code for transactions that the wallet chooses not to relay. Existing callers such as RPCs and the Qt widgets interface currently discard the result to preserve existing behavior.
Problem: Frontends relying on `interfaces::Wallet::commitTransaction` cannot know if a transaction was accepted into the mempool because `CWallet::CommitTransaction()` only logged errors and returned `void`. Consequently, interfaces such as the QML GUI report 'Transaction sent' even when the node rejected the transaction.
Evidence of importance:
- PR description: 'The QML GUI shows "Transaction sent" even when the node rejected the transaction, because CWallet::CommitTransaction() only logs the rejection and returns void' (bitcoin-core/gui-qml#1008)
Scope: Modifies public interfaces across `interfaces::Wallet`, `interfaces::Chain`, and `interfaces::Node`, refactoring `BroadcastTransaction` signatures and updating all internal invocation sites.
Risk of a mistake: medium (wallet, gui, rpc_api). A mistake in transaction submission error handling or mempool state tracking in CWallet could cause wallet transactions to incorrectly fail or become desynchronized from the node.
Changed since the previous assessment: Initial description was evaluated without patch data; the full patch confirms the signature refactoring across interfaces and the addition of unit tests in `wallet_interfaces_tests.cpp` and `wallet_tests.cpp`.
Reviewability
Paused · Waiting on author
Open objection from ViniciusCestarii with no author reply for 9 days; review would repeat what has been asked.
Waiting on (from the thread read):
- author: respond to ViniciusCestarii's test coverage observation 2026-10-23
- reviewer: maflcko to review author's explanation of use cases 2026-10-23
Agreement
Positive
support without stated reasons, no open objection (w0xlt, Naomi-Gift)
Thread notes: Added maflcko's inquiry questioning the rationale for CommitTransaction errors (answered by pseudoramdom) and ViniciusCestarii's mutation test observation indicating missing test coverage in interface tests.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| Naomi-Gift (none) | question, interface | Will the QML GUI treat SUBMISSION_SKIPPED with -walletbroadcast=0 as saved rather than failure? | answered · author confirmed that SUBMISSION_SKIPPED is intended to allow callers to differentiate skipped submissions from rejections | answered | yes | 2026-10-22: 'Will the QML GUI treat that as "saved, not broadcast" rather than as a failure?' Status from: 2026-10-22: pseudoramdom: 'Yes, that's the intent. `SUBMISSION_SKIPPED` is a separate code precisely so a caller can differentiate' |
| maflcko (member) | suggestion, usefulness | Explain why returning broadcast errors is needed rather than fixing creation bugs, warning about fees before creation, or reporting asynchronously | answered · author explained that imported PSBTs bypass create checks, and sync errors complement async notifications | answered | yes | 2026-10-23: 'Can you explain why this would be needed? If the wallet creates a consensus-invalid (permanently invalid) transaction, that seems like a severe bug that should be fixed instead.' Status from: 2026-10-23: pseudoramdom: 'The GUI can import a PSBT that spends the wallet's coins, sign it with the wallet and commit it. Its inputs and fee were chosen elsewhere and none of `createTransaction()`'s checks ran' |
| ViniciusCestarii (contributor) | suggestion, maintenance | Add test coverage for MEMPOOL_REJECTED in interfaces::Wallet commit_transaction test to kill surviving mutant | open | answered | no | 2026-10-23: 'returning success on `MEMPOOL_REJECTED` survives. `CommitTransactionErrors` covers the rejection on `CWallet`, but the interface test `commit_transaction` (the path gui-qml#1008 uses) only covers `SUBMISSION_SKIPPED` and success.' |
Support:
- w0xlt (contributor) (Concept ACK, 2026-10-21): (no reason given) [not substantive]
- Naomi-Gift (none) (Concept ACK, 2026-10-22): (no reason given) [not substantive]
Participants:
- w0xlt (contributor, support, 1 statements 2026-10-21 to 2026-10-21): gave Concept ACK
- Naomi-Gift (none, support, 1 statements 2026-10-22 to 2026-10-22): Concept ACK; asked how QML GUI handles SUBMISSION_SKIPPED
- ViniciusCestarii (contributor, neutral, 1 statements 2026-10-23 to 2026-10-23): pointed out surviving mutant from missing test coverage for MEMPOOL_REJECTED
- maflcko (member, question, 1 statements 2026-10-23 to 2026-10-23): asked why broadcast errors are needed instead of fixing wallet bugs or using async feedback
Dependencies
Enables:
- bitcoin-core/gui-qml update to report broadcast errors to users (gui-qml#1008)
- Follow-up PR propagating errors from commitBumpTransaction
Files
116 lines under test/bench/ci.
- src/wallet/test/wallet_tests.cpp +77/-6
- src/wallet/wallet.cpp +32/-21
- src/node/transaction.cpp +21/-12
- src/wallet/test/wallet_interfaces_tests.cpp +32/-0
- src/rpc/mempool.cpp +12/-16
- src/node/interfaces.cpp +8/-13
- src/interfaces/chain.h +9/-8
- src/node/transaction.h +8/-9
- src/net_processing.cpp +9/-5
- src/node/types.h +13/-1
- src/wallet/wallet.h +10/-3
- src/qt/psbtoperationsdialog.cpp +4/-6
- src/interfaces/node.h +5/-3
- src/interfaces/wallet.h +5/-2
- src/net_processing.h +3/-3
- src/wallet/interfaces.cpp +3/-2
- src/common/messages.cpp +2/-2
- src/wallet/rpc/spend.cpp +2/-2
- src/qt/walletmodel.cpp +1/-1
- src/rpc/util.cpp +2/-0
- src/wallet/feebumper.cpp +1/-1
- src/test/fuzz/kitchen_sink.cpp +1/-0
Card
The short text the ranking pass compares across PRs.
Changes CWallet::CommitTransaction and interfaces::Wallet::commitTransaction to return broadcast errors via util::Expected instead of returning void. This allows interfaces such as the QML GUI to inform users when a transaction has been rejected instead of falsely claiming 'Transaction sent' (bitcoin-core/gui-qml#1008). Existing wallet RPC and Qt widget callers ignore the returned error to maintain existing behavior.
Data
thread read through 2026-10-23 (6 statements), head 4e3d167559
labels: Wallet
Categories
IPC / multiprocess
P3 · unblocks #1008
Extends node and wallet interface methods to return structured broadcast errors needed by multiprocess consumers like the QML GUI. The PR description notes that frontends relying on `interfaces::Wallet::commitTransaction` could not detect rejected transactions because the method returned `void`, unblocking gui-qml#1008.
Membership: Modifies public interfaces in src/interfaces/wallet.h, src/interfaces/chain.h, and src/interfaces/node.h to propagate broadcast errors across process boundaries.
Factors: security/stability 0, bug 1, performance 0, user value 2, leverage 2
Wallet
P3 · bug fix (assessed alone as P2; Lowered from P2: no behavior change for current Core callers; the payoff accrues to downstream gui-qml, like #36685.)
Prevents wallet frontends from falsely displaying 'Transaction sent' when the node rejects a transaction. The PR description highlights that `CWallet::CommitTransaction()` previously discarded rejections by returning `void`, masking broadcast failures from the user.
Membership: Labeled 'Wallet' and modifies CWallet::CommitTransaction() alongside wallet spend and bump fee interfaces.
Factors: security/stability 0, bug 1, performance 0, user value 2, leverage 2