diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2017-01-09 08:20:41 -0800 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2017-01-09 08:37:35 -0800 |
commit | 12e31127948fa4bb01c3bddc1b8c85b432f7465b (patch) | |
tree | b47324dcd8031b65b834e5261384d24fc749a6b5 /src/wallet/wallet.cpp | |
parent | 8c87f175d335e9d9e93f987d871ae9f05f6a10a7 (diff) | |
parent | 20449ef09edf8f4f51a3e531d947dd89973c2a31 (diff) |
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)
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r-- | src/wallet/wallet.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ff7a03bc55..2775f4def3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2534,8 +2534,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; |