wallet: feebumper, fix crash when combined bump fee is unavailable
What changed, and why it matters
This commit fixes a bug in Bitcoin Core's transaction fee-bumping feature. When a user tried to increase the fee on a transaction that was tied to a very large cluster of unconfirmed transactions, the software could not calculate the required fee and returned an empty value. The old code then tried to use that empty value anyway, causing the program to crash (in the GUI) or throw an unhandled exception (in command-line tools). The fix simply checks for the empty value and returns a proper error message instead of crashing.
Apply the patch. It is a minimal, correct fix. Consider whether other optional-returning wallet helpers have similar missing-early-return patterns.
Security signals we found
Denial-of-service vector: unhandled std::bad_optional_access causes GUI crash and RPC uncaught exception
Null-opt optional dereference in fee-bumping logic
Missing early return after error condition check
Trigger depends on wallet state: large unconfirmed transaction cluster
Evidence from the diff
In src/wallet/feebumper.cpp, CheckFeeRate() calls wallet.chain().calculateCombinedBumpFee() which returns std::optional
Changed components
src/wallet/feebumper.cppCheckFeeRate()calculateCombinedBumpFee()GUI bump fee flowRPC bumpfeeRPC psbtbumpfeeInspect captured patch +2 / −1
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp
index ff7a9f5a..7f84c6fa 100644
--- a/src/wallet/feebumper.cpp
+++ b/src/wallet/feebumper.cpp
@@ -80,9 +80,10 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CMutableTrans
reused_inputs.push_back(txin.prevout);
}
- std::optional<CAmount> combined_bump_fee = wallet.chain().calculateCombinedBumpFee(reused_inputs, newFeerate);
+ const std::optional<CAmount> combined_bump_fee = wallet.chain().calculateCombinedBumpFee(reused_inputs, newFeerate);
if (!combined_bump_fee.has_value()) {
errors.push_back(Untranslated(strprintf("Failed to calculate bump fees, because unconfirmed UTXOs depend on an enormous cluster of unconfirmed transactions.")));
+ return feebumper::Result::WALLET_ERROR;
}
CAmount new_total_fee = newFeerate.GetFee(maxTxSize) + combined_bump_fee.value();
Why this scored 45/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.