diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/spend.cpp | 27 |
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 |