Bitcoin ABC 0.30.12
P2P Digital Currency
txmempool.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <txmempool.h>
7
8#include <clientversion.h>
9#include <coins.h>
10#include <common/system.h>
11#include <config.h>
12#include <consensus/consensus.h>
13#include <consensus/tx_verify.h>
15#include <logging.h>
16#include <policy/fees.h>
17#include <policy/policy.h>
18#include <reverse_iterator.h>
19#include <undo.h>
20#include <util/moneystr.h>
21#include <util/time.h>
22#include <validationinterface.h>
23#include <version.h>
24
25#include <algorithm>
26#include <cmath>
27#include <limits>
28
30 setEntries &setAncestors,
31 CTxMemPoolEntry::Parents &staged_ancestors) const {
32 while (!staged_ancestors.empty()) {
33 const auto stage = staged_ancestors.begin()->get();
34
35 txiter stageit = mapTx.find(stage->GetTx().GetId());
36 assert(stageit != mapTx.end());
37 setAncestors.insert(stageit);
38 staged_ancestors.erase(staged_ancestors.begin());
39
40 const CTxMemPoolEntry::Parents &parents =
41 (*stageit)->GetMemPoolParentsConst();
42 for (const auto &parent : parents) {
43 txiter parent_it = mapTx.find(parent.get()->GetTx().GetId());
44 assert(parent_it != mapTx.end());
45
46 // If this is a new ancestor, add it.
47 if (setAncestors.count(parent_it) == 0) {
48 staged_ancestors.insert(parent);
49 }
50 }
51 }
52
53 return true;
54}
55
57 const CTxMemPoolEntryRef &entry, setEntries &setAncestors,
58 bool fSearchForParents /* = true */) const {
59 CTxMemPoolEntry::Parents staged_ancestors;
60 const CTransaction &tx = entry->GetTx();
61
62 if (fSearchForParents) {
63 // Get parents of this transaction that are in the mempool
64 // GetMemPoolParents() is only valid for entries in the mempool, so we
65 // iterate mapTx to find parents.
66 for (const CTxIn &in : tx.vin) {
67 std::optional<txiter> piter = GetIter(in.prevout.GetTxId());
68 if (!piter) {
69 continue;
70 }
71 staged_ancestors.insert(**piter);
72 }
73 } else {
74 // If we're not searching for parents, we require this to be an entry in
75 // the mempool already.
76 staged_ancestors = entry->GetMemPoolParentsConst();
77 }
78
79 return CalculateAncestors(setAncestors, staged_ancestors);
80}
81
83 // add or remove this tx as a child of each parent
84 for (const auto &parent : (*it)->GetMemPoolParentsConst()) {
85 auto parent_it = mapTx.find(parent.get()->GetTx().GetId());
86 assert(parent_it != mapTx.end());
87 UpdateChild(parent_it, it, add);
88 }
89}
90
92 const CTxMemPoolEntry::Children &children =
93 (*it)->GetMemPoolChildrenConst();
94 for (const auto &child : children) {
95 auto updateIt = mapTx.find(child.get()->GetTx().GetId());
96 assert(updateIt != mapTx.end());
97 UpdateParent(updateIt, it, false);
98 }
99}
100
102 for (txiter removeIt : entriesToRemove) {
103 // Note that UpdateParentsOf severs the child links that point to
104 // removeIt in the entries for the parents of removeIt.
105 UpdateParentsOf(false, removeIt);
106 }
107
108 // After updating all the parent links, we can now sever the link between
109 // each transaction being removed and any mempool children (ie, update
110 // CTxMemPoolEntry::m_parents for each direct child of a transaction being
111 // removed).
112 for (txiter removeIt : entriesToRemove) {
113 UpdateChildrenForRemoval(removeIt);
114 }
115}
116
118 : m_check_ratio(opts.check_ratio),
119 m_orphanage(std::make_unique<TxOrphanage>()),
120 m_conflicting(std::make_unique<TxConflicting>()),
121 m_max_size_bytes{opts.max_size_bytes}, m_expiry{opts.expiry},
122 m_min_relay_feerate{opts.min_relay_feerate},
123 m_dust_relay_feerate{opts.dust_relay_feerate},
124 m_permit_bare_multisig{opts.permit_bare_multisig},
125 m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
126 m_require_standard{opts.require_standard} {
127 // lock free clear
128 _clear();
129}
130
132
133bool CTxMemPool::isSpent(const COutPoint &outpoint) const {
134 LOCK(cs);
135 return mapNextTx.count(outpoint);
136}
137
140}
141
144}
145
147 // get a guaranteed unique id (in case tests re-use the same object)
148 entry->SetEntryId(nextEntryId++);
149
150 // Update transaction for any feeDelta created by PrioritiseTransaction
151 {
152 Amount feeDelta = Amount::zero();
153 ApplyDelta(entry->GetTx().GetId(), feeDelta);
154 entry->UpdateFeeDelta(feeDelta);
155 }
156
157 // Add to memory pool without checking anything.
158 // Used by AcceptToMemoryPool(), which DOES do all the appropriate checks.
159 auto [newit, inserted] = mapTx.insert(entry);
160 // Sanity check: It is a programming error if insertion fails (uniqueness
161 // invariants in mapTx are violated, etc)
162 assert(inserted);
163 // Sanity check: We should always end up inserting at the end of the
164 // entry_id index
165 assert(&*mapTx.get<entry_id>().rbegin() == &*newit);
166
167 // Update cachedInnerUsage to include contained transaction's usage.
168 // (When we update the entry for in-mempool parents, memory usage will be
169 // further updated.)
170 cachedInnerUsage += entry->DynamicMemoryUsage();
171
172 const CTransactionRef tx = entry->GetSharedTx();
173 std::set<TxId> setParentTransactions;
174 for (const CTxIn &in : tx->vin) {
175 mapNextTx.insert(std::make_pair(&in.prevout, tx));
176 setParentTransactions.insert(in.prevout.GetTxId());
177 }
178 // Don't bother worrying about child transactions of this one. It is
179 // guaranteed that a new transaction arriving will not have any children,
180 // because such children would be orphans.
181
182 // Update ancestors with information about this tx
183 for (const auto &pit : GetIterSet(setParentTransactions)) {
184 UpdateParent(newit, pit, true);
185 }
186
187 UpdateParentsOf(true, newit);
188
190 totalTxSize += entry->GetTxSize();
191 m_total_fee += entry->GetFee();
192}
193
195 // We increment mempool sequence value no matter removal reason
196 // even if not directly reported below.
197 uint64_t mempool_sequence = GetAndIncrementSequence();
198
199 const TxId &txid = (*it)->GetTx().GetId();
200
201 if (reason != MemPoolRemovalReason::BLOCK) {
202 // Notify clients that a transaction has been removed from the mempool
203 // for any reason except being included in a block. Clients interested
204 // in transactions included in blocks can subscribe to the
205 // BlockConnected notification.
207 (*it)->GetSharedTx(), reason, mempool_sequence);
208
209 if (auto removed_tx = finalizedTxs.remove(txid)) {
210 totalFinalizedTxSize -= removed_tx->GetTxSize();
211 totalFinalizedTxSigchecks -= removed_tx->GetSigChecks();
212 }
213 }
214
215 for (const CTxIn &txin : (*it)->GetTx().vin) {
216 mapNextTx.erase(txin.prevout);
217 }
218
219 /* add logging because unchecked */
220 RemoveUnbroadcastTx(txid, true);
221
222 totalTxSize -= (*it)->GetTxSize();
223 m_total_fee -= (*it)->GetFee();
224 cachedInnerUsage -= (*it)->DynamicMemoryUsage();
225 cachedInnerUsage -=
226 memusage::DynamicUsage((*it)->GetMemPoolParentsConst()) +
227 memusage::DynamicUsage((*it)->GetMemPoolChildrenConst());
228 mapTx.erase(it);
230}
231
232// Calculates descendants of entry that are not already in setDescendants, and
233// adds to setDescendants. Assumes entryit is already a tx in the mempool and
234// CTxMemPoolEntry::m_children is correct for tx and all descendants. Also
235// assumes that if an entry is in setDescendants already, then all in-mempool
236// descendants of it are already in setDescendants as well, so that we can save
237// time by not iterating over those entries.
239 setEntries &setDescendants) const {
240 setEntries stage;
241 if (setDescendants.count(entryit) == 0) {
242 stage.insert(entryit);
243 }
244 // Traverse down the children of entry, only adding children that are not
245 // accounted for in setDescendants already (because those children have
246 // either already been walked, or will be walked in this iteration).
247 while (!stage.empty()) {
248 txiter it = *stage.begin();
249 setDescendants.insert(it);
250 stage.erase(stage.begin());
251
252 const CTxMemPoolEntry::Children &children =
253 (*it)->GetMemPoolChildrenConst();
254 for (const auto &child : children) {
255 txiter childiter = mapTx.find(child.get()->GetTx().GetId());
256 assert(childiter != mapTx.end());
257
258 if (!setDescendants.count(childiter)) {
259 stage.insert(childiter);
260 }
261 }
262 }
263}
264
265void CTxMemPool::removeRecursive(const CTransaction &origTx,
266 MemPoolRemovalReason reason) {
267 // Remove transaction from memory pool.
269 setEntries txToRemove;
270 txiter origit = mapTx.find(origTx.GetId());
271 if (origit != mapTx.end()) {
272 txToRemove.insert(origit);
273 } else {
274 // When recursively removing but origTx isn't in the mempool be sure to
275 // remove any children that are in the pool. This can happen during
276 // chain re-orgs if origTx isn't re-accepted into the mempool for any
277 // reason.
278 auto it = mapNextTx.lower_bound(COutPoint(origTx.GetId(), 0));
279 while (it != mapNextTx.end() &&
280 it->first->GetTxId() == origTx.GetId()) {
281 txiter nextit = mapTx.find(it->second->GetId());
282 assert(nextit != mapTx.end());
283 txToRemove.insert(nextit);
284 ++it;
285 }
286 }
287
288 setEntries setAllRemoves;
289 for (txiter it : txToRemove) {
290 CalculateDescendants(it, setAllRemoves);
291 }
292
293 RemoveStaged(setAllRemoves, reason);
294}
295
296void CTxMemPool::removeConflicts(const CTransaction &tx) {
297 // Remove transactions which depend on inputs of tx, recursively
299 for (const CTxIn &txin : tx.vin) {
300 auto it = mapNextTx.find(txin.prevout);
301 if (it != mapNextTx.end()) {
302 const CTransaction &txConflict = *it->second;
303 if (txConflict != tx) {
304 ClearPrioritisation(txConflict.GetId());
306 }
307 }
308 }
309}
310
316
317 lastRollingFeeUpdate = GetTime();
318 blockSinceLastRollingFeeBump = true;
319}
320
322 const std::vector<CTransactionRef> &vtx) {
324
325 for (const auto &tx : vtx) {
326 // If the tx has a parent, it will be in the block as well or the block
327 // is invalid. If the tx has a child, it can remain in the tree for the
328 // next block. So we can simply remove the txs from the block with no
329 // further check.
330 if (auto removed_tx = finalizedTxs.remove(tx->GetId())) {
331 totalFinalizedTxSize -= removed_tx->GetTxSize();
332 totalFinalizedTxSigchecks -= removed_tx->GetSigChecks();
333 }
334 }
335}
336
338 mapTx.clear();
339 mapNextTx.clear();
340 totalTxSize = 0;
341 m_total_fee = Amount::zero();
342 cachedInnerUsage = 0;
343 lastRollingFeeUpdate = GetTime();
344 blockSinceLastRollingFeeBump = false;
345 rollingMinimumFeeRate = 0;
347}
348
350 LOCK(cs);
351 _clear();
352}
353
354void CTxMemPool::check(const CCoinsViewCache &active_coins_tip,
355 int64_t spendheight) const {
356 if (m_check_ratio == 0) {
357 return;
358 }
359
360 if (GetRand(m_check_ratio) >= 1) {
361 return;
362 }
363
365 LOCK(cs);
367 "Checking mempool with %u transactions and %u inputs\n",
368 (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
369
370 uint64_t checkTotal = 0;
371 Amount check_total_fee{Amount::zero()};
372 uint64_t innerUsage = 0;
373
374 CCoinsViewCache mempoolDuplicate(
375 const_cast<CCoinsViewCache *>(&active_coins_tip));
376
377 for (const CTxMemPoolEntryRef &entry : mapTx.get<entry_id>()) {
378 checkTotal += entry->GetTxSize();
379 check_total_fee += entry->GetFee();
380 innerUsage += entry->DynamicMemoryUsage();
381 const CTransaction &tx = entry->GetTx();
382 innerUsage += memusage::DynamicUsage(entry->GetMemPoolParentsConst()) +
383 memusage::DynamicUsage(entry->GetMemPoolChildrenConst());
384
385 CTxMemPoolEntry::Parents setParentCheck;
386 for (const CTxIn &txin : tx.vin) {
387 // Check that every mempool transaction's inputs refer to available
388 // coins, or other mempool tx's.
389 txiter parentIt = mapTx.find(txin.prevout.GetTxId());
390 if (parentIt != mapTx.end()) {
391 const CTransaction &parentTx = (*parentIt)->GetTx();
392 assert(parentTx.vout.size() > txin.prevout.GetN() &&
393 !parentTx.vout[txin.prevout.GetN()].IsNull());
394 setParentCheck.insert(*parentIt);
395 // also check that parents have a topological ordering before
396 // their children
397 assert((*parentIt)->GetEntryId() < entry->GetEntryId());
398 }
399 // We are iterating through the mempool entries sorted
400 // topologically.
401 // All parents must have been checked before their children and
402 // their coins added to the mempoolDuplicate coins cache.
403 assert(mempoolDuplicate.HaveCoin(txin.prevout));
404 // Check whether its inputs are marked in mapNextTx.
405 auto prevoutNextIt = mapNextTx.find(txin.prevout);
406 assert(prevoutNextIt != mapNextTx.end());
407 assert(prevoutNextIt->first == &txin.prevout);
408 assert(prevoutNextIt->second.get() == &tx);
409 }
410 auto comp = [](const auto &a, const auto &b) -> bool {
411 return a.get()->GetTx().GetId() == b.get()->GetTx().GetId();
412 };
413 assert(setParentCheck.size() == entry->GetMemPoolParentsConst().size());
414 assert(std::equal(setParentCheck.begin(), setParentCheck.end(),
415 entry->GetMemPoolParentsConst().begin(), comp));
416
417 // Verify ancestor state is correct.
418 setEntries setAncestors;
419 std::string dummy;
420
421 const bool ok = CalculateMemPoolAncestors(entry, setAncestors);
422 assert(ok);
423
424 // all ancestors should have entryId < this tx's entryId
425 for (const auto &ancestor : setAncestors) {
426 assert((*ancestor)->GetEntryId() < entry->GetEntryId());
427 }
428
429 // Check children against mapNextTx
430 CTxMemPoolEntry::Children setChildrenCheck;
431 auto iter = mapNextTx.lower_bound(COutPoint(entry->GetTx().GetId(), 0));
432 for (; iter != mapNextTx.end() &&
433 iter->first->GetTxId() == entry->GetTx().GetId();
434 ++iter) {
435 txiter childIt = mapTx.find(iter->second->GetId());
436 // mapNextTx points to in-mempool transactions
437 assert(childIt != mapTx.end());
438 setChildrenCheck.insert(*childIt);
439 }
440 assert(setChildrenCheck.size() ==
441 entry->GetMemPoolChildrenConst().size());
442 assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(),
443 entry->GetMemPoolChildrenConst().begin(), comp));
444
445 // Not used. CheckTxInputs() should always pass
446 TxValidationState dummy_state;
447 Amount txfee{Amount::zero()};
448 assert(!tx.IsCoinBase());
449 assert(Consensus::CheckTxInputs(tx, dummy_state, mempoolDuplicate,
450 spendheight, txfee));
451 for (const auto &input : tx.vin) {
452 mempoolDuplicate.SpendCoin(input.prevout);
453 }
454 AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
455 }
456
457 for (auto &[_, nextTx] : mapNextTx) {
458 txiter it = mapTx.find(nextTx->GetId());
459 assert(it != mapTx.end());
460 assert((*it)->GetSharedTx() == nextTx);
461 }
462
463 assert(totalTxSize == checkTotal);
464 assert(m_total_fee == check_total_fee);
465 assert(innerUsage == cachedInnerUsage);
466}
467
469 const TxId &txidb) const {
470 LOCK(cs);
471 auto it1 = mapTx.find(txida);
472 if (it1 == mapTx.end()) {
473 return false;
474 }
475 auto it2 = mapTx.find(txidb);
476 if (it2 == mapTx.end()) {
477 return true;
478 }
479 return (*it1)->GetEntryId() < (*it2)->GetEntryId();
480}
481
482void CTxMemPool::getAllTxIds(std::vector<TxId> &vtxid) const {
483 LOCK(cs);
484
485 vtxid.clear();
486 vtxid.reserve(mapTx.size());
487
488 for (const auto &entry : mapTx.get<entry_id>()) {
489 vtxid.push_back(entry->GetTx().GetId());
490 }
491}
492
493static TxMempoolInfo
494GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
495 return TxMempoolInfo{(*it)->GetSharedTx(), (*it)->GetTime(),
496 (*it)->GetFee(), (*it)->GetTxSize(),
497 (*it)->GetModifiedFee() - (*it)->GetFee()};
498}
499
500std::vector<TxMempoolInfo> CTxMemPool::infoAll() const {
501 LOCK(cs);
502
503 std::vector<TxMempoolInfo> ret;
504 ret.reserve(mapTx.size());
505
506 const auto &index = mapTx.get<entry_id>();
507 for (auto it = index.begin(); it != index.end(); ++it) {
508 ret.push_back(GetInfo(mapTx.project<0>(it)));
509 }
510
511 return ret;
512}
513
515 LOCK(cs);
516 indexed_transaction_set::const_iterator i = mapTx.find(txid);
517 if (i == mapTx.end()) {
518 return nullptr;
519 }
520
521 return (*i)->GetSharedTx();
522}
523
525 LOCK(cs);
526 indexed_transaction_set::const_iterator i = mapTx.find(txid);
527 if (i == mapTx.end()) {
528 return TxMempoolInfo();
529 }
530
531 return GetInfo(i);
532}
533
535 LOCK(cs);
536
537 // minerPolicy uses recent blocks to figure out a reasonable fee. This
538 // may disagree with the rollingMinimumFeerate under certain scenarios
539 // where the mempool increases rapidly, or blocks are being mined which
540 // do not contain propagated transactions.
541 return std::max(m_min_relay_feerate, GetMinFee());
542}
543
545 const Amount nFeeDelta) {
546 {
547 LOCK(cs);
548 Amount &delta = mapDeltas[txid];
549 delta += nFeeDelta;
550 txiter it = mapTx.find(txid);
551 if (it != mapTx.end()) {
552 mapTx.modify(it, [&delta](CTxMemPoolEntryRef &e) {
553 e->UpdateFeeDelta(delta);
554 });
556 }
557 }
558 LogPrintf("PrioritiseTransaction: %s fee += %s\n", txid.ToString(),
559 FormatMoney(nFeeDelta));
560}
561
562void CTxMemPool::ApplyDelta(const TxId &txid, Amount &nFeeDelta) const {
564 std::map<TxId, Amount>::const_iterator pos = mapDeltas.find(txid);
565 if (pos == mapDeltas.end()) {
566 return;
567 }
568
569 nFeeDelta += pos->second;
570}
571
574 mapDeltas.erase(txid);
575}
576
577CTransactionRef CTxMemPool::GetConflictTx(const COutPoint &prevout) const {
578 const auto it = mapNextTx.find(prevout);
579 return it == mapNextTx.end() ? nullptr : it->second;
580}
581
582std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const TxId &txid) const {
583 auto it = mapTx.find(txid);
584 if (it != mapTx.end()) {
585 return it;
586 }
587 return std::nullopt;
588}
589
591CTxMemPool::GetIterSet(const std::set<TxId> &txids) const {
593 for (const auto &txid : txids) {
594 const auto mi = GetIter(txid);
595 if (mi) {
596 ret.insert(*mi);
597 }
598 }
599 return ret;
600}
601
602bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const {
603 for (const CTxIn &in : tx.vin) {
604 if (exists(in.prevout.GetTxId())) {
605 return false;
606 }
607 }
608
609 return true;
610}
611
613 const CTxMemPool &mempoolIn)
614 : CCoinsViewBacked(baseIn), mempool(mempoolIn) {}
615
616bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
617 // Check to see if the inputs are made available by another tx in the
618 // package. These Coins would not be available in the underlying CoinsView.
619 if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) {
620 coin = it->second;
621 return true;
622 }
623
624 // If an entry in the mempool exists, always return that one, as it's
625 // guaranteed to never conflict with the underlying cache, and it cannot
626 // have pruned entries (as it contains full) transactions. First checking
627 // the underlying cache risks returning a pruned entry instead.
628 CTransactionRef ptx = mempool.get(outpoint.GetTxId());
629 if (ptx) {
630 if (outpoint.GetN() < ptx->vout.size()) {
631 coin = Coin(ptx->vout[outpoint.GetN()], MEMPOOL_HEIGHT, false);
632 m_non_base_coins.emplace(outpoint);
633 return true;
634 }
635 return false;
636 }
637 return base->GetCoin(outpoint, coin);
638}
639
641 for (uint32_t n = 0; n < tx->vout.size(); ++n) {
642 m_temp_added.emplace(COutPoint(tx->GetId(), n),
643 Coin(tx->vout[n], MEMPOOL_HEIGHT, false));
644 m_non_base_coins.emplace(COutPoint(tx->GetId(), n));
645 }
646}
648 m_temp_added.clear();
649 m_non_base_coins.clear();
650}
651
653 LOCK(cs);
654 // Estimate the overhead of mapTx to be 12 pointers + an allocation, as no
655 // exact formula for boost::multi_index_contained is implemented.
657 12 * sizeof(void *)) *
658 mapTx.size() +
659 memusage::DynamicUsage(mapNextTx) +
660 memusage::DynamicUsage(mapDeltas) + cachedInnerUsage;
661}
662
663void CTxMemPool::RemoveUnbroadcastTx(const TxId &txid, const bool unchecked) {
664 LOCK(cs);
665
666 if (m_unbroadcast_txids.erase(txid)) {
667 LogPrint(
668 BCLog::MEMPOOL, "Removed %i from set of unbroadcast txns%s\n",
669 txid.GetHex(),
670 (unchecked ? " before confirmation that txn was sent out" : ""));
671 }
672}
673
675 MemPoolRemovalReason reason) {
678
679 // Remove txs in reverse-topological order
680 const setRevTopoEntries stageRevTopo(stage.begin(), stage.end());
681 for (txiter it : stageRevTopo) {
682 removeUnchecked(it, reason);
683 }
684}
685
686int CTxMemPool::Expire(std::chrono::seconds time) {
688 indexed_transaction_set::index<entry_time>::type::iterator it =
689 mapTx.get<entry_time>().begin();
690 setEntries toremove;
691 while (it != mapTx.get<entry_time>().end() && (*it)->GetTime() < time) {
692 toremove.insert(mapTx.project<0>(it));
693 it++;
694 }
695
696 setEntries stage;
697 for (txiter removeit : toremove) {
698 CalculateDescendants(removeit, stage);
699 }
700
702 return stage.size();
703}
704
708 int expired = Expire(GetTime<std::chrono::seconds>() - m_expiry);
709 if (expired != 0) {
711 "Expired %i transactions from the memory pool\n", expired);
712 }
713
714 std::vector<COutPoint> vNoSpendsRemaining;
715 TrimToSize(m_max_size_bytes, &vNoSpendsRemaining);
716 for (const COutPoint &removed : vNoSpendsRemaining) {
717 coins_cache.Uncache(removed);
718 }
719}
720
721void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add) {
724 if (add && (*entry)->GetMemPoolChildren().insert(*child).second) {
725 cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
726 } else if (!add && (*entry)->GetMemPoolChildren().erase(*child)) {
727 cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
728 }
729}
730
731void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add) {
734 if (add && (*entry)->GetMemPoolParents().insert(*parent).second) {
735 cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
736 } else if (!add && (*entry)->GetMemPoolParents().erase(*parent)) {
737 cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
738 }
739}
740
741CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
742 LOCK(cs);
743 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0) {
744 return CFeeRate(int64_t(ceill(rollingMinimumFeeRate)) * SATOSHI);
745 }
746
747 int64_t time = GetTime();
748 if (time > lastRollingFeeUpdate + 10) {
749 double halflife = ROLLING_FEE_HALFLIFE;
750 if (DynamicMemoryUsage() < sizelimit / 4) {
751 halflife /= 4;
752 } else if (DynamicMemoryUsage() < sizelimit / 2) {
753 halflife /= 2;
754 }
755
756 rollingMinimumFeeRate =
757 rollingMinimumFeeRate /
758 pow(2.0, (time - lastRollingFeeUpdate) / halflife);
759 lastRollingFeeUpdate = time;
760 }
761 return CFeeRate(int64_t(ceill(rollingMinimumFeeRate)) * SATOSHI);
762}
763
766 if ((rate.GetFeePerK() / SATOSHI) > rollingMinimumFeeRate) {
767 rollingMinimumFeeRate = rate.GetFeePerK() / SATOSHI;
768 blockSinceLastRollingFeeBump = false;
769 }
770}
771
772void CTxMemPool::TrimToSize(size_t sizelimit,
773 std::vector<COutPoint> *pvNoSpendsRemaining) {
775
776 unsigned nTxnRemoved = 0;
777 CFeeRate maxFeeRateRemoved(Amount::zero());
778 while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) {
779 auto it = mapTx.get<modified_feerate>().end();
780 --it;
781
782 // We set the new mempool min fee to the feerate of the removed
783 // transaction, plus the "minimum reasonable fee rate" (ie some value
784 // under which we consider txn to have 0 fee). This way, we don't allow
785 // txn to enter mempool with feerate equal to txn which were removed
786 // with no block in between.
787 CFeeRate removed = (*it)->GetModifiedFeeRate();
789
790 trackPackageRemoved(removed);
791 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
792
793 setEntries stage;
794 CalculateDescendants(mapTx.project<0>(it), stage);
795 nTxnRemoved += stage.size();
796
797 if (pvNoSpendsRemaining) {
798 for (const txiter &iter : stage) {
799 for (const CTxIn &txin : (*iter)->GetTx().vin) {
800 if (!exists(txin.prevout.GetTxId())) {
801 pvNoSpendsRemaining->push_back(txin.prevout);
802 }
803 }
804 }
805 }
806
808 }
809
810 if (maxFeeRateRemoved > CFeeRate(Amount::zero())) {
812 "Removed %u txn, rolling minimum fee bumped to %s\n",
813 nTxnRemoved, maxFeeRateRemoved.ToString());
814 }
815}
816
818 LOCK(cs);
819 return m_load_tried;
820}
821
822void CTxMemPool::SetLoadTried(bool load_tried) {
823 LOCK(cs);
824 m_load_tried = load_tried;
825}
826
827const std::string
829 switch (r) {
831 return "expiry";
833 return "sizelimit";
835 return "reorg";
837 return "block";
839 return "conflict";
841 return "avalanche";
842 }
843 assert(false);
844}
static constexpr Amount SATOSHI
Definition: amount.h:143
CCoinsView backed by another CCoinsView.
Definition: coins.h:201
CCoinsView * base
Definition: coins.h:203
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:221
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:330
Abstract view on the open txout dataset.
Definition: coins.h:163
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:13
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
GetCoin, returning whether it exists and is not spent.
Definition: txmempool.cpp:616
void Reset()
Clear m_temp_added and m_non_base_coins.
Definition: txmempool.cpp:647
std::unordered_map< COutPoint, Coin, SaltedOutpointHasher > m_temp_added
Coins made available by transactions being validated.
Definition: txmempool.h:645
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
Definition: txmempool.cpp:612
std::unordered_set< COutPoint, SaltedOutpointHasher > m_non_base_coins
Set of all coins that have been fetched from mempool or created using PackageAddTransaction (not base...
Definition: txmempool.h:653
void PackageAddTransaction(const CTransactionRef &tx)
Add the coins created by this transaction.
Definition: txmempool.cpp:640
const CTxMemPool & mempool
Definition: txmempool.h:656
Fee rate in satoshis per kilobyte: Amount / kB.
Definition: feerate.h:21
std::string ToString() const
Definition: feerate.cpp:57
Amount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:54
void TransactionRemovedFromMempool(const CTransactionRef &, MemPoolRemovalReason, uint64_t mempool_sequence)
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: mempool_entry.h:65
std::set< std::reference_wrapper< const CTxMemPoolEntryRef >, CompareIteratorById > Children
Definition: mempool_entry.h:73
std::set< std::reference_wrapper< const CTxMemPoolEntryRef >, CompareIteratorById > Parents
Definition: mempool_entry.h:70
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:213
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:296
CFeeRate estimateFee() const
Definition: txmempool.cpp:534
bool HasNoInputsOf(const CTransaction &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Check that none of this transactions inputs are in the mempool, and thus the tx is not dependent on o...
Definition: txmempool.cpp:602
void ClearPrioritisation(const TxId &txid) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:572
std::set< txiter, CompareIteratorById > setEntries
Definition: txmempool.h:316
void RemoveUnbroadcastTx(const TxId &txid, const bool unchecked=false)
Removes a transaction from the unbroadcast set.
Definition: txmempool.cpp:663
bool GetLoadTried() const
Definition: txmempool.cpp:817
bool CalculateAncestors(setEntries &setAncestors, CTxMemPoolEntry::Parents &staged_ancestors) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Helper function to calculate all in-mempool ancestors of staged_ancestors param@[in] staged_ancestors...
Definition: txmempool.cpp:29
void updateFeeForBlock() EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
Definition: txmempool.cpp:314
CFeeRate GetMinFee() const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
Definition: txmempool.h:456
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:312
void trackPackageRemoved(const CFeeRate &rate) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:764
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:265
void UpdateForRemoveFromMempool(const setEntries &entriesToRemove) EXCLUSIVE_LOCKS_REQUIRED(cs)
For each transaction being removed, update ancestors and any direct children.
Definition: txmempool.cpp:101
const int m_check_ratio
Value n means that 1 times in n we check.
Definition: txmempool.h:216
void TrimToSize(size_t sizelimit, std::vector< COutPoint > *pvNoSpendsRemaining=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove transactions from the mempool until its dynamic size is <= sizelimit.
Definition: txmempool.cpp:772
const std::chrono::seconds m_expiry
Definition: txmempool.h:350
void AddTransactionsUpdated(unsigned int n)
Definition: txmempool.cpp:142
void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs)
Sever link between specified transaction and direct children.
Definition: txmempool.cpp:91
bool CompareTopologically(const TxId &txida, const TxId &txidb) const
Definition: txmempool.cpp:468
TxMempoolInfo info(const TxId &txid) const
Definition: txmempool.cpp:524
const int64_t m_max_size_bytes
Definition: txmempool.h:349
void getAllTxIds(std::vector< TxId > &vtxid) const
Definition: txmempool.cpp:482
std::atomic< uint32_t > nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
Definition: txmempool.h:218
setEntries GetIterSet(const std::set< TxId > &txids) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Translate a set of txids into a set of pool iterators to avoid repeated lookups.
Definition: txmempool.cpp:591
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:652
std::vector< TxMempoolInfo > infoAll() const
Definition: txmempool.cpp:500
void LimitSize(CCoinsViewCache &coins_cache) EXCLUSIVE_LOCKS_REQUIRED(cs
Reduce the size of the mempool by expiring and then trimming the mempool.
Definition: txmempool.cpp:705
void UpdateParent(txiter entry, txiter parent, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:731
CTransactionRef GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
Definition: txmempool.cpp:577
void removeUnchecked(txiter entry, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Before calling removeUnchecked for a given transaction, UpdateForRemoveFromMempool must be called on ...
Definition: txmempool.cpp:194
int Expire(std::chrono::seconds time) EXCLUSIVE_LOCKS_REQUIRED(cs)
Expire all transaction (and their dependencies) in the mempool older than time.
Definition: txmempool.cpp:686
void clear()
Definition: txmempool.cpp:349
std::set< txiter, CompareIteratorByRevEntryId > setRevTopoEntries
Definition: txmempool.h:317
bool exists(const TxId &txid) const
Definition: txmempool.h:518
static const int ROLLING_FEE_HALFLIFE
Definition: txmempool.h:260
CTransactionRef get(const TxId &txid) const
Definition: txmempool.cpp:514
const CFeeRate m_min_relay_feerate
Definition: txmempool.h:351
void PrioritiseTransaction(const TxId &txid, const Amount nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
Definition: txmempool.cpp:544
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
Definition: txmempool.h:315
uint64_t GetAndIncrementSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Guards this internal counter for external reporting.
Definition: txmempool.h:573
void UpdateChild(txiter entry, txiter child, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:721
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(CTxMemPoolEntryRef entry) EXCLUSIVE_LOCKS_REQUIRED(cs
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
Definition: txmempool.h:377
RadixTree< CTxMemPoolEntry, MemPoolEntryRadixTreeAdapter > finalizedTxs
Definition: txmempool.h:319
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void cs_main
Definition: txmempool.h:378
CTxMemPool(const Options &opts)
Create a new CTxMemPool.
Definition: txmempool.cpp:117
bool CalculateMemPoolAncestors(const CTxMemPoolEntryRef &entry, setEntries &setAncestors, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Try to calculate all in-mempool ancestors of entry.
Definition: txmempool.cpp:56
void removeForFinalizedBlock(const std::vector< CTransactionRef > &vtx) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:321
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
Definition: txmempool.cpp:238
void RemoveStaged(const setEntries &stage, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove a set of transactions from the mempool.
Definition: txmempool.cpp:674
void UpdateParentsOf(bool add, txiter it) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update parents of it to add/remove it as a child transaction.
Definition: txmempool.cpp:82
void ApplyDelta(const TxId &txid, Amount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:562
void SetLoadTried(bool load_tried)
Set whether or not we've made an attempt to load the mempool (regardless of whether the attempt was s...
Definition: txmempool.cpp:822
std::optional< txiter > GetIter(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given txid, if found.
Definition: txmempool.cpp:582
bool isSpent(const COutPoint &outpoint) const
Definition: txmempool.cpp:133
unsigned int GetTransactionsUpdated() const
Definition: txmempool.cpp:138
void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:337
A UTXO entry.
Definition: coins.h:28
Definition: rcu.h:85
T * get()
Get allows to access the undelying pointer.
Definition: rcu.h:170
std::string ToString() const
Definition: uint256.h:80
std::string GetHex() const
Definition: uint256.cpp:16
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
Definition: coins.cpp:156
#define LogPrint(category,...)
Definition: logging.h:238
#define LogPrintf(...)
Definition: logging.h:227
std::string FormatMoney(const Amount amt)
Do not use these functions to represent or parse monetary amounts to or from JSON but use AmountFromV...
Definition: moneystr.cpp:13
@ MEMPOOL
Definition: logging.h:42
bool CheckTxInputs(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, Amount &txfee)
Check whether all inputs of this transaction are valid (no double spends and amounts).
Definition: tx_verify.cpp:168
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:27
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
Definition: memusage.h:123
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
Definition: memusage.h:73
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
static constexpr CFeeRate MEMPOOL_FULL_FEE_INCREMENT(1000 *SATOSHI)
Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP...
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:315
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition: random.h:85
Definition: amount.h:19
static constexpr Amount zero() noexcept
Definition: amount.h:32
RCUPtr< T > remove(const KeyType &key)
Remove an element from the tree.
Definition: radix.h:181
A TxId is the identifier of a transaction.
Definition: txid.h:14
Information about a mempool transaction.
Definition: txmempool.h:131
Options struct containing options for constructing a CTxMemPool.
#define LOCK(cs)
Definition: sync.h:306
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition: time.cpp:109
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:68
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
Definition: txmempool.cpp:494
const std::string RemovalReasonToString(const MemPoolRemovalReason &r) noexcept
Definition: txmempool.cpp:828
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
Definition: txmempool.h:152
@ SIZELIMIT
Removed in size limiting.
@ BLOCK
Removed for block.
@ EXPIRY
Expired from mempool.
@ AVALANCHE
Removed by avalanche vote.
@ CONFLICT
Removed for conflict with in-block transaction.
@ REORG
Removed for reorganization.
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coins to signify they are only in the memory pool(since 0....
Definition: txmempool.h:49
AssertLockHeld(pool.cs)
assert(!tx.IsCoinBase())
CMainSignals & GetMainSignals()