35 while (!staged_ancestors.empty()) {
36 const auto stage = staged_ancestors.begin()->get();
38 txiter stageit = mapTx.find(stage->GetTx().GetId());
39 assert(stageit != mapTx.end());
40 setAncestors.insert(stageit);
41 staged_ancestors.erase(staged_ancestors.begin());
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());
50 if (setAncestors.count(parent_it) == 0) {
51 staged_ancestors.insert(parent);
68 for (
const auto &parent : (*it)->GetMemPoolParentsConst()) {
69 auto parent_it = mapTx.find(parent.get()->GetTx().GetId());
70 assert(parent_it != mapTx.end());
77 (*it)->GetMemPoolChildrenConst();
78 for (
const auto &child : children) {
79 auto updateIt = mapTx.find(child.get()->GetTx().GetId());
80 assert(updateIt != mapTx.end());
86 for (
txiter removeIt : entriesToRemove) {
96 for (
txiter removeIt : entriesToRemove) {
102 : m_finalizedTxsFitter(
node::BlockFitter(config)),
105 m_opts{
std::move(opts)} {
114 return mapNextTx.count(outpoint);
127 entry->SetEntryId(nextEntryId++);
135 Assume(entry->GetFee() == entry->GetModifiedFee());
136 entry->UpdateModifiedFee(feeDelta);
141 auto [newit, inserted] = mapTx.insert(entry);
152 cachedInnerUsage += entry->DynamicMemoryUsage();
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());
165 for (
const auto &pit :
GetIterSet(setParentTransactions)) {
172 totalTxSize += entry->GetTxSize();
173 m_total_fee += entry->GetFee();
181 const TxId &txid = (*it)->GetTx().GetId();
190 (*it)->GetSharedTx(), reason, mempool_sequence);
194 m_finalizedTxsFitter.removeTxUnchecked(removed_tx->GetTxSize(),
195 removed_tx->GetSigChecks(),
196 removed_tx->GetFee());
200 for (
const CTxIn &txin : (*it)->GetTx().vin) {
201 mapNextTx.erase(txin.prevout);
207 totalTxSize -= (*it)->GetTxSize();
208 m_total_fee -= (*it)->GetFee();
209 cachedInnerUsage -= (*it)->DynamicMemoryUsage();
226 if (setDescendants.count(entryit) == 0) {
227 stage.insert(entryit);
232 while (!stage.empty()) {
233 txiter it = *stage.begin();
234 setDescendants.insert(it);
235 stage.erase(stage.begin());
238 (*it)->GetMemPoolChildrenConst();
239 for (
const auto &child : children) {
240 txiter childiter = mapTx.find(child.get()->GetTx().GetId());
241 assert(childiter != mapTx.end());
243 if (!setDescendants.count(childiter)) {
244 stage.insert(childiter);
255 txiter origit = mapTx.find(origTx.GetId());
256 if (origit != mapTx.end()) {
257 txToRemove.insert(origit);
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);
274 for (
txiter it : txToRemove) {
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) {
304 lastRollingFeeUpdate =
GetTime();
305 blockSinceLastRollingFeeBump =
true;
309 const std::unordered_set<TxId, SaltedTxIdHasher>
310 &confirmedTxIdsInNonFinalizedBlocks) {
313 std::vector<CTxMemPoolEntryRef> finalizedTxsToKeep;
316 if (mapTx.count(entry->GetTx().GetId()) > 0 ||
317 confirmedTxIdsInNonFinalizedBlocks.count(
318 entry->GetTx().GetId()) > 0) {
322 finalizedTxsToKeep.push_back(entry);
334 m_finalizedTxsFitter.resetBlock();
335 for (
const auto &entry : finalizedTxsToKeep) {
339 m_finalizedTxsFitter.addTx(entry->GetTxSize(),
340 entry->GetSigChecks(), entry->GetFee());
352 cachedInnerUsage = 0;
353 lastRollingFeeUpdate =
GetTime();
354 blockSinceLastRollingFeeBump =
false;
355 rollingMinimumFeeRate = 0;
362 if (include_finalized_txs) {
365 m_finalizedTxsFitter.resetBlock();
370 int64_t spendheight)
const {
382 "Checking mempool with %u transactions and %u inputs\n",
383 (
unsigned int)mapTx.size(), (
unsigned int)mapNextTx.size());
385 uint64_t checkTotal = 0;
387 uint64_t innerUsage = 0;
393 checkTotal += entry->GetTxSize();
394 check_total_fee += entry->GetFee();
395 innerUsage += entry->DynamicMemoryUsage();
396 const CTransaction &tx = entry->GetTx();
401 for (
const CTxIn &txin : tx.vin) {
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);
412 assert((*parentIt)->GetEntryId() < entry->GetEntryId());
418 assert(mempoolDuplicate.HaveCoin(txin.prevout));
420 auto prevoutNextIt = mapNextTx.find(txin.prevout);
421 assert(prevoutNextIt != mapNextTx.end());
422 assert(prevoutNextIt->first == &txin.prevout);
423 assert(prevoutNextIt->second.get() == &tx);
425 auto comp = [](
const auto &a,
const auto &b) ->
bool {
426 return a.get()->GetTx().GetId() == b.get()->GetTx().GetId();
428 assert(setParentCheck.size() == entry->GetMemPoolParentsConst().size());
429 assert(std::equal(setParentCheck.begin(), setParentCheck.end(),
430 entry->GetMemPoolParentsConst().begin(), comp));
437 for (
const auto &ancestor : setAncestors) {
438 assert((*ancestor)->GetEntryId() < entry->GetEntryId());
443 auto iter = mapNextTx.lower_bound(COutPoint(entry->GetTx().GetId(), 0));
444 for (; iter != mapNextTx.end() &&
445 iter->first->GetTxId() == entry->GetTx().GetId();
447 txiter childIt = mapTx.find(iter->second->GetId());
449 assert(childIt != mapTx.end());
450 setChildrenCheck.insert(*childIt);
452 assert(setChildrenCheck.size() ==
453 entry->GetMemPoolChildrenConst().size());
454 assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(),
455 entry->GetMemPoolChildrenConst().begin(), comp));
462 spendheight, txfee));
463 for (
const auto &input : tx.vin) {
464 mempoolDuplicate.SpendCoin(input.prevout);
466 AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
469 for (
auto &[
_, nextTx] : mapNextTx) {
470 txiter it = mapTx.find(nextTx->GetId());
471 assert(it != mapTx.end());
472 assert((*it)->GetSharedTx() == nextTx);
475 assert(totalTxSize == checkTotal);
476 assert(m_total_fee == check_total_fee);
477 assert(innerUsage == cachedInnerUsage);
481 const TxId &txidb)
const {
483 auto it1 = mapTx.find(txida);
484 if (it1 == mapTx.end()) {
487 auto it2 = mapTx.find(txidb);
488 if (it2 == mapTx.end()) {
491 return (*it1)->GetEntryId() < (*it2)->GetEntryId();
498 vtxid.reserve(mapTx.size());
501 vtxid.push_back(entry->GetTx().GetId());
506GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
508 (*it)->GetFee(), (*it)->GetTxSize(),
509 (*it)->GetModifiedFee() - (*it)->GetFee()};
515 std::vector<TxMempoolInfo> ret;
516 ret.reserve(mapTx.size());
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)));
530 std::vector<TxId> &finalizedTxIds) {
534 auto it = mapTx.find(tx->GetTx().GetId());
535 if (it == mapTx.end()) {
537 LogPrintf(
"Trying to finalize tx %s that is not in the mempool\n",
538 tx->GetTx().GetId().ToString());
543 setAncestors.insert(it);
547 uint64_t sumOfTxSize{0};
548 uint64_t sumOfTxSigChecks{0};
549 for (
auto iter_it = setAncestors.begin(); iter_it != setAncestors.end();) {
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()
563 entry->GetSharedTx()->GetId().ToString()),
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()
577 entry->GetSharedTx()->GetId().ToString()));
583 for (
const CTxIn &txin : entry->GetTx().vin) {
585 if (mapTx.count(txin.prevout.GetTxId()) != 0) {
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()
608 entry->GetSharedTx()->GetId().ToString()));
616 iter_it = setAncestors.erase(iter_it);
620 sumOfTxSize += entry->GetTxSize();
621 sumOfTxSigChecks += entry->GetSigChecks();
625 if (!m_finalizedTxsFitter.testTxFits(sumOfTxSize, sumOfTxSigChecks)) {
628 "Delay storing finalized tx %s as it won't fit in the next block\n",
629 tx->GetTx().GetId().ToString());
633 finalizedTxIds.clear();
637 for (
txiter ancestor_it : setAncestors) {
639 m_finalizedTxsFitter.addTx((*ancestor_it)->GetTxSize(),
640 (*ancestor_it)->GetSigChecks(),
641 (*ancestor_it)->GetFee());
643 finalizedTxIds.push_back((*ancestor_it)->GetTx().GetId());
647 (*ancestor_it)->GetSharedTx());
661 const TxId &txid = tx->GetId();
667 return !m_finalizedTxsFitter.isBelowBlockMinFeeRate(
668 entry->GetModifiedFeeRate()) &&
669 m_finalizedTxsFitter.testTxFits(entry->GetTxSize(),
670 entry->GetSigChecks());
678 return m_conflicting && m_conflicting->HaveTx(txid));
683 indexed_transaction_set::const_iterator i = mapTx.find(txid);
684 if (i == mapTx.end()) {
688 return (*i)->GetSharedTx();
693 indexed_transaction_set::const_iterator i = mapTx.find(txid);
694 if (i == mapTx.end()) {
715 Amount &delta = mapDeltas[txid];
717 txiter it = mapTx.find(txid);
718 if (it != mapTx.end()) {
720 e->UpdateModifiedFee(nFeeDelta);
731 std::map<TxId, Amount>::const_iterator pos = mapDeltas.find(txid);
732 if (pos == mapDeltas.end()) {
736 nFeeDelta += pos->second;
741 mapDeltas.erase(txid);
745 const auto it = mapNextTx.find(prevout);
746 return it == mapNextTx.end() ? nullptr : it->second;
750 auto it = mapTx.find(txid);
751 if (it != mapTx.end()) {
760 for (
const auto &txid : txids) {
770 for (
const CTxIn &in : tx.vin) {
771 if (
exists(in.prevout.GetTxId())) {
797 if (outpoint.GetN() < ptx->vout.size()) {
808 for (uint32_t n = 0; n < tx->vout.size(); ++n) {
824 12 *
sizeof(
void *)) *
833 if (m_unbroadcast_txids.erase(txid)) {
837 (unchecked ?
" before confirmation that txn was sent out" :
""));
848 for (
txiter it : stageRevTopo) {
855 indexed_transaction_set::index<entry_time>::type::iterator it =
858 size_t skippedFinalizedTxs{0};
859 while (it != mapTx.get<
entry_time>().end() && (*it)->GetTime() < time) {
862 ++skippedFinalizedTxs;
864 toremove.insert(mapTx.project<0>(it));
870 if (skippedFinalizedTxs > 0) {
872 skippedFinalizedTxs);
876 for (
txiter removeit : toremove) {
890 "Expired %i transactions from the memory pool\n", expired);
893 std::vector<COutPoint> vNoSpendsRemaining;
895 for (
const COutPoint &removed : vNoSpendsRemaining) {
903 if (add && (*entry)->GetMemPoolChildren().insert(*child).second) {
905 }
else if (!add && (*entry)->GetMemPoolChildren().erase(*child)) {
913 if (add && (*entry)->GetMemPoolParents().insert(*parent).second) {
915 }
else if (!add && (*entry)->GetMemPoolParents().erase(*parent)) {
922 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0) {
927 if (time > lastRollingFeeUpdate + 10) {
935 rollingMinimumFeeRate =
936 rollingMinimumFeeRate /
937 pow(2.0, (time - lastRollingFeeUpdate) / halflife);
938 lastRollingFeeUpdate = time;
947 blockSinceLastRollingFeeBump =
false;
952 std::vector<COutPoint> *pvNoSpendsRemaining) {
955 unsigned nTxnRemoved = 0;
956 size_t finalizedTxsSkipped = 0;
961 auto rit = by_modified_feerate.rbegin();
965 ++finalizedTxsSkipped;
967 if (rit == by_modified_feerate.rend()) {
979 if (rit == by_modified_feerate.rend()) {
982 auto it = rit.base();
990 CFeeRate removed = (*it)->GetModifiedFeeRate();
994 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
998 nTxnRemoved += stage.size();
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);
1015 "Removed %u txn, rolling minimum fee bumped to %s\n",
1016 nTxnRemoved, maxFeeRateRemoved.
ToString());
1019 if (finalizedTxsSkipped > 0) {
1021 "Not evicting %u finalized txn for low fee\n",
1022 finalizedTxsSkipped);
1028 return m_load_tried;
1033 m_load_tried = load_tried;
static constexpr Amount SATOSHI
#define Assume(val)
Assume is the identity function.
The block chain is a tree shaped structure starting with the genesis block at the root,...
CCoinsView backed by another CCoinsView.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Abstract view on the open txout dataset.
virtual std::optional< Coin > GetCoin(const COutPoint &outpoint) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
GetCoin, returning whether it exists and is not spent.
void Reset()
Clear m_temp_added and m_non_base_coins.
std::unordered_map< COutPoint, Coin, SaltedOutpointHasher > m_temp_added
Coins made available by transactions being validated.
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
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...
void PackageAddTransaction(const CTransactionRef &tx)
Add the coins created by this transaction.
const CTxMemPool & mempool
Fee rate in satoshis per virtualbyte: Amount / vB the feerate is represented internally as FeeFrac.
std::string ToString() const
Amount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
std::set< std::reference_wrapper< const CTxMemPoolEntryRef >, CompareIteratorById > Children
std::set< std::reference_wrapper< const CTxMemPoolEntryRef >, CompareIteratorById > Parents
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs)
CFeeRate estimateFee() const
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...
void ClearPrioritisation(const TxId &txid) EXCLUSIVE_LOCKS_REQUIRED(cs)
std::set< txiter, CompareIteratorById > setEntries
void RemoveUnbroadcastTx(const TxId &txid, const bool unchecked=false)
Removes a transaction from the unbroadcast set.
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...
bool GetLoadTried() const
void updateFeeForBlock() EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
CFeeRate GetMinFee() const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
void trackPackageRemoved(const CFeeRate &rate) EXCLUSIVE_LOCKS_REQUIRED(cs)
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
void UpdateForRemoveFromMempool(const setEntries &entriesToRemove) EXCLUSIVE_LOCKS_REQUIRED(cs)
For each transaction being removed, update ancestors and any direct children.
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.
void AddTransactionsUpdated(unsigned int n)
void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs)
Sever link between specified transaction and direct children.
bool setAvalancheFinalized(const CTxMemPoolEntryRef &tx, const Consensus::Params ¶ms, 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)
bool CompareTopologically(const TxId &txida, const TxId &txidb) const
TxMempoolInfo info(const TxId &txid) const
void getAllTxIds(std::vector< TxId > &vtxid) const
std::atomic< uint32_t > nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
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.
size_t DynamicMemoryUsage() const
std::vector< TxMempoolInfo > infoAll() const
void LimitSize(CCoinsViewCache &coins_cache) EXCLUSIVE_LOCKS_REQUIRED(cs
Reduce the size of the mempool by expiring and then trimming the mempool.
void UpdateParent(txiter entry, txiter parent, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
CTransactionRef GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
void removeUnchecked(txiter entry, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Before calling removeUnchecked for a given transaction, UpdateForRemoveFromMempool must be called on ...
int Expire(std::chrono::seconds time) EXCLUSIVE_LOCKS_REQUIRED(cs)
Expire all transaction (and their dependencies) in the mempool older than time.
bool isWorthPolling(const CTransactionRef &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs
std::set< txiter, CompareIteratorByRevEntryId > setRevTopoEntries
bool exists(const TxId &txid) const
static const int ROLLING_FEE_HALFLIFE
CTransactionRef get(const TxId &txid) const
void PrioritiseTransaction(const TxId &txid, const Amount nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
CTxMemPool(const Config &config, Options opts)
Create a new CTxMemPool.
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
uint64_t GetAndIncrementSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Guards this internal counter for external reporting.
void UpdateChild(txiter entry, txiter child, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
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...
RadixTree< CTxMemPoolEntry, MemPoolEntryRadixTreeAdapter > finalizedTxs
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void cs_main
void CalculateMemPoolAncestors(const CTxMemPoolEntryRef &entry, setEntries &setAncestors) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Calculate all in-mempool ancestors of entry.
void removeForFinalizedBlock(const std::unordered_set< TxId, SaltedTxIdHasher > &confirmedTxIdsInNonFinalizedBlocks) EXCLUSIVE_LOCKS_REQUIRED(cs)
void clear(bool include_finalized_txs=false)
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
void RemoveStaged(const setEntries &stage, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove a set of transactions from the mempool.
void UpdateParentsOf(bool add, txiter it) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update parents of it to add/remove it as a child transaction.
void ApplyDelta(const TxId &txid, Amount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs)
void SetLoadTried(bool load_tried)
Set whether or not an initial attempt to load the persisted mempool was made (regardless of whether t...
std::optional< txiter > GetIter(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given txid, if found.
bool isSpent(const COutPoint &outpoint) const
unsigned int GetTransactionsUpdated() const
void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs)
Chainstate stores and provides an API to update our local knowledge of the current best chain.
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.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
uint32_t GetHeight() const
T * get()
Get allows to access the undelying pointer.
void TransactionFinalized(const CTransactionRef &tx)
void TransactionRemovedFromMempool(const CTransactionRef &, MemPoolRemovalReason, uint64_t mempool_sequence)
std::string ToString() const
std::string ToString() const
std::string GetHex() const
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.
#define LogDebug(category,...)
std::string FormatMoney(const Amount amt)
Do not use these functions to represent or parse monetary amounts to or from JSON but use AmountFromV...
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).
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
Implement std::hash so RCUPtr can be used as a key for maps or sets.
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
void SaturatingAdd(const Amount &other) noexcept
Amount addition with integer saturation.
static constexpr Amount zero() noexcept
Parameters that influence chain consensus.
RCUPtr< T > remove(const KeyType &key)
Remove an element from the tree.
bool forEachLeaf(Callable &&func) const
bool insert(const RCUPtr< T > &value)
Insert a value into the tree.
A TxId is the identifier of a transaction.
Information about a mempool transaction.
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)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define NO_THREAD_SAFETY_ANALYSIS
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
bilingual_str _(const char *psz)
Translation function.
bool ContextualCheckTransactionForCurrentBlock(const CBlockIndex &active_chain_tip, const Consensus::Params ¶ms, const CTransaction &tx, TxValidationState &state)
std::string RemovalReasonToString(const MemPoolRemovalReason &r) noexcept
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
@ 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....