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