Merge #9404: Smarter coordination of change and fee in CreateTransaction.
20449ef Don't overpay fee if we have selected new coins that result in a smaller transaction. (Alex Morcos) 42f5ce4 Try to reduce change output to make needed fee in CreateTransaction (Alex Morcos)
This commit is contained in:
parent
17e51db71f
commit
7c5de865d8
@ -3669,8 +3669,37 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& 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<CTxOut>::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) {
|
||||
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.
|
||||
nFeeRet = nFeeNeeded;
|
||||
|
@ -52,8 +52,10 @@ static const CAmount DEFAULT_TRANSACTION_FEE = 0;
|
||||
static const CAmount DEFAULT_FALLBACK_FEE = 1000;
|
||||
//! -mintxfee default
|
||||
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
|
||||
//! minimum change amount
|
||||
//! target minimum change amount
|
||||
static const CAmount MIN_CHANGE = CENT;
|
||||
//! final minimum change amount after paying for fees
|
||||
static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2;
|
||||
//! Default for -spendzeroconfchange
|
||||
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true;
|
||||
//! Default for -sendfreetransactions
|
||||
|
Loading…
Reference in New Issue
Block a user