aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorAndrew Chow <github@achow101.com>2022-12-05 14:33:35 -0500
committerAndrew Chow <github@achow101.com>2022-12-09 14:52:26 -0500
commitc1a84f108e320bd44c172a4dd3bb486ab777ff69 (patch)
treea257f489d858ec571cd502f953af70f83edd2939 /src/wallet
parente5daf976d5b064b585029d4bb38d68a8153ea13b (diff)
downloadbitcoin-c1a84f108e320bd44c172a4dd3bb486ab777ff69.tar.xz
wallet: Move fee underpayment check to after fee setting
It doesn't make sense to be checking whether the fee paid is underpaying before we've finished setting the fees. So do that after we have done the reduction for SFFO and change adjustment for fee overpayment.
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/spend.cpp27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index d92fd52ead..a1a98381e5 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -8,6 +8,7 @@
#include <interfaces/chain.h>
#include <numeric>
#include <policy/policy.h>
+#include <primitives/transaction.h>
#include <script/signingprovider.h>
#include <util/check.h>
#include <util/fees.h>
@@ -959,19 +960,18 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
return util::Error{_("Missing solving data for estimating transaction size")};
}
CAmount fee_needed = coin_selection_params.m_effective_feerate.GetFee(nBytes);
- CAmount current_fee = result->GetSelectedValue() - recipients_sum - change_amount;
-
- // The only time that fee_needed should be less than the amount available for fees is when
- // we are subtracting the fee from the outputs. If this occurs at any other time, it is a bug.
- if (!coin_selection_params.m_subtract_fee_outputs && fee_needed > current_fee) {
- return util::Error{Untranslated(STR_INTERNAL_BUG("Fee needed > fee paid"))};
- }
+ const CAmount output_value = CalculateOutputValue(txNew);
+ Assume(recipients_sum + change_amount == output_value);
+ CAmount current_fee = result->GetSelectedValue() - output_value;
// If there is a change output and we overpay the fees then increase the change to match the fee needed
if (nChangePosInOut != -1 && fee_needed < current_fee) {
auto& change = txNew.vout.at(nChangePosInOut);
change.nValue += current_fee - fee_needed;
- current_fee = fee_needed;
+ current_fee = result->GetSelectedValue() - CalculateOutputValue(txNew);
+ if (fee_needed != current_fee) {
+ return util::Error{Untranslated(STR_INTERNAL_BUG("Change adjustment: Fee needed != fee paid"))};
+ }
}
// Reduce output values for subtractFeeFromAmount
@@ -1007,7 +1007,16 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
}
++i;
}
- current_fee = fee_needed;
+ current_fee = result->GetSelectedValue() - CalculateOutputValue(txNew);
+ if (fee_needed != current_fee) {
+ return util::Error{Untranslated(STR_INTERNAL_BUG("SFFO: Fee needed != fee paid"))};
+ }
+ }
+
+ // fee_needed should now always be less than or equal to the current fees that we pay.
+ // If it is not, it is a bug.
+ if (fee_needed > current_fee) {
+ return util::Error{Untranslated(STR_INTERNAL_BUG("Fee needed > fee paid"))};
}
// Give up if change keypool ran out and change is required