Changeset View
Changeset View
Standalone View
Standalone View
src/txmempool.cpp
Show First 20 Lines • Show All 179 Lines • ▼ Show 20 Lines | for (const TxId &txid : reverse_iterate(txidsToUpdate)) { | ||||
} | } | ||||
} | } | ||||
} // release epoch guard for UpdateForDescendants | } // release epoch guard for UpdateForDescendants | ||||
UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, | UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, | ||||
setAlreadyIncluded); | setAlreadyIncluded); | ||||
} | } | ||||
} | } | ||||
bool CTxMemPool::CalculateMemPoolAncestors( | bool CTxMemPool::CalculateAncestorsAndCheckLimits( | ||||
const CTxMemPoolEntry &entry, setEntries &setAncestors, | const CTxMemPoolEntry &entry, setEntries &setAncestors, | ||||
uint64_t limitAncestorCount, uint64_t limitAncestorSize, | CTxMemPoolEntry::Parents &staged_ancestors, uint64_t limitAncestorCount, | ||||
uint64_t limitDescendantCount, uint64_t limitDescendantSize, | uint64_t limitAncestorSize, uint64_t limitDescendantCount, | ||||
std::string &errString, bool fSearchForParents /* = true */) const { | uint64_t limitDescendantSize, std::string &errString) const { | ||||
CTxMemPoolEntry::Parents staged_ancestors; | |||||
const CTransaction &tx = entry.GetTx(); | |||||
if (fSearchForParents) { | |||||
// Get parents of this transaction that are in the mempool | |||||
// GetMemPoolParents() is only valid for entries in the mempool, so we | |||||
// iterate mapTx to find parents. | |||||
for (const CTxIn &in : tx.vin) { | |||||
std::optional<txiter> piter = GetIter(in.prevout.GetTxId()); | |||||
if (!piter) { | |||||
continue; | |||||
} | |||||
staged_ancestors.insert(**piter); | |||||
if (staged_ancestors.size() + 1 > limitAncestorCount) { | |||||
errString = | |||||
strprintf("too many unconfirmed parents [limit: %u]", | |||||
limitAncestorCount); | |||||
return false; | |||||
} | |||||
} | |||||
} else { | |||||
// If we're not searching for parents, we require this to be an entry in | |||||
// the mempool already. | |||||
txiter it = mapTx.iterator_to(entry); | |||||
staged_ancestors = it->GetMemPoolParentsConst(); | |||||
} | |||||
size_t totalSizeWithAncestors = entry.GetTxSize(); | size_t totalSizeWithAncestors = entry.GetTxSize(); | ||||
while (!staged_ancestors.empty()) { | while (!staged_ancestors.empty()) { | ||||
const CTxMemPoolEntry &stage = staged_ancestors.begin()->get(); | const CTxMemPoolEntry &stage = staged_ancestors.begin()->get(); | ||||
txiter stageit = mapTx.iterator_to(stage); | txiter stageit = mapTx.iterator_to(stage); | ||||
setAncestors.insert(stageit); | setAncestors.insert(stageit); | ||||
staged_ancestors.erase(stage); | staged_ancestors.erase(stage); | ||||
Show All 37 Lines | while (!staged_ancestors.empty()) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CTxMemPool::CalculateMemPoolAncestors( | |||||
const CTxMemPoolEntry &entry, setEntries &setAncestors, | |||||
uint64_t limitAncestorCount, uint64_t limitAncestorSize, | |||||
uint64_t limitDescendantCount, uint64_t limitDescendantSize, | |||||
std::string &errString, bool fSearchForParents /* = true */) const { | |||||
CTxMemPoolEntry::Parents staged_ancestors; | |||||
const CTransaction &tx = entry.GetTx(); | |||||
if (fSearchForParents) { | |||||
// Get parents of this transaction that are in the mempool | |||||
// GetMemPoolParents() is only valid for entries in the mempool, so we | |||||
// iterate mapTx to find parents. | |||||
for (const CTxIn &in : tx.vin) { | |||||
std::optional<txiter> piter = GetIter(in.prevout.GetTxId()); | |||||
if (!piter) { | |||||
continue; | |||||
} | |||||
staged_ancestors.insert(**piter); | |||||
if (staged_ancestors.size() + 1 > limitAncestorCount) { | |||||
errString = | |||||
strprintf("too many unconfirmed parents [limit: %u]", | |||||
limitAncestorCount); | |||||
return false; | |||||
} | |||||
} | |||||
} else { | |||||
// If we're not searching for parents, we require this to be an entry in | |||||
// the mempool already. | |||||
txiter it = mapTx.iterator_to(entry); | |||||
staged_ancestors = it->GetMemPoolParentsConst(); | |||||
} | |||||
return CalculateAncestorsAndCheckLimits( | |||||
entry, setAncestors, staged_ancestors, limitAncestorCount, | |||||
limitAncestorSize, limitDescendantCount, limitDescendantSize, | |||||
errString); | |||||
} | |||||
void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, | void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, | ||||
setEntries &setAncestors) { | setEntries &setAncestors) { | ||||
CTxMemPoolEntry::Parents parents = it->GetMemPoolParents(); | CTxMemPoolEntry::Parents parents = it->GetMemPoolParents(); | ||||
// add or remove this tx as a child of each parent | // add or remove this tx as a child of each parent | ||||
for (const CTxMemPoolEntry &parent : parents) { | for (const CTxMemPoolEntry &parent : parents) { | ||||
UpdateChild(mapTx.iterator_to(parent), it, add); | UpdateChild(mapTx.iterator_to(parent), it, add); | ||||
} | } | ||||
const int64_t updateCount = (add ? 1 : -1); | const int64_t updateCount = (add ? 1 : -1); | ||||
▲ Show 20 Lines • Show All 1,197 Lines • Show Last 20 Lines |