29 int64_t _nTime,
unsigned int _entryHeight,
30 bool _spendsCoinbase, int64_t _sigOpsCount,
32 : tx(_tx), nFee(_nFee), nTxSize(tx->GetTotalSize()),
35 sigOpCount(_sigOpsCount), lockPoints(lp), m_epoch(0) {
70 feeDelta = newFeeDelta;
82 const std::set<TxId> &setExclude) {
84 stageEntries = GetMemPoolChildren(updateIt);
86 while (!stageEntries.empty()) {
87 const txiter cit = *stageEntries.begin();
88 setAllDescendants.insert(cit);
89 stageEntries.erase(cit);
90 const setEntries &setChildren = GetMemPoolChildren(cit);
91 for (
txiter childEntry : setChildren) {
92 cacheMap::iterator cacheIt = cachedDescendants.find(childEntry);
93 if (cacheIt != cachedDescendants.end()) {
96 for (
txiter cacheEntry : cacheIt->second) {
97 setAllDescendants.insert(cacheEntry);
99 }
else if (!setAllDescendants.count(childEntry)) {
101 stageEntries.insert(childEntry);
107 int64_t modifySize = 0;
108 int64_t modifyCount = 0;
110 int64_t modifySigOpCount = 0;
111 for (
txiter cit : setAllDescendants) {
112 if (!setExclude.count(cit->GetTx().GetId())) {
113 modifySize += cit->GetTxSize();
114 modifyFee += cit->GetModifiedFee();
116 modifySigOpCount += cit->GetSigOpCount();
117 cachedDescendants[updateIt].insert(cit);
121 updateIt->GetModifiedFee(), 1,
122 updateIt->GetSigOpCount()));
125 mapTx.modify(updateIt,
136 const std::vector<TxId> &txidsToUpdate) {
141 cacheMap mapMemPoolDescendantsToUpdate;
145 std::set<TxId> setAlreadyIncluded(txidsToUpdate.begin(),
146 txidsToUpdate.end());
155 txiter it = mapTx.find(txid);
156 if (it == mapTx.end()) {
160 auto iter = mapNextTx.lower_bound(
COutPoint(txid, 0));
165 const auto epoch = GetFreshEpoch();
166 for (; iter != mapNextTx.end() && iter->first->GetTxId() == txid;
168 const TxId &childTxId = iter->second->GetId();
169 txiter childIter = mapTx.find(childTxId);
170 assert(childIter != mapTx.end());
173 if (!visited(childIter) &&
174 !setAlreadyIncluded.count(childTxId)) {
175 UpdateChild(it, childIter,
true);
176 UpdateParent(childIter, it,
true);
180 UpdateForDescendants(it, mapMemPoolDescendantsToUpdate,
187 uint64_t limitAncestorCount, uint64_t limitAncestorSize,
188 uint64_t limitDescendantCount, uint64_t limitDescendantSize,
189 std::string &errString,
bool fSearchForParents )
const {
193 if (fSearchForParents) {
202 parentHashes.insert(*piter);
203 if (parentHashes.size() + 1 > limitAncestorCount) {
205 strprintf(
"too many unconfirmed parents [limit: %u]",
213 txiter it = mapTx.iterator_to(entry);
214 parentHashes = GetMemPoolParents(it);
217 size_t totalSizeWithAncestors = entry.
GetTxSize();
219 while (!parentHashes.empty()) {
220 txiter stageit = *parentHashes.begin();
222 setAncestors.insert(stageit);
223 parentHashes.erase(stageit);
224 totalSizeWithAncestors += stageit->GetTxSize();
226 if (stageit->GetSizeWithDescendants() + entry.
GetTxSize() >
227 limitDescendantSize) {
229 "exceeds descendant size limit for tx %s [limit: %u]",
230 stageit->GetTx().GetId().ToString(), limitDescendantSize);
234 if (stageit->GetCountWithDescendants() + 1 > limitDescendantCount) {
235 errString =
strprintf(
"too many descendants for tx %s [limit: %u]",
236 stageit->GetTx().GetId().ToString(),
237 limitDescendantCount);
241 if (totalSizeWithAncestors > limitAncestorSize) {
242 errString =
strprintf(
"exceeds ancestor size limit [limit: %u]",
247 const setEntries &setMemPoolParents = GetMemPoolParents(stageit);
248 for (
txiter phash : setMemPoolParents) {
250 if (setAncestors.count(phash) == 0) {
251 parentHashes.insert(phash);
253 if (parentHashes.size() + setAncestors.size() + 1 >
254 limitAncestorCount) {
256 strprintf(
"too many unconfirmed ancestors [limit: %u]",
268 setEntries parentIters = GetMemPoolParents(it);
270 for (
txiter piter : parentIters) {
271 UpdateChild(piter, it, add);
273 const int64_t updateCount = (add ? 1 : -1);
274 const int64_t updateSize = updateCount * it->GetTxSize();
275 const int64_t updateSigOpCount = updateCount * it->GetSigOpCount();
276 const Amount updateFee = updateCount * it->GetModifiedFee();
277 for (
txiter ancestorIt : setAncestors) {
278 mapTx.modify(ancestorIt,
286 int64_t updateCount = setAncestors.size();
287 int64_t updateSize = 0;
288 int64_t updateSigOpsCount = 0;
291 for (
txiter ancestorIt : setAncestors) {
292 updateSize += ancestorIt->GetTxSize();
293 updateFee += ancestorIt->GetModifiedFee();
294 updateSigOpsCount += ancestorIt->GetSigOpCount();
301 const setEntries &setMemPoolChildren = GetMemPoolChildren(it);
302 for (
txiter updateIt : setMemPoolChildren) {
303 UpdateParent(updateIt, it,
false);
308 bool updateDescendants) {
311 const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
312 if (updateDescendants) {
318 for (
txiter removeIt : entriesToRemove) {
320 CalculateDescendants(removeIt, setDescendants);
321 setDescendants.erase(removeIt);
322 int64_t modifySize = -int64_t(removeIt->GetTxSize());
323 Amount modifyFee = -1 * removeIt->GetModifiedFee();
324 int modifySigOps = -removeIt->GetSigOpCount();
325 for (
txiter dit : setDescendants) {
332 for (
txiter removeIt : entriesToRemove) {
353 CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit,
354 nNoLimit, nNoLimit, dummy,
false);
357 UpdateAncestorsOf(
false, removeIt, setAncestors);
362 for (
txiter removeIt : entriesToRemove) {
363 UpdateChildrenForRemoval(removeIt);
370 int64_t modifySigOpCount) {
382 int64_t modifySigOps) {
393 : nTransactionsUpdated(0),
m_epoch(0), m_has_epoch_guard(false) {
407 return mapNextTx.count(outpoint);
422 indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
440 std::set<TxId> setParentTransactions;
442 mapNextTx.insert(std::make_pair(&in.
prevout, &tx));
453 for (
const auto &pit :
GetIterSet(setParentTransactions)) {
462 vTxHashes.emplace_back(tx.
GetHash(), newit);
463 newit->vTxHashesIdx = vTxHashes.size() - 1;
475 for (
const CTxIn &txin : it->GetTx().vin) {
476 mapNextTx.erase(txin.prevout);
479 if (vTxHashes.size() > 1) {
480 vTxHashes[it->vTxHashesIdx] = std::move(vTxHashes.back());
481 vTxHashes[it->vTxHashesIdx].second->vTxHashesIdx = it->vTxHashesIdx;
482 vTxHashes.pop_back();
483 if (vTxHashes.size() * 2 < vTxHashes.capacity()) {
484 vTxHashes.shrink_to_fit();
508 if (setDescendants.count(entryit) == 0) {
509 stage.insert(entryit);
514 while (!stage.empty()) {
515 txiter it = *stage.begin();
516 setDescendants.insert(it);
520 for (
txiter childiter : setChildren) {
521 if (!setDescendants.count(childiter)) {
522 stage.insert(childiter);
534 if (origit != mapTx.end()) {
535 txToRemove.insert(origit);
541 for (
size_t i = 0; i < origTx.
vout.size(); i++) {
543 if (it == mapNextTx.end()) {
547 txiter nextit = mapTx.find(it->second->GetId());
548 assert(nextit != mapTx.end());
549 txToRemove.insert(nextit);
554 for (
txiter it : txToRemove) {
563 unsigned int nMemPoolHeight,
int flags) {
568 for (indexed_transaction_set::const_iterator it = mapTx.begin();
569 it != mapTx.end(); it++) {
581 txToRemove.insert(it);
582 }
else if (it->GetSpendsCoinbase()) {
584 indexed_transaction_set::const_iterator it2 =
586 if (it2 != mapTx.end()) {
591 if (nCheckFrequency != 0) {
597 int64_t(nMemPoolHeight) - coin.
GetHeight() <
599 txToRemove.insert(it);
609 for (
txiter it : txToRemove) {
619 auto it = mapNextTx.find(txin.
prevout);
620 if (it != mapNextTx.end()) {
622 if (txConflict != tx) {
635 unsigned int nBlockHeight) {
641 std::vector<const CTxMemPoolEntry *> entries;
644 const TxId &txid = tx->GetId();
646 indexed_transaction_set::iterator i = mapTx.find(txid);
647 if (i != mapTx.end()) {
648 entries.push_back(&*i);
654 txiter it = mapTx.find(tx->GetId());
655 if (it != mapTx.end()) {
664 disconnectpool.
clear();
690 const int64_t spendheight) {
698 assert(fCheckResult);
699 UpdateCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
704 if (nCheckFrequency == 0) {
708 if (
GetRand(std::numeric_limits<uint32_t>::max()) >= nCheckFrequency) {
713 "Checking mempool with %u transactions and %u inputs\n",
714 (
unsigned int)mapTx.size(), (
unsigned int)mapNextTx.size());
716 uint64_t checkTotal = 0;
717 uint64_t innerUsage = 0;
719 CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache *>(pcoins));
722 std::list<const CTxMemPoolEntry *> waitingOnDependants;
723 for (indexed_transaction_set::const_iterator it = mapTx.begin();
724 it != mapTx.end(); it++) {
726 checkTotal += it->GetTxSize();
727 innerUsage += it->DynamicMemoryUsage();
729 txlinksMap::const_iterator linksiter =
mapLinks.find(it);
730 assert(linksiter !=
mapLinks.end());
731 const TxLinks &links = linksiter->second;
734 bool fDependsWait =
false;
739 indexed_transaction_set::const_iterator it2 =
741 if (it2 != mapTx.end()) {
746 setParentCheck.insert(it2);
751 auto it3 = mapNextTx.find(txin.
prevout);
752 assert(it3 != mapNextTx.end());
753 assert(it3->first == &txin.
prevout);
754 assert(it3->second == &tx);
760 uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
763 nNoLimit, nNoLimit, dummy);
764 uint64_t nCountCheck = setAncestors.size() + 1;
765 uint64_t nSizeCheck = it->GetTxSize();
766 Amount nFeesCheck = it->GetModifiedFee();
767 int64_t nSigOpCheck = it->GetSigOpCount();
769 for (
txiter ancestorIt : setAncestors) {
770 nSizeCheck += ancestorIt->GetTxSize();
771 nFeesCheck += ancestorIt->GetModifiedFee();
772 nSigOpCheck += ancestorIt->GetSigOpCount();
775 assert(it->GetCountWithAncestors() == nCountCheck);
776 assert(it->GetSizeWithAncestors() == nSizeCheck);
777 assert(it->GetSigOpCountWithAncestors() == nSigOpCheck);
778 assert(it->GetModFeesWithAncestors() == nFeesCheck);
782 auto iter = mapNextTx.lower_bound(
COutPoint(it->GetTx().GetId(), 0));
783 uint64_t child_sizes = 0;
784 int64_t child_sigop_counts = 0;
785 for (; iter != mapNextTx.end() &&
786 iter->first->GetTxId() == it->GetTx().GetId();
788 txiter childit = mapTx.find(iter->second->GetId());
790 assert(childit != mapTx.end());
791 if (setChildrenCheck.insert(childit).second) {
792 child_sizes += childit->GetTxSize();
793 child_sigop_counts += childit->GetSigOpCount();
800 assert(it->GetSizeWithDescendants() >= child_sizes + it->GetTxSize());
801 assert(it->GetSigOpCountWithDescendants() >=
802 child_sigop_counts + it->GetSigOpCount());
805 waitingOnDependants.push_back(&(*it));
811 unsigned int stepsSinceLastRemove = 0;
812 while (!waitingOnDependants.empty()) {
814 waitingOnDependants.pop_front();
816 waitingOnDependants.push_back(entry);
817 stepsSinceLastRemove++;
818 assert(stepsSinceLastRemove < waitingOnDependants.size());
822 stepsSinceLastRemove = 0;
826 for (
auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
827 const TxId &txid = it->second->GetId();
828 indexed_transaction_set::const_iterator it2 = mapTx.find(txid);
830 assert(it2 != mapTx.end());
831 assert(&tx == it->second);
840 indexed_transaction_set::const_iterator i = mapTx.find(txida);
841 if (i == mapTx.end()) {
844 indexed_transaction_set::const_iterator j = mapTx.find(txidb);
845 if (j == mapTx.end()) {
848 uint64_t counta = i->GetCountWithAncestors();
849 uint64_t countb = j->GetCountWithAncestors();
850 if (counta == countb) {
853 return counta < countb;
857 class DepthAndScoreComparator {
860 operator()(
const CTxMemPool::indexed_transaction_set::const_iterator &a,
861 const CTxMemPool::indexed_transaction_set::const_iterator &b) {
862 uint64_t counta = a->GetCountWithAncestors();
863 uint64_t countb = b->GetCountWithAncestors();
864 if (counta == countb) {
867 return counta < countb;
872 std::vector<CTxMemPool::indexed_transaction_set::const_iterator>
874 std::vector<indexed_transaction_set::const_iterator> iters;
877 iters.reserve(mapTx.size());
878 for (indexed_transaction_set::iterator mi = mapTx.begin();
879 mi != mapTx.end(); ++mi) {
883 std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
892 vtxid.reserve(mapTx.size());
894 for (
auto it : iters) {
895 vtxid.push_back(it->GetTx().GetId());
900 GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
901 return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(),
902 it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
909 std::vector<TxMempoolInfo> ret;
910 ret.reserve(mapTx.size());
911 for (
auto it : iters) {
920 indexed_transaction_set::const_iterator i = mapTx.find(txid);
921 if (i == mapTx.end()) {
925 return i->GetSharedTx();
930 indexed_transaction_set::const_iterator i = mapTx.find(txid);
931 if (i == mapTx.end()) {
941 uint64_t maxMempoolSize =
956 txiter it = mapTx.find(txid);
957 if (it != mapTx.end()) {
961 uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
964 nNoLimit, nNoLimit, dummy,
false);
965 for (
txiter ancestorIt : setAncestors) {
966 mapTx.modify(ancestorIt,
973 setDescendants.erase(it);
974 for (
txiter descendantIt : setDescendants) {
975 mapTx.modify(descendantIt,
987 std::map<TxId, Amount>::const_iterator pos =
mapDeltas.find(txid);
992 nFeeDelta += pos->second;
1001 const auto it = mapNextTx.find(prevout);
1002 return it == mapNextTx.end() ? nullptr : it->second;
1006 auto it = mapTx.find(txid);
1007 if (it != mapTx.end()) {
1010 return std::optional<txiter>{std::nullopt};
1016 for (
const auto &txid : txids) {
1017 const auto mi =
GetIter(txid);
1046 if (outpoint.
GetN() < ptx->vout.size()) {
1060 12 *
sizeof(
void *)) *
1071 UpdateForRemoveFromMempool(stage, updateDescendants);
1072 for (
txiter it : stage) {
1073 removeUnchecked(it, reason);
1079 indexed_transaction_set::index<entry_time>::type::iterator it =
1082 while (it != mapTx.get<
entry_time>().end() && it->GetTime() < time) {
1083 toremove.insert(mapTx.project<0>(it));
1088 for (
txiter removeit : toremove) {
1089 CalculateDescendants(removeit, stage);
1093 return stage.size();
1097 int expired = Expire(GetTime<std::chrono::seconds>() - age);
1100 "Expired %i transactions from the memory pool\n", expired);
1103 std::vector<COutPoint> vNoSpendsRemaining;
1104 TrimToSize(limit, &vNoSpendsRemaining);
1105 for (
const COutPoint &removed : vNoSpendsRemaining) {
1112 uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
1114 CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit,
1121 if (add && mapLinks[entry].children.insert(child).second) {
1123 }
else if (!add && mapLinks[entry].children.erase(child)) {
1130 if (add && mapLinks[entry].parents.insert(parent).second) {
1132 }
else if (!add && mapLinks[entry].parents.erase(parent)) {
1139 assert(entry != mapTx.end());
1140 txlinksMap::const_iterator it = mapLinks.find(entry);
1141 assert(it != mapLinks.end());
1142 return it->second.parents;
1147 assert(entry != mapTx.end());
1148 txlinksMap::const_iterator it = mapLinks.find(entry);
1149 assert(it != mapLinks.end());
1150 return it->second.children;
1155 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0) {
1160 if (time > lastRollingFeeUpdate + 10) {
1161 double halflife = ROLLING_FEE_HALFLIFE;
1162 if (DynamicMemoryUsage() < sizelimit / 4) {
1164 }
else if (DynamicMemoryUsage() < sizelimit / 2) {
1168 rollingMinimumFeeRate =
1169 rollingMinimumFeeRate /
1170 pow(2.0, (time - lastRollingFeeUpdate) / halflife);
1171 lastRollingFeeUpdate = time;
1180 blockSinceLastRollingFeeBump =
false;
1185 std::vector<COutPoint> *pvNoSpendsRemaining) {
1188 unsigned nTxnRemoved = 0;
1190 while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) {
1191 indexed_transaction_set::index<descendant_score>::type::iterator it =
1199 CFeeRate removed(it->GetModFeesWithDescendants(),
1200 it->GetVirtualSizeWithDescendants());
1203 trackPackageRemoved(removed);
1204 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
1207 CalculateDescendants(mapTx.project<0>(it), stage);
1208 nTxnRemoved += stage.size();
1210 std::vector<CTransaction> txn;
1211 if (pvNoSpendsRemaining) {
1212 txn.reserve(stage.size());
1213 for (
txiter iter : stage) {
1214 txn.push_back(iter->GetTx());
1218 if (pvNoSpendsRemaining) {
1220 for (
const CTxIn &txin : tx.vin) {
1224 pvNoSpendsRemaining->push_back(txin.
prevout);
1232 "Removed %u txn, rolling minimum fee bumped to %s\n",
1233 nTxnRemoved, maxFeeRateRemoved.
ToString());
1239 std::vector<txiter> candidates;
1241 candidates.push_back(entry);
1242 uint64_t maximum = 0;
1243 while (candidates.size()) {
1244 txiter candidate = candidates.back();
1245 candidates.pop_back();
1246 if (!counted.insert(candidate).second) {
1249 const setEntries &parents = GetMemPoolParents(candidate);
1250 if (parents.size() == 0) {
1251 maximum = std::max(maximum, candidate->GetCountWithDescendants());
1253 for (
txiter i : parents) {
1254 candidates.push_back(i);
1262 size_t &descendants)
const {
1264 auto it = mapTx.find(txid);
1265 ancestors = descendants = 0;
1266 if (it != mapTx.end()) {
1267 ancestors = it->GetCountWithAncestors();
1268 descendants = CalculateDescendantMaximum(it);
1279 m_is_loaded = loaded;
1286 const std::vector<CTransactionRef> &vtx,
CTxMemPool &pool) {
1290 auto it = queuedTx.find(tx->GetId());
1291 if (it != queuedTx.end()) {
1299 std::unordered_set<TxId, SaltedTxIdHasher> parents;
1300 for (
const CTxIn &in : tx->vin) {
1307 while (parents.size() > 0) {
1308 std::unordered_set<TxId, SaltedTxIdHasher> worklist(
1309 std::move(parents));
1312 for (
const TxId &txid : worklist) {
1315 auto pit = queuedTx.find(txid);
1316 if (pit == queuedTx.end()) {
1323 queuedTx.erase(pit);
1324 queuedTx.insert(ptx);
1327 for (
const CTxIn &in : ptx->vin) {
1355 std::vector<CTransactionRef> vtx;
1357 vtx.reserve(pool.mapTx.
size());
1359 vtx.push_back(e.GetSharedTx());
1385 std::vector<TxId> txidsUpdate;
1397 if (!fAddToMempool || tx->IsCoinBase() ||
1404 }
else if (pool.
exists(tx->GetId())) {
1405 txidsUpdate.push_back(tx->GetId());
std::shared_ptr< const CTransaction > CTransactionRef
const int64_t sigOpCount
Total sigop plus P2SH sigops count.
CTransactionRef get(const TxId &txid) const
void queryHashes(std::vector< uint256 > &vtxid) const
Information about a mempool transaction.
bool CompareDepthAndScore(const TxId &txida, const TxId &txidb)
uint64_t GetRand(uint64_t nMax) noexcept
void UpdateLockPoints(const LockPoints &lp)
static constexpr Amount zero()
#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.
void GetTransactionAncestry(const TxId &txid, size_t &ancestors, size_t &descendants) const
Calculate the ancestor and descendant count for the given transaction.
std::vector< TxMempoolInfo > infoAll() const
void PrioritiseTransaction(const TxId &txid, const Amount nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
bool exists(const TxId &txid) const
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
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
Retrieve the Coin (unspent transaction output) for a given outpoint.
reverse_range< T > reverse_iterate(T &x)
void removeForReorg(const Config &config, const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) EXCLUSIVE_LOCKS_REQUIRED(cs
CTxMemPool()
Create a new CTxMemPool.
Removed in size limiting.
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs)
void UpdateAncestorState(int64_t modifySize, Amount modifyFee, int64_t modifyCount, int64_t modifySigOps)
void RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove a set of transactions from the mempool.
unsigned long size() const
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule)...
uint64_t m_epoch
epoch when last touched, useful for graph algorithms
static void LogPrintf(const char *fmt, const Args &... args)
CFeeRate estimateFee() const
const TxId & GetTxId() const
uint64_t GetVirtualSizeWithAncestors() const
void UpdateDescendantState(int64_t modifySize, Amount modifyFee, int64_t modifyCount, int64_t modifySigOpCount)
const TxHash GetHash() const
static constexpr Amount SATOSHI
void TransactionRemovedFromMempool(const CTransactionRef &)
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
static const CFeeRate MEMPOOL_FULL_FEE_INCREMENT(1000 *SATOSHI)
Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP...
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
void UpdateCoins(CCoinsViewCache &view, const CTransaction &tx, CTxUndo &txundo, int nHeight)
bool HaveInputs(const CTransaction &tx) const
Check whether all prevouts of the transaction are present in the UTXO set represented by this view...
bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx, int flags, LockPoints *lp, bool useExistingLockPoints)
Check if transaction will be BIP 68 final in the next block to be created.
void ApplyDelta(const TxId &txid, Amount &nFeeDelta) const
uint64_t nCountWithDescendants
number of descendant transactions
int64_t lastRollingFeeUpdate
virtual const CChainParams & GetChainParams() const =0
bool isSpent(const COutPoint &outpoint) const
const std::vector< CTxIn > vin
void importMempool(CTxMemPool &pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
CChainState & ChainstateActive()
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
void check(const CCoinsViewCache *pcoins) const
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
Amount nModFeesWithAncestors
void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update ancestors of hash to add/remove it as a descendant transaction.
void UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, const std::set< TxId > &setExclude) EXCLUSIVE_LOCKS_REQUIRED(cs)
UpdateForDescendants is used by UpdateTransactionsFromBlock to update the descendants for a single tr...
void updateMempoolForReorg(const Config &config, bool fAddToMempool, CTxMemPool &pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Make mempool consistent after a reorg, by re-adding or recursively erasing disconnected block transac...
size_t GetTxVirtualSize() const
bool blockSinceLastRollingFeeBump
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...
const indexed_disconnected_transactions & GetQueuedTx() const
Amount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
void LimitSize(size_t limit, std::chrono::seconds age) EXCLUSIVE_LOCKS_REQUIRED(cs
Reduce the size of the mempool by expiring and then trimming the mempool.
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
int GetSpendHeight(const CCoinsViewCache &inputs)
Return the spend height, which is one more than the inputs.GetBestBlock().
uint64_t nSizeWithAncestors
Abstract view on the open txout dataset.
size_t DynamicMemoryUsage() const
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
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.
Removed for conflict with in-block transaction.
void UpdateParent(txiter entry, txiter parent, bool add)
void removeUnchecked(txiter entry, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Before calling removeUnchecked for a given transaction, UpdateForRemoveFromMempool must be called on ...
void ClearPrioritisation(const TxId &txid)
static const size_t MAX_DISCONNECTED_TX_POOL_SIZE
Maximum bytes for transactions to store for processing during reorg.
const std::vector< CTxOut > vout
static const unsigned int DEFAULT_MEMPOOL_EXPIRY
Default for -mempoolexpiry, expiration time for mempool transactions in hours.
RecursiveMutex cs_main
Global state.
CMainSignals & GetMainSignals()
std::set< txiter, CompareIteratorById > setEntries
const size_t nTxSize
... and avoid recomputing tx size
uint64_t cachedInnerUsage
sum of dynamic memory usage of all the map elements (NOT the maps themselves)
bool TestLockPointValidity(const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
CTxMemPoolEntry(const CTransactionRef &_tx, const Amount _nFee, int64_t _nTime, unsigned int _entryHeight, bool spendsCoinbase, int64_t _nSigOpCount, LockPoints lp)
std::string ToString() const
const setEntries & GetMemPoolChildren(txiter entry) const EXCLUSIVE_LOCKS_REQUIRED(cs)
const CTransaction * GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Try to calculate all in-mempool ancestors of entry.
An outpoint - a combination of a transaction hash and an index n into its vout.
uint64_t nSizeWithDescendants
... and size
TxMempoolInfo info(const TxId &txid) const
bool ContextualCheckTransactionForCurrentBlock(const Consensus::Params ¶ms, const CTransaction &tx, TxValidationState &state, int flags)
This is a variant of ContextualCheckTransaction which computes the contextual check for a transaction...
void AddTransactionsUpdated(unsigned int n)
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
uint64_t totalTxSize
sum of all mempool tx's sizes.
static constexpr uint32_t STANDARD_LOCKTIME_VERIFY_FLAGS
Used as the flags parameter to sequence and nLocktime checks in non-consensus code.
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.
EpochGuard(const CTxMemPool &in)
int64_t nSigOpCountWithAncestors
void addUnchecked(const CTxMemPoolEntry &entry) EXCLUSIVE_LOCKS_REQUIRED(cs
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.
pool addUnchecked(CTxMemPoolEntry(tx, nFee, nTime, nHeight, spendsCoinbase, nSigOpCount, lp))
static void CheckInputsAndUpdateCoins(const CTransaction &tx, CCoinsViewCache &mempoolDuplicate, const int64_t spendheight)
std::vector< indexed_transaction_set::const_iterator > GetSortedDepthAndScore() const EXCLUSIVE_LOCKS_REQUIRED(cs)
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...
indexed_disconnected_transactions queuedTx
EpochGuard GetFreshEpoch() const EXCLUSIVE_LOCKS_REQUIRED(cs)
LockPoints lockPoints
Track the height and time at which tx was final.
const CTransaction & GetTx() const
A TxId is the identifier of a transaction.
void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs)
uint32_t GetHeight() const
void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors) EXCLUSIVE_LOCKS_REQUIRED(cs)
Set ancestor state for an entry.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
uint64_t nCountWithAncestors
Fee rate in satoshis per kilobyte: Amount / kB.
void UpdateChild(txiter entry, txiter child, bool add)
unsigned int GetTransactionsUpdated() const
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
static size_t RecursiveDynamicUsage(const CScript &script)
const setEntries & GetMemPoolParents(txiter entry) const EXCLUSIVE_LOCKS_REQUIRED(cs)
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
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.
uint64_t GetVirtualSizeWithDescendants() const
Amount nModFeesWithDescendants
... and total fees (all including us)
void trackPackageRemoved(const CFeeRate &rate) EXCLUSIVE_LOCKS_REQUIRED(cs)
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).
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
std::string ToString() const
The basic transaction that is broadcasted on the network and contained in blocks. ...
CCoinsView backed by another CCoinsView.
const Consensus::Params & GetConsensus() const
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...
uint64_t cachedInnerUsage
static const uint64_t DEFAULT_MAX_BLOCK_SIZE
Default setting for maximum allowed size for a block, in bytes.
Amount feeDelta
Used for determining the priority of the transaction for mining in a block.
AssertLockHeld(g_cs_orphans)
std::map< TxId, Amount > mapDeltas
const CTxMemPool & mempool
int64_t GetTime()
Return system time (or mocked time, if set)
void SetIsLoaded(bool loaded)
Sets the current loaded state.
void UpdateTransactionsFromBlock(const std::vector< TxId > &txidsToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs
When adding transactions from a disconnected block back to the mempool, new mempool entries may have ...
const Amount nFee
Cached to avoid expensive parent-transaction lookups.
void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs)
Sever link between specified transaction and direct children.
int64_t GetVirtualTransactionSize(int64_t nSize, int64_t nSigOpCount, unsigned int bytes_per_sigop)
Compute the virtual transaction size (size, or more if sigops are too dense).
double rollingMinimumFeeRate
minimum fee to get into the pool, decreases exponentially
std::map< txiter, setEntries, CompareIteratorById > cacheMap
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
bool AcceptToMemoryPool(const Config &config, CTxMemPool &pool, TxValidationState &state, const CTransactionRef &tx, bool bypass_limits, const Amount nAbsurdFee, bool test_accept)
(try to) add transaction to memory pool
EpochGuard: RAII-style guard for using epoch-based graph traversal algorithms.
void addForBlock(const std::vector< CTransactionRef > &vtx, CTxMemPool &pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
int64_t nSigOpCountWithDescendants
... and sigop count
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...
std::string FormatMoney(const Amount amt)
Money parsing/formatting utilities.
std::optional< txiter > GetIter(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given txid, if found.
std::atomic< uint32_t > nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
void UpdateFeeDelta(Amount feeDelta)