Bitcoin ABC 0.34.3
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 <validation.h> // For Chainstate
25#include <validationinterface.h>
26
27#include <algorithm>
28#include <cmath>
29#include <limits>
30#include <vector>
31
33 CTxMemPoolEntry::Parents &staged_ancestors,
34 bool unfinalizedOnly /* = false */) 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 if (unfinalizedOnly && isAvalancheFinalizedPreConsensus(
47 parent.get()->GetTx().GetId())) {
48 continue;
49 }
50 txiter parent_it = mapTx.find(parent.get()->GetTx().GetId());
51 assert(parent_it != mapTx.end());
52
53 // If this is a new ancestor, add it.
54 if (setAncestors.count(parent_it) == 0) {
55 staged_ancestors.insert(parent);
56 }
57 }
58 }
59}
60
62 const CTxMemPoolEntryRef &entry, setEntries &setAncestors,
63 bool unfinalizedOnly /* = false */) const {
64 CTxMemPoolEntry::Parents staged_ancestors;
65 // The entry must already be in the mempool, so its parent links are
66 // populated.
67 if (unfinalizedOnly) {
68 for (const auto &parent : entry->GetMemPoolParentsConst()) {
70 parent.get()->GetTx().GetId())) {
71 staged_ancestors.insert(parent);
72 }
73 }
74 } else {
75 staged_ancestors = entry->GetMemPoolParentsConst();
76 }
77
78 CalculateAncestors(setAncestors, staged_ancestors, unfinalizedOnly);
79}
80
82 // add or remove this tx as a child of each parent
83 for (const auto &parent : (*it)->GetMemPoolParentsConst()) {
84 auto parent_it = mapTx.find(parent.get()->GetTx().GetId());
85 assert(parent_it != mapTx.end());
86 UpdateChild(parent_it, it, add);
87 }
88}
89
91 const CTxMemPoolEntry::Children &children =
92 (*it)->GetMemPoolChildrenConst();
93 for (const auto &child : children) {
94 auto updateIt = mapTx.find(child.get()->GetTx().GetId());
95 assert(updateIt != mapTx.end());
96 UpdateParent(updateIt, it, false);
97 }
98}
99
101 for (txiter removeIt : entriesToRemove) {
102 // Note that UpdateParentsOf severs the child links that point to
103 // removeIt in the entries for the parents of removeIt.
104 UpdateParentsOf(false, removeIt);
105 }
106
107 // After updating all the parent links, we can now sever the link between
108 // each transaction being removed and any mempool children (ie, update
109 // CTxMemPoolEntry::m_parents for each direct child of a transaction being
110 // removed).
111 for (txiter removeIt : entriesToRemove) {
112 UpdateChildrenForRemoval(removeIt);
113 }
114}
115
117 : m_finalizedTxsFitter(node::BlockFitter(config)),
118 m_orphanage(std::make_unique<TxOrphanage>()),
119 m_conflicting(std::make_unique<TxConflicting>()),
120 m_opts{std::move(opts)} {
121 // lock free clear
122 _clear();
123}
124
125CTxMemPool::~CTxMemPool() = default;
126
127bool CTxMemPool::isSpent(const COutPoint &outpoint) const {
128 LOCK(cs);
129 return mapNextTx.count(outpoint);
130}
131
134}
135
138}
139
141 // get a guaranteed unique id (in case tests re-use the same object)
142 entry->SetEntryId(nextEntryId++);
143
144 // Update transaction for any feeDelta created by PrioritiseTransaction
145 {
146 Amount feeDelta = Amount::zero();
147 ApplyDelta(entry->GetTx().GetId(), feeDelta);
148 // The following call to UpdateModifiedFee assumes no previous fee
149 // modifications
150 Assume(entry->GetFee() == entry->GetModifiedFee());
151 entry->UpdateModifiedFee(feeDelta);
152 }
153
154 // Add to memory pool without checking anything.
155 // Used by AcceptToMemoryPool(), which DOES do all the appropriate checks.
156 auto [newit, inserted] = mapTx.insert(entry);
157 // Sanity check: It is a programming error if insertion fails (uniqueness
158 // invariants in mapTx are violated, etc)
159 assert(inserted);
160 // Sanity check: We should always end up inserting at the end of the
161 // entry_id index
162 assert(&*mapTx.get<entry_id>().rbegin() == &*newit);
163
164 // Update cachedInnerUsage to include contained transaction's usage.
165 // (When we update the entry for in-mempool parents, memory usage will be
166 // further updated.)
167 cachedInnerUsage += entry->DynamicMemoryUsage();
168
169 const CTransactionRef tx = entry->GetSharedTx();
170 std::set<TxId> setParentTransactions;
171 for (const CTxIn &in : tx->vin) {
172 mapNextTx.insert(std::make_pair(&in.prevout, tx));
173 setParentTransactions.insert(in.prevout.GetTxId());
174 }
175 // Don't bother worrying about child transactions of this one. It is
176 // guaranteed that a new transaction arriving will not have any children,
177 // because such children would be orphans.
178
179 // Update ancestors with information about this tx
180 for (const auto &pit : GetIterSet(setParentTransactions)) {
181 UpdateParent(newit, pit, true);
182 }
183
184 UpdateParentsOf(true, newit);
185
187 totalTxSize += entry->GetTxSize();
188 m_total_fee += entry->GetFee();
189}
190
192 // We increment mempool sequence value no matter removal reason
193 // even if not directly reported below.
194 uint64_t mempool_sequence = GetAndIncrementSequence();
195
196 const TxId &txid = (*it)->GetTx().GetId();
197
198 if (reason != MemPoolRemovalReason::BLOCK) {
199 if (m_opts.signals) {
200 // Notify clients that a transaction has been removed from the
201 // mempool for any reason except being included in a block. Clients
202 // interested in transactions included in blocks can subscribe to
203 // the BlockConnected notification.
205 (*it)->GetSharedTx(), reason, mempool_sequence);
206 }
207
208 if (auto removed_tx = finalizedTxs.remove(txid)) {
209 m_finalizedTxsFitter.removeTxUnchecked(removed_tx->GetTxSize(),
210 removed_tx->GetSigChecks(),
211 removed_tx->GetFee());
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 // We reject blocks that contains a tx conflicting with a
305 // finalized tx, so this should never happen
306 Assume(!isAvalancheFinalizedPreConsensus(txConflict.GetId()));
307 ClearPrioritisation(txConflict.GetId());
309 }
310 }
311 }
312}
313
319 lastRollingFeeUpdate = GetTime();
320 blockSinceLastRollingFeeBump = true;
321}
322
324 const std::unordered_set<TxId, SaltedTxIdHasher>
325 &confirmedTxIdsInNonFinalizedBlocks) {
327
328 std::vector<CTxMemPoolEntryRef> finalizedTxsToKeep;
331 if (mapTx.count(entry->GetTx().GetId()) > 0 ||
332 confirmedTxIdsInNonFinalizedBlocks.count(
333 entry->GetTx().GetId()) > 0) {
334 // The transaction is either in the mempool (not confirmed) or
335 // confirmed in a non-finalized block (which might be rejeted by
336 // avalanche), so we keep it in the radix tree.
337 finalizedTxsToKeep.push_back(entry);
338 }
339
340 // All the other transactions are either confirmed in the finalized
341 // block or in one of its ancestors.
342 return true;
343 });
344
345 // Clear the radix tree and add back the transactions that are not confirmed
346 decltype(finalizedTxs) empty;
347 std::swap(finalizedTxs, empty);
348
349 m_finalizedTxsFitter.resetBlock();
350 for (const auto &entry : finalizedTxsToKeep) {
351 // We don't need to proceed to all the checks that happen during
352 // finalization here so we only recompute the size and sigchecks.
353 if (finalizedTxs.insert(entry)) {
354 m_finalizedTxsFitter.addTx(entry->GetTxSize(),
355 entry->GetSigChecks(), entry->GetFee());
356 }
357 }
358
360}
361
363 mapTx.clear();
364 mapNextTx.clear();
365 totalTxSize = 0;
366 m_total_fee = Amount::zero();
367 cachedInnerUsage = 0;
368 lastRollingFeeUpdate = GetTime();
369 blockSinceLastRollingFeeBump = false;
370 rollingMinimumFeeRate = 0;
372}
373
374void CTxMemPool::clear(bool include_finalized_txs) {
375 LOCK(cs);
376 _clear();
377 if (include_finalized_txs) {
379 std::swap(finalizedTxs, empty);
380 m_finalizedTxsFitter.resetBlock();
381 }
382}
383
384void CTxMemPool::check(const CCoinsViewCache &active_coins_tip,
385 int64_t spendheight) const {
386 if (m_opts.check_ratio == 0) {
387 return;
388 }
389
390 if (FastRandomContext().randrange(m_opts.check_ratio) >= 1) {
391 return;
392 }
393
395 LOCK(cs);
397 "Checking mempool with %u transactions and %u inputs\n",
398 (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
399
400 uint64_t checkTotal = 0;
401 Amount check_total_fee{Amount::zero()};
402 uint64_t innerUsage = 0;
403
404 CCoinsViewCache mempoolDuplicate(
405 const_cast<CCoinsViewCache *>(&active_coins_tip));
406
407 for (const CTxMemPoolEntryRef &entry : mapTx.get<entry_id>()) {
408 checkTotal += entry->GetTxSize();
409 check_total_fee += entry->GetFee();
410 innerUsage += entry->DynamicMemoryUsage();
411 const CTransaction &tx = entry->GetTx();
412 innerUsage += memusage::DynamicUsage(entry->GetMemPoolParentsConst()) +
413 memusage::DynamicUsage(entry->GetMemPoolChildrenConst());
414
415 CTxMemPoolEntry::Parents setParentCheck;
416 for (const CTxIn &txin : tx.vin) {
417 // Check that every mempool transaction's inputs refer to available
418 // coins, or other mempool tx's.
419 txiter parentIt = mapTx.find(txin.prevout.GetTxId());
420 if (parentIt != mapTx.end()) {
421 const CTransaction &parentTx = (*parentIt)->GetTx();
422 assert(parentTx.vout.size() > txin.prevout.GetN() &&
423 !parentTx.vout[txin.prevout.GetN()].IsNull());
424 setParentCheck.insert(*parentIt);
425 // also check that parents have a topological ordering before
426 // their children
427 assert((*parentIt)->GetEntryId() < entry->GetEntryId());
428 }
429 // We are iterating through the mempool entries sorted
430 // topologically.
431 // All parents must have been checked before their children and
432 // their coins added to the mempoolDuplicate coins cache.
433 assert(mempoolDuplicate.HaveCoin(txin.prevout));
434 // Check whether its inputs are marked in mapNextTx.
435 auto prevoutNextIt = mapNextTx.find(txin.prevout);
436 assert(prevoutNextIt != mapNextTx.end());
437 assert(prevoutNextIt->first == &txin.prevout);
438 assert(prevoutNextIt->second.get() == &tx);
439 }
440 auto comp = [](const auto &a, const auto &b) -> bool {
441 return a.get()->GetTx().GetId() == b.get()->GetTx().GetId();
442 };
443 assert(setParentCheck.size() == entry->GetMemPoolParentsConst().size());
444 assert(std::equal(setParentCheck.begin(), setParentCheck.end(),
445 entry->GetMemPoolParentsConst().begin(), comp));
446
447 // Verify ancestor state is correct.
448 setEntries setAncestors;
449 CalculateMemPoolAncestors(entry, setAncestors);
450
451 // all ancestors should have entryId < this tx's entryId
452 for (const auto &ancestor : setAncestors) {
453 assert((*ancestor)->GetEntryId() < entry->GetEntryId());
454 }
455
456 // Check children against mapNextTx
457 CTxMemPoolEntry::Children setChildrenCheck;
458 auto iter = mapNextTx.lower_bound(COutPoint(entry->GetTx().GetId(), 0));
459 for (; iter != mapNextTx.end() &&
460 iter->first->GetTxId() == entry->GetTx().GetId();
461 ++iter) {
462 txiter childIt = mapTx.find(iter->second->GetId());
463 // mapNextTx points to in-mempool transactions
464 assert(childIt != mapTx.end());
465 setChildrenCheck.insert(*childIt);
466 }
467 assert(setChildrenCheck.size() ==
468 entry->GetMemPoolChildrenConst().size());
469 assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(),
470 entry->GetMemPoolChildrenConst().begin(), comp));
471
472 // Not used. CheckTxInputs() should always pass
473 TxValidationState dummy_state;
474 Amount txfee{Amount::zero()};
475 assert(!tx.IsCoinBase());
476 assert(Consensus::CheckTxInputs(tx, dummy_state, mempoolDuplicate,
477 spendheight, txfee));
478 for (const auto &input : tx.vin) {
479 mempoolDuplicate.SpendCoin(input.prevout);
480 }
481 AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
482 }
483
484 for (auto &[_, nextTx] : mapNextTx) {
485 txiter it = mapTx.find(nextTx->GetId());
486 assert(it != mapTx.end());
487 assert((*it)->GetSharedTx() == nextTx);
488 }
489
490 assert(totalTxSize == checkTotal);
491 assert(m_total_fee == check_total_fee);
492 assert(innerUsage == cachedInnerUsage);
493}
494
496 const TxId &txidb) const {
497 LOCK(cs);
498 auto it1 = mapTx.find(txida);
499 if (it1 == mapTx.end()) {
500 return false;
501 }
502 auto it2 = mapTx.find(txidb);
503 if (it2 == mapTx.end()) {
504 return true;
505 }
506 return (*it1)->GetEntryId() < (*it2)->GetEntryId();
507}
508
509void CTxMemPool::getAllTxIds(std::vector<TxId> &vtxid) const {
510 LOCK(cs);
511
512 vtxid.clear();
513 vtxid.reserve(mapTx.size());
514
515 for (const auto &entry : mapTx.get<entry_id>()) {
516 vtxid.push_back(entry->GetTx().GetId());
517 }
518}
519
520static TxMempoolInfo
521GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
522 return TxMempoolInfo{(*it)->GetSharedTx(), (*it)->GetTime(),
523 (*it)->GetFee(), (*it)->GetTxSize(),
524 (*it)->GetModifiedFee() - (*it)->GetFee()};
525}
526
527std::vector<TxMempoolInfo> CTxMemPool::infoAll() const {
528 LOCK(cs);
529
530 std::vector<TxMempoolInfo> ret;
531 ret.reserve(mapTx.size());
532
533 const auto &index = mapTx.get<entry_id>();
534 for (auto it = index.begin(); it != index.end(); ++it) {
535 ret.push_back(GetInfo(mapTx.project<0>(it)));
536 }
537
538 return ret;
539}
540
541bool CTxMemPool::setAvalancheFinalized(const CTxMemPoolEntryRef &tx,
542 const Consensus::Params &params,
543 const CBlockIndex &active_chain_tip,
544 Chainstate &active_chainstate,
545 std::vector<TxId> &finalizedTxIds) {
548
549 auto it = mapTx.find(tx->GetTx().GetId());
550 if (it == mapTx.end()) {
551 // Trying to finalize a tx that is not in the mempool !
552 LogPrintf("Trying to finalize tx %s that is not in the mempool\n",
553 tx->GetTx().GetId().ToString());
554 return false;
555 }
556
557 if (isAvalancheFinalizedPreConsensus(tx->GetTx().GetId())) {
558 finalizedTxIds.clear();
559 return true;
560 }
561
562 setEntries setAncestors;
563 setAncestors.insert(it);
564 CalculateMemPoolAncestors(tx, setAncestors, /*unfinalizedOnly=*/true);
565
566 // Make sure the unfinalized tx chain would fit the block before adding
567 // them.
568 uint64_t sumOfTxSize{0};
569 uint64_t sumOfTxSigChecks{0};
570 for (txiter ancestor_it : setAncestors) {
571 const CTxMemPoolEntryRef &entry = *ancestor_it;
572
573 TxValidationState state;
574 if (!ContextualCheckTransactionForCurrentBlock(active_chain_tip, params,
575 entry->GetTx(), state)) {
577 "Delay storing finalized tx %s that would cause the block "
578 "to be invalid%s (%s)\n",
579 tx->GetTx().GetId().ToString(),
580 entry->GetSharedTx()->GetId() == tx->GetSharedTx()->GetId()
581 ? ""
582 : strprintf(" for parent %s",
583 entry->GetSharedTx()->GetId().ToString()),
584 state.ToString());
585 return false;
586 }
587
588 if (m_finalizedTxsFitter.isBelowBlockMinFeeRate(
589 entry->GetModifiedFeeRate())) {
591 "Delay storing finalized tx %s due to fee rate below the "
592 "block mininmum%s (see -blockmintxfee)\n",
593 tx->GetTx().GetId().ToString(),
594 entry->GetSharedTx()->GetId() == tx->GetSharedTx()->GetId()
595 ? ""
596 : strprintf(" for parent %s",
597 entry->GetSharedTx()->GetId().ToString()));
598 return false;
599 }
600
601 // Avoid transient state by delaying finalization until the block that
602 // spends the coin is avalanche-finalized.
603 for (const CTxIn &txin : entry->GetTx().vin) {
604 // Mempool parent
605 if (mapTx.count(txin.prevout.GetTxId()) != 0) {
606 continue;
607 }
608
609 const Coin &coin =
610 active_chainstate.CoinsTip().AccessCoin(txin.prevout);
611 if (coin.IsSpent()) {
612 // Coin is empty, aka not in the UTXO set. Should never happen
613 // outside of tests.
614 continue;
615 }
616
617 const CBlockIndex *pindex =
618 active_chainstate.m_chain[coin.GetHeight()];
619 if (!active_chainstate.IsBlockAvalancheFinalized(pindex)) {
620 LogDebug(
622 "Delay storing finalized tx %s as it spends a "
623 "coin from a non-finalized block%s\n",
624 tx->GetTx().GetId().ToString(),
625 entry->GetSharedTx()->GetId() == tx->GetSharedTx()->GetId()
626 ? ""
627 : strprintf(" for parent %s",
628 entry->GetSharedTx()->GetId().ToString()));
629 return false;
630 }
631 }
632
633 sumOfTxSize += entry->GetTxSize();
634 sumOfTxSigChecks += entry->GetSigChecks();
635 }
636
637 if (!m_finalizedTxsFitter.testTxFits(sumOfTxSize, sumOfTxSigChecks)) {
638 LogDebug(
640 "Delay storing finalized tx %s as it won't fit in the next block\n",
641 tx->GetTx().GetId().ToString());
642 return false;
643 }
644
645 finalizedTxIds.clear();
646
647 // Now let's add the txs !
648 // At this stage the set of ancestors is free of already finalized txs
649 for (txiter ancestor_it : setAncestors) {
650 if (finalizedTxs.insert(*ancestor_it)) {
651 m_finalizedTxsFitter.addTx((*ancestor_it)->GetTxSize(),
652 (*ancestor_it)->GetSigChecks(),
653 (*ancestor_it)->GetFee());
654
655 finalizedTxIds.push_back((*ancestor_it)->GetTx().GetId());
656
657 if (m_opts.signals) {
659 (*ancestor_it)->GetSharedTx());
660 }
661 }
662 }
663
665
666 return true;
667}
668
672
673 const TxId &txid = tx->GetId();
674 if (auto it = GetIter(txid)) {
675 CTxMemPoolEntryRef entry = **it;
676
677 // The tx is in the mempool, check it would fit the next block or if
678 // it's already full of finalized txs.
679 return !m_finalizedTxsFitter.isBelowBlockMinFeeRate(
680 entry->GetModifiedFeeRate()) &&
681 m_finalizedTxsFitter.testTxFits(entry->GetTxSize(),
682 entry->GetSigChecks());
683 }
684
685 // Otherwise check if it's in the conflicting pool. If we reach this point
686 // this means that the transaction has been rejected so no need to check if
687 // it fits the block, however we don't want to discard it either so the vote
688 // continue until the tx is invalidated.
690 return m_conflicting && m_conflicting->HaveTx(txid));
691}
692
694 LOCK(cs);
695 indexed_transaction_set::const_iterator i = mapTx.find(txid);
696 if (i == mapTx.end()) {
697 return nullptr;
698 }
699
700 return (*i)->GetSharedTx();
701}
702
704 LOCK(cs);
705 indexed_transaction_set::const_iterator i = mapTx.find(txid);
706 if (i == mapTx.end()) {
707 return TxMempoolInfo();
708 }
709
710 return GetInfo(i);
711}
712
714 LOCK(cs);
715
716 // minerPolicy uses recent blocks to figure out a reasonable fee. This
717 // may disagree with the rollingMinimumFeerate under certain scenarios
718 // where the mempool increases rapidly, or blocks are being mined which
719 // do not contain propagated transactions.
720 return std::max(m_opts.min_relay_feerate, GetMinFee());
721}
722
724 const Amount nFeeDelta) {
725 {
726 LOCK(cs);
727 Amount &delta = mapDeltas[txid];
728 delta.SaturatingAdd(nFeeDelta);
729 txiter it = mapTx.find(txid);
730 if (it != mapTx.end()) {
731 mapTx.modify(it, [&nFeeDelta](CTxMemPoolEntryRef &e) {
732 e->UpdateModifiedFee(nFeeDelta);
733 });
735 }
736 }
737 LogPrintf("PrioritiseTransaction: %s fee += %s\n", txid.ToString(),
738 FormatMoney(nFeeDelta));
739}
740
741void CTxMemPool::ApplyDelta(const TxId &txid, Amount &nFeeDelta) const {
743 std::map<TxId, Amount>::const_iterator pos = mapDeltas.find(txid);
744 if (pos == mapDeltas.end()) {
745 return;
746 }
747
748 nFeeDelta += pos->second;
749}
750
753 mapDeltas.erase(txid);
754}
755
756CTransactionRef CTxMemPool::GetConflictTx(const COutPoint &prevout) const {
757 const auto it = mapNextTx.find(prevout);
758 return it == mapNextTx.end() ? nullptr : it->second;
759}
760
761std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const TxId &txid) const {
762 auto it = mapTx.find(txid);
763 if (it != mapTx.end()) {
764 return it;
765 }
766 return std::nullopt;
767}
768
770CTxMemPool::GetIterSet(const std::set<TxId> &txids) const {
772 for (const auto &txid : txids) {
773 const auto mi = GetIter(txid);
774 if (mi) {
775 ret.insert(*mi);
776 }
777 }
778 return ret;
779}
780
781bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const {
782 for (const CTxIn &in : tx.vin) {
783 if (exists(in.prevout.GetTxId())) {
784 return false;
785 }
786 }
787
788 return true;
789}
790
792 const CTxMemPool &mempoolIn)
793 : CCoinsViewBacked(baseIn), mempool(mempoolIn) {}
794
795std::optional<Coin>
796CCoinsViewMemPool::GetCoin(const COutPoint &outpoint) const {
797 // Check to see if the inputs are made available by another tx in the
798 // package. These Coins would not be available in the underlying CoinsView.
799 if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) {
800 return it->second;
801 }
802
803 // If an entry in the mempool exists, always return that one, as it's
804 // guaranteed to never conflict with the underlying cache, and it cannot
805 // have pruned entries (as it contains full) transactions. First checking
806 // the underlying cache risks returning a pruned entry instead.
807 CTransactionRef ptx = mempool.get(outpoint.GetTxId());
808 if (ptx) {
809 if (outpoint.GetN() < ptx->vout.size()) {
810 Coin coin(ptx->vout[outpoint.GetN()], MEMPOOL_HEIGHT, false);
811 m_non_base_coins.emplace(outpoint);
812 return coin;
813 }
814 return std::nullopt;
815 }
816 return base->GetCoin(outpoint);
817}
818
820 for (uint32_t n = 0; n < tx->vout.size(); ++n) {
821 m_temp_added.emplace(COutPoint(tx->GetId(), n),
822 Coin(tx->vout[n], MEMPOOL_HEIGHT, false));
823 m_non_base_coins.emplace(COutPoint(tx->GetId(), n));
824 }
825}
827 m_temp_added.clear();
828 m_non_base_coins.clear();
829}
830
832 LOCK(cs);
833 // Estimate the overhead of mapTx to be 12 pointers + an allocation, as no
834 // exact formula for boost::multi_index_contained is implemented.
836 12 * sizeof(void *)) *
837 mapTx.size() +
838 memusage::DynamicUsage(mapNextTx) +
839 memusage::DynamicUsage(mapDeltas) + cachedInnerUsage;
840}
841
842void CTxMemPool::RemoveUnbroadcastTx(const TxId &txid, const bool unchecked) {
843 LOCK(cs);
844
845 if (m_unbroadcast_txids.erase(txid)) {
846 LogDebug(
847 BCLog::MEMPOOL, "Removed %i from set of unbroadcast txns%s\n",
848 txid.GetHex(),
849 (unchecked ? " before confirmation that txn was sent out" : ""));
850 }
851}
852
854 MemPoolRemovalReason reason) {
857
858 // Remove txs in reverse-topological order
859 const setRevTopoEntries stageRevTopo(stage.begin(), stage.end());
860 for (txiter it : stageRevTopo) {
861 removeUnchecked(it, reason);
862 }
863}
864
865int CTxMemPool::Expire(std::chrono::seconds time) {
867 indexed_transaction_set::index<entry_time>::type::iterator it =
868 mapTx.get<entry_time>().begin();
869 setEntries toremove;
870 size_t skippedFinalizedTxs{0};
871 while (it != mapTx.get<entry_time>().end() && (*it)->GetTime() < time) {
872 if (isAvalancheFinalizedPreConsensus((*it)->GetTx().GetId())) {
873 // Don't expire finalized transactions
874 ++skippedFinalizedTxs;
875 } else {
876 toremove.insert(mapTx.project<0>(it));
877 }
878
879 it++;
880 }
881
882 if (skippedFinalizedTxs > 0) {
883 LogDebug(BCLog::MEMPOOL, "Not expiring %u finalized transaction\n",
884 skippedFinalizedTxs);
885 }
886
887 setEntries stage;
888 for (txiter removeit : toremove) {
889 CalculateDescendants(removeit, stage);
890 }
891
893 return stage.size();
894}
895
899 int expired = Expire(GetTime<std::chrono::seconds>() - m_opts.expiry);
900 if (expired != 0) {
902 "Expired %i transactions from the memory pool\n", expired);
903 }
904
905 std::vector<COutPoint> vNoSpendsRemaining;
906 TrimToSize(m_opts.max_size_bytes, &vNoSpendsRemaining);
907 for (const COutPoint &removed : vNoSpendsRemaining) {
908 coins_cache.Uncache(removed);
909 }
910}
911
912void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add) {
915 if (add && (*entry)->GetMemPoolChildren().insert(*child).second) {
916 cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
917 } else if (!add && (*entry)->GetMemPoolChildren().erase(*child)) {
918 cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
919 }
920}
921
922void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add) {
925 if (add && (*entry)->GetMemPoolParents().insert(*parent).second) {
926 cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
927 } else if (!add && (*entry)->GetMemPoolParents().erase(*parent)) {
928 cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
929 }
930}
931
932CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
933 LOCK(cs);
934 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0) {
935 return CFeeRate(int64_t(ceill(rollingMinimumFeeRate)) * SATOSHI);
936 }
937
938 int64_t time = GetTime();
939 if (time > lastRollingFeeUpdate + 10) {
940 double halflife = ROLLING_FEE_HALFLIFE;
941 if (DynamicMemoryUsage() < sizelimit / 4) {
942 halflife /= 4;
943 } else if (DynamicMemoryUsage() < sizelimit / 2) {
944 halflife /= 2;
945 }
946
947 rollingMinimumFeeRate =
948 rollingMinimumFeeRate /
949 pow(2.0, (time - lastRollingFeeUpdate) / halflife);
950 lastRollingFeeUpdate = time;
951 }
952 return CFeeRate(int64_t(ceill(rollingMinimumFeeRate)) * SATOSHI);
953}
954
957 if ((rate.GetFeePerK() / SATOSHI) > rollingMinimumFeeRate) {
958 rollingMinimumFeeRate = rate.GetFeePerK() / SATOSHI;
959 blockSinceLastRollingFeeBump = false;
960 }
961}
962
963void CTxMemPool::TrimToSize(size_t sizelimit,
964 std::vector<COutPoint> *pvNoSpendsRemaining) {
966
967 unsigned nTxnRemoved = 0;
968 size_t finalizedTxsSkipped = 0;
969 CFeeRate maxFeeRateRemoved(Amount::zero());
970 while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) {
971 auto &by_modified_feerate = mapTx.get<modified_feerate>();
972 // Lowest fee first
973 auto rit = by_modified_feerate.rbegin();
974
975 // We don't evict finalized transactions, even if they have lower fee
976 while (isAvalancheFinalizedPreConsensus((*rit)->GetTx().GetId())) {
977 ++finalizedTxsSkipped;
978 ++rit;
979 if (rit == by_modified_feerate.rend()) {
980 // Nothing we can trim
981 break;
982 }
983 }
984
985 // Convert to forward iterator.
986 // If rit == rend(), the forward iterator will be equivalent to begin()
987 // and we can't decrement it, there is nothing to remove. This could
988 // only happen if all the transactions are finalized, which in turns
989 // implies that the mempool cannot contain a block worth of txs.
990 // In this case we still exit the loop so we get the proper log message.
991 if (rit == by_modified_feerate.rend()) {
992 break;
993 }
994 auto it = rit.base();
995 --it;
996
997 // We set the new mempool min fee to the feerate of the removed
998 // transaction, plus the "minimum reasonable fee rate" (ie some value
999 // under which we consider txn to have 0 fee). This way, we don't allow
1000 // txn to enter mempool with feerate equal to txn which were removed
1001 // with no block in between.
1002 CFeeRate removed = (*it)->GetModifiedFeeRate();
1003 removed += MEMPOOL_FULL_FEE_INCREMENT;
1004
1005 trackPackageRemoved(removed);
1006 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
1007
1008 setEntries stage;
1009 CalculateDescendants(mapTx.project<0>(it), stage);
1010 nTxnRemoved += stage.size();
1011
1012 if (pvNoSpendsRemaining) {
1013 for (const txiter &iter : stage) {
1014 for (const CTxIn &txin : (*iter)->GetTx().vin) {
1015 if (!exists(txin.prevout.GetTxId())) {
1016 pvNoSpendsRemaining->push_back(txin.prevout);
1017 }
1018 }
1019 }
1020 }
1021
1023 }
1024
1025 if (maxFeeRateRemoved > CFeeRate(Amount::zero())) {
1027 "Removed %u txn, rolling minimum fee bumped to %s\n",
1028 nTxnRemoved, maxFeeRateRemoved.ToString());
1029 }
1030
1031 if (finalizedTxsSkipped > 0) {
1033 "Not evicting %u finalized txn for low fee\n",
1034 finalizedTxsSkipped);
1035 }
1036}
1037
1039 LOCK(cs);
1040 return m_load_tried;
1041}
1042
1043void CTxMemPool::SetLoadTried(bool load_tried) {
1044 LOCK(cs);
1045 m_load_tried = load_tried;
1046}
1047
1048std::string RemovalReasonToString(const MemPoolRemovalReason &r) noexcept {
1049 switch (r) {
1051 return "expiry";
1053 return "sizelimit";
1055 return "reorg";
1057 return "block";
1059 return "conflict";
1061 return "avalanche";
1063 return "manual";
1064 }
1065 assert(false);
1066}
static constexpr Amount SATOSHI
Definition: amount.h:153
#define Assume(val)
Assume is the identity function.
Definition: check.h:100
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:337
CCoinsView * base
Definition: coins.h:339
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:357
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:337
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:199
Abstract view on the open txout dataset.
Definition: coins.h:303
virtual std::optional< Coin > GetCoin(const COutPoint &outpoint) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:13
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
GetCoin, returning whether it exists and is not spent.
Definition: txmempool.cpp:796
void Reset()
Clear m_temp_added and m_non_base_coins.
Definition: txmempool.cpp:826
std::unordered_map< COutPoint, Coin, SaltedOutpointHasher > m_temp_added
Coins made available by transactions being validated.
Definition: txmempool.h:656
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
Definition: txmempool.cpp:791
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:664
void PackageAddTransaction(const CTransactionRef &tx)
Add the coins created by this transaction.
Definition: txmempool.cpp:819
const CTxMemPool & mempool
Definition: txmempool.h:667
Fee rate in satoshis per virtualbyte: Amount / vB the feerate is represented internally as FeeFrac.
Definition: feerate.h:24
std::string ToString() const
Definition: feerate.cpp:43
Amount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:55
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:222
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:296
CFeeRate estimateFee() const
Definition: txmempool.cpp:713
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:781
void ClearPrioritisation(const TxId &txid) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:751
std::set< txiter, CompareIteratorById > setEntries
Definition: txmempool.h:320
void CalculateAncestors(setEntries &setAncestors, CTxMemPoolEntry::Parents &staged_ancestors, bool unfinalizedOnly=false) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Helper function to calculate all in-mempool ancestors of staged_ancestors.
Definition: txmempool.cpp:32
void RemoveUnbroadcastTx(const TxId &txid, const bool unchecked=false)
Removes a transaction from the unbroadcast set.
Definition: txmempool.cpp:842
bool GetLoadTried() const
Definition: txmempool.cpp:1038
void updateFeeForBlock() EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
Definition: txmempool.cpp:317
CFeeRate GetMinFee() const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
Definition: txmempool.h:460
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:316
void trackPackageRemoved(const CFeeRate &rate) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:955
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:100
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:963
void AddTransactionsUpdated(unsigned int n)
Definition: txmempool.cpp:136
void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs)
Sever link between specified transaction and direct children.
Definition: txmempool.cpp:90
bool setAvalancheFinalized(const CTxMemPoolEntryRef &tx, const Consensus::Params &params, const CBlockIndex &active_chain_tip, Chainstate &active_chainstate, std::vector< TxId > &finalizedTxIds) EXCLUSIVE_LOCKS_REQUIRED(bool isAvalancheFinalizedPreConsensus(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.h:544
bool CompareTopologically(const TxId &txida, const TxId &txidb) const
Definition: txmempool.cpp:495
TxMempoolInfo info(const TxId &txid) const
Definition: txmempool.cpp:703
void getAllTxIds(std::vector< TxId > &vtxid) const
Definition: txmempool.cpp:509
std::atomic< uint32_t > nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
Definition: txmempool.h:225
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:770
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:831
const Options m_opts
Definition: txmempool.h:356
std::vector< TxMempoolInfo > infoAll() const
Definition: txmempool.cpp:527
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:896
void UpdateParent(txiter entry, txiter parent, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:922
CTransactionRef GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
Definition: txmempool.cpp:756
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:191
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:865
bool isWorthPolling(const CTransactionRef &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs
Definition: txmempool.cpp:669
std::set< txiter, CompareIteratorByRevEntryId > setRevTopoEntries
Definition: txmempool.h:321
bool exists(const TxId &txid) const
Definition: txmempool.h:532
static const int ROLLING_FEE_HALFLIFE
Definition: txmempool.h:265
CTransactionRef get(const TxId &txid) const
Definition: txmempool.cpp:693
void PrioritiseTransaction(const TxId &txid, const Amount nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
Definition: txmempool.cpp:723
CTxMemPool(const Config &config, Options opts)
Create a new CTxMemPool.
Definition: txmempool.cpp:116
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
Definition: txmempool.h:319
uint64_t GetAndIncrementSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Guards this internal counter for external reporting.
Definition: txmempool.h:584
void UpdateChild(txiter entry, txiter child, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:912
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:378
RadixTree< CTxMemPoolEntry, MemPoolEntryRadixTreeAdapter > finalizedTxs
Definition: txmempool.h:323
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void cs_main
Definition: txmempool.h:379
void CalculateMemPoolAncestors(const CTxMemPoolEntryRef &entry, setEntries &setAncestors, bool unfinalizedOnly=false) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Calculate all in-mempool ancestors of entry.
Definition: txmempool.cpp:61
void removeForFinalizedBlock(const std::unordered_set< TxId, SaltedTxIdHasher > &confirmedTxIdsInNonFinalizedBlocks) EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:323
void clear(bool include_finalized_txs=false)
Definition: txmempool.cpp:374
Mutex cs_conflicting
Definition: txmempool.h:259
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:853
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:81
void ApplyDelta(const TxId &txid, Amount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:741
void SetLoadTried(bool load_tried)
Set whether or not an initial attempt to load the persisted mempool was made (regardless of whether t...
Definition: txmempool.cpp:1043
std::optional< txiter > GetIter(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given txid, if found.
Definition: txmempool.cpp:761
bool isSpent(const COutPoint &outpoint) const
Definition: txmempool.cpp:127
unsigned int GetTransactionsUpdated() const
Definition: txmempool.cpp:132
void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:362
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:727
bool IsBlockAvalancheFinalized(const CBlockIndex *pindex) const EXCLUSIVE_LOCKS_REQUIRED(!cs_avalancheFinalizedBlockIndex)
Checks if a block is finalized by avalanche voting.
CChain m_chain
The current chain of blockheaders we consult and build on.
Definition: validation.h:826
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
Definition: validation.h:853
A UTXO entry.
Definition: coins.h:31
uint32_t GetHeight() const
Definition: coins.h:48
bool IsSpent() const
Definition: coins.h:50
Definition: config.h:19
Fast randomness source.
Definition: random.h:411
Definition: rcu.h:85
T * get()
Get allows to access the undelying pointer.
Definition: rcu.h:170
void TransactionFinalized(const CTransactionRef &tx)
void TransactionRemovedFromMempool(const CTransactionRef &, MemPoolRemovalReason, uint64_t mempool_sequence)
std::string ToString() const
Definition: validation.h:125
std::string ToString() const
Definition: uint256.h:117
std::string GetHex() const
Definition: uint256.cpp:10
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:157
#define LogDebug(category,...)
Definition: logging.h:446
#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:190
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: messages.h:12
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
static const 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
Definition: amount.h:23
void SaturatingAdd(const Amount &other) noexcept
Amount addition with integer saturation.
Definition: amount.cpp:57
static constexpr Amount zero() noexcept
Definition: amount.h:36
Parameters that influence chain consensus.
Definition: params.h:34
RCUPtr< T > remove(const KeyType &key)
Remove an element from the tree.
Definition: radix.h:180
bool forEachLeaf(Callable &&func) const
Definition: radix.h:143
bool insert(const RCUPtr< T > &value)
Insert a value into the tree.
Definition: radix.h:111
A TxId is the identifier of a transaction.
Definition: txid.h:14
Information about a mempool transaction.
Definition: txmempool.h:138
Options struct containing options for constructing a CTxMemPool.
int check_ratio
The ratio used to determine how often sanity checks will run.
ValidationSignals * signals
CFeeRate min_relay_feerate
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
std::chrono::seconds expiry
#define AssertLockNotHeld(cs)
Definition: sync.h:163
#define LOCK(cs)
Definition: sync.h:295
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:343
#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:80
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1203
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:72
std::string RemovalReasonToString(const MemPoolRemovalReason &r) noexcept
Definition: txmempool.cpp:1048
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
Definition: txmempool.cpp:521
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
Definition: txmempool.h:159
@ 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:56
AssertLockHeld(pool.cs)
assert(!tx.IsCoinBase())