Move+rename GetDustIndexes -> GetDust

Use to replace HasDust and where appropraite
This commit is contained in:
Greg Sanders 2024-11-12 12:14:32 -05:00
parent 62016b3230
commit c6859ce2de
8 changed files with 17 additions and 33 deletions

View file

@ -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 PreCheckEphemeralTx(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");
}

View file

@ -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.

View file

@ -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;
@ -129,7 +138,6 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
}
unsigned int nDataOut = 0;
unsigned int num_dust_outputs{0};
TxoutType whichType;
for (const CTxOut& txout : tx.vout) {
if (!::IsStandard(txout.scriptPubKey, max_datacarrier_bytes, whichType)) {
@ -142,13 +150,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;
}

View file

@ -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

View file

@ -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.");
}

View file

@ -167,7 +167,7 @@ std::optional<COutPoint> GetChildEvictingPrevout(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)};
if (!dust_indexes.empty()) {
const auto& children = entry.GetMemPoolChildrenConst();
if (!children.empty()) {
@ -311,7 +311,7 @@ FUZZ_TARGET(ephemeral_package_eval, .init = initialize_tx_pool)
// filter for ephemeral dust GetEntry
if (tx_pool.exists(GenTxid::Txid(txid))) {
const auto tx_info{tx_pool.info(GenTxid::Txid(txid))};
if (GetDustIndexes(tx_info.tx, tx_pool.m_opts.dust_relay_feerate).empty()) {
if (GetDust(*tx_info.tx, tx_pool.m_opts.dust_relay_feerate).empty()) {
tx_pool.PrioritiseTransaction(txid.ToUint256(), delta);
}
}

View file

@ -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);

View file

@ -54,11 +54,6 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns,
*/
void CheckMempoolEphemeralInvariants(const CTxMemPool& tx_pool);
/** Return indexes of the transaction's outputs that are considered dust
* at given dust_relay_rate.
*/
std::vector<uint32_t> GetDustIndexes(const CTransactionRef& tx_ref, CFeeRate dust_relay_rate);
/** For every transaction in tx_pool, check TRUC invariants:
* - a TRUC tx's ancestor count must be within TRUC_ANCESTOR_LIMIT
* - a TRUC tx's descendant count must be within TRUC_DESCENDANT_LIMIT