Skip to content

Commit

Permalink
Implement GetDust to replace HasDust, use where appropriate
Browse files Browse the repository at this point in the history
  • Loading branch information
instagibbs committed Nov 12, 2024
1 parent 831a5a4 commit cf265d5
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 25 deletions.
7 changes: 1 addition & 6 deletions src/policy/ephemeral_policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@
#include <policy/ephemeral_policy.h>
#include <policy/policy.h>

bool HasDust(const CTransaction& tx, CFeeRate dust_relay_rate)
{
return std::ranges::any_of(tx.vout, [&](const auto& output) { return IsDust(output, dust_relay_rate); });
}

bool PreCheckValidEphemeralTx(const CTransaction& tx, CFeeRate dust_relay_rate, CAmount base_fee, CAmount mod_fee, TxValidationState& state)
{
// We never want to give incentives to mine this transaction alone
if ((base_fee != 0 || mod_fee != 0) && HasDust(tx, dust_relay_rate)) {
if ((base_fee != 0 || mod_fee != 0) && !GetDust(tx, dust_relay_rate).empty()) {
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "dust", "tx with dust output must be 0-fee");
}

Expand Down
3 changes: 0 additions & 3 deletions src/policy/ephemeral_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@
* are the only way to bring fees.
*/

/** Returns true if transaction contains dust */
bool HasDust(const CTransaction& tx, CFeeRate dust_relay_rate);

/* All the following checks are only called if standardness rules are being applied. */

/** Must be called for each transaction once transaction fees are known.
Expand Down
13 changes: 10 additions & 3 deletions src/policy/policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
}

std::vector<uint32_t> GetDust(const CTransaction& tx, CFeeRate dust_relay_rate)
{
std::vector<uint32_t> dust_outputs;
for (uint32_t i{0}; i < tx.vout.size(); ++i) {
if (IsDust(tx.vout[i], dust_relay_rate)) dust_outputs.push_back(i);
}
return dust_outputs;
}

bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_datacarrier_bytes, TxoutType& whichType)
{
std::vector<std::vector<unsigned char> > vSolutions;
Expand Down Expand Up @@ -142,13 +151,11 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
else if ((whichType == TxoutType::MULTISIG) && (!permit_bare_multisig)) {
reason = "bare-multisig";
return false;
} else if (IsDust(txout, dust_relay_fee)) {
num_dust_outputs++;
}
}

// Only MAX_DUST_OUTPUTS_PER_TX dust is permitted(on otherwise valid ephemeral dust)
if (num_dust_outputs > MAX_DUST_OUTPUTS_PER_TX) {
if (GetDust(tx, dust_relay_fee).size() > MAX_DUST_OUTPUTS_PER_TX) {
reason = "dust";
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFee);

bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_datacarrier_bytes, TxoutType& whichType);

/** Get the vout index numbers of all dust outputs */
std::vector<uint32_t> GetDust(const CTransaction& tx, CFeeRate dust_relay_rate);

// Changing the default transaction version requires a two step process: first
// adapting relay policy by bumping TX_MAX_STANDARD_VERSION, and then later
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ static RPCHelpMan prioritisetransaction()

// Non-0 fee dust transactions are not allowed for entry, and modification not allowed afterwards
const auto& tx = mempool.get(hash);
if (tx && HasDust(*tx, mempool.m_opts.dust_relay_feerate)) {
if (tx && !GetDust(*tx, mempool.m_opts.dust_relay_feerate).empty()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is not supported for transactions with dust outputs.");
}

Expand Down
13 changes: 1 addition & 12 deletions src/test/util/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,24 +141,13 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns,
return std::nullopt;
}

std::vector<uint32_t> GetDustIndexes(const CTransactionRef& tx_ref, CFeeRate dust_relay_rate)
{
std::vector<uint32_t> dust_indexes;
for (size_t i = 0; i < tx_ref->vout.size(); ++i) {
const auto& output = tx_ref->vout[i];
if (IsDust(output, dust_relay_rate)) dust_indexes.push_back(i);
}

return dust_indexes;
}

void CheckMempoolEphemeralInvariants(const CTxMemPool& tx_pool)
{
LOCK(tx_pool.cs);
for (const auto& tx_info : tx_pool.infoAll()) {
const auto& entry = *Assert(tx_pool.GetEntry(tx_info.tx->GetHash()));

std::vector<uint32_t> dust_indexes = GetDustIndexes(tx_info.tx, tx_pool.m_opts.dust_relay_feerate);
std::vector<uint32_t> dust_indexes = GetDust(*tx_info.tx, tx_pool.m_opts.dust_relay_feerate);

Assert(dust_indexes.size() < 2);

Expand Down

0 comments on commit cf265d5

Please sign in to comment.