aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/feebumper.cpp
diff options
context:
space:
mode:
authorAndrew Chow <github@achow101.com>2022-11-07 14:52:56 -0500
committerAndrew Chow <github@achow101.com>2023-06-26 17:49:09 -0400
commit7d83502d3d52218e7b0b0634cff2a9aba9cc77ef (patch)
tree6859f2c2da1687f04c9288fcd0ddf60b3952e457 /src/wallet/feebumper.cpp
parenta36134fcc7b40671d538931f621c8c15ffacc3d2 (diff)
downloadbitcoin-7d83502d3d52218e7b0b0634cff2a9aba9cc77ef.tar.xz
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.cpp25
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;
}