Skip to content

Commit

Permalink
Add -allowpackagebelowminrelayfeerate option
Browse files Browse the repository at this point in the history
  • Loading branch information
Sjors committed Nov 23, 2023
1 parent d72aab3 commit 03baacd
Show file tree
Hide file tree
Showing 7 changed files with 12 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/init.cpp
Expand Up @@ -603,6 +603,7 @@ void SetupServerArgs(ArgsManager& argsman)
OptionsCategory::NODE_RELAY);
argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-allowpackagebelowminrelayfeerate", strprintf("Allow indivual transactions below -minrelaytxfee for packages (default: %u)", DEFAULT_ALLOW_PACKAGE_BELOW_MIN_RELAY_FEE_RATE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted inbound peers with default permissions. This will relay transactions even if the transactions were already in the mempool. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-whitelistrelay", strprintf("Add 'relay' permission to whitelisted inbound peers with default permissions. This will accept relayed transactions even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);

Expand Down
3 changes: 3 additions & 0 deletions src/kernel/mempool_options.h
Expand Up @@ -25,6 +25,8 @@ static constexpr unsigned int DEFAULT_MEMPOOL_EXPIRY_HOURS{336};
static constexpr bool DEFAULT_MEMPOOL_FULL_RBF{false};
/** Default for -acceptnonstdtxn */
static constexpr bool DEFAULT_ACCEPT_NON_STD_TXN{false};
/** Default for -allowpackagebelowminrelayfeerate */
static constexpr bool DEFAULT_ALLOW_PACKAGE_BELOW_MIN_RELAY_FEE_RATE{false};

namespace kernel {
/**
Expand All @@ -44,6 +46,7 @@ struct MemPoolOptions {
CFeeRate incremental_relay_feerate{DEFAULT_INCREMENTAL_RELAY_FEE};
/** A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) */
CFeeRate min_relay_feerate{DEFAULT_MIN_RELAY_TX_FEE};
bool allow_package_below_min_relay_feerate{DEFAULT_ALLOW_PACKAGE_BELOW_MIN_RELAY_FEE_RATE};
CFeeRate dust_relay_feerate{DUST_RELAY_TX_FEE};
/**
* A data carrying output is an unspendable output containing data. The script
Expand Down
2 changes: 2 additions & 0 deletions src/node/mempool_args.cpp
Expand Up @@ -68,6 +68,8 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& argsman, const CChainP
LogPrintf("Increasing minrelaytxfee to %s to match incrementalrelayfee\n", mempool_opts.min_relay_feerate.ToString());
}

mempool_opts.allow_package_below_min_relay_feerate = argsman.GetBoolArg("-allowpackagebelowminrelayfeerate", DEFAULT_ALLOW_PACKAGE_BELOW_MIN_RELAY_FEE_RATE);

// Feerate used to define dust. Shouldn't be changed lightly as old
// implementations may inadvertently create non-standard transactions
if (argsman.IsArgSet("-dustrelayfee")) {
Expand Down
1 change: 1 addition & 0 deletions src/txmempool.cpp
Expand Up @@ -407,6 +407,7 @@ CTxMemPool::CTxMemPool(const Options& opts)
m_expiry{opts.expiry},
m_incremental_relay_feerate{opts.incremental_relay_feerate},
m_min_relay_feerate{opts.min_relay_feerate},
m_allow_package_below_min_relay_feerate{opts.allow_package_below_min_relay_feerate},
m_dust_relay_feerate{opts.dust_relay_feerate},
m_permit_bare_multisig{opts.permit_bare_multisig},
m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
Expand Down
1 change: 1 addition & 0 deletions src/txmempool.h
Expand Up @@ -441,6 +441,7 @@ class CTxMemPool
const std::chrono::seconds m_expiry;
const CFeeRate m_incremental_relay_feerate;
const CFeeRate m_min_relay_feerate;
const bool m_allow_package_below_min_relay_feerate;
const CFeeRate m_dust_relay_feerate;
const bool m_permit_bare_multisig;
const std::optional<unsigned> m_max_datacarrier_bytes;
Expand Down
6 changes: 3 additions & 3 deletions src/validation.cpp
Expand Up @@ -670,11 +670,11 @@ class MemPoolAccept
AssertLockHeld(m_pool.cs);
CAmount mempoolRejectFee = m_pool.GetMinFee().GetFee(package_size);
if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee));
return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "mempool min fee not met for package", strprintf("%d < %d", package_fee, mempoolRejectFee));
}

if (package_fee < m_pool.m_min_relay_feerate.GetFee(package_size)) {
return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "min relay fee not met",
return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "min relay fee not met for pacage",
strprintf("%d < %d", package_fee, m_pool.m_min_relay_feerate.GetFee(package_size)));
}
return true;
Expand Down Expand Up @@ -866,7 +866,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// while a tx could be package CPFP'd when entering the mempool, we do not have a DoS-resistant
// method of ensuring the tx remains bumped. For example, the fee-bumping child could disappear
// due to a replacement.
if (!bypass_limits && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) {
if (!bypass_limits && !m_pool.m_allow_package_below_min_relay_feerate && ws.m_modified_fees < m_pool.m_min_relay_feerate.GetFee(ws.m_vsize)) {
// Even though this is a fee-related failure, this result is TX_MEMPOOL_POLICY, not
// TX_RECONSIDERABLE, because it cannot be bypassed using package validation.
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met",
Expand Down
2 changes: 1 addition & 1 deletion test/functional/mempool_limit.py
Expand Up @@ -170,7 +170,7 @@ def test_mid_package_eviction(self):
confirmed_only=True)
package_hex.append(cpfp_parent["hex"])
parent_utxos.append(cpfp_parent["new_utxo"])
assert_equal(node.testmempoolaccept([cpfp_parent["hex"]])[0]["reject-reason"], "mempool min fee not met")
assert_equal(node.testmempoolaccept([cpfp_parent["hex"]])[0]["reject-reason"], "mempool min fee not met for package")

self.wallet.rescan_utxos()

Expand Down

0 comments on commit 03baacd

Please sign in to comment.