Skip to content

Commit eb30d1a

Browse files
committed
Introduce -dustrelayfee
1 parent 7b1add3 commit eb30d1a

File tree

8 files changed

+37
-17
lines changed

8 files changed

+37
-17
lines changed

src/init.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ std::string HelpMessage(HelpMessageMode mode)
468468
if (showDebug) {
469469
strUsage += HelpMessageOpt("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !Params(CBaseChainParams::TESTNET).RequireStandard()));
470470
strUsage += HelpMessageOpt("-incrementalrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to define cost of relay, used for mempool limiting and BIP 125 replacement. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_INCREMENTAL_RELAY_FEE)));
471+
strUsage += HelpMessageOpt("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to defined dust, the value of an output such that it will cost about 1/3 of its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)));
471472
}
472473
strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Equivalent bytes per sigop in transactions for relay and mining (default: %u)"), DEFAULT_BYTES_PER_SIGOP));
473474
strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER));
@@ -995,6 +996,16 @@ bool AppInitParameterInteraction()
995996
return InitError(AmountErrMsg("blockmintxfee", GetArg("-blockmintxfee", "")));
996997
}
997998

999+
// Feerate used to define dust. Shouldn't be changed lightly as old
1000+
// implementations may inadvertently create non-standard transactions
1001+
if (IsArgSet("-dustrelayfee"))
1002+
{
1003+
CAmount n = 0;
1004+
if (!ParseMoney(GetArg("-dustrelayfee", ""), n) || 0 == n)
1005+
return InitError(AmountErrMsg("dustrelayfee", GetArg("-dustrelayfee", "")));
1006+
dustRelayFee = CFeeRate(n);
1007+
}
1008+
9981009
fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
9991010
if (chainparams.RequireStandard() && !fRequireStandard)
10001011
return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.NetworkIDString()));

src/policy/policy.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnes
105105
else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
106106
reason = "bare-multisig";
107107
return false;
108-
} else if (txout.IsDust(::minRelayTxFee)) {
108+
} else if (txout.IsDust(dustRelayFee)) {
109109
reason = "dust";
110110
return false;
111111
}
@@ -207,6 +207,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
207207
}
208208

209209
CFeeRate incrementalRelayFee = CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE);
210+
CFeeRate dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
210211
unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP;
211212

212213
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)

src/policy/policy.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS = 100;
4040
static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEM_SIZE = 80;
4141
/** The maximum size of a standard witnessScript */
4242
static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
43+
/** Min feerate for defining dust. Historically this has been the same as the
44+
* minRelayTxFee, however changing the dust limit changes which transactions are
45+
* standard and should be done with care and ideally rarely. It makes sense to
46+
* only increase the dust limit after prior releases were already not creating
47+
* outputs below the new threshold */
48+
static const unsigned int DUST_RELAY_TX_FEE = 1000;
4349
/**
4450
* Standard script verification flags that standard transactions will comply
4551
* with. However scripts violating these flags may still be present in valid
@@ -88,6 +94,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
8894
bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
8995

9096
extern CFeeRate incrementalRelayFee;
97+
extern CFeeRate dustRelayFee;
9198
extern unsigned int nBytesPerSigOp;
9299

93100
/** Compute the virtual transaction size (weight reinterpreted as bytes). */

src/qt/coincontroldialog.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515

1616
#include "wallet/coincontrol.h"
1717
#include "init.h"
18-
#include "validation.h" // For minRelayTxFee
18+
#include "policy/policy.h"
19+
#include "validation.h" // For mempool
1920
#include "wallet/wallet.h"
2021

2122
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
@@ -432,7 +433,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
432433
{
433434
CTxOut txout(amount, (CScript)std::vector<unsigned char>(24, 0));
434435
txDummy.vout.push_back(txout);
435-
if (txout.IsDust(::minRelayTxFee))
436+
if (txout.IsDust(dustRelayFee))
436437
fDust = true;
437438
}
438439
}
@@ -545,10 +546,10 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
545546
if (nChange > 0 && nChange < MIN_CHANGE)
546547
{
547548
CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0));
548-
if (txout.IsDust(::minRelayTxFee))
549+
if (txout.IsDust(dustRelayFee))
549550
{
550551
if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust
551-
nChange = txout.GetDustThreshold(::minRelayTxFee);
552+
nChange = txout.GetDustThreshold(dustRelayFee);
552553
else
553554
{
554555
nPayFee += nChange;

src/qt/guiutil.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#include "primitives/transaction.h"
1313
#include "init.h"
14-
#include "validation.h" // For minRelayTxFee
14+
#include "policy/policy.h"
1515
#include "protocol.h"
1616
#include "script/script.h"
1717
#include "script/standard.h"
@@ -257,7 +257,7 @@ bool isDust(const QString& address, const CAmount& amount)
257257
CTxDestination dest = CBitcoinAddress(address.toStdString()).Get();
258258
CScript script = GetScriptForDestination(dest);
259259
CTxOut txOut(amount, script);
260-
return txOut.IsDust(::minRelayTxFee);
260+
return txOut.IsDust(dustRelayFee);
261261
}
262262

263263
QString HtmlEscape(const QString& str, bool fMultiLine)

src/qt/paymentserver.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include "base58.h"
1212
#include "chainparams.h"
13-
#include "validation.h" // For minRelayTxFee
13+
#include "policy/policy.h"
1414
#include "ui_interface.h"
1515
#include "util.h"
1616
#include "wallet/wallet.h"
@@ -582,7 +582,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen
582582

583583
// Extract and check amounts
584584
CTxOut txOut(sendingTo.second, sendingTo.first);
585-
if (txOut.IsDust(::minRelayTxFee)) {
585+
if (txOut.IsDust(dustRelayFee)) {
586586
Q_EMIT message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).")
587587
.arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)),
588588
CClientUIInterface::MSG_ERROR);

src/test/transaction_tests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
692692
BOOST_CHECK(IsStandardTx(t, reason));
693693

694694
// Check dust with default relay fee:
695-
CAmount nDustThreshold = 182 * minRelayTxFee.GetFeePerK()/1000 * 3;
695+
CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK()/1000 * 3;
696696
BOOST_CHECK_EQUAL(nDustThreshold, 546);
697697
// dust:
698698
t.vout[0].nValue = nDustThreshold - 1;
@@ -703,14 +703,14 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
703703

704704
// Check dust with odd relay fee to verify rounding:
705705
// nDustThreshold = 182 * 1234 / 1000 * 3
706-
minRelayTxFee = CFeeRate(1234);
706+
dustRelayFee = CFeeRate(1234);
707707
// dust:
708708
t.vout[0].nValue = 672 - 1;
709709
BOOST_CHECK(!IsStandardTx(t, reason));
710710
// not dust:
711711
t.vout[0].nValue = 672;
712712
BOOST_CHECK(IsStandardTx(t, reason));
713-
minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
713+
dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
714714

715715
t.vout[0].scriptPubKey = CScript() << OP_1;
716716
BOOST_CHECK(!IsStandardTx(t, reason));

src/wallet/wallet.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,7 +2335,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
23352335
}
23362336
}
23372337

2338-
if (txout.IsDust(::minRelayTxFee))
2338+
if (txout.IsDust(dustRelayFee))
23392339
{
23402340
if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
23412341
{
@@ -2413,16 +2413,16 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
24132413
// We do not move dust-change to fees, because the sender would end up paying more than requested.
24142414
// This would be against the purpose of the all-inclusive feature.
24152415
// So instead we raise the change and deduct from the recipient.
2416-
if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
2416+
if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(dustRelayFee))
24172417
{
2418-
CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
2418+
CAmount nDust = newTxOut.GetDustThreshold(dustRelayFee) - newTxOut.nValue;
24192419
newTxOut.nValue += nDust; // raise change until no more dust
24202420
for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
24212421
{
24222422
if (vecSend[i].fSubtractFeeFromAmount)
24232423
{
24242424
txNew.vout[i].nValue -= nDust;
2425-
if (txNew.vout[i].IsDust(::minRelayTxFee))
2425+
if (txNew.vout[i].IsDust(dustRelayFee))
24262426
{
24272427
strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
24282428
return false;
@@ -2434,7 +2434,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
24342434

24352435
// Never create dust outputs; if we would, just
24362436
// add the dust to the fee.
2437-
if (newTxOut.IsDust(::minRelayTxFee))
2437+
if (newTxOut.IsDust(dustRelayFee))
24382438
{
24392439
nChangePosInOut = -1;
24402440
nFeeRet += nChange;

0 commit comments

Comments
 (0)