Can’t we actually cope with merging packages this way too though? If you’ve got a tx that has parents A, B, C; and that conflicts with tx’s X (parent A) and Y (parent B), then beforehand you had:
0..., A, X, [children X]
1..., B, Y, [children Y]
(maybe some tx’s were descendants of both X and Y, but it’s worse if there weren’t any like that) and afterwards you have:
You don’t have C in the mempool because that would fail the “replacement-adds-unconfirmed” test later.
So you know tx’s ancestor checks pass, because they’re actually worked out; you know A,B’s ancestor checks pass because they don’t change, tx’s descendant check is trivial, and you know A,B and all their parent’s descendant checks passed, because they did so when X and Y were there – as far as sizes go, if they were all at their limit, then the max size for tx is the minimum of the descendant sizes of each tx that was replaced.
So I think you could replace the setConflicts.size() == 1
test with:
0if (!setConflicts.empty()) {
1 auto conflict = setIterConflicting.begin();
2 assert(conflict != setIterConflicting.end());
3 uint64_t bump = (*conflict)->GetSizeWithDescendants();
4 while(++conflict != setIterConflicting.end()) {
5 bump = std::min(bump, (*conflict)->GetSizeWithDescendants());
6 }
7 nLimitDescendants += 1;
8 nLimitDescendantSize += bump;
9}
Maybe I’m missing something though?