31 #include <string_view> 52 const std::set<uint256>& setExclude, std::set<uint256>& descendants_to_remove)
55 stageEntries = updateIt->GetMemPoolChildrenConst();
57 while (!stageEntries.empty()) {
59 descendants.insert(descendant);
60 stageEntries.erase(descendant);
63 cacheMap::iterator cacheIt = cachedDescendants.find(mapTx.iterator_to(childEntry));
64 if (cacheIt != cachedDescendants.end()) {
67 for (
txiter cacheEntry : cacheIt->second) {
68 descendants.insert(*cacheEntry);
70 }
else if (!descendants.count(childEntry)) {
72 stageEntries.insert(childEntry);
78 int32_t modifySize = 0;
80 int64_t modifyCount = 0;
82 if (!setExclude.count(descendant.GetTx().GetHash())) {
83 modifySize += descendant.GetTxSize();
84 modifyFee += descendant.GetModifiedFee();
86 cachedDescendants[updateIt].insert(mapTx.iterator_to(descendant));
89 e.UpdateAncestorState(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost());
95 descendants_to_remove.insert(descendant.GetTx().GetHash());
108 cacheMap mapMemPoolDescendantsToUpdate;
112 std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end());
114 std::set<uint256> descendants_to_remove;
124 if (
it == mapTx.end()) {
127 auto iter = mapNextTx.lower_bound(
COutPoint(hash, 0));
133 for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) {
134 const uint256 &childHash = iter->second->GetHash();
135 txiter childIter = mapTx.find(childHash);
136 assert(childIter != mapTx.end());
139 if (!
visited(childIter) && !setAlreadyIncluded.count(childHash)) {
148 for (
const auto& txid : descendants_to_remove) {
161 const Limits& limits)
const 163 int64_t totalSizeWithAncestors = entry_size;
166 while (!staged_ancestors.empty()) {
168 txiter stageit = mapTx.iterator_to(stage);
170 ancestors.insert(stageit);
171 staged_ancestors.erase(stage);
172 totalSizeWithAncestors += stageit->
GetTxSize();
176 }
else if (stageit->GetCountWithDescendants() + entry_count >
static_cast<uint64_t
>(limits.
descendant_count)) {
184 txiter parent_it = mapTx.iterator_to(parent);
187 if (ancestors.count(parent_it) == 0) {
188 staged_ancestors.insert(parent);
190 if (staged_ancestors.size() + ancestors.size() + entry_count >
static_cast<uint64_t
>(limits.
ancestor_count)) {
200 const int64_t total_vsize,
201 std::string &errString)
const 203 size_t pack_count = package.size();
221 for (
const auto& tx : package) {
222 for (
const auto& input : tx->vin) {
223 std::optional<txiter> piter =
GetIter(input.prevout.hash);
225 staged_ancestors.insert(**piter);
240 return ancestors.has_value();
246 bool fSearchForParents )
const 251 if (fSearchForParents) {
255 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
256 std::optional<txiter> piter =
GetIter(tx.
vin[i].prevout.hash);
258 staged_ancestors.insert(**piter);
259 if (staged_ancestors.size() + 1 >
static_cast<uint64_t
>(limits.
ancestor_count)) {
267 txiter it = mapTx.iterator_to(entry);
268 staged_ancestors =
it->GetMemPoolParentsConst();
276 std::string_view calling_fn_name,
279 bool fSearchForParents )
const 296 const int32_t updateCount = (add ? 1 : -1);
297 const int32_t updateSize{updateCount *
it->GetTxSize()};
298 const CAmount updateFee = updateCount *
it->GetModifiedFee();
299 for (
txiter ancestorIt : setAncestors) {
306 int64_t updateCount = setAncestors.size();
307 int64_t updateSize = 0;
309 int64_t updateSigOpsCost = 0;
310 for (
txiter ancestorIt : setAncestors) {
311 updateSize += ancestorIt->GetTxSize();
312 updateFee += ancestorIt->GetModifiedFee();
313 updateSigOpsCost += ancestorIt->GetSigOpCost();
330 if (updateDescendants) {
337 for (
txiter removeIt : entriesToRemove) {
340 setDescendants.erase(removeIt);
341 int32_t modifySize = -removeIt->GetTxSize();
342 CAmount modifyFee = -removeIt->GetModifiedFee();
343 int modifySigOps = -removeIt->GetSigOpCost();
344 for (
txiter dit : setDescendants) {
349 for (
txiter removeIt : entriesToRemove) {
378 for (
txiter removeIt : entriesToRemove) {
405 minerPolicyEstimator{opts.estimator},
406 m_max_size_bytes{opts.max_size_bytes},
407 m_expiry{opts.expiry},
408 m_incremental_relay_feerate{opts.incremental_relay_feerate},
409 m_min_relay_feerate{opts.min_relay_feerate},
410 m_dust_relay_feerate{opts.dust_relay_feerate},
411 m_permit_bare_multisig{opts.permit_bare_multisig},
412 m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
413 m_require_standard{opts.require_standard},
414 m_full_rbf{opts.full_rbf},
415 m_limits{opts.limits}
422 return mapNextTx.count(outpoint);
440 indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
457 std::set<uint256> setParentTransactions;
458 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
459 mapNextTx.insert(std::make_pair(&tx.
vin[i].prevout, &tx));
460 setParentTransactions.insert(tx.
vin[i].prevout.hash);
470 for (
const auto& pit :
GetIterSet(setParentTransactions)) {
478 m_total_fee += entry.
GetFee();
484 newit->vTxHashesIdx = vTxHashes.size() - 1;
507 it->GetTx().GetHash().data(),
511 std::chrono::duration_cast<std::chrono::duration<std::uint64_t>>(
it->GetTime()).
count()
514 const uint256 hash =
it->GetTx().GetHash();
515 for (
const CTxIn& txin :
it->GetTx().vin)
516 mapNextTx.erase(txin.prevout);
520 if (vTxHashes.size() > 1) {
521 vTxHashes[
it->vTxHashesIdx] = std::move(vTxHashes.back());
522 vTxHashes[
it->vTxHashesIdx].second->vTxHashesIdx =
it->vTxHashesIdx;
523 vTxHashes.pop_back();
524 if (vTxHashes.size() * 2 < vTxHashes.capacity())
525 vTxHashes.shrink_to_fit();
529 totalTxSize -=
it->GetTxSize();
530 m_total_fee -=
it->GetFee();
531 cachedInnerUsage -=
it->DynamicMemoryUsage();
547 if (setDescendants.count(entryit) == 0) {
548 stage.insert(entryit);
553 while (!stage.empty()) {
555 setDescendants.insert(
it);
560 txiter childiter = mapTx.iterator_to(child);
561 if (!setDescendants.count(childiter)) {
562 stage.insert(childiter);
574 if (origit != mapTx.end()) {
575 txToRemove.insert(origit);
581 for (
unsigned int i = 0; i < origTx.
vout.size(); i++) {
583 if (
it == mapNextTx.end())
585 txiter nextit = mapTx.find(
it->second->GetHash());
586 assert(nextit != mapTx.end());
587 txToRemove.insert(nextit);
605 for (indexed_transaction_set::const_iterator
it = mapTx.begin();
it != mapTx.end();
it++) {
606 if (check_final_and_mature(
it)) txToRemove.insert(
it);
613 for (indexed_transaction_set::const_iterator
it = mapTx.begin();
it != mapTx.end();
it++) {
624 if (
it != mapNextTx.end()) {
626 if (txConflict != tx)
641 std::vector<const CTxMemPoolEntry*> entries;
642 for (
const auto& tx : vtx)
646 indexed_transaction_set::iterator i = mapTx.find(hash);
647 if (i != mapTx.end())
648 entries.push_back(&*i);
652 for (
const auto& tx : vtx)
655 if (
it != mapTx.end()) {
663 lastRollingFeeUpdate =
GetTime();
664 blockSinceLastRollingFeeBump =
true;
667 void CTxMemPool::check(
const CCoinsViewCache& active_coins_tip, int64_t spendheight)
const 675 LogPrint(
BCLog::MEMPOOL,
"Checking mempool with %u transactions and %u inputs\n", (
unsigned int)mapTx.size(), (
unsigned int)mapNextTx.size());
677 uint64_t checkTotal = 0;
679 uint64_t innerUsage = 0;
680 uint64_t prev_ancestor_count{0};
682 CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
685 checkTotal +=
it->GetTxSize();
686 check_total_fee +=
it->GetFee();
687 innerUsage +=
it->DynamicMemoryUsage();
693 indexed_transaction_set::const_iterator it2 = mapTx.find(txin.
prevout.
hash);
694 if (it2 != mapTx.end()) {
697 setParentCheck.insert(*it2);
704 auto it3 = mapNextTx.find(txin.
prevout);
705 assert(it3 != mapNextTx.end());
707 assert(it3->second == &tx);
712 assert(setParentCheck.size() ==
it->GetMemPoolParentsConst().size());
713 assert(std::equal(setParentCheck.begin(), setParentCheck.end(),
it->GetMemPoolParentsConst().begin(), comp));
716 uint64_t nCountCheck = ancestors.size() + 1;
717 int32_t nSizeCheck =
it->GetTxSize();
718 CAmount nFeesCheck =
it->GetModifiedFee();
719 int64_t nSigOpCheck =
it->GetSigOpCost();
721 for (
txiter ancestorIt : ancestors) {
722 nSizeCheck += ancestorIt->GetTxSize();
723 nFeesCheck += ancestorIt->GetModifiedFee();
724 nSigOpCheck += ancestorIt->GetSigOpCost();
727 assert(
it->GetCountWithAncestors() == nCountCheck);
728 assert(
it->GetSizeWithAncestors() == nSizeCheck);
729 assert(
it->GetSigOpCostWithAncestors() == nSigOpCheck);
730 assert(
it->GetModFeesWithAncestors() == nFeesCheck);
732 assert(prev_ancestor_count <= it->GetCountWithAncestors());
733 prev_ancestor_count =
it->GetCountWithAncestors();
737 auto iter = mapNextTx.lower_bound(
COutPoint(
it->GetTx().GetHash(), 0));
738 int32_t child_sizes{0};
739 for (; iter != mapNextTx.end() && iter->first->hash ==
it->GetTx().GetHash(); ++iter) {
740 txiter childit = mapTx.find(iter->second->GetHash());
741 assert(childit != mapTx.end());
742 if (setChildrenCheck.insert(*childit).second) {
743 child_sizes += childit->GetTxSize();
746 assert(setChildrenCheck.size() ==
it->GetMemPoolChildrenConst().size());
747 assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(),
it->GetMemPoolChildrenConst().begin(), comp));
750 assert(
it->GetSizeWithDescendants() >= child_sizes +
it->GetTxSize());
756 for (
const auto& input: tx.
vin) mempoolDuplicate.SpendCoin(input.prevout);
757 AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
759 for (
auto it = mapNextTx.cbegin();
it != mapNextTx.cend();
it++) {
761 indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
763 assert(it2 != mapTx.end());
767 assert(totalTxSize == checkTotal);
768 assert(m_total_fee == check_total_fee);
769 assert(innerUsage == cachedInnerUsage);
780 indexed_transaction_set::const_iterator j = wtxid ?
get_iter_from_wtxid(hashb) : mapTx.find(hashb);
781 if (j == mapTx.end())
return false;
782 indexed_transaction_set::const_iterator i = wtxid ?
get_iter_from_wtxid(hasha) : mapTx.find(hasha);
783 if (i == mapTx.end())
return true;
784 uint64_t counta = i->GetCountWithAncestors();
785 uint64_t countb = j->GetCountWithAncestors();
786 if (counta == countb) {
789 return counta < countb;
793 class DepthAndScoreComparator
796 bool operator()(
const CTxMemPool::indexed_transaction_set::const_iterator& a,
const CTxMemPool::indexed_transaction_set::const_iterator& b)
798 uint64_t counta = a->GetCountWithAncestors();
799 uint64_t countb = b->GetCountWithAncestors();
800 if (counta == countb) {
803 return counta < countb;
810 std::vector<indexed_transaction_set::const_iterator> iters;
813 iters.reserve(mapTx.size());
815 for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) {
818 std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
828 vtxid.reserve(mapTx.size());
830 for (
auto it : iters) {
831 vtxid.push_back(
it->GetTx().GetHash());
836 return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
843 std::vector<CTxMemPoolEntryRef>
ret;
844 ret.reserve(mapTx.size());
846 ret.emplace_back(*
it);
856 std::vector<TxMempoolInfo>
ret;
857 ret.reserve(mapTx.size());
858 for (
auto it : iters) {
868 indexed_transaction_set::const_iterator i = mapTx.find(hash);
869 if (i == mapTx.end())
871 return i->GetSharedTx();
878 if (i == mapTx.end())
887 if (i != mapTx.end() && i->GetSequence() < last_sequence) {
898 CAmount &delta = mapDeltas[hash];
901 if (
it != mapTx.end()) {
905 for (
txiter ancestorIt : ancestors) {
911 setDescendants.erase(
it);
912 for (
txiter descendantIt : setDescendants) {
918 mapDeltas.erase(hash);
919 LogPrintf(
"PrioritiseTransaction: %s (%sin mempool) delta cleared\n", hash.
ToString(),
it == mapTx.end() ?
"not " :
"");
921 LogPrintf(
"PrioritiseTransaction: %s (%sin mempool) fee += %s, new delta=%s\n",
923 it == mapTx.end() ?
"not " :
"",
933 std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(hash);
934 if (pos == mapDeltas.end())
936 const CAmount &delta = pos->second;
943 mapDeltas.erase(hash);
950 std::vector<delta_info> result;
951 result.reserve(mapDeltas.size());
952 for (
const auto& [txid, delta] : mapDeltas) {
953 const auto iter{mapTx.find(txid)};
954 const bool in_mempool{iter != mapTx.end()};
955 std::optional<CAmount> modified_fee;
956 if (in_mempool) modified_fee = iter->GetModifiedFee();
957 result.emplace_back(
delta_info{in_mempool, delta, modified_fee, txid});
964 const auto it = mapNextTx.find(prevout);
965 return it == mapNextTx.end() ? nullptr :
it->second;
970 auto it = mapTx.find(txid);
971 if (
it != mapTx.end())
return it;
978 for (
const auto& h : hashes) {
980 if (mi)
ret.insert(*mi);
988 std::vector<txiter>
ret;
989 ret.reserve(txids.size());
990 for (
const auto& txid : txids) {
1000 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
1021 if (outpoint.
n < ptx->vout.size()) {
1034 for (
unsigned int n = 0; n < tx->vout.size(); ++n) {
1054 if (m_unbroadcast_txids.erase(txid))
1056 LogPrint(
BCLog::MEMPOOL,
"Removed %i from set of unbroadcast txns%s\n", txid.
GetHex(), (unchecked ?
" before confirmation that txn was sent out" :
""));
1071 indexed_transaction_set::index<entry_time>::type::iterator
it = mapTx.get<
entry_time>().begin();
1073 while (
it != mapTx.get<
entry_time>().end() &&
it->GetTime() < time) {
1074 toremove.insert(mapTx.project<0>(
it));
1078 for (
txiter removeit : toremove) {
1082 return stage.size();
1088 return addUnchecked(entry, ancestors, validFeeEstimate);
1095 if (add && entry->GetMemPoolChildren().insert(*child).second) {
1097 }
else if (!add && entry->GetMemPoolChildren().erase(*child)) {
1106 if (add && entry->GetMemPoolParents().insert(*parent).second) {
1108 }
else if (!add && entry->GetMemPoolParents().erase(*parent)) {
1115 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0)
1116 return CFeeRate(llround(rollingMinimumFeeRate));
1119 if (time > lastRollingFeeUpdate + 10) {
1126 rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
1127 lastRollingFeeUpdate = time;
1130 rollingMinimumFeeRate = 0;
1139 if (rate.
GetFeePerK() > rollingMinimumFeeRate) {
1141 blockSinceLastRollingFeeBump =
false;
1148 unsigned nTxnRemoved = 0;
1151 indexed_transaction_set::index<descendant_score>::type::iterator
it = mapTx.get<
descendant_score>().begin();
1157 CFeeRate removed(
it->GetModFeesWithDescendants(),
it->GetSizeWithDescendants());
1160 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
1164 nTxnRemoved += stage.size();
1166 std::vector<CTransaction> txn;
1167 if (pvNoSpendsRemaining) {
1168 txn.reserve(stage.size());
1169 for (
txiter iter : stage)
1170 txn.push_back(iter->GetTx());
1173 if (pvNoSpendsRemaining) {
1177 pvNoSpendsRemaining->push_back(txin.
prevout);
1183 if (maxFeeRateRemoved >
CFeeRate(0)) {
1190 std::vector<txiter> candidates;
1192 candidates.push_back(entry);
1193 uint64_t maximum = 0;
1194 while (candidates.size()) {
1195 txiter candidate = candidates.back();
1196 candidates.pop_back();
1197 if (!counted.insert(candidate).second)
continue;
1199 if (parents.size() == 0) {
1200 maximum = std::max(maximum, candidate->GetCountWithDescendants());
1203 candidates.push_back(mapTx.iterator_to(i));
1212 auto it = mapTx.find(txid);
1213 ancestors = descendants = 0;
1214 if (
it != mapTx.end()) {
1215 ancestors =
it->GetCountWithAncestors();
1216 if (ancestorsize) *ancestorsize =
it->GetSizeWithAncestors();
1217 if (ancestorfees) *ancestorfees =
it->GetModFeesWithAncestors();
1225 return m_load_tried;
1231 m_load_tried = load_tried;
1237 std::vector<txiter> clustered_txs{
GetIterVec(txids)};
1241 for (
const auto&
it : clustered_txs) {
1245 for (
size_t i{0}; i < clustered_txs.size(); ++i) {
1247 if (clustered_txs.size() > 500)
return {};
1248 const txiter& tx_iter = clustered_txs.at(i);
1249 for (
const auto& entries : {tx_iter->GetMemPoolParentsConst(), tx_iter->GetMemPoolChildrenConst()}) {
1251 const auto entry_it = mapTx.iterator_to(entry);
1253 clustered_txs.push_back(entry_it);
1258 return clustered_txs;
std::shared_ptr< const CTransaction > CTransactionRef
void UpdateDescendantState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount)
void queryHashes(std::vector< uint256 > &vtxid) const
Information about a mempool transaction.
std::vector< txiter > GetIterVec(const std::vector< uint256 > &txids) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Translate a list of hashes into a list of mempool iterators to avoid repeated lookups.
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...
bool CheckTxInputs(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, CAmount &txfee)
Check whether all inputs of this transaction are valid (no double spends and amounts) This does not m...
CAmount nModFeesWithDescendants
... and total fees (all including us)
std::string RemovalReasonToString(const MemPoolRemovalReason &r) noexcept
void UpdateModifiedFee(CAmount fee_diff)
void processBlock(unsigned int nBlockHeight, std::vector< const CTxMemPoolEntry *> &entries) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator)
Process all the transactions that have been included in a block.
#define LogPrint(category,...)
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
std::vector< TxMempoolInfo > infoAll() const
int32_t GetTxSize() const
bool exists(const GenTxid >xid) const
void UpdateTransactionsFromBlock(const std::vector< uint256 > &vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs
UpdateTransactionsFromBlock is called when adding transactions from a disconnected block back to the ...
Options struct containing limit options for a CTxMemPool.
An in-memory indexed chain of blocks.
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
size_t DynamicMemoryUsage() const
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
GetCoin, returning whether it exists and is not spent.
reverse_range< T > reverse_iterate(T &x)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs)
void RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove a set of transactions from the mempool.
const uint256 & GetHash() const
Removed for conflict with in-block transaction.
bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb, bool wtxid=false)
std::set< txiter, CompareIteratorByHash > setEntries
const Children & GetMemPoolChildrenConst() const
CTxMemPool(const Options &opts)
Create a new CTxMemPool.
std::atomic< unsigned int > nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) 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...
CFeeRate GetMinFee() const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
setEntries AssumeCalculateMemPoolAncestors(std::string_view calling_fn_name, const CTxMemPoolEntry &entry, const Limits &limits, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Same as CalculateMemPoolAncestors, but always returns a (non-optional) setEntries.
CAmount GetModifiedFee() const
#define WITH_FRESH_EPOCH(epoch)
util::Result< setEntries > CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, const Limits &limits, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Try to calculate all in-mempool ancestors of entry.
bool isSpent(const COutPoint &outpoint) const
const std::vector< CTxIn > vin
void removeForReorg(CChain &chain, std::function< bool(txiter)> filter_final_and_mature) EXCLUSIVE_LOCKS_REQUIRED(cs
After reorg, filter the entries that would no longer be valid in the next block, and update the entri...
bool removeTx(uint256 hash, bool inBlock) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator)
Remove a transaction from the mempool tracking stats.
std::vector< txiter > GatherClusters(const std::vector< uint256 > &txids) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Collect the entire cluster of connected transactions for each transaction in txids.
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
int64_t nSizeWithAncestors
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate=true) EXCLUSIVE_LOCKS_REQUIRED(cs
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
const int m_check_ratio
Value n means that 1 times in n we check.
void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update ancestors of hash to add/remove it as a descendant transaction.
int64_t CAmount
Amount in satoshis (Can be negative)
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
void UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, const std::set< uint256 > &setExclude, std::set< uint256 > &descendants_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs)
UpdateForDescendants is used by UpdateTransactionsFromBlock to update the descendants for a single tr...
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.
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0...
int64_t nSigOpCostWithAncestors
std::set< CTxMemPoolEntryRef, CompareIteratorByHash > Parents
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
int64_t m_count_with_descendants
number of descendant transactions
Abstract view on the open txout dataset.
size_t DynamicMemoryUsage() const
int Expire(std::chrono::seconds time) EXCLUSIVE_LOCKS_REQUIRED(cs)
Expire all transaction (and their dependencies) in the mempool older than time.
An input of a transaction.
const uint256 & GetWitnessHash() const
int64_t descendant_count
The maximum allowed number of transactions in a package including the entry and its descendants...
Removed for reorganization.
const uint256 & GetHash() const
const CAmount & GetFee() const
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
void removeUnchecked(txiter entry, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Before calling removeUnchecked for a given transaction, UpdateForRemoveFromMempool must be called on ...
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
const std::vector< CTxOut > vout
Removed in size limiting.
bool TestLockPointValidity(CChain &active_chain, const LockPoints &lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
std::vector< delta_info > GetPrioritisedTransactions() const EXCLUSIVE_LOCKS_REQUIRED(!cs)
Return a vector of all entries in mapDeltas with their corresponding delta_info.
CMainSignals & GetMainSignals()
#define LogPrintLevel(category, level,...)
static const int ROLLING_FEE_HALFLIFE
CAmount nModFeesWithAncestors
std::string ToString() const
const CTransaction * GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
int64_t m_count_with_ancestors
An outpoint - a combination of a transaction hash and an index n into its vout.
void AddTransactionsUpdated(unsigned int n)
void processTransaction(const CTxMemPoolEntry &entry, bool validFeeEstimate) EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator)
Process a transaction accepted to the mempool.
void ApplyDelta(const uint256 &hash, CAmount &nFeeDelta) const EXCLUSIVE_LOCKS_REQUIRED(cs)
#define Assume(val)
Assume is the identity function.
const CFeeRate m_incremental_relay_feerate
int64_t ancestor_size_vbytes
The maximum allowed size in virtual bytes of an entry and its ancestors within a package.
#define TRACE5(context, event, a, b, c, d, e)
uint64_t CalculateDescendantMaximum(txiter entry) const EXCLUSIVE_LOCKS_REQUIRED(cs)
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
bool GetLoadTried() const
TxMempoolInfo info_for_relay(const GenTxid >xid, uint64_t last_sequence) const
Returns info for a transaction if its entry_sequence < last_sequence.
std::optional< txiter > GetIter(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given hash, if found.
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void cs_main
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
T SaturatingAdd(const T i, const T j) noexcept
uint64_t GetAndIncrementSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Guards this internal counter for external reporting.
std::vector< indexed_transaction_set::const_iterator > GetSortedDepthAndScore() const EXCLUSIVE_LOCKS_REQUIRED(cs)
bool visited(const txiter it) const EXCLUSIVE_LOCKS_REQUIRED(cs
visited marks a CTxMemPoolEntry as having been traversed during the lifetime of the most recently cre...
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
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...
#define TRACE3(context, event, a, b, c)
constexpr const unsigned char * data() const
void UpdateAncestorState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps)
void Reset()
Clear m_temp_added and m_non_base_coins.
int64_t nSizeWithDescendants
... and size
std::map< txiter, setEntries, CompareIteratorByHash > cacheMap
int64_t descendant_size_vbytes
The maximum allowed size in virtual bytes of an entry and its descendants within a package...
const CTransaction & GetTx() const
void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors) EXCLUSIVE_LOCKS_REQUIRED(cs)
Set ancestor state for an entry.
TxMempoolInfo info(const GenTxid >xid) const
txiter get_iter_from_wtxid(const uint256 &wtxid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
void UpdateChild(txiter entry, txiter child, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
void ClearPrioritisation(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs)
setEntries GetIterSet(const std::set< uint256 > &hashes) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Translate a set of hashes into a set of pool iterators to avoid repeated lookups. ...
CBlockPolicyEstimator *const minerPolicyEstimator
void GetTransactionAncestry(const uint256 &txid, size_t &ancestors, size_t &descendants, size_t *ancestorsize=nullptr, CAmount *ancestorfees=nullptr) const
Calculate the ancestor and descendant count for the given transaction.
std::string GetHex() const
std::set< CTxMemPoolEntryRef, CompareIteratorByHash > Children
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
#define AssertLockNotHeld(cs)
unsigned int GetTransactionsUpdated() const
bilingual_str ErrorString(const Result< T > &result)
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
void PackageAddTransaction(const CTransactionRef &tx)
Add the coins created by this transaction.
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.
CTransactionRef get(const uint256 &hash) const
util::Result< setEntries > CalculateAncestorsAndCheckLimits(int64_t entry_size, size_t entry_count, CTxMemPoolEntry::Parents &staged_ancestors, const Limits &limits) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Helper function to calculate all in-mempool ancestors of staged_ancestors and apply ancestor and desc...
void RemoveUnbroadcastTx(const uint256 &txid, const bool unchecked=false)
Removes a transaction from the unbroadcast set.
void trackPackageRemoved(const CFeeRate &rate) EXCLUSIVE_LOCKS_REQUIRED(cs)
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
static constexpr MemPoolLimits NoLimits()
Options struct containing options for constructing a CTxMemPool.
The basic transaction that is broadcasted on the network and contained in blocks. ...
CCoinsView backed by another CCoinsView.
int64_t ancestor_count
The maximum allowed number of transactions in a package including the entry and its ancestors...
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Sort by feerate of entry (fee/size) in descending order This is only used for transaction relay...
void UpdateParent(txiter entry, txiter parent, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
const CTxMemPool & mempool
int64_t GetTime()
DEPRECATED, see GetTime.
void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs)
Sever link between specified transaction and direct children.
CBlockIndex * maxInputBlock
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
A generic txid reference (txid or wtxid).
bool CheckPackageLimits(const Package &package, int64_t total_vsize, std::string &errString) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Calculate all in-mempool ancestors of a set of transactions not already in the mempool and check ance...
CAmount GetFeePerK() const
Return the fee in satoshis for a vsize of 1000 vbytes.
std::unordered_map< COutPoint, Coin, SaltedOutpointHasher > m_temp_added
Coins made available by transactions being validated.
static GenTxid Txid(const uint256 &hash)
std::vector< CTxMemPoolEntryRef > entryAll() const EXCLUSIVE_LOCKS_REQUIRED(cs)
void UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants) EXCLUSIVE_LOCKS_REQUIRED(cs)
For each transaction being removed, update ancestors and any direct children.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
void TransactionRemovedFromMempool(const CTransactionRef &, MemPoolRemovalReason, uint64_t mempool_sequence)