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()) {
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)
const 202 size_t pack_count = package.size();
216 for (
const auto& tx : package) {
217 for (
const auto& input : tx->vin) {
218 std::optional<txiter> piter =
GetIter(input.prevout.hash);
220 staged_ancestors.insert(**piter);
240 bool fSearchForParents )
const 245 if (fSearchForParents) {
249 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
250 std::optional<txiter> piter =
GetIter(tx.
vin[i].prevout.hash);
252 staged_ancestors.insert(**piter);
253 if (staged_ancestors.size() + 1 >
static_cast<uint64_t
>(limits.
ancestor_count)) {
261 txiter it = mapTx.iterator_to(entry);
262 staged_ancestors =
it->GetMemPoolParentsConst();
270 std::string_view calling_fn_name,
273 bool fSearchForParents )
const 290 const int32_t updateCount = (add ? 1 : -1);
291 const int32_t updateSize{updateCount *
it->GetTxSize()};
292 const CAmount updateFee = updateCount *
it->GetModifiedFee();
293 for (
txiter ancestorIt : setAncestors) {
300 int64_t updateCount = setAncestors.size();
301 int64_t updateSize = 0;
303 int64_t updateSigOpsCost = 0;
304 for (
txiter ancestorIt : setAncestors) {
305 updateSize += ancestorIt->GetTxSize();
306 updateFee += ancestorIt->GetModifiedFee();
307 updateSigOpsCost += ancestorIt->GetSigOpCost();
324 if (updateDescendants) {
331 for (
txiter removeIt : entriesToRemove) {
334 setDescendants.erase(removeIt);
335 int32_t modifySize = -removeIt->GetTxSize();
336 CAmount modifyFee = -removeIt->GetModifiedFee();
337 int modifySigOps = -removeIt->GetSigOpCost();
338 for (
txiter dit : setDescendants) {
343 for (
txiter removeIt : entriesToRemove) {
372 for (
txiter removeIt : entriesToRemove) {
399 m_max_size_bytes{opts.max_size_bytes},
400 m_expiry{opts.expiry},
401 m_incremental_relay_feerate{opts.incremental_relay_feerate},
402 m_min_relay_feerate{opts.min_relay_feerate},
403 m_dust_relay_feerate{opts.dust_relay_feerate},
404 m_permit_bare_multisig{opts.permit_bare_multisig},
405 m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
406 m_require_standard{opts.require_standard},
407 m_full_rbf{opts.full_rbf},
408 m_persist_v1_dat{opts.persist_v1_dat},
409 m_limits{opts.limits}
416 return mapNextTx.count(outpoint);
451 std::set<Txid> setParentTransactions;
452 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
453 mapNextTx.insert(std::make_pair(&tx.
vin[i].prevout, &tx));
454 setParentTransactions.insert(tx.
vin[i].prevout.hash);
464 for (
const auto& pit :
GetIterSet(setParentTransactions)) {
472 m_total_fee += entry.
GetFee();
474 txns_randomized.emplace_back(newit->GetSharedTx());
475 newit->idx_randomized = txns_randomized.size() - 1;
498 it->GetTx().GetHash().data(),
502 std::chrono::duration_cast<std::chrono::duration<std::uint64_t>>(
it->GetTime()).
count()
505 for (
const CTxIn& txin :
it->GetTx().vin)
506 mapNextTx.erase(txin.prevout);
510 if (txns_randomized.size() > 1) {
512 Assert(
GetEntry(txns_randomized.back()->GetHash()))->idx_randomized =
it->idx_randomized;
514 txns_randomized[
it->idx_randomized] = std::move(txns_randomized.back());
515 txns_randomized.pop_back();
516 if (txns_randomized.size() * 2 < txns_randomized.capacity())
517 txns_randomized.shrink_to_fit();
519 txns_randomized.clear();
521 totalTxSize -=
it->GetTxSize();
522 m_total_fee -=
it->GetFee();
523 cachedInnerUsage -=
it->DynamicMemoryUsage();
538 if (setDescendants.count(entryit) == 0) {
539 stage.insert(entryit);
544 while (!stage.empty()) {
546 setDescendants.insert(
it);
551 txiter childiter = mapTx.iterator_to(child);
552 if (!setDescendants.count(childiter)) {
553 stage.insert(childiter);
565 if (origit != mapTx.end()) {
566 txToRemove.insert(origit);
572 for (
unsigned int i = 0; i < origTx.
vout.size(); i++) {
574 if (
it == mapNextTx.end())
576 txiter nextit = mapTx.find(
it->second->GetHash());
577 assert(nextit != mapTx.end());
578 txToRemove.insert(nextit);
596 for (indexed_transaction_set::const_iterator
it = mapTx.begin();
it != mapTx.end();
it++) {
597 if (check_final_and_mature(
it)) txToRemove.insert(
it);
604 for (indexed_transaction_set::const_iterator
it = mapTx.begin();
it != mapTx.end();
it++) {
615 if (
it != mapNextTx.end()) {
617 if (txConflict != tx)
632 std::vector<RemovedMempoolTransactionInfo> txs_removed_for_block;
633 txs_removed_for_block.reserve(vtx.size());
634 for (
const auto& tx : vtx)
637 if (
it != mapTx.end()) {
640 txs_removed_for_block.emplace_back(*
it);
647 lastRollingFeeUpdate =
GetTime();
648 blockSinceLastRollingFeeBump =
true;
651 void CTxMemPool::check(
const CCoinsViewCache& active_coins_tip, int64_t spendheight)
const 659 LogPrint(
BCLog::MEMPOOL,
"Checking mempool with %u transactions and %u inputs\n", (
unsigned int)mapTx.size(), (
unsigned int)mapNextTx.size());
661 uint64_t checkTotal = 0;
663 uint64_t innerUsage = 0;
664 uint64_t prev_ancestor_count{0};
666 CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
669 checkTotal +=
it->GetTxSize();
670 check_total_fee +=
it->GetFee();
671 innerUsage +=
it->DynamicMemoryUsage();
677 indexed_transaction_set::const_iterator it2 = mapTx.find(txin.
prevout.
hash);
678 if (it2 != mapTx.end()) {
681 setParentCheck.insert(*it2);
688 auto it3 = mapNextTx.find(txin.
prevout);
689 assert(it3 != mapNextTx.end());
691 assert(it3->second == &tx);
696 assert(setParentCheck.size() ==
it->GetMemPoolParentsConst().size());
697 assert(std::equal(setParentCheck.begin(), setParentCheck.end(),
it->GetMemPoolParentsConst().begin(), comp));
700 uint64_t nCountCheck = ancestors.size() + 1;
701 int32_t nSizeCheck =
it->GetTxSize();
702 CAmount nFeesCheck =
it->GetModifiedFee();
703 int64_t nSigOpCheck =
it->GetSigOpCost();
705 for (
txiter ancestorIt : ancestors) {
706 nSizeCheck += ancestorIt->GetTxSize();
707 nFeesCheck += ancestorIt->GetModifiedFee();
708 nSigOpCheck += ancestorIt->GetSigOpCost();
711 assert(
it->GetCountWithAncestors() == nCountCheck);
712 assert(
it->GetSizeWithAncestors() == nSizeCheck);
713 assert(
it->GetSigOpCostWithAncestors() == nSigOpCheck);
714 assert(
it->GetModFeesWithAncestors() == nFeesCheck);
716 assert(prev_ancestor_count <= it->GetCountWithAncestors());
717 prev_ancestor_count =
it->GetCountWithAncestors();
721 auto iter = mapNextTx.lower_bound(
COutPoint(
it->GetTx().GetHash(), 0));
722 int32_t child_sizes{0};
723 for (; iter != mapNextTx.end() && iter->first->hash ==
it->GetTx().GetHash(); ++iter) {
724 txiter childit = mapTx.find(iter->second->GetHash());
725 assert(childit != mapTx.end());
726 if (setChildrenCheck.insert(*childit).second) {
727 child_sizes += childit->GetTxSize();
730 assert(setChildrenCheck.size() ==
it->GetMemPoolChildrenConst().size());
731 assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(),
it->GetMemPoolChildrenConst().begin(), comp));
734 assert(
it->GetSizeWithDescendants() >= child_sizes +
it->GetTxSize());
740 for (
const auto& input: tx.
vin) mempoolDuplicate.SpendCoin(input.prevout);
741 AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
743 for (
auto it = mapNextTx.cbegin();
it != mapNextTx.cend();
it++) {
745 indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
747 assert(it2 != mapTx.end());
751 assert(totalTxSize == checkTotal);
752 assert(m_total_fee == check_total_fee);
753 assert(innerUsage == cachedInnerUsage);
764 indexed_transaction_set::const_iterator j = wtxid ?
get_iter_from_wtxid(hashb) : mapTx.find(hashb);
765 if (j == mapTx.end())
return false;
766 indexed_transaction_set::const_iterator i = wtxid ?
get_iter_from_wtxid(hasha) : mapTx.find(hasha);
767 if (i == mapTx.end())
return true;
768 uint64_t counta = i->GetCountWithAncestors();
769 uint64_t countb = j->GetCountWithAncestors();
770 if (counta == countb) {
773 return counta < countb;
777 class DepthAndScoreComparator
780 bool operator()(
const CTxMemPool::indexed_transaction_set::const_iterator& a,
const CTxMemPool::indexed_transaction_set::const_iterator& b)
782 uint64_t counta = a->GetCountWithAncestors();
783 uint64_t countb = b->GetCountWithAncestors();
784 if (counta == countb) {
787 return counta < countb;
794 std::vector<indexed_transaction_set::const_iterator> iters;
797 iters.reserve(mapTx.size());
799 for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) {
802 std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
807 return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
814 std::vector<CTxMemPoolEntryRef>
ret;
815 ret.reserve(mapTx.size());
817 ret.emplace_back(*
it);
827 std::vector<TxMempoolInfo>
ret;
828 ret.reserve(mapTx.size());
829 for (
auto it : iters) {
839 const auto i = mapTx.find(txid);
840 return i == mapTx.end() ? nullptr : &(*i);
846 indexed_transaction_set::const_iterator i = mapTx.find(hash);
847 if (i == mapTx.end())
849 return i->GetSharedTx();
856 if (i == mapTx.end())
865 if (i != mapTx.end() && i->GetSequence() < last_sequence) {
876 CAmount &delta = mapDeltas[hash];
879 if (
it != mapTx.end()) {
883 for (
txiter ancestorIt : ancestors) {
889 setDescendants.erase(
it);
890 for (
txiter descendantIt : setDescendants) {
896 mapDeltas.erase(hash);
897 LogPrintf(
"PrioritiseTransaction: %s (%sin mempool) delta cleared\n", hash.
ToString(),
it == mapTx.end() ?
"not " :
"");
899 LogPrintf(
"PrioritiseTransaction: %s (%sin mempool) fee += %s, new delta=%s\n",
901 it == mapTx.end() ?
"not " :
"",
911 std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(hash);
912 if (pos == mapDeltas.end())
914 const CAmount &delta = pos->second;
921 mapDeltas.erase(hash);
928 std::vector<delta_info> result;
929 result.reserve(mapDeltas.size());
930 for (
const auto& [txid, delta] : mapDeltas) {
931 const auto iter{mapTx.find(txid)};
932 const bool in_mempool{iter != mapTx.end()};
933 std::optional<CAmount> modified_fee;
934 if (in_mempool) modified_fee = iter->GetModifiedFee();
935 result.emplace_back(
delta_info{in_mempool, delta, modified_fee, txid});
942 const auto it = mapNextTx.find(prevout);
943 return it == mapNextTx.end() ? nullptr :
it->second;
948 auto it = mapTx.find(txid);
949 if (
it != mapTx.end())
return it;
956 for (
const auto& h : hashes) {
958 if (mi)
ret.insert(*mi);
966 std::vector<txiter>
ret;
967 ret.reserve(txids.size());
968 for (
const auto& txid : txids) {
978 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
999 if (outpoint.
n < ptx->vout.size()) {
1012 for (
unsigned int n = 0; n < tx->vout.size(); ++n) {
1032 if (m_unbroadcast_txids.erase(txid))
1034 LogPrint(
BCLog::MEMPOOL,
"Removed %i from set of unbroadcast txns%s\n", txid.
GetHex(), (unchecked ?
" before confirmation that txn was sent out" :
""));
1049 indexed_transaction_set::index<entry_time>::type::iterator
it = mapTx.get<
entry_time>().begin();
1051 while (
it != mapTx.get<
entry_time>().end() &&
it->GetTime() < time) {
1052 toremove.insert(mapTx.project<0>(
it));
1056 for (
txiter removeit : toremove) {
1060 return stage.size();
1073 if (add && entry->GetMemPoolChildren().insert(*child).second) {
1075 }
else if (!add && entry->GetMemPoolChildren().erase(*child)) {
1084 if (add && entry->GetMemPoolParents().insert(*parent).second) {
1086 }
else if (!add && entry->GetMemPoolParents().erase(*parent)) {
1093 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0)
1094 return CFeeRate(llround(rollingMinimumFeeRate));
1097 if (time > lastRollingFeeUpdate + 10) {
1104 rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
1105 lastRollingFeeUpdate = time;
1108 rollingMinimumFeeRate = 0;
1117 if (rate.
GetFeePerK() > rollingMinimumFeeRate) {
1119 blockSinceLastRollingFeeBump =
false;
1126 unsigned nTxnRemoved = 0;
1129 indexed_transaction_set::index<descendant_score>::type::iterator
it = mapTx.get<
descendant_score>().begin();
1135 CFeeRate removed(
it->GetModFeesWithDescendants(),
it->GetSizeWithDescendants());
1138 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
1142 nTxnRemoved += stage.size();
1144 std::vector<CTransaction> txn;
1145 if (pvNoSpendsRemaining) {
1146 txn.reserve(stage.size());
1147 for (
txiter iter : stage)
1148 txn.push_back(iter->GetTx());
1151 if (pvNoSpendsRemaining) {
1155 pvNoSpendsRemaining->push_back(txin.
prevout);
1161 if (maxFeeRateRemoved >
CFeeRate(0)) {
1168 std::vector<txiter> candidates;
1170 candidates.push_back(entry);
1171 uint64_t maximum = 0;
1172 while (candidates.size()) {
1173 txiter candidate = candidates.back();
1174 candidates.pop_back();
1175 if (!counted.insert(candidate).second)
continue;
1177 if (parents.size() == 0) {
1178 maximum = std::max(maximum, candidate->GetCountWithDescendants());
1181 candidates.push_back(mapTx.iterator_to(i));
1190 auto it = mapTx.find(txid);
1191 ancestors = descendants = 0;
1192 if (
it != mapTx.end()) {
1193 ancestors =
it->GetCountWithAncestors();
1194 if (ancestorsize) *ancestorsize =
it->GetSizeWithAncestors();
1195 if (ancestorfees) *ancestorfees =
it->GetModFeesWithAncestors();
1203 return m_load_tried;
1209 m_load_tried = load_tried;
1215 std::vector<txiter> clustered_txs{
GetIterVec(txids)};
1219 for (
const auto&
it : clustered_txs) {
1223 for (
size_t i{0}; i < clustered_txs.size(); ++i) {
1225 if (clustered_txs.size() > 500)
return {};
1226 const txiter& tx_iter = clustered_txs.at(i);
1227 for (
const auto& entries : {tx_iter->GetMemPoolParentsConst(), tx_iter->GetMemPoolChildrenConst()}) {
1229 const auto entry_it = mapTx.iterator_to(entry);
1231 clustered_txs.push_back(entry_it);
1236 return clustered_txs;
std::shared_ptr< const CTransaction > CTransactionRef
void UpdateDescendantState(int32_t modifySize, CAmount modifyFee, int64_t modifyCount)
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)
#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.
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
static constexpr ExplicitCopyTag ExplicitCopy
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...
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
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.
void MempoolTransactionsRemovedForBlock(const std::vector< RemovedMempoolTransactionInfo > &, unsigned int nBlockHeight)
int64_t descendant_count
The maximum allowed number of transactions in a package including the entry and its descendants...
Removed for reorganization.
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
constexpr const std::byte * data() 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 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.
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(const CTxMemPoolEntry &entry) EXCLUSIVE_LOCKS_REQUIRED(cs
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
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
const CTxMemPoolEntry * GetEntry(const Txid &txid) const LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(cs)
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)
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
static transaction_identifier FromUint256(const uint256 &id)
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)
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...
util::Result< void > CheckPackageLimits(const Package &package, int64_t total_vsize) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Calculate all in-mempool ancestors of a set of transactions not already in the mempool and check ance...
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
setEntries GetIterSet(const std::set< Txid > &hashes) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Translate a set of hashes into a set of pool iterators to avoid repeated lookups. ...
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
A generic txid reference (txid or wtxid).
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.
const uint256 & GetHash() const LIFETIMEBOUND
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
#define Assert(val)
Identity function.
void TransactionRemovedFromMempool(const CTransactionRef &, MemPoolRemovalReason, uint64_t mempool_sequence)
const Txid & GetHash() const LIFETIMEBOUND