@@ -57,6 +57,8 @@ CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE);
57
57
*/
58
58
CFeeRate CWallet::fallbackFee = CFeeRate(DEFAULT_FALLBACK_FEE);
59
59
60
+ CFeeRate CWallet::m_discard_rate = CFeeRate(DEFAULT_DISCARD_FEE);
61
+
60
62
const uint256 CMerkleTx::ABANDON_HASH (uint256S(" 0000000000000000000000000000000000000000000000000000000000000001" ));
61
63
62
64
/* * @defgroup mapWallet
@@ -2501,6 +2503,17 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
2501
2503
return true ;
2502
2504
}
2503
2505
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
+
2504
2517
bool CWallet::CreateTransaction (const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
2505
2518
int & nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
2506
2519
{
@@ -2600,6 +2613,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
2600
2613
CTxOut change_prototype_txout (0 , scriptChange);
2601
2614
size_t change_prototype_size = GetSerializeSize (change_prototype_txout, SER_DISK, 0 );
2602
2615
2616
+ CFeeRate discard_rate = GetDiscardRate (::feeEstimator);
2603
2617
nFeeRet = 0 ;
2604
2618
bool pick_new_inputs = true ;
2605
2619
CAmount nValueIn = 0 ;
@@ -2667,7 +2681,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
2667
2681
2668
2682
// Never create dust outputs; if we would, just
2669
2683
// add the dust to the fee.
2670
- if (IsDust (newTxOut, ::dustRelayFee ))
2684
+ if (IsDust (newTxOut, discard_rate ))
2671
2685
{
2672
2686
nChangePosInOut = -1 ;
2673
2687
nFeeRet += nChange;
@@ -2747,7 +2761,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
2747
2761
// (because of reduced tx size) and so we should add a
2748
2762
// change output. Only try this once.
2749
2763
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 );
2751
2765
CAmount max_excess_fee = fee_needed_for_change + minimum_value_for_change;
2752
2766
if (nFeeRet > nFeeNeeded + max_excess_fee && nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
2753
2767
pick_new_inputs = false ;
@@ -3788,6 +3802,9 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
3788
3802
strUsage += HelpMessageOpt (" -keypool=<n>" , strprintf (_ (" Set key pool size to <n> (default: %u)" ), DEFAULT_KEYPOOL_SIZE));
3789
3803
strUsage += HelpMessageOpt (" -fallbackfee=<amt>" , strprintf (_ (" A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)" ),
3790
3804
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)));
3791
3808
strUsage += HelpMessageOpt (" -mintxfee=<amt>" , strprintf (_ (" Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)" ),
3792
3809
CURRENCY_UNIT, FormatMoney (DEFAULT_TRANSACTION_MINFEE)));
3793
3810
strUsage += HelpMessageOpt (" -paytxfee=<amt>" , strprintf (_ (" Fee (in %s/kB) to add to transactions you send (default: %s)" ),
@@ -4113,6 +4130,16 @@ bool CWallet::ParameterInteraction()
4113
4130
_ (" This is the transaction fee you may pay when fee estimates are not available." ));
4114
4131
CWallet::fallbackFee = CFeeRate (nFeePerK);
4115
4132
}
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
+ }
4116
4143
if (IsArgSet (" -paytxfee" ))
4117
4144
{
4118
4145
CAmount nFeePerK = 0 ;
0 commit comments