I understand your reasoning and the one from the linked comment, but I’m not sure it makes sense here. A lot of the comparisons we do are with other size_t
’s, e.g. from std::set::size()
. So, we’d either have to unsafely cast them into an int64_t (probably fine, but… not ideal?) or implement a function that does it with bounds checking etc.
I’m not sure that’s preferable? See e.g. the below diff, with some unsafe static_cast as well as implicit conversion (e.g. CheckPackageLimits()
passing package.size()
to CalculateAncestorsAndCheckLimits()
)
0diff --git a/src/kernel/mempool_limits.h b/src/kernel/mempool_limits.h
1index fd0979c6c..584af5679 100644
2--- a/src/kernel/mempool_limits.h
3+++ b/src/kernel/mempool_limits.h
4@@ -17,20 +17,20 @@ namespace kernel {
5 */
6 struct MemPoolLimits {
7 //! The maximum allowed number of transactions in a package including the entry and its ancestors.
8- uint64_t ancestor_count{DEFAULT_ANCESTOR_LIMIT};
9+ int64_t ancestor_count{DEFAULT_ANCESTOR_LIMIT};
10 //! The maximum allowed size in virtual bytes of an entry and its ancestors within a package.
11- uint64_t ancestor_size_vbytes{DEFAULT_ANCESTOR_SIZE_LIMIT_KVB * 1'000};
12+ int64_t ancestor_size_vbytes{DEFAULT_ANCESTOR_SIZE_LIMIT_KVB * 1'000};
13 //! The maximum allowed number of transactions in a package including the entry and its descendants.
14- uint64_t descendant_count{DEFAULT_DESCENDANT_LIMIT};
15+ int64_t descendant_count{DEFAULT_DESCENDANT_LIMIT};
16 //! The maximum allowed size in virtual bytes of an entry and its descendants within a package.
17- uint64_t descendant_size_vbytes{DEFAULT_DESCENDANT_SIZE_LIMIT_KVB * 1'000};
18+ int64_t descendant_size_vbytes{DEFAULT_DESCENDANT_SIZE_LIMIT_KVB * 1'000};
19
20 /**
21 * [@return](/bitcoin-bitcoin/contributor/return/) MemPoolLimits with all the limits set to the maximum
22 */
23 static MemPoolLimits NoLimits()
24 {
25- uint64_t no_limit{std::numeric_limits<uint64_t>::max()};
26+ int64_t no_limit{std::numeric_limits<int64_t>::max()};
27 return {no_limit, no_limit, no_limit, no_limit};
28 }
29
30diff --git a/src/txmempool.cpp b/src/txmempool.cpp
31index 3097473ac..ee5ffff7b 100644
32--- a/src/txmempool.cpp
33+++ b/src/txmempool.cpp
34@@ -183,14 +183,14 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256>& vHashes
35 }
36 }
37
38-bool CTxMemPool::CalculateAncestorsAndCheckLimits(size_t entry_size,
39- size_t entry_count,
40+bool CTxMemPool::CalculateAncestorsAndCheckLimits(int64_t entry_size,
41+ int64_t entry_count,
42 setEntries& setAncestors,
43 CTxMemPoolEntry::Parents& staged_ancestors,
44 const Limits& limits,
45 std::string &errString) const
46 {
47- size_t totalSizeWithAncestors = entry_size;
48+ int64_t totalSizeWithAncestors = entry_size;
49
50 while (!staged_ancestors.empty()) {
51 const CTxMemPoolEntry& stage = staged_ancestors.begin()->get();
52@@ -241,7 +241,7 @@ bool CTxMemPool::CheckPackageLimits(const Package& package,
53 std::optional<txiter> piter = GetIter(input.prevout.hash);
54 if (piter) {
55 staged_ancestors.insert(**piter);
56- if (staged_ancestors.size() + package.size() > limits.ancestor_count) {
57+ if (static_cast<int64_t>(staged_ancestors.size() + package.size()) > limits.ancestor_count) {
58 errString = strprintf("too many unconfirmed parents [limit: %u]", limits.ancestor_count);
59 return false;
60 }
61@@ -277,7 +277,7 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry,
62 std::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
63 if (piter) {
64 staged_ancestors.insert(**piter);
65- if (staged_ancestors.size() + 1 > limits.ancestor_count) {
66+ if (static_cast<int64_t>(staged_ancestors.size() + 1) > limits.ancestor_count) {
67 errString = strprintf("too many unconfirmed parents [limit: %u]", limits.ancestor_count);
68 return false;
69 }