1717#include < util/check.h>
1818#include < util/moneystr.h>
1919#include < util/overflow.h>
20+ #include < util/result.h>
2021#include < util/system.h>
2122#include < util/time.h>
23+ #include < util/translation.h>
2224#include < validationinterface.h>
2325
2426#include < cmath>
@@ -147,50 +149,46 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256>& vHashes
147149 }
148150}
149151
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
156157{
157158 size_t totalSizeWithAncestors = entry_size;
159+ setEntries ancestors;
158160
159161 while (!staged_ancestors.empty ()) {
160162 const CTxMemPoolEntry& stage = staged_ancestors.begin ()->get ();
161163 txiter stageit = mapTx.iterator_to (stage);
162164
163- setAncestors .insert (stageit);
165+ ancestors .insert (stageit);
164166 staged_ancestors.erase (stage);
165167 totalSizeWithAncestors += stageit->GetTxSize ();
166168
167169 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 ))};
170171 } 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 ))};
173173 } 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 ))};
176175 }
177176
178177 const CTxMemPoolEntry::Parents& parents = stageit->GetMemPoolParentsConst ();
179178 for (const CTxMemPoolEntry& parent : parents) {
180179 txiter parent_it = mapTx.iterator_to (parent);
181180
182181 // If this is a new ancestor, add it.
183- if (setAncestors .count (parent_it) == 0 ) {
182+ if (ancestors .count (parent_it) == 0 ) {
184183 staged_ancestors.insert (parent);
185184 }
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 ))};
189187 }
190188 }
191189 }
192190
193- return true ;
191+ return ancestors ;
194192}
195193
196194bool CTxMemPool::CheckPackageLimits (const Package& package,
@@ -215,13 +213,11 @@ bool CTxMemPool::CheckPackageLimits(const Package& package,
215213 // When multiple transactions are passed in, the ancestors and descendants of all transactions
216214 // considered together must be within limits even if they are not interdependent. This may be
217215 // 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)};
222218 // 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 () ;
225221}
226222
227223bool CTxMemPool::CalculateMemPoolAncestors (const CTxMemPoolEntry &entry,
@@ -254,9 +250,14 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry,
254250 staged_ancestors = it->GetMemPoolParentsConst ();
255251 }
256252
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 ;
260261}
261262
262263void CTxMemPool::UpdateAncestorsOf (bool add, txiter it, setEntries &setAncestors)
0 commit comments