Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 3,126 Lines • ▼ Show 20 Lines | assert(txNew.nLockTime < LOCKTIME_THRESHOLD); | ||||
} | } | ||||
if (nFeeRet >= nFeeNeeded) { | if (nFeeRet >= nFeeNeeded) { | ||||
// Reduce fee to only the needed amount if possible. This | // Reduce fee to only the needed amount if possible. This | ||||
// prevents potential overpayment in fees if the coins selected | // prevents potential overpayment in fees if the coins selected | ||||
// to meet nFeeNeeded result in a transaction that requires less | // to meet nFeeNeeded result in a transaction that requires less | ||||
// fee than the prior iteration. | // 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. | |||||
// If we have no change and a big enough excess fee, then try to | // If we have no change and a big enough excess fee, then try to | ||||
// construct transaction again only without picking new inputs. | // construct transaction again only without picking new inputs. | ||||
// We now know we only need the smaller fee (because of reduced | // We now know we only need the smaller fee (because of reduced | ||||
// tx size) and so we should add a change output. Only try this | // tx size) and so we should add a change output. Only try this | ||||
// once. | // once. | ||||
Amount fee_needed_for_change = GetMinimumFee( | Amount fee_needed_for_change = GetMinimumFee( | ||||
change_prototype_size, coinControl, g_mempool); | change_prototype_size, coinControl, g_mempool); | ||||
Amount minimum_value_for_change = | Amount minimum_value_for_change = | ||||
Show All 17 Lines | assert(txNew.nLockTime < LOCKTIME_THRESHOLD); | ||||
change_position->nValue += extraFeePaid; | change_position->nValue += extraFeePaid; | ||||
nFeeRet -= extraFeePaid; | nFeeRet -= extraFeePaid; | ||||
} | } | ||||
// Done, enough fee included. | // Done, enough fee included. | ||||
break; | break; | ||||
} else if (!pick_new_inputs) { | } else if (!pick_new_inputs) { | ||||
// This shouldn't happen, we should have had enough excess fee | // This shouldn't happen, we should have had enough excess fee | ||||
// to pay for the new output and still meet nFeeNeeded | // to pay for the new output and still meet nFeeNeeded. | ||||
// Or we should have just subtracted fee from recipients and | |||||
// nFeeNeeded should not have changed. | |||||
strFailReason = | strFailReason = | ||||
_("Transaction fee and change calculation failed"); | _("Transaction fee and change calculation failed"); | ||||
return false; | return false; | ||||
} | } | ||||
// Try to reduce change to include necessary fee. | // Try to reduce change to include necessary fee. | ||||
if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) { | if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) { | ||||
Amount additionalFeeNeeded = nFeeNeeded - nFeeRet; | Amount additionalFeeNeeded = nFeeNeeded - nFeeRet; | ||||
std::vector<CTxOut>::iterator change_position = | std::vector<CTxOut>::iterator change_position = | ||||
txNew.vout.begin() + nChangePosInOut; | txNew.vout.begin() + nChangePosInOut; | ||||
// Only reduce change if remaining amount is still a large | // Only reduce change if remaining amount is still a large | ||||
// enough output. | // enough output. | ||||
if (change_position->nValue >= | if (change_position->nValue >= | ||||
MIN_FINAL_CHANGE + additionalFeeNeeded) { | MIN_FINAL_CHANGE + additionalFeeNeeded) { | ||||
change_position->nValue -= additionalFeeNeeded; | change_position->nValue -= additionalFeeNeeded; | ||||
nFeeRet += additionalFeeNeeded; | nFeeRet += additionalFeeNeeded; | ||||
// Done, able to increase fee from change. | // Done, able to increase fee from change. | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
// If subtracting fee from recipients, we now know what fee we | |||||
// need to subtract, we have no reason to reselect inputs. | |||||
if (nSubtractFeeFromAmount > 0) { | |||||
pick_new_inputs = false; | |||||
} | |||||
// Include more fee and try again. | // Include more fee and try again. | ||||
nFeeRet = nFeeNeeded; | nFeeRet = nFeeNeeded; | ||||
continue; | continue; | ||||
} | } | ||||
if (nChangePosInOut == -1) { | if (nChangePosInOut == -1) { | ||||
// Return any reserved key if we don't have change | // Return any reserved key if we don't have change | ||||
reservekey.ReturnKey(); | reservekey.ReturnKey(); | ||||
▲ Show 20 Lines • Show All 1,360 Lines • Show Last 20 Lines |