aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Morcos <morcos@chaincode.com>2017-01-05 09:12:48 -0500
committerAlex Morcos <morcos@chaincode.com>2017-01-06 10:18:56 -0500
commit20449ef09edf8f4f51a3e531d947dd89973c2a31 (patch)
tree7453c2fb8de3e66d2a81dda0c0ffb63951cd21b9
parent42f5ce40931402aaa395ef2959deb64e9a9fff02 (diff)
Don't overpay fee if we have selected new coins that result in a smaller transaction.
On repeated calls to SelectCoins we try to meet the fee necessary for the last transaction, the new fee required might be smaller, so increase our change by the difference if we can.
-rw-r--r--src/wallet/wallet.cpp19
1 files changed, 18 insertions, 1 deletions
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<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) {