diff options
author | Andrew Chow <github@achow101.com> | 2022-11-07 14:52:56 -0500 |
---|---|---|
committer | Andrew Chow <github@achow101.com> | 2023-06-26 17:49:09 -0400 |
commit | 7d83502d3d52218e7b0b0634cff2a9aba9cc77ef (patch) | |
tree | 6859f2c2da1687f04c9288fcd0ddf60b3952e457 /src/wallet/feebumper.cpp | |
parent | a36134fcc7b40671d538931f621c8c15ffacc3d2 (diff) |
bumpfee: Allow original change position to be specified
If the user used a custom change address, it may not be detected as a
change output, resulting in an additional change output being added to
the bumped transaction. We can avoid this issue by allowing the user to
specify the position of the change output.
Diffstat (limited to 'src/wallet/feebumper.cpp')
-rw-r--r-- | src/wallet/feebumper.cpp | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index 0e1f1f9847..3720d144eb 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -152,8 +152,14 @@ bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid) } Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<bilingual_str>& errors, - CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx, bool require_mine, const std::vector<CTxOut>& outputs) + CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx, bool require_mine, const std::vector<CTxOut>& outputs, std::optional<uint32_t> reduce_output) { + // Cannot both specify new outputs and an output to reduce + if (!outputs.empty() && reduce_output.has_value()) { + errors.push_back(Untranslated("Cannot specify both new outputs to use and an output index to reduce")); + return Result::INVALID_PARAMETER; + } + // We are going to modify coin control later, copy to re-use CCoinControl new_coin_control(coin_control); @@ -166,6 +172,12 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo } const CWalletTx& wtx = it->second; + // Make sure that reduce_output is valid + if (reduce_output.has_value() && reduce_output.value() >= wtx.tx->vout.size()) { + errors.push_back(Untranslated("Change position is out of range")); + return Result::INVALID_PARAMETER; + } + // Retrieve all of the UTXOs and add them to coin control // While we're here, calculate the input amount std::map<COutPoint, Coin> coins; @@ -233,14 +245,15 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo std::vector<CRecipient> recipients; CAmount new_outputs_value = 0; const auto& txouts = outputs.empty() ? wtx.tx->vout : outputs; - for (const auto& output : txouts) { - if (!OutputIsChange(wallet, output)) { - CRecipient recipient = {output.scriptPubKey, output.nValue, false}; - recipients.push_back(recipient); - } else { + for (size_t i = 0; i < txouts.size(); ++i) { + const CTxOut& output = txouts.at(i); + if (reduce_output.has_value() ? reduce_output.value() == i : OutputIsChange(wallet, output)) { CTxDestination change_dest; ExtractDestination(output.scriptPubKey, change_dest); new_coin_control.destChange = change_dest; + } else { + CRecipient recipient = {output.scriptPubKey, output.nValue, false}; + recipients.push_back(recipient); } new_outputs_value += output.nValue; } |