New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[refactor] Check CTxMemPool options in ctor #28830
base: master
Are you sure you want to change the base?
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
9f635cf
to
29818f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
29818f5
to
3aa41a3
Compare
Rebased 29818f5 -> 1d18cc6 (mempoolArgs_0 -> mempoolArgs_1, compare) Updated 1d18cc6 -> 3aa41a3 (mempoolArgs_1 -> mempoolArgs_2, compare)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 3aa41a3 when fuzzer is fixed
src/test/fuzz/package_eval.cpp
Outdated
@@ -125,7 +125,7 @@ CTxMemPool MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeConte | |||
mempool_opts.require_standard = fuzzed_data_provider.ConsumeBool(); | |||
|
|||
// ...and construct a CTxMemPool from it | |||
return CTxMemPool{mempool_opts}; | |||
return std::move(Assert(CTxMemPool::Make(mempool_opts)).value()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wdyt about this approach to fix the fuzzer (this impl requires rebase to use c++20 for std::string::starts_with
)? This should be efficient without relying too much (but still somewhat) on the implementation of CTxMemPool::Make
?
After #25665 is merged, could have a Make
return an enum failure value and avoid the errorstring checking.
git diff on 3aa41a3
diff --git a/src/test/fuzz/package_eval.cpp b/src/test/fuzz/package_eval.cpp
index ec708a5c53..7f8aecb1ae 100644
--- a/src/test/fuzz/package_eval.cpp
+++ b/src/test/fuzz/package_eval.cpp
@@ -111,13 +111,15 @@ std::unique_ptr<CTxMemPool> MakeMempool(FuzzedDataProvider& fuzzed_data_provider
// Take the default options for tests...
CTxMemPool::Options mempool_opts{MemPoolOptionsForTest(node)};
-
// ...override specific options for this specific fuzz suite
mempool_opts.limits.ancestor_count = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 50);
mempool_opts.limits.ancestor_size_vbytes = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 202) * 1'000;
mempool_opts.limits.descendant_count = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 50);
- mempool_opts.limits.descendant_size_vbytes = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 202) * 1'000;
- mempool_opts.max_size_bytes = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 200) * 1'000'000;
+ auto set_descendants_size = [&]() {
+ mempool_opts.limits.descendant_size_vbytes = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 202) * 1'000;
+ mempool_opts.max_size_bytes = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 200) * 1'000'000;
+ };
+ set_descendants_size();
mempool_opts.expiry = std::chrono::hours{fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 999)};
nBytesPerSigOp = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(1, 999);
@@ -125,7 +127,15 @@ std::unique_ptr<CTxMemPool> MakeMempool(FuzzedDataProvider& fuzzed_data_provider
mempool_opts.require_standard = fuzzed_data_provider.ConsumeBool();
// ...and construct a CTxMemPool from it
- return std::move(Assert(CTxMemPool::Make(mempool_opts)).value());
+ while (true) {
+ if (auto res{CTxMemPool::Make(mempool_opts)}) {
+ return std::move(res.value());
+ } else {
+ // Ensure this harness is updated when additional mempool construction failure paths are introduced
+ assert(util::ErrorString(res).original.starts_with("-maxmempool must be at least"));
+ set_descendants_size();
+ }
+ }
}
FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
3aa41a3
to
364456f
Compare
Rebased 3aa41a3 -> 571fa4f (mempoolArgs_2 -> mempoolArgs_3, compare) Updated 571fa4f -> 364456f (mempoolArgs_3 -> mempoolArgs_4, compare)
I'm still not quite happy with the fuzz test, which is why I left it in a separate commit. Maybe a better approach would be to let the fuzzer do its job and just return early in the fuzz test if |
src/test/fuzz/tx_pool.cpp
Outdated
auto tx_pool_{MakeMempool(fuzzed_data_provider, node)}; | ||
while (true) { | ||
if (tx_pool_) { | ||
break; | ||
} else { | ||
// Ensure this harness is updated when additional mempool construction failure paths are introduced | ||
assert(util::ErrorString(tx_pool_).original.starts_with("-maxmempool must be at least")); | ||
SetMempoolConstraints(*node.args, fuzzed_data_provider); | ||
tx_pool_ = MakeMempool(fuzzed_data_provider, node); | ||
} | ||
} | ||
|
||
MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(tx_pool_.value().get()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're resetting all constraints on every loop, is this not overly verbose? (+below)
git diff on 364456f
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index 1400fadea0..7ddc45c4b4 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -200,17 +200,10 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
// The sum of the values of all spendable outpoints
constexpr CAmount SUPPLY_TOTAL{COINBASE_MATURITY * 50 * COIN};
- SetMempoolConstraints(*node.args, fuzzed_data_provider);
- auto tx_pool_{MakeMempool(fuzzed_data_provider, node)};
- while (true) {
- if (tx_pool_) {
- break;
- } else {
- // Ensure this harness is updated when additional mempool construction failure paths are introduced
- assert(util::ErrorString(tx_pool_).original.starts_with("-maxmempool must be at least"));
- SetMempoolConstraints(*node.args, fuzzed_data_provider);
- tx_pool_ = MakeMempool(fuzzed_data_provider, node);
- }
+ util::Result<std::unique_ptr<CTxMemPool>> tx_pool_;
+ while (!tx_pool_) {
+ SetMempoolConstraints(*node.args, fuzzed_data_provider);
+ tx_pool_ = MakeMempool(fuzzed_data_provider, node);
}
MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(tx_pool_.value().get());
364456f
to
de5353b
Compare
Rebased d447bdc -> dacdb79 (mempoolArgs_6 -> mempoolArgs_7, compare) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK dacdb79
nit: some IWYU fixes, mostly because of the newly introduced bilingual_str
and Assert
usage:
git diff on dacdb79
diff --git a/src/test/fuzz/mini_miner.cpp b/src/test/fuzz/mini_miner.cpp
index a52c566076..3cc28a2b14 100644
--- a/src/test/fuzz/mini_miner.cpp
+++ b/src/test/fuzz/mini_miner.cpp
@@ -12,6 +12,8 @@
#include <primitives/transaction.h>
#include <random.h>
#include <txmempool.h>
+#include <util/check.h>
+#include <util/translation.h>
#include <deque>
#include <vector>
diff --git a/src/test/fuzz/package_eval.cpp b/src/test/fuzz/package_eval.cpp
index eefa566d31..9b5019696e 100644
--- a/src/test/fuzz/package_eval.cpp
+++ b/src/test/fuzz/package_eval.cpp
@@ -16,6 +16,7 @@
#include <test/util/setup_common.h>
#include <test/util/txmempool.h>
#include <util/rbf.h>
+#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
diff --git a/src/test/fuzz/partially_downloaded_block.cpp b/src/test/fuzz/partially_downloaded_block.cpp
index 8a13a12069..1faf65e6ad 100644
--- a/src/test/fuzz/partially_downloaded_block.cpp
+++ b/src/test/fuzz/partially_downloaded_block.cpp
@@ -10,6 +10,9 @@
#include <test/util/setup_common.h>
#include <test/util/txmempool.h>
#include <txmempool.h>
+#include <util/check.h>
+#include <util/translation.h>
+
#include <cstddef>
#include <cstdint>
diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp
index 9cf053a290..4c7e70e3b0 100644
--- a/src/test/fuzz/rbf.cpp
+++ b/src/test/fuzz/rbf.cpp
@@ -13,6 +13,8 @@
#include <test/util/setup_common.h>
#include <test/util/txmempool.h>
#include <txmempool.h>
+#include <util/check.h>
+#include <util/translation.h>
#include <cstdint>
#include <optional>
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index 77fd038a79..d62e9f02f2 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -15,7 +15,9 @@
#include <test/util/script.h>
#include <test/util/setup_common.h>
#include <test/util/txmempool.h>
+#include <util/check.h>
#include <util/rbf.h>
+#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
diff --git a/src/test/fuzz/validation_load_mempool.cpp b/src/test/fuzz/validation_load_mempool.cpp
index 4b0aad8c47..51140ae039 100644
--- a/src/test/fuzz/validation_load_mempool.cpp
+++ b/src/test/fuzz/validation_load_mempool.cpp
@@ -13,7 +13,9 @@
#include <test/util/setup_common.h>
#include <test/util/txmempool.h>
#include <txmempool.h>
+#include <util/check.h>
#include <util/time.h>
+#include <util/translation.h>
#include <validation.h>
#include <cstdint>
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index fd153f8207..042a8a9ba5 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -14,8 +14,10 @@
#include <test/util/txmempool.h>
#include <txmempool.h>
#include <uint256.h>
+#include <util/check.h>
#include <util/strencodings.h>
#include <util/time.h>
+#include <util/translation.h>
#include <validation.h>
#include <versionbits.h>
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 816413dbb7..deea6ff27d 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -16,6 +16,7 @@
#include <policy/settings.h>
#include <random.h>
#include <reverse_iterator.h>
+#include <tinyformat.h>
#include <util/check.h>
#include <util/feefrac.h>
#include <util/moneystr.h>
@@ -26,6 +27,7 @@
#include <util/translation.h>
#include <validationinterface.h>
+#include <algorithm>
#include <cmath>
#include <numeric>
#include <optional>
A bunch of these were broken before this PR, so I wasn't sure if they make sense to repair here. For test files I stopped asking for repairing them when reviewing other PRs, it just feels too Sisyphean if they are not consistently checked by other reviewers anyway. I wish we'd start enforcing this properly though. |
Thank you for the review @stickies-v, Updated dacdb79 -> 27af391 (mempoolArgs_7 -> mempoolArgs_8, compare)
|
re-ACK 27af391 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK 27af391
Thanks for the reviews, going to take @ryanofsky's suggestion, hope it is not much work to review again Updated 27af391 -> 33f2a70 (mempoolArgs_8 -> mempoolArgs_9, compare)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK 33f2a70. I actually didn't notice this push when I made my last two comments, so feel free to ignore the comments if you want to keep the current code.
Sorry for the many pushes, but I think it's important to get this consistent. Updated 33f2a70 -> 856c856 (mempoolArgs_9 -> mempoolArgs_10, compare)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK 856c856, just tweaked since last review to be more consistent with validation.cpp Flatten code
Sorry for the many pushes, but I think it's important to get this consistent.
Thanks for the update! I agree it's much nicer to be consistent. And sorry for the detour I caused by not fully understanding the original approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 856c856
src/txmempool.cpp
Outdated
@@ -395,8 +397,19 @@ void CTxMemPoolEntry::UpdateAncestorState(int32_t modifySize, CAmount modifyFee, | |||
assert(int(nSigOpCostWithAncestors) >= 0); | |||
} | |||
|
|||
CTxMemPool::CTxMemPool(const Options& opts) | |||
: m_opts{opts} | |||
//! Clamp option values and return error if options are not valid. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: slightly confusing docstring: the Options
ref is always returned, error is non-empty if options are not valid. Since Flatten
is internal, this is probably something that mostly should be documented in the CTxMemPool
ctor anyway though (highlighting that callers should check that error.empty()
)
ACK 856c856 |
856c856 -> 09ef322 (mempoolArgs_10 -> mempoolArgs_11, compare)
|
This ensures that the tests run the same checks on the mempool options that the init code also applies.
re-ACK 09ef322 . Fixed unreachable assert and updated docstring, and also added an exception for "-maxmempool must be at least " in the |
The tests should run the same checks on the mempool options that the init code also applies. The downside to this patch is that the log line may now be printed more than once in the for loop.
This was originally noticed here #25290 (comment).