MCPcopy Create free account
hub / github.com/ElementsProject/elements / UpdateTransactionsFromBlock

Method UpdateTransactionsFromBlock

src/txmempool.cpp:181–234  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

179}
180
181void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate, uint64_t ancestor_size_limit, uint64_t ancestor_count_limit)
182{
183 AssertLockHeld(cs);
184 // For each entry in vHashesToUpdate, store the set of in-mempool, but not
185 // in-vHashesToUpdate transactions, so that we don't have to recalculate
186 // descendants when we come across a previously seen entry.
187 cacheMap mapMemPoolDescendantsToUpdate;
188
189 // Use a set for lookups into vHashesToUpdate (these entries are already
190 // accounted for in the state of their ancestors)
191 std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end());
192
193 std::set<uint256> descendants_to_remove;
194
195 // Iterate in reverse, so that whenever we are looking at a transaction
196 // we are sure that all in-mempool descendants have already been processed.
197 // This maximizes the benefit of the descendant cache and guarantees that
198 // CTxMemPool::m_children will be updated, an assumption made in
199 // UpdateForDescendants.
200 for (const uint256 &hash : reverse_iterate(vHashesToUpdate)) {
201 // calculate children from mapNextTx
202 txiter it = mapTx.find(hash);
203 if (it == mapTx.end()) {
204 continue;
205 }
206 auto iter = mapNextTx.lower_bound(COutPoint(hash, 0));
207 // First calculate the children, and update CTxMemPool::m_children to
208 // include them, and update their CTxMemPoolEntry::m_parents to include this tx.
209 // we cache the in-mempool children to avoid duplicate updates
210 {
211 WITH_FRESH_EPOCH(m_epoch);
212 for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) {
213 const uint256 &childHash = iter->second->GetHash();
214 txiter childIter = mapTx.find(childHash);
215 assert(childIter != mapTx.end());
216 // We can skip updating entries we've encountered before or that
217 // are in the block (which are already accounted for).
218 if (!visited(childIter) && !setAlreadyIncluded.count(childHash)) {
219 UpdateChild(it, childIter, true);
220 UpdateParent(childIter, it, true);
221 }
222 }
223 } // release epoch guard for UpdateForDescendants
224 UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded, descendants_to_remove, ancestor_size_limit, ancestor_count_limit);
225 }
226
227 for (const auto& txid : descendants_to_remove) {
228 // This txid may have been removed already in a prior call to removeRecursive.
229 // Therefore we ensure it is not yet removed already.
230 if (const std::optional<txiter> txiter = GetIter(txid)) {
231 removeRecursive((*txiter)->GetTx(), MemPoolRemovalReason::SIZELIMIT);
232 }
233 }
234}
235
236bool CTxMemPool::CalculateAncestorsAndCheckLimits(size_t entry_size,
237 size_t entry_count,

Callers 1

Calls 9

reverse_iterateFunction · 0.85
findMethod · 0.80
lower_boundMethod · 0.80
countMethod · 0.80
GetTxMethod · 0.80
COutPointClass · 0.50
beginMethod · 0.45
endMethod · 0.45
GetHashMethod · 0.45

Tested by

no test coverage detected