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:
commit
12e3112794
2 changed files with 33 additions and 2 deletions
|
@ -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;
|
||||||
|
|
|
@ -48,8 +48,10 @@ static const CAmount DEFAULT_TRANSACTION_FEE = 0;
|
||||||
static const CAmount DEFAULT_FALLBACK_FEE = 20000;
|
static const CAmount DEFAULT_FALLBACK_FEE = 20000;
|
||||||
//! -mintxfee default
|
//! -mintxfee default
|
||||||
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
|
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
|
||||||
//! minimum change amount
|
//! target minimum change amount
|
||||||
static const CAmount MIN_CHANGE = CENT;
|
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
|
//! Default for -spendzeroconfchange
|
||||||
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true;
|
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true;
|
||||||
//! Default for -sendfreetransactions
|
//! Default for -sendfreetransactions
|
||||||
|
|
Loading…
Reference in a new issue