This change is good because:
- It moves module-specific init-logic out of the bloated init.cpp
- It removes a global from validation.cpp and places it into the data structure that needs it (mempool)
This change is good because:
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
Reviewers, this pull request conflicts with the following ones:
MemPoolBypass
by w0xlt)interpreter.cpp
by david-bakin)If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
Approach ACK
MemPoolOptions
seems like the correct place to put these things since full_rbf
is already there.
I would put ::incrementalRelayFee
, ::minRelayFee
, dustRelayFee
, fIsBareMultisigStd
in the same boat (sorry for scope creep, probably for a future PR).
35@@ -33,6 +36,9 @@ struct MemPoolOptions {
36 int check_ratio{0};
37 int64_t max_size_bytes{DEFAULT_MAX_MEMPOOL_SIZE_MB * 1'000'000};
38 std::chrono::seconds expiry{std::chrono::hours{DEFAULT_MEMPOOL_EXPIRY_HOURS}};
39+ CFeeRate incremental_relay_fee{DEFAULT_INCREMENTAL_RELAY_FEE};
40+ /** A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) */
41+ CFeeRate min_relay_fee{DEFAULT_MIN_RELAY_TX_FEE};
sorry for scope creep, probably for a future PR
Thx, all done here
19@@ -16,7 +20,7 @@ struct MemPoolOptions;
20 * @param[in] argsman The ArgsManager in which to check set options.
21 * @param[in,out] mempool_opts The MemPoolOptions to modify according to \p argsman.
22 */
23-void ApplyArgsManOptions(const ArgsManager& argsman, kernel::MemPoolOptions& mempool_opts);
24+std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& argsman, const CChainParams& chainparams, kernel::MemPoolOptions& mempool_opts);
nit in fad91bf9a97d62a11a419fda7654107a54454f86
Add documentation to doxygen comment?
840@@ -840,7 +841,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
841 return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "bad-txns-too-many-sigops",
842 strprintf("%d", nSigOpsCost));
843
844- // No individual transactions are allowed below minRelayTxFee and mempool min fee except from
845+ // No individual transactions are allowed below the min relay fee and mempool min fee except from
nit in 2222644eb37da606e1eeabeda78007b687889de6
0 // No individual transactions are allowed below the min relay feerate and mempool min feerate except from
744@@ -745,7 +745,6 @@ BOOST_AUTO_TEST_CASE(test_witness)
745
746 BOOST_AUTO_TEST_CASE(test_IsStandard)
747 {
748- LOCK(cs_main);
123 CTxMemPool::Options mempool_opts{MemPoolOptionsForTest(node)};
124
125 // ...override specific options for this specific fuzz suite
126 mempool_opts.estimator = nullptr;
127 mempool_opts.check_ratio = 1;
128+ mempool_opts.require_standard = fuzzed_data_provider.ConsumeBool();
check_ratio
set to 1, since any other value just means you run check()
less often. AFAICT it’s the same idea with standardness checks; if you turn it off, you’re running fewer tests. Is it another branch if the codepaths you can hit with true
is a superset of the codepaths you can hit with false
? Am I misunderstanding?
I think it is good to also fuzz for non standard transactions, since we support it. Otherwise the validation codepath for non standard transactions that would be executed in “production” would not be fuzzed. On the other hand, “production” is only testnet here since we don’t allow -acceptnonstdtxn
for mainnet..
nit: Since this is using cycles for a test-only option, maybe we could lower the probability of setting require_standard
to false
? Something like require_standard = (ConsumeIntegralInRange(1, 10) % 10 != 0)
?
AFAICT it’s the same idea with standardness checks;
Not really. check
will not mutate the mempool. However, require_standard
may leave the mempool in a different state with the same ATMP calls, but a different value of require_standard
. For example tx-size may create more inputs in the mempool. Or a raw non-standard script may trigger more paths in script evaluation. I think the mempool also uses script caching, so I was hoping for this to also be a check that the mempool doesn’t print coins out of thin air.
check will not mutate the mempool. However, require_standard may leave the mempool in a different state with the same ATMP calls, but a different value of require_standar
Ahh yeah, makes sense that it’s different branches, thanks!
63+ }
64+ } else if (mempool_opts.incremental_relay_feerate > mempool_opts.min_relay_feerate) {
65+ // Allow only setting incremental fee to control both
66+ mempool_opts.min_relay_feerate = mempool_opts.incremental_relay_feerate;
67+ LogPrintf("Increasing minrelaytxfee to %s to match incrementalrelayfee\n", mempool_opts.min_relay_feerate.ToString());
68+ }
41@@ -41,11 +42,11 @@ static const unsigned int MAX_OP_RETURN_RELAY = 83;
42 /**
43 * A data carrying output is an unspendable output containing data. The script
44 * type is designated as TxoutType::NULL_DATA.
45+ *
46+ * Maximum size of TxoutType::NULL_DATA scripts that this node considers standard.
47+ * If nullopt, any size is nonstandard.
g_max_datacarrier_bytes
, then realized it was moved into policy in fa727f139c38e24fa23a6455b0b274177b41747c.
ACK fa727f139c38e24fa23a6455b0b274177b41747c
Lightly reviewed and tested each commit, nice move and cleanup. Would like at least another reviewer to take a look.
644@@ -645,8 +645,11 @@ static RPCHelpMan getnetworkinfo()
645 obj.pushKV("connections_out", node.connman->GetNodeCount(ConnectionDirection::Out));
646 }
647 obj.pushKV("networks", GetNetworksInfo());
648- obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()));
649- obj.pushKV("incrementalfee", ValueFromAmount(::incrementalRelayFee.GetFeePerK()));
650+ if (node.mempool) {
651+ // Those fields can be deprecated, to be replaced by the getmempoolinfo fields
-blocksonly
would make these fields optional but doesn’t appear to be the case (and checked that bitcoin-cli -rpcwait getnetworkinfo
on a -blocksonly startup returns the fields).
43- * type is designated as TxoutType::NULL_DATA.
44- *
45- * Maximum size of TxoutType::NULL_DATA scripts that this node considers standard.
46- * If nullopt, any size is nonstandard.
47- */
48-extern std::optional<unsigned> g_max_datacarrier_bytes;
nMaxDatacarrierBytes
is still mentionned just above in the comment for MAX_OP_RETURN_RELAY
.
Also pass in a (for now unused) reference to the params.
Both changes are needed for the next commit.
Apart from tests, it is only used in one place, so there is no need for
an alias.
Each alias is only used in one place.
It is part of the node library. Also, it won't be moved to the kernel
lib, as it will be pruned of ArgsManager.
-BEGIN VERIFY SCRIPT-
# Move module
git mv src/mempool_args.cpp src/node/
git mv src/mempool_args.h src/node/
# Replacements
sed -i 's:mempool_args\.h:node/mempool_args.h:g' $(git grep -l mempool_args)
sed -i 's:mempool_args\.cpp:node/mempool_args.cpp:g' $(git grep -l mempool_args)
sed -i 's:MEMPOOL_ARGS_H:NODE_MEMPOOL_ARGS_H:g' $(git grep -l MEMPOOL_ARGS_H)
-END VERIFY SCRIPT-
20 *
21 * @param[in] argsman The ArgsManager in which to check set options.
22 * @param[in,out] mempool_opts The MemPoolOptions to modify according to \p argsman.
23 */
24-void ApplyArgsManOptions(const ArgsManager& argsman, kernel::MemPoolOptions& mempool_opts);
25+[[nodiscard]] std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& argsman, const CChainParams& chainparams, kernel::MemPoolOptions& mempool_opts);
git grep 'std::optional<bilingual_str>'
.
17@@ -18,6 +18,11 @@
18 #include <boost/test/unit_test.hpp>
19
20 // Helpers:
21+bool IsStandardTx(const CTransaction& tx, std::string& reason)
In commit “Remove ::IsStandardTx(tx, reason) alias” (fa8a7f01fe1b6db98097021276ed5d929faadbec)
Would be good to declare this static to make sure nobody outside this file can call this
49+ * Maximum size of TxoutType::NULL_DATA scripts that this node considers standard.
50+ * If nullopt, any size is nonstandard.
51+ */
52+ std::optional<unsigned> max_datacarrier_bytes{DEFAULT_ACCEPT_DATACARRIER ? std::optional{MAX_OP_RETURN_RELAY} : std::nullopt};
53+ bool permit_bare_multisig{DEFAULT_PERMIT_BAREMULTISIG};
54+ bool require_standard{true};
-acceptnonstdtxn
. Happy to review a docs pull if there is need for one and someone creates one.
84+ mempool_opts.max_datacarrier_bytes = argsman.GetIntArg("-datacarriersize", MAX_OP_RETURN_RELAY);
85+ } else {
86+ mempool_opts.max_datacarrier_bytes = std::nullopt;
87+ }
88+
89+ mempool_opts.require_standard = !argsman.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
require_txstandard
we might have standard package in the future, good to dissociate
require_standard
is applied to both txs and packages, so I think the current name is fine, no?
-acceptnonstdtxn
anyway, can’t really think of a reason not to. Feel free to reopen if something changes, we can cross this bridge if/when we come to it.
86@@ -87,7 +87,7 @@ CFeeRate GetDiscardRate(const CWallet& wallet)
87 CFeeRate discard_rate = wallet.chain().estimateSmartFee(highest_target, false /* conservative */);
88 // Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate
89 discard_rate = (discard_rate == CFeeRate(0)) ? wallet.m_discard_rate : std::min(discard_rate, wallet.m_discard_rate);
90- // Discard rate must be at least dustRelayFee
91+ // Discard rate must be at least dust relay feerate
m_dust_relay_feerate
we do so for other variables doc refs make the code more greppable
wallet.m_dust_relay_feerate
doesn’t exist, only wallet.chain().relayDustFee()
. Happy to switch to relayDustFee
or similar, or just remove the comment completely, as the code is self-explanatory. Just let me know.
re ACK ddddd69
changes since last review: