diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index bdf6d3c7a6..2775f4def3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2534,8 +2534,25 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt return false; } - if (nFeeRet >= nFeeNeeded) + if (nFeeRet >= nFeeNeeded) { + // Reduce fee to only the needed amount if we have change + // output to increase. This prevents potential overpayment + // in fees if the coins selected to meet nFeeNeeded result + // in a transaction that requires less fee than the prior + // iteration. + // TODO: The case where nSubtractFeeFromAmount > 0 remains + // to be addressed because it requires returning the fee to + // the payees and not the change output. + // TODO: The case where there is no change output remains + // to be addressed so we avoid creating too small an output. + if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) { + CAmount extraFeePaid = nFeeRet - nFeeNeeded; + vector::iterator change_position = txNew.vout.begin()+nChangePosInOut; + change_position->nValue += extraFeePaid; + nFeeRet -= extraFeePaid; + } break; // Done, enough fee included. + } // Try to reduce change to include necessary fee if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {