17
17
#include < util/check.h>
18
18
#include < util/moneystr.h>
19
19
#include < util/overflow.h>
20
+ #include < util/result.h>
20
21
#include < util/system.h>
21
22
#include < util/time.h>
23
+ #include < util/translation.h>
22
24
#include < validationinterface.h>
23
25
24
26
#include < cmath>
@@ -147,50 +149,46 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256>& vHashes
147
149
}
148
150
}
149
151
150
- bool CTxMemPool::CalculateAncestorsAndCheckLimits (size_t entry_size,
151
- size_t entry_count,
152
- setEntries& setAncestors,
153
- CTxMemPoolEntry::Parents& staged_ancestors,
154
- const Limits& limits,
155
- std::string &errString) const
152
+ util::Result<CTxMemPool::setEntries> CTxMemPool::CalculateAncestorsAndCheckLimits (
153
+ size_t entry_size,
154
+ size_t entry_count,
155
+ CTxMemPoolEntry::Parents& staged_ancestors,
156
+ const Limits& limits) const
156
157
{
157
158
size_t totalSizeWithAncestors = entry_size;
159
+ setEntries ancestors;
158
160
159
161
while (!staged_ancestors.empty ()) {
160
162
const CTxMemPoolEntry& stage = staged_ancestors.begin ()->get ();
161
163
txiter stageit = mapTx.iterator_to (stage);
162
164
163
- setAncestors .insert (stageit);
165
+ ancestors .insert (stageit);
164
166
staged_ancestors.erase (stage);
165
167
totalSizeWithAncestors += stageit->GetTxSize ();
166
168
167
169
if (stageit->GetSizeWithDescendants () + entry_size > static_cast <uint64_t >(limits.descendant_size_vbytes )) {
168
- errString = strprintf (" exceeds descendant size limit for tx %s [limit: %u]" , stageit->GetTx ().GetHash ().ToString (), limits.descendant_size_vbytes );
169
- return false ;
170
+ return util::Error{Untranslated (strprintf (" exceeds descendant size limit for tx %s [limit: %u]" , stageit->GetTx ().GetHash ().ToString (), limits.descendant_size_vbytes ))};
170
171
} else if (stageit->GetCountWithDescendants () + entry_count > static_cast <uint64_t >(limits.descendant_count )) {
171
- errString = strprintf (" too many descendants for tx %s [limit: %u]" , stageit->GetTx ().GetHash ().ToString (), limits.descendant_count );
172
- return false ;
172
+ return util::Error{Untranslated (strprintf (" too many descendants for tx %s [limit: %u]" , stageit->GetTx ().GetHash ().ToString (), limits.descendant_count ))};
173
173
} else if (totalSizeWithAncestors > static_cast <uint64_t >(limits.ancestor_size_vbytes )) {
174
- errString = strprintf (" exceeds ancestor size limit [limit: %u]" , limits.ancestor_size_vbytes );
175
- return false ;
174
+ return util::Error{Untranslated (strprintf (" exceeds ancestor size limit [limit: %u]" , limits.ancestor_size_vbytes ))};
176
175
}
177
176
178
177
const CTxMemPoolEntry::Parents& parents = stageit->GetMemPoolParentsConst ();
179
178
for (const CTxMemPoolEntry& parent : parents) {
180
179
txiter parent_it = mapTx.iterator_to (parent);
181
180
182
181
// If this is a new ancestor, add it.
183
- if (setAncestors .count (parent_it) == 0 ) {
182
+ if (ancestors .count (parent_it) == 0 ) {
184
183
staged_ancestors.insert (parent);
185
184
}
186
- if (staged_ancestors.size () + setAncestors.size () + entry_count > static_cast <uint64_t >(limits.ancestor_count )) {
187
- errString = strprintf (" too many unconfirmed ancestors [limit: %u]" , limits.ancestor_count );
188
- return false ;
185
+ if (staged_ancestors.size () + ancestors.size () + entry_count > static_cast <uint64_t >(limits.ancestor_count )) {
186
+ return util::Error{Untranslated (strprintf (" too many unconfirmed ancestors [limit: %u]" , limits.ancestor_count ))};
189
187
}
190
188
}
191
189
}
192
190
193
- return true ;
191
+ return ancestors ;
194
192
}
195
193
196
194
bool CTxMemPool::CheckPackageLimits (const Package& package,
@@ -215,13 +213,11 @@ bool CTxMemPool::CheckPackageLimits(const Package& package,
215
213
// When multiple transactions are passed in, the ancestors and descendants of all transactions
216
214
// considered together must be within limits even if they are not interdependent. This may be
217
215
// stricter than the limits for each individual transaction.
218
- setEntries setAncestors;
219
- const auto ret = CalculateAncestorsAndCheckLimits (total_size, package.size (),
220
- setAncestors, staged_ancestors,
221
- limits, errString);
216
+ const auto ancestors{CalculateAncestorsAndCheckLimits (total_size, package.size (),
217
+ staged_ancestors, limits)};
222
218
// It's possible to overestimate the ancestor/descendant totals.
223
- if (!ret) errString. insert ( 0 , " possibly " ) ;
224
- return ret ;
219
+ if (!ancestors. has_value ()) errString = " possibly " + util::ErrorString (ancestors). original ;
220
+ return ancestors. has_value () ;
225
221
}
226
222
227
223
bool CTxMemPool::CalculateMemPoolAncestors (const CTxMemPoolEntry &entry,
@@ -254,9 +250,14 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry,
254
250
staged_ancestors = it->GetMemPoolParentsConst ();
255
251
}
256
252
257
- return CalculateAncestorsAndCheckLimits (entry.GetTxSize (), /* entry_count=*/ 1 ,
258
- setAncestors, staged_ancestors,
259
- limits, errString);
253
+ const auto calculated_ancestors{CalculateAncestorsAndCheckLimits (entry.GetTxSize (), /* entry_count=*/ 1 ,
254
+ staged_ancestors, limits)};
255
+ if (!calculated_ancestors.has_value ()) {
256
+ errString = util::ErrorString (calculated_ancestors).original ;
257
+ return false ;
258
+ }
259
+ setAncestors = *calculated_ancestors;
260
+ return true ;
260
261
}
261
262
262
263
void CTxMemPool::UpdateAncestorsOf (bool add, txiter it, setEntries &setAncestors)
0 commit comments