@ -2534,8 +2534,37 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
return false ;
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 < CTxOut > : : iterator change_position = txNew . vout . begin ( ) + nChangePosInOut ;
change_position - > nValue + = extraFeePaid ;
nFeeRet - = extraFeePaid ;
}
break ; // Done, enough fee included.
break ; // Done, enough fee included.
}
// Try to reduce change to include necessary fee
if ( nChangePosInOut ! = - 1 & & nSubtractFeeFromAmount = = 0 ) {
CAmount additionalFeeNeeded = nFeeNeeded - nFeeRet ;
vector < CTxOut > : : iterator change_position = txNew . vout . begin ( ) + nChangePosInOut ;
// Only reduce change if remaining amount is still a large enough output.
if ( change_position - > nValue > = MIN_FINAL_CHANGE + additionalFeeNeeded ) {
change_position - > nValue - = additionalFeeNeeded ;
nFeeRet + = additionalFeeNeeded ;
break ; // Done, able to increase fee from change
}
}
// Include more fee and try again.
// Include more fee and try again.
nFeeRet = nFeeNeeded ;
nFeeRet = nFeeNeeded ;