Bitcoin ABC 0.32.4
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 <blockindex.h>
9#include <clientversion.h>
10#include <coins.h>
11#include <common/system.h>
12#include <config.h>
13#include <consensus/consensus.h>
14#include <consensus/tx_verify.h>
16#include <logging.h>
17#include <policy/fees.h>
18#include <policy/policy.h>
19#include <reverse_iterator.h>
20#include <undo.h>
21#include <util/check.h>
22#include <util/moneystr.h>
23#include <util/time.h>
24#include <validationinterface.h>
25#include <version.h>
26
27#include <algorithm>
28#include <cmath>
29#include <limits>
30#include <vector>
31
33 setEntries &setAncestors,
34 CTxMemPoolEntry::Parents &staged_ancestors) const {
35 while (!staged_ancestors.empty()) {
36 const auto stage = staged_ancestors.begin()->get();
37
38 txiter stageit = mapTx.find(stage->GetTx().GetId());
39 assert(stageit != mapTx.end());
40 setAncestors.insert(stageit);
41 staged_ancestors.erase(staged_ancestors.begin());
42
43 const CTxMemPoolEntry::Parents &parents =
44 (*stageit)->GetMemPoolParentsConst();
45 for (const auto &parent : parents) {
46 txiter parent_it = mapTx.find(parent.get()->GetTx().GetId());
47 assert(parent_it != mapTx.end());
48
49 // If this is a new ancestor, add it.
50 if (setAncestors.count(parent_it) == 0) {
51 staged_ancestors.insert(parent);
52 }
53 }
54 }
55
56 return true;
57}
58
60 const CTxMemPoolEntryRef &entry, setEntries &setAncestors,
61 bool fSearchForParents /* = true */) const {
62 CTxMemPoolEntry::Parents staged_ancestors;
63 const CTransaction &tx = entry->GetTx();
64
65 if (fSearchForParents) {
66 // Get parents of this transaction that are in the mempool
67 // GetMemPoolParents() is only valid for entries in the mempool, so we
68 // iterate mapTx to find parents.
69 for (const CTxIn &in : tx.vin) {
70 std::optional<txiter> piter = GetIter(in.prevout.GetTxId());
71 if (!piter) {
72 continue;
73 }
74 staged_ancestors.insert(**piter);
75 }
76 } else {
77 // If we're not searching for parents, we require this to be an entry in
78 // the mempool already.
79 staged_ancestors = entry->GetMemPoolParentsConst();
80 }
81
82 return CalculateAncestors(setAncestors, staged_ancestors);
83}
84
86 // add or remove this tx as a child of each parent
87 for (const auto &parent : (*it)->GetMemPoolParentsConst()) {
88 auto parent_it = mapTx.find(parent.get()->GetTx().GetId());
89 assert(parent_it != mapTx.end());
90 UpdateChild(parent_it, it, add);
91 }
92}
93
95 const CTxMemPoolEntry::Children &children =
96 (*it)->GetMemPoolChildrenConst();
97 for (const auto &child : children) {
98 auto updateIt = mapTx.find(child.get()->GetTx().GetId());
99 assert(updateIt != mapTx.end());
100 UpdateParent(updateIt, it, false);
101 }
102}
103
105 for (txiter removeIt : entriesToRemove) {
106 // Note that UpdateParentsOf severs the child links that point to
107 // removeIt in the entries for the parents of removeIt.
108 UpdateParentsOf(false, removeIt);
109 }
110
111 // After updating all the parent links, we can now sever the link between
112 // each transaction being removed and any mempool children (ie, update
113 // CTxMemPoolEntry::m_parents for each direct child of a transaction being
114 // removed).
115 for (txiter removeIt : entriesToRemove) {
116 UpdateChildrenForRemoval(removeIt);
117 }
118}
119
120CTxMemPool::CTxMemPool(const Config &config, const Options &opts)
121 : m_check_ratio(opts.check_ratio),
122 m_finalizedTxsFitter(node::BlockFitter(config)),
123 m_orphanage(std::make_unique<TxOrphanage>()),
124 m_conflicting(std::make_unique<TxConflicting>()),
125 m_max_size_bytes{opts.max_size_bytes}, m_expiry{opts.expiry},
126 m_min_relay_feerate{opts.min_relay_feerate},
127 m_dust_relay_feerate{opts.dust_relay_feerate},
128 m_permit_bare_multisig{opts.permit_bare_multisig},
129 m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
130 m_require_standard{opts.require_standard} {
131 // lock free clear
132 _clear();
133}
134
136
137bool CTxMemPool::isSpent(const COutPoint &outpoint) const {
138 LOCK(cs);
139 return mapNextTx.count(outpoint);
140}
141
144}
145
148}
149
151 // get a guaranteed unique id (in case tests re-use the same object)
152 entry->SetEntryId(nextEntryId++);
153
154 // Update transaction for any feeDelta created by PrioritiseTransaction
155 {
156 Amount feeDelta = Amount::zero();
157 ApplyDelta(entry->GetTx().GetId(), feeDelta);
158 entry->UpdateFeeDelta(feeDelta);
159 }
160
161 // Add to memory pool without checking anything.
162 // Used by AcceptToMemoryPool(), which DOES do all the appropriate checks.
163 auto [newit, inserted] = mapTx.insert(entry);
164 // Sanity check: It is a programming error if insertion fails (uniqueness
165 // invariants in mapTx are violated, etc)
166 assert(inserted);
167 // Sanity check: We should always end up inserting at the end of the
168 // entry_id index
169 assert(&*mapTx.get<entry_id>().rbegin() == &*newit);
170
171 // Update cachedInnerUsage to include contained transaction's usage.
172 // (When we update the entry for in-mempool parents, memory usage will be
173 // further updated.)
174 cachedInnerUsage += entry->DynamicMemoryUsage();
175
176 const CTransactionRef tx = entry->GetSharedTx();
177 std::set<TxId> setParentTransactions;
178 for (const CTxIn &in : tx->vin) {
179 mapNextTx.insert(std::make_pair(&in.prevout, tx));
180 setParentTransactions.insert(in.prevout.GetTxId());
181 }
182 // Don't bother worrying about child transactions of this one. It is
183 // guaranteed that a new transaction arriving will not have any children,
184 // because such children would be orphans.
185
186 // Update ancestors with information about this tx
187 for (const auto &pit : GetIterSet(setParentTransactions)) {
188 UpdateParent(newit, pit, true);
189 }
190
191 UpdateParentsOf(true, newit);
192
194 totalTxSize += entry->GetTxSize();
195 m_total_fee += entry->GetFee();
196}
197
199 // We increment mempool sequence value no matter removal reason
200 // even if not directly reported below.
201 uint64_t mempool_sequence = GetAndIncrementSequence();
202
203 const TxId &txid = (*it)->GetTx().GetId();
204
205 if (reason != MemPoolRemovalReason::BLOCK) {
206 // Notify clients that a transaction has been removed from the mempool
207 // for any reason except being included in a block. Clients interested
208 // in transactions included in blocks can subscribe to the
209 // BlockConnected notification.
211 (*it)->GetSharedTx(), reason, mempool_sequence);
212
213 if (auto removed_tx = finalizedTxs.remove(txid)) {
214 m_finalizedTxsFitter.removeTxUnchecked(removed_tx->GetTxSize(),
215 removed_tx->GetSigChecks(),
216 removed_tx->GetFee());
217 }
218 }
219
220 for (const CTxIn &txin : (*it)->GetTx().vin) {
221 mapNextTx.erase(txin.prevout);
222 }
223
224 /* add logging because unchecked */
225 RemoveUnbroadcastTx(txid, true);
226
227 totalTxSize -= (*it)->GetTxSize();
228 m_total_fee -= (*it)->GetFee();
229 cachedInnerUsage -= (*it)->DynamicMemoryUsage();
230 cachedInnerUsage -=
231 memusage::DynamicUsage((*it)->GetMemPoolParentsConst()) +
232 memusage::DynamicUsage((*it)->GetMemPoolChildrenConst());
233 mapTx.erase(it);
235}
236
237// Calculates descendants of entry that are not already in setDescendants, and
238// adds to setDescendants. Assumes entryit is already a tx in the mempool and
239// CTxMemPoolEntry::m_children is correct for tx and all descendants. Also
240// assumes that if an entry is in setDescendants already, then all in-mempool
241// descendants of it are already in setDescendants as well, so that we can save
242// time by not iterating over those entries.
244 setEntries &setDescendants) const {
245 setEntries stage;
246 if (setDescendants.count(entryit) == 0) {
247 stage.insert(entryit);
248 }
249 // Traverse down the children of entry, only adding children that are not
250 // accounted for in setDescendants already (because those children have
251 // either already been walked, or will be walked in this iteration).
252 while (!stage.empty()) {
253 txiter it = *stage.begin();
254 setDescendants.insert(it);
255 stage.erase(stage.begin());
256
257 const CTxMemPoolEntry::Children &children =
258 (*it)->GetMemPoolChildrenConst();
259 for (const auto &child : children) {
260 txiter childiter = mapTx.find(child.get()->GetTx().GetId());
261 assert(childiter != mapTx.end());
262
263 if (!setDescendants.count(childiter)) {
264 stage.insert(childiter);
265 }
266 }
267 }
268}
269
270void CTxMemPool::removeRecursive(const CTransaction &origTx,
271 MemPoolRemovalReason reason) {
272 // Remove transaction from memory pool.
274 setEntries txToRemove;
275 txiter origit = mapTx.find(origTx.GetId());
276 if (origit != mapTx.end()) {
277 txToRemove.insert(origit);
278 } else {
279 // When recursively removing but origTx isn't in the mempool be sure to
280 // remove any children that are in the pool. This can happen during
281 // chain re-orgs if origTx isn't re-accepted into the mempool for any
282 // reason.
283 auto it = mapNextTx.lower_bound(COutPoint(origTx.GetId(), 0));
284 while (it != mapNextTx.end() &&
285 it->first->GetTxId() == origTx.GetId()) {
286 txiter nextit = mapTx.find(it->second->GetId());
287 assert(nextit != mapTx.end());
288 txToRemove.insert(nextit);
289 ++it;
290 }
291 }
292
293 setEntries setAllRemoves;
294 for (txiter it : txToRemove) {
295 CalculateDescendants(it, setAllRemoves);
296 }
297
298 RemoveStaged(setAllRemoves, reason);
299}
300
301void CTxMemPool::removeConflicts(const CTransaction &tx) {
302 // Remove transactions which depend on inputs of tx, recursively
304 for (const CTxIn &txin : tx.vin) {
305 auto it = mapNextTx.find(txin.prevout);
306 if (it != mapNextTx.end()) {
307 const CTransaction &txConflict = *it->second;
308 if (txConflict != tx) {
309 // We reject blocks that contains a tx conflicting with a
310 // finalized tx, so this should never happen
311 Assume(!isAvalancheFinalizedPreConsensus(txConflict.GetId()));
312 ClearPrioritisation(txConflict.GetId());
314 }
315 }
316 }
317}
318
324
325 lastRollingFeeUpdate = GetTime();
326 blockSinceLastRollingFeeBump = true;
327}
328
330 const std::unordered_set<TxId, SaltedTxIdHasher>
331 &confirmedTxIdsInNonFinalizedBlocks) {
333
334 std::vector<CTxMemPoolEntryRef> finalizedTxsToKeep;
337 if (mapTx.count(entry->GetTx().GetId()) > 0 ||
338 confirmedTxIdsInNonFinalizedBlocks.count(
339 entry->GetTx().GetId()) > 0) {
340 // The transaction is either in the mempool (not confirmed) or
341 // confirmed in a non-finalized block (which might be rejeted by
342 // avalanche), so we keep it in the radix tree.
343 finalizedTxsToKeep.push_back(entry);
344 }
345
346 // All the other transactions are either confirmed in the finalized
347 // block or in one of its ancestors.
348 return true;
349 });
350
351 // Clear the radix tree and add back the transactions that are not confirmed
352 decltype(finalizedTxs) empty;
353 std::swap(finalizedTxs, empty);
354
355 m_finalizedTxsFitter.resetBlock();
356 for (const auto &entry : finalizedTxsToKeep) {
357 // We don't need to proceed to all the checks that happen during
358 // finalization here so we only recompute the size and sigchecks.
359 if (finalizedTxs.insert(entry)) {
360 m_finalizedTxsFitter.addTx(entry->GetTxSize(),
361 entry->GetSigChecks(), entry->GetFee());
362 }
363 }
364
366}
367
369 mapTx.clear();
370 mapNextTx.clear();
371 totalTxSize = 0;
372 m_total_fee = Amount::zero();
373 cachedInnerUsage = 0;
374 lastRollingFeeUpdate = GetTime();
375 blockSinceLastRollingFeeBump = false;
376 rollingMinimumFeeRate = 0;
378}
379
380void CTxMemPool::clear(bool include_finalized_txs) {
381 LOCK(cs);
382 _clear();
383 if (include_finalized_txs) {
385 std::swap(finalizedTxs, empty);
386 m_finalizedTxsFitter.resetBlock();
387 }
388}
389
390void CTxMemPool::check(const CCoinsViewCache &active_coins_tip,
391 int64_t spendheight) const {
392 if (m_check_ratio == 0) {
393 return;
394 }
395
396 if (GetRand(m_check_ratio) >= 1) {
397 return;
398 }
399
401 LOCK(cs);
403 "Checking mempool with %u transactions and %u inputs\n",
404 (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
405
406 uint64_t checkTotal = 0;
407 Amount check_total_fee{Amount::zero()};
408 uint64_t innerUsage = 0;
409
410 CCoinsViewCache mempoolDuplicate(
411 const_cast<CCoinsViewCache *>(&active_coins_tip));
412
413 for (const CTxMemPoolEntryRef &entry : mapTx.get<entry_id>()) {
414 checkTotal += entry->GetTxSize();
415 check_total_fee += entry->GetFee();
416 innerUsage += entry->DynamicMemoryUsage();
417 const CTransaction &tx = entry->GetTx();
418 innerUsage += memusage::DynamicUsage(entry->GetMemPoolParentsConst()) +
419 memusage::DynamicUsage(entry->GetMemPoolChildrenConst());
420
421 CTxMemPoolEntry::Parents setParentCheck;
422 for (const CTxIn &txin : tx.vin) {
423 // Check that every mempool transaction's inputs refer to available
424 // coins, or other mempool tx's.
425 txiter parentIt = mapTx.find(txin.prevout.GetTxId());
426 if (parentIt != mapTx.end()) {
427 const CTransaction &parentTx = (*parentIt)->GetTx();
428 assert(parentTx.vout.size() > txin.prevout.GetN() &&
429 !parentTx.vout[txin.prevout.GetN()].IsNull());
430 setParentCheck.insert(*parentIt);
431 // also check that parents have a topological ordering before
432 // their children
433 assert((*parentIt)->GetEntryId() < entry->GetEntryId());
434 }
435 // We are iterating through the mempool entries sorted
436 // topologically.
437 // All parents must have been checked before their children and
438 // their coins added to the mempoolDuplicate coins cache.
439 assert(mempoolDuplicate.HaveCoin(txin.prevout));
440 // Check whether its inputs are marked in mapNextTx.
441 auto prevoutNextIt = mapNextTx.find(txin.prevout);
442 assert(prevoutNextIt != mapNextTx.end());
443 assert(prevoutNextIt->first == &txin.prevout);
444 assert(prevoutNextIt->second.get() == &tx);
445 }
446 auto comp = [](const auto &a, const auto &b) -> bool {
447 return a.get()->GetTx().GetId() == b.get()->GetTx().GetId();
448 };
449 assert(setParentCheck.size() == entry->GetMemPoolParentsConst().size());
450 assert(std::equal(setParentCheck.begin(), setParentCheck.end(),
451 entry->GetMemPoolParentsConst().begin(), comp));
452
453 // Verify ancestor state is correct.
454 setEntries setAncestors;
455 std::string dummy;
456
457 const bool ok = CalculateMemPoolAncestors(entry, setAncestors);
458 assert(ok);
459
460 // all ancestors should have entryId < this tx's entryId
461 for (const auto &ancestor : setAncestors) {
462 assert((*ancestor)->GetEntryId() < entry->GetEntryId());
463 }
464
465 // Check children against mapNextTx
466 CTxMemPoolEntry::Children setChildrenCheck;
467 auto iter = mapNextTx.lower_bound(COutPoint(entry->GetTx().GetId(), 0));
468 for (; iter != mapNextTx.end() &&
469 iter->first->GetTxId() == entry->GetTx().GetId();
470 ++iter) {
471 txiter childIt = mapTx.find(iter->second->GetId());
472 // mapNextTx points to in-mempool transactions
473 assert(childIt != mapTx.end());
474 setChildrenCheck.insert(*childIt);
475 }
476 assert(setChildrenCheck.size() ==
477 entry->GetMemPoolChildrenConst().size());
478 assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(),
479 entry->GetMemPoolChildrenConst().begin(), comp));
480
481 // Not used. CheckTxInputs() should always pass
482 TxValidationState dummy_state;
483 Amount txfee{Amount::zero()};
484 assert(!tx.IsCoinBase());
485 assert(Consensus::CheckTxInputs(tx, dummy_state, mempoolDuplicate,
486 spendheight, txfee));
487 for (const auto &input : tx.vin) {
488 mempoolDuplicate.SpendCoin(input.prevout);
489 }
490 AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
491 }
492
493 for (auto &[_, nextTx] : mapNextTx) {
494 txiter it = mapTx.find(nextTx->GetId());
495 assert(it != mapTx.end());
496 assert((*it)->GetSharedTx() == nextTx);
497 }
498
499 assert(totalTxSize == checkTotal);
500 assert(m_total_fee == check_total_fee);
501 assert(innerUsage == cachedInnerUsage);
502}
503
505 const TxId &txidb) const {
506 LOCK(cs);
507 auto it1 = mapTx.find(txida);
508 if (it1 == mapTx.end()) {
509 return false;
510 }
511 auto it2 = mapTx.find(txidb);
512 if (it2 == mapTx.end()) {
513 return true;
514 }
515 return (*it1)->GetEntryId() < (*it2)->GetEntryId();
516}
517
518void CTxMemPool::getAllTxIds(std::vector<TxId> &vtxid) const {
519 LOCK(cs);
520
521 vtxid.clear();
522 vtxid.reserve(mapTx.size());
523
524 for (const auto &entry : mapTx.get<entry_id>()) {
525 vtxid.push_back(entry->GetTx().GetId());
526 }
527}
528
529static TxMempoolInfo
530GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
531 return TxMempoolInfo{(*it)->GetSharedTx(), (*it)->GetTime(),
532 (*it)->GetFee(), (*it)->GetTxSize(),
533 (*it)->GetModifiedFee() - (*it)->GetFee()};
534}
535
536std::vector<TxMempoolInfo> CTxMemPool::infoAll() const {
537 LOCK(cs);
538
539 std::vector<TxMempoolInfo> ret;
540 ret.reserve(mapTx.size());
541
542 const auto &index = mapTx.get<entry_id>();
543 for (auto it = index.begin(); it != index.end(); ++it) {
544 ret.push_back(GetInfo(mapTx.project<0>(it)));
545 }
546
547 return ret;
548}
549
550bool CTxMemPool::setAvalancheFinalized(const CTxMemPoolEntryRef &tx,
551 const Consensus::Params &params,
552 const CBlockIndex &active_chain_tip,
553 std::vector<TxId> &finalizedTxIds) {
556
557 auto it = mapTx.find(tx->GetTx().GetId());
558 if (it == mapTx.end()) {
559 // Trying to finalize a tx that is not in the mempool !
560 LogPrintf("Trying to finalize tx %s that is not in the mempool\n",
561 tx->GetTx().GetId().ToString());
562 return false;
563 }
564
565 setEntries setAncestors;
566 setAncestors.insert(it);
567 if (!CalculateMemPoolAncestors(tx, setAncestors,
568 /*fSearchForParents=*/false)) {
569 // Failed to get a list of parents for this tx. If we finalize it we
570 // might be missing a parent and generate an invalid block.
571 LogPrintf("Failed to calculate ancestors for tx %s\n",
572 tx->GetTx().GetId().ToString());
573 return false;
574 }
575
576 // Make sure the tx chain would fit the block before adding them.
577 uint64_t sumOfTxSize{0};
578 uint64_t sumOfTxSigChecks{0};
579 for (auto iter_it = setAncestors.begin(); iter_it != setAncestors.end();) {
580 // iter_it is an iterator of mapTx iterator (aka txiter)
581 CTxMemPoolEntryRef entry = **iter_it;
582
583 TxValidationState state;
584 if (!ContextualCheckTransactionForCurrentBlock(active_chain_tip, params,
585 entry->GetTx(), state)) {
587 "Delay storing finalized tx %s that would cause the block "
588 "to be invalid%s (%s)\n",
589 tx->GetTx().GetId().ToString(),
590 entry->GetSharedTx()->GetId() == tx->GetSharedTx()->GetId()
591 ? ""
592 : strprintf(" for parent %s",
593 entry->GetSharedTx()->GetId().ToString()),
594 state.ToString());
595 return false;
596 }
597
598 if (m_finalizedTxsFitter.isBelowBlockMinFeeRate(
599 entry->GetModifiedFeeRate())) {
601 "Delay storing finalized tx %s due to fee rate below the "
602 "block mininmum%s (see -blockmintxfee)\n",
603 tx->GetTx().GetId().ToString(),
604 entry->GetSharedTx()->GetId() == tx->GetSharedTx()->GetId()
605 ? ""
606 : strprintf(" for parent %s",
607 entry->GetSharedTx()->GetId().ToString()));
608 return false;
609 }
610
611 // It is possible (and normal) that an ancestor is already finalized.
612 // Beware to not account for it in this case.
613 if (isAvalancheFinalizedPreConsensus(entry->GetTx().GetId())) {
614 iter_it = setAncestors.erase(iter_it);
615 continue;
616 }
617
618 sumOfTxSize += entry->GetTxSize();
619 sumOfTxSigChecks += entry->GetSigChecks();
620 ++iter_it;
621 }
622
623 if (!m_finalizedTxsFitter.testTxFits(sumOfTxSize, sumOfTxSigChecks)) {
624 LogPrint(
626 "Delay storing finalized tx %s as it won't fit in the next block\n",
627 tx->GetTx().GetId().ToString());
628 return false;
629 }
630
631 finalizedTxIds.clear();
632
633 // Now let's add the txs !
634 // At this stage the set of ancestors is free if already finalized txs
635 for (txiter ancestor_it : setAncestors) {
636 if (finalizedTxs.insert(*ancestor_it)) {
637 m_finalizedTxsFitter.addTx((*ancestor_it)->GetTxSize(),
638 (*ancestor_it)->GetSigChecks(),
639 (*ancestor_it)->GetFee());
640
641 finalizedTxIds.push_back((*ancestor_it)->GetTx().GetId());
642
644 (*ancestor_it)->GetSharedTx());
645 }
646 }
647
649
650 return true;
651}
652
656
657 const TxId &txid = tx->GetId();
658 if (auto it = GetIter(txid)) {
659 CTxMemPoolEntryRef entry = **it;
660
661 // The tx is in the mempool, check it would fit the next block or if
662 // it's already full of finalized txs.
663 return !m_finalizedTxsFitter.isBelowBlockMinFeeRate(
664 entry->GetModifiedFeeRate()) &&
665 m_finalizedTxsFitter.testTxFits(entry->GetTxSize(),
666 entry->GetSigChecks());
667 }
668
669 // Otherwise check if it's in the conflicting pool. If we reach this point
670 // this means that the transaction has been rejected so no need to check if
671 // it fits the block, however we don't want to discard it either so the vote
672 // continue until the tx is invalidated.
674 return m_conflicting && m_conflicting->HaveTx(txid));
675}
676
678 LOCK(cs);
679 indexed_transaction_set::const_iterator i = mapTx.find(txid);
680 if (i == mapTx.end()) {
681 return nullptr;
682 }
683
684 return (*i)->GetSharedTx();
685}
686
688 LOCK(cs);
689 indexed_transaction_set::const_iterator i = mapTx.find(txid);
690 if (i == mapTx.end()) {
691 return TxMempoolInfo();
692 }
693
694 return GetInfo(i);
695}
696
698 LOCK(cs);
699
700 // minerPolicy uses recent blocks to figure out a reasonable fee. This
701 // may disagree with the rollingMinimumFeerate under certain scenarios
702 // where the mempool increases rapidly, or blocks are being mined which
703 // do not contain propagated transactions.
704 return std::max(m_min_relay_feerate, GetMinFee());
705}
706
708 const Amount nFeeDelta) {
709 {
710 LOCK(cs);
711 Amount &delta = mapDeltas[txid];
712 delta += nFeeDelta;
713 txiter it = mapTx.find(txid);
714 if (it != mapTx.end()) {
715 mapTx.modify(it, [&delta](CTxMemPoolEntryRef &e) {
716 e->UpdateFeeDelta(delta);
717 });
719 }
720 }
721 LogPrintf("PrioritiseTransaction: %s fee += %s\n", txid.ToString(),
722 FormatMoney(nFeeDelta));
723}
724
725void CTxMemPool::ApplyDelta(const TxId &txid, Amount &nFeeDelta) const {
727 std::map<TxId, Amount>::const_iterator pos = mapDeltas.find(txid);
728 if (pos == mapDeltas.end()) {
729 return;
730 }
731
732 nFeeDelta += pos->second;
733}
734
737 mapDeltas.erase(txid);
738}
739
740CTransactionRef CTxMemPool::GetConflictTx(const COutPoint &prevout) const {
741 const auto it = mapNextTx.find(prevout);
742 return it == mapNextTx.end() ? nullptr : it->second;
743}
744
745std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const TxId &txid) const {
746 auto it = mapTx.find(txid);
747 if (it != mapTx.end()) {
748 return it;
749 }
750 return std::nullopt;
751}
752
754CTxMemPool::GetIterSet(const std::set<TxId> &txids) const {
756 for (const auto &txid : txids) {
757 const auto mi = GetIter(txid);
758 if (mi) {
759 ret.insert(*mi);
760 }
761 }
762 return ret;
763}
764
765bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const {
766 for (const CTxIn &in : tx.vin) {
767 if (exists(in.prevout.GetTxId())) {
768 return false;
769 }
770 }
771
772 return true;
773}
774
776 const CTxMemPool &mempoolIn)
777 : CCoinsViewBacked(baseIn), mempool(mempoolIn) {}
778
779bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
780 // Check to see if the inputs are made available by another tx in the
781 // package. These Coins would not be available in the underlying CoinsView.
782 if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) {
783 coin = it->second;
784 return true;
785 }
786
787 // If an entry in the mempool exists, always return that one, as it's
788 // guaranteed to never conflict with the underlying cache, and it cannot
789 // have pruned entries (as it contains full) transactions. First checking
790 // the underlying cache risks returning a pruned entry instead.
791 CTransactionRef ptx = mempool.get(outpoint.GetTxId());
792 if (ptx) {
793 if (outpoint.GetN() < ptx->vout.size()) {
794 coin = Coin(ptx->vout[outpoint.GetN()], MEMPOOL_HEIGHT, false);
795 m_non_base_coins.emplace(outpoint);
796 return true;
797 }
798 return false;
799 }
800 return base->GetCoin(outpoint, coin);
801}
802
804 for (uint32_t n = 0; n < tx->vout.size(); ++n) {
805 m_temp_added.emplace(COutPoint(tx->GetId(), n),
806 Coin(tx->vout[n], MEMPOOL_HEIGHT, false));
807 m_non_base_coins.emplace(COutPoint(tx->GetId(), n));
808 }
809}
811 m_temp_added.clear();
812 m_non_base_coins.clear();
813}
814
816 LOCK(cs);
817 // Estimate the overhead of mapTx to be 12 pointers + an allocation, as no
818 // exact formula for boost::multi_index_contained is implemented.
820 12 * sizeof(void *)) *
821 mapTx.size() +
822 memusage::DynamicUsage(mapNextTx) +
823 memusage::DynamicUsage(mapDeltas) + cachedInnerUsage;
824}
825
826void CTxMemPool::RemoveUnbroadcastTx(const TxId &txid, const bool unchecked) {
827 LOCK(cs);
828
829 if (m_unbroadcast_txids.erase(txid)) {
830 LogPrint(
831 BCLog::MEMPOOL, "Removed %i from set of unbroadcast txns%s\n",
832 txid.GetHex(),
833 (unchecked ? " before confirmation that txn was sent out" : ""));
834 }
835}
836
838 MemPoolRemovalReason reason) {
841
842 // Remove txs in reverse-topological order
843 const setRevTopoEntries stageRevTopo(stage.begin(), stage.end());
844 for (txiter it : stageRevTopo) {
845 removeUnchecked(it, reason);
846 }
847}
848
849int CTxMemPool::Expire(std::chrono::seconds time) {
851 indexed_transaction_set::index<entry_time>::type::iterator it =
852 mapTx.get<entry_time>().begin();
853 setEntries toremove;
854 size_t skippedFinalizedTxs{0};
855 while (it != mapTx.get<entry_time>().end() && (*it)->GetTime() < time) {
856 if (isAvalancheFinalizedPreConsensus((*it)->GetTx().GetId())) {
857 // Don't expire finalized transactions
858 ++skippedFinalizedTxs;
859 } else {
860 toremove.insert(mapTx.project<0>(it));
861 }
862
863 it++;
864 }
865
866 if (skippedFinalizedTxs > 0) {
867 LogPrint(BCLog::MEMPOOL, "Not expiring %u finalized transaction\n",
868 skippedFinalizedTxs);
869 }
870
871 setEntries stage;
872 for (txiter removeit : toremove) {
873 CalculateDescendants(removeit, stage);
874 }
875
877 return stage.size();
878}
879
883 int expired = Expire(GetTime<std::chrono::seconds>() - m_expiry);
884 if (expired != 0) {
886 "Expired %i transactions from the memory pool\n", expired);
887 }
888
889 std::vector<COutPoint> vNoSpendsRemaining;
890 TrimToSize(m_max_size_bytes, &vNoSpendsRemaining);
891 for (const COutPoint &removed : vNoSpendsRemaining) {
892 coins_cache.Uncache(removed);
893 }
894}
895
896void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add) {
899 if (add && (*entry)->GetMemPoolChildren().insert(*child).second) {
900 cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
901 } else if (!add && (*entry)->GetMemPoolChildren().erase(*child)) {
902 cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
903 }
904}
905
906void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add) {
909 if (add && (*entry)->GetMemPoolParents().insert(*parent).second) {
910 cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
911 } else if (!add && (*entry)->GetMemPoolParents().erase(*parent)) {
912 cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
913 }
914}
915
916CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
917 LOCK(cs);
918 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0) {
919 return CFeeRate(int64_t(ceill(rollingMinimumFeeRate)) * SATOSHI);
920 }
921
922 int64_t time = GetTime();
923 if (time > lastRollingFeeUpdate + 10) {
924 double halflife = ROLLING_FEE_HALFLIFE;
925 if (DynamicMemoryUsage() < sizelimit / 4) {
926 halflife /= 4;
927 } else if (DynamicMemoryUsage() < sizelimit / 2) {
928 halflife /= 2;
929 }
930
931 rollingMinimumFeeRate =
932 rollingMinimumFeeRate /
933 pow(2.0, (time - lastRollingFeeUpdate) / halflife);
934 lastRollingFeeUpdate = time;
935 }
936 return CFeeRate(int64_t(ceill(rollingMinimumFeeRate)) * SATOSHI);
937}
938
941 if ((rate.GetFeePerK() / SATOSHI) > rollingMinimumFeeRate) {
942 rollingMinimumFeeRate = rate.GetFeePerK() / SATOSHI;
943 blockSinceLastRollingFeeBump = false;
944 }
945}
946
947void CTxMemPool::TrimToSize(size_t sizelimit,
948 std::vector<COutPoint> *pvNoSpendsRemaining) {
950
951 unsigned nTxnRemoved = 0;
952 size_t finalizedTxsSkipped = 0;
953 CFeeRate maxFeeRateRemoved(Amount::zero());
954 while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) {
955 auto &by_modified_feerate = mapTx.get<modified_feerate>();
956 // Lowest fee first
957 auto rit = by_modified_feerate.rbegin();
958
959 // We don't evict finalized transactions, even if they have lower fee
960 while (isAvalancheFinalizedPreConsensus((*rit)->GetTx().GetId())) {
961 ++finalizedTxsSkipped;
962 ++rit;
963 if (rit == by_modified_feerate.rend()) {
964 // Nothing we can trim
965 break;
966 }
967 }
968
969 // Convert to forward iterator.
970 // If rit == rend(), the forward iterator will be equivalent to begin()
971 // and we can't decrement it, there is nothing to remove. This could
972 // only happen if all the transactions are finalized, which in turns
973 // implies that the mempool cannot contain a block worth of txs.
974 // In this case we still exit the loop so we get the proper log message.
975 if (rit == by_modified_feerate.rend()) {
976 break;
977 }
978 auto it = rit.base();
979 --it;
980
981 // We set the new mempool min fee to the feerate of the removed
982 // transaction, plus the "minimum reasonable fee rate" (ie some value
983 // under which we consider txn to have 0 fee). This way, we don't allow
984 // txn to enter mempool with feerate equal to txn which were removed
985 // with no block in between.
986 CFeeRate removed = (*it)->GetModifiedFeeRate();
988
989 trackPackageRemoved(removed);
990 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
991
992 setEntries stage;
993 CalculateDescendants(mapTx.project<0>(it), stage);
994 nTxnRemoved += stage.size();
995
996 if (pvNoSpendsRemaining) {
997 for (const txiter &iter : stage) {
998 for (const CTxIn &txin : (*iter)->GetTx().vin) {
999 if (!exists(txin.prevout.GetTxId())) {
1000 pvNoSpendsRemaining->push_back(txin.prevout);
1001 }
1002 }
1003 }
1004 }
1005
1007 }
1008
1009 if (maxFeeRateRemoved > CFeeRate(Amount::zero())) {
1011 "Removed %u txn, rolling minimum fee bumped to %s\n",
1012 nTxnRemoved, maxFeeRateRemoved.ToString());
1013 }
1014
1015 if (finalizedTxsSkipped > 0) {
1017 "Not evicting %u finalized txn for low fee\n",
1018 finalizedTxsSkipped);
1019 }
1020}
1021
1023 LOCK(cs);
1024 return m_load_tried;
1025}
1026
1027void CTxMemPool::SetLoadTried(bool load_tried) {
1028 LOCK(cs);
1029 m_load_tried = load_tried;
1030}
1031
1032std::string RemovalReasonToString(const MemPoolRemovalReason &r) noexcept {
1033 switch (r) {
1035 return "expiry";
1037 return "sizelimit";
1039 return "reorg";
1041 return "block";
1043 return "conflict";
1045 return "avalanche";
1047 return "manual";
1048 }
1049 assert(false);
1050}
static constexpr Amount SATOSHI
Definition: amount.h:143
#define Assume(val)
Assume is the identity function.
Definition: check.h:97
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:25
CCoinsView backed by another CCoinsView.
Definition: coins.h:343
CCoinsView * base
Definition: coins.h:345
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:363
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:324
Abstract view on the open txout dataset.
Definition: coins.h:305
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:779
void Reset()
Clear m_temp_added and m_non_base_coins.
Definition: txmempool.cpp:810
std::unordered_map< COutPoint, Coin, SaltedOutpointHasher > m_temp_added
Coins made available by transactions being validated.
Definition: txmempool.h:653
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
Definition: txmempool.cpp:775
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:661
void PackageAddTransaction(const CTransactionRef &tx)
Add the coins created by this transaction.
Definition: txmempool.cpp:803
const CTxMemPool & mempool
Definition: txmempool.h:664
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)
void TransactionFinalized(const CTransactionRef &tx)
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:221
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:301
CFeeRate estimateFee() const
Definition: txmempool.cpp:697
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:765
void ClearPrioritisation(const TxId &txid) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:735
std::set< txiter, CompareIteratorById > setEntries
Definition: txmempool.h:321
void RemoveUnbroadcastTx(const TxId &txid, const bool unchecked=false)
Removes a transaction from the unbroadcast set.
Definition: txmempool.cpp:826
bool GetLoadTried() const
Definition: txmempool.cpp:1022
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:32
void updateFeeForBlock() EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
Definition: txmempool.cpp:322
CFeeRate GetMinFee() const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
Definition: txmempool.h:463
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:317
void trackPackageRemoved(const CFeeRate &rate) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:939
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:270
void UpdateForRemoveFromMempool(const setEntries &entriesToRemove) EXCLUSIVE_LOCKS_REQUIRED(cs)
For each transaction being removed, update ancestors and any direct children.
Definition: txmempool.cpp:104
const int m_check_ratio
Value n means that 1 times in n we check.
Definition: txmempool.h:224
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:947
const std::chrono::seconds m_expiry
Definition: txmempool.h:355
void AddTransactionsUpdated(unsigned int n)
Definition: txmempool.cpp:146
void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs)
Sever link between specified transaction and direct children.
Definition: txmempool.cpp:94
bool CompareTopologically(const TxId &txida, const TxId &txidb) const
Definition: txmempool.cpp:504
TxMempoolInfo info(const TxId &txid) const
Definition: txmempool.cpp:687
const int64_t m_max_size_bytes
Definition: txmempool.h:354
void getAllTxIds(std::vector< TxId > &vtxid) const
Definition: txmempool.cpp:518
std::atomic< uint32_t > nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
Definition: txmempool.h:226
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:754
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:815
bool setAvalancheFinalized(const CTxMemPoolEntryRef &tx, const Consensus::Params &params, const CBlockIndex &active_chain_tip, std::vector< TxId > &finalizedTxIds) EXCLUSIVE_LOCKS_REQUIRED(bool isAvalancheFinalizedPreConsensus(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:541
std::vector< TxMempoolInfo > infoAll() const
Definition: txmempool.cpp:536
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:880
void UpdateParent(txiter entry, txiter parent, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:906
CTransactionRef GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
Definition: txmempool.cpp:740
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:198
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:849
bool isWorthPolling(const CTransactionRef &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs
Definition: txmempool.cpp:653
std::set< txiter, CompareIteratorByRevEntryId > setRevTopoEntries
Definition: txmempool.h:322
bool exists(const TxId &txid) const
Definition: txmempool.h:530
static const int ROLLING_FEE_HALFLIFE
Definition: txmempool.h:266
CTransactionRef get(const TxId &txid) const
Definition: txmempool.cpp:677
const CFeeRate m_min_relay_feerate
Definition: txmempool.h:356
void PrioritiseTransaction(const TxId &txid, const Amount nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
Definition: txmempool.cpp:707
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
Definition: txmempool.h:320
uint64_t GetAndIncrementSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Guards this internal counter for external reporting.
Definition: txmempool.h:581
void UpdateChild(txiter entry, txiter child, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:896
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:382
RadixTree< CTxMemPoolEntry, MemPoolEntryRadixTreeAdapter > finalizedTxs
Definition: txmempool.h:324
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void cs_main
Definition: txmempool.h:383
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:59
void removeForFinalizedBlock(const std::unordered_set< TxId, SaltedTxIdHasher > &confirmedTxIdsInNonFinalizedBlocks) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:329
void clear(bool include_finalized_txs=false)
Definition: txmempool.cpp:380
Mutex cs_conflicting
Definition: txmempool.h:260
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
Definition: txmempool.cpp:243
void RemoveStaged(const setEntries &stage, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove a set of transactions from the mempool.
Definition: txmempool.cpp:837
CTxMemPool(const Config &config, const Options &opts)
Create a new CTxMemPool.
Definition: txmempool.cpp:120
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:85
void ApplyDelta(const TxId &txid, Amount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:725
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:1027
std::optional< txiter > GetIter(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given txid, if found.
Definition: txmempool.cpp:745
bool isSpent(const COutPoint &outpoint) const
Definition: txmempool.cpp:137
unsigned int GetTransactionsUpdated() const
Definition: txmempool.cpp:142
void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:368
A UTXO entry.
Definition: coins.h:29
Definition: config.h:19
Definition: rcu.h:85
T * get()
Get allows to access the undelying pointer.
Definition: rcu.h:170
std::string ToString() const
Definition: validation.h:125
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:452
#define LogPrintf(...)
Definition: logging.h:424
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
@ AVALANCHE
Definition: logging.h:91
@ MEMPOOL
Definition: logging.h:71
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:195
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:28
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
Definition: memusage.h:124
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
Definition: memusage.h:74
Definition: init.h:31
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
Parameters that influence chain consensus.
Definition: params.h:34
RCUPtr< T > remove(const KeyType &key)
Remove an element from the tree.
Definition: radix.h:181
bool forEachLeaf(Callable &&func) const
Definition: radix.h:144
bool insert(const RCUPtr< T > &value)
Insert a value into the tree.
Definition: radix.h:112
A TxId is the identifier of a transaction.
Definition: txid.h:14
Information about a mempool transaction.
Definition: txmempool.h:137
Options struct containing options for constructing a CTxMemPool.
#define AssertLockNotHeld(cs)
Definition: sync.h:163
#define LOCK(cs)
Definition: sync.h:306
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
#define NO_THREAD_SAFETY_ANALYSIS
Definition: threadsafety.h:58
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition: time.cpp:105
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:68
bool ContextualCheckTransactionForCurrentBlock(const CBlockIndex &active_chain_tip, const Consensus::Params &params, const CTransaction &tx, TxValidationState &state)
Definition: tx_verify.cpp:73
std::string RemovalReasonToString(const MemPoolRemovalReason &r) noexcept
Definition: txmempool.cpp:1032
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
Definition: txmempool.cpp:530
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
Definition: txmempool.h:158
@ SIZELIMIT
Removed in size limiting.
@ BLOCK
Removed for block.
@ MANUAL
Manual removal via RPC.
@ 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:55
AssertLockHeld(pool.cs)
assert(!tx.IsCoinBase())
CMainSignals & GetMainSignals()