Skip to content

Commit 7bffec6

Browse files
committed
bumpfee: enable send coins back to yourself
Simple example: 1) User_1 sends 0.1 btc to user_2 on a low fee transaction. 2) After few hours, the tx is still in the mempool, user_2 is not interested anymore, so user_1 decides to cancel it by sending coins back to himself. 3) User_1 has the bright idea of opening the explorer and copy the change output address of the transaction. Then call bumpfee providing such output (in the "outputs" arg). Currently, this is not possible. The wallet fails with "Unable to create transaction. Transaction must have at least one recipient" error. The error reason is that we discard the provided output from the recipients list and set it inside the coin control so the process adds it later (when the change is calculated). But.. there is no later if the tx has no outputs.
1 parent b22c275 commit 7bffec6

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

src/wallet/feebumper.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
231231
// is one). If outputs vector is non-empty, replace original
232232
// outputs with its contents, otherwise use original outputs.
233233
std::vector<CRecipient> recipients;
234+
CAmount new_outputs_value = 0;
234235
const auto& txouts = outputs.empty() ? wtx.tx->vout : outputs;
235236
for (const auto& output : txouts) {
236237
if (!OutputIsChange(wallet, output)) {
@@ -241,6 +242,21 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
241242
ExtractDestination(output.scriptPubKey, change_dest);
242243
new_coin_control.destChange = change_dest;
243244
}
245+
new_outputs_value += output.nValue;
246+
}
247+
248+
// If no recipients, means that we are sending coins to a change address
249+
if (recipients.empty()) {
250+
// Just as a sanity check, ensure that the change address exist
251+
if (std::get_if<CNoDestination>(&new_coin_control.destChange)) {
252+
errors.emplace_back(Untranslated("Unable to create transaction. Transaction must have at least one recipient"));
253+
return Result::INVALID_PARAMETER;
254+
}
255+
256+
// Add change as recipient with SFFO flag enabled, so fees are deduced from it.
257+
// If the output differs from the original tx output (because the user customized it) a new change output will be created.
258+
recipients.emplace_back(CRecipient{GetScriptForDestination(new_coin_control.destChange), new_outputs_value, /*fSubtractFeeFromAmount=*/true});
259+
new_coin_control.destChange = CNoDestination();
244260
}
245261

246262
if (coin_control.m_feerate) {

0 commit comments

Comments
 (0)