Skip to content

Commit f4d00e6

Browse files
committed
Add a discard_rate
Any change output which would be dust at the discard_rate you are willing to discard completely and add to fee (as well as continuing to pay the fee that would have been needed for creating the change).
1 parent b138585 commit f4d00e6

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/wallet/wallet.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE);
5757
*/
5858
CFeeRate CWallet::fallbackFee = CFeeRate(DEFAULT_FALLBACK_FEE);
5959

60+
CFeeRate CWallet::m_discard_rate = CFeeRate(DEFAULT_DISCARD_FEE);
61+
6062
const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
6163

6264
/** @defgroup mapWallet
@@ -2501,6 +2503,17 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
25012503
return true;
25022504
}
25032505

2506+
static CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator)
2507+
{
2508+
unsigned int highest_target = estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
2509+
CFeeRate discard_rate = estimator.estimateSmartFee(highest_target, nullptr /* FeeCalculation */, false /* conservative */);
2510+
// Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate
2511+
discard_rate = (discard_rate == CFeeRate(0)) ? CWallet::m_discard_rate : std::min(discard_rate, CWallet::m_discard_rate);
2512+
// Discard rate must be at least dustRelayFee
2513+
discard_rate = std::max(discard_rate, ::dustRelayFee);
2514+
return discard_rate;
2515+
}
2516+
25042517
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
25052518
int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
25062519
{
@@ -2600,6 +2613,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
26002613
CTxOut change_prototype_txout(0, scriptChange);
26012614
size_t change_prototype_size = GetSerializeSize(change_prototype_txout, SER_DISK, 0);
26022615

2616+
CFeeRate discard_rate = GetDiscardRate(::feeEstimator);
26032617
nFeeRet = 0;
26042618
bool pick_new_inputs = true;
26052619
CAmount nValueIn = 0;
@@ -2667,7 +2681,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
26672681

26682682
// Never create dust outputs; if we would, just
26692683
// add the dust to the fee.
2670-
if (IsDust(newTxOut, ::dustRelayFee))
2684+
if (IsDust(newTxOut, discard_rate))
26712685
{
26722686
nChangePosInOut = -1;
26732687
nFeeRet += nChange;
@@ -2747,7 +2761,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
27472761
// (because of reduced tx size) and so we should add a
27482762
// change output. Only try this once.
27492763
CAmount fee_needed_for_change = GetMinimumFee(change_prototype_size, coin_control, ::mempool, ::feeEstimator, nullptr);
2750-
CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, ::dustRelayFee);
2764+
CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, discard_rate);
27512765
CAmount max_excess_fee = fee_needed_for_change + minimum_value_for_change;
27522766
if (nFeeRet > nFeeNeeded + max_excess_fee && nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
27532767
pick_new_inputs = false;
@@ -3788,6 +3802,9 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
37883802
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE));
37893803
strUsage += HelpMessageOpt("-fallbackfee=<amt>", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"),
37903804
CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE)));
3805+
strUsage += HelpMessageOpt("-discardfee=<amt>", strprintf(_("The fee rate (in %s/kB) used to discard change (to fee) if it would be dust at this fee rate (default: %s) "
3806+
"Note: We will always discard up to the dust relay fee and a discard fee above that is limited by the longest target fee estimate"),
3807+
CURRENCY_UNIT, FormatMoney(DEFAULT_DISCARD_FEE)));
37913808
strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"),
37923809
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
37933810
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
@@ -4113,6 +4130,16 @@ bool CWallet::ParameterInteraction()
41134130
_("This is the transaction fee you may pay when fee estimates are not available."));
41144131
CWallet::fallbackFee = CFeeRate(nFeePerK);
41154132
}
4133+
if (IsArgSet("-discardfee"))
4134+
{
4135+
CAmount nFeePerK = 0;
4136+
if (!ParseMoney(GetArg("-discardfee", ""), nFeePerK))
4137+
return InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), GetArg("-discardfee", "")));
4138+
if (nFeePerK > HIGH_TX_FEE_PER_KB)
4139+
InitWarning(AmountHighWarn("-discardfee") + " " +
4140+
_("This is the transaction fee you may discard if change is smaller than dust at this level"));
4141+
CWallet::m_discard_rate = CFeeRate(nFeePerK);
4142+
}
41164143
if (IsArgSet("-paytxfee"))
41174144
{
41184145
CAmount nFeePerK = 0;

src/wallet/wallet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ static const unsigned int DEFAULT_KEYPOOL_SIZE = 100;
4545
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
4646
//! -fallbackfee default
4747
static const CAmount DEFAULT_FALLBACK_FEE = 20000;
48+
//! -m_discard_rate default
49+
static const CAmount DEFAULT_DISCARD_FEE = 10000;
4850
//! -mintxfee default
4951
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
5052
//! minimum recommended increment for BIP 125 replacement txs
@@ -965,6 +967,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
965967

966968
static CFeeRate minTxFee;
967969
static CFeeRate fallbackFee;
970+
static CFeeRate m_discard_rate;
968971
/**
969972
* Estimate the minimum fee considering user set parameters
970973
* and the required fee

0 commit comments

Comments
 (0)