35 inline constexpr uint64_t
nNoLimit = std::numeric_limits<uint64_t>::max();
41 int64_t _modifyCount, int64_t _modifySigChecks)
59 int64_t _modifyCount, int64_t _modifySigChecks)
94 int64_t time,
unsigned int entry_height,
95 bool spends_coinbase, int64_t _sigChecks,
99 nTime(time), entryHeight{entry_height},
spendsCoinbase(spends_coinbase),
100 sigChecks(_sigChecks), lockPoints(
lp), nSizeWithDescendants{GetTxSize()},
101 nModFeesWithDescendants{nFee}, nSigChecksWithDescendants{
sigChecks},
102 nSizeWithAncestors{GetTxSize()}, nModFeesWithAncestors{nFee},
137 size_t entry_size,
size_t entry_count,
setEntries &setAncestors,
139 uint64_t limitAncestorSize, uint64_t limitDescendantCount,
140 uint64_t limitDescendantSize, std::string &errString)
const {
141 size_t totalSizeWithAncestors = entry_size;
143 while (!staged_ancestors.empty()) {
145 txiter stageit = mapTx.iterator_to(stage);
147 setAncestors.insert(stageit);
148 staged_ancestors.erase(staged_ancestors.begin());
149 totalSizeWithAncestors += stageit->
GetTxSize();
151 if (stageit->GetSizeWithDescendants() + entry_size >
152 limitDescendantSize) {
154 "exceeds descendant size limit for tx %s [limit: %u]",
155 stageit->GetTx().GetId().ToString(), limitDescendantSize);
159 if (stageit->GetCountWithDescendants() + entry_count >
160 limitDescendantCount) {
161 errString =
strprintf(
"too many descendants for tx %s [limit: %u]",
162 stageit->GetTx().GetId().ToString(),
163 limitDescendantCount);
167 if (totalSizeWithAncestors > limitAncestorSize) {
168 errString =
strprintf(
"exceeds ancestor size limit [limit: %u]",
174 stageit->GetMemPoolParentsConst();
176 txiter parent_it = mapTx.iterator_to(parent);
179 if (setAncestors.count(parent_it) == 0) {
180 staged_ancestors.insert(parent);
182 if (staged_ancestors.size() + setAncestors.size() + entry_count >
183 limitAncestorCount) {
185 strprintf(
"too many unconfirmed ancestors [limit: %u]",
196 uint64_t limitAncestorCount,
197 uint64_t limitAncestorSize,
198 uint64_t limitDescendantCount,
199 uint64_t limitDescendantSize,
200 std::string &errString)
const {
202 size_t total_size = 0;
203 for (
const auto &tx : package) {
205 for (
const auto &input : tx->vin) {
206 std::optional<txiter> piter =
GetIter(input.prevout.GetTxId());
208 staged_ancestors.insert(**piter);
209 if (staged_ancestors.size() + package.size() >
210 limitAncestorCount) {
212 strprintf(
"too many unconfirmed parents [limit: %u]",
225 total_size, package.size(), setAncestors, staged_ancestors,
226 limitAncestorCount, limitAncestorSize, limitDescendantCount,
227 limitDescendantSize, errString);
230 errString.insert(0,
"possibly ");
237 uint64_t limitAncestorCount, uint64_t limitAncestorSize,
238 uint64_t limitDescendantCount, uint64_t limitDescendantSize,
239 std::string &errString,
bool fSearchForParents )
const {
243 if (fSearchForParents) {
252 staged_ancestors.insert(**piter);
253 if (staged_ancestors.size() + 1 > limitAncestorCount) {
255 strprintf(
"too many unconfirmed parents [limit: %u]",
267 entry.
GetTxSize(), 1, setAncestors, staged_ancestors,
268 limitAncestorCount, limitAncestorSize, limitDescendantCount,
269 limitDescendantSize, errString);
281 const int64_t updateCount = (add ? 1 : -1);
282 const int64_t updateSize = updateCount * it->GetTxSize();
283 const int64_t updateSigChecks = updateCount * it->GetSigChecks();
284 const Amount updateFee = updateCount * it->GetModifiedFee();
285 for (
txiter ancestorIt : *setAncestors) {
286 mapTx.modify(ancestorIt,
288 updateCount, updateSigChecks));
299 int64_t updateCount = setAncestors->size();
300 int64_t updateSize = 0;
301 int64_t updateSigChecks = 0;
304 for (
txiter ancestorIt : *setAncestors) {
305 updateSize += ancestorIt->GetTxSize();
306 updateFee += ancestorIt->GetModifiedFee();
307 updateSigChecks += ancestorIt->GetSigChecks();
321 bool updateDescendants) {
328 if (updateDescendants) {
336 for (
txiter removeIt : entriesToRemove) {
339 setDescendants.erase(removeIt);
340 int64_t modifySize = -int64_t(removeIt->GetTxSize());
341 Amount modifyFee = -1 * removeIt->GetModifiedFee();
342 int modifySigChecks = -removeIt->GetSigChecks();
343 for (
txiter dit : setDescendants) {
346 -1, modifySigChecks));
351 for (
txiter removeIt : entriesToRemove) {
366 for (
txiter removeIt : entriesToRemove) {
376 for (
txiter removeIt : entriesToRemove) {
384 int64_t modifySigChecks) {
396 int64_t modifySigChecks) {
415 return mapNextTx.count(outpoint);
427 const setEntries &setAncestors) {
436 entry.UpdateFeeDelta(feeDelta);
441 auto [newit, inserted] = mapTx.insert(entry);
452 cachedInnerUsage += entry.DynamicMemoryUsage();
455 std::set<TxId> setParentTransactions;
457 mapNextTx.insert(std::make_pair(&in.
prevout, &tx));
465 for (
const auto &pit :
GetIterSet(setParentTransactions)) {
474 totalTxSize += entry.GetTxSize();
475 m_total_fee += entry.GetFee();
489 it->GetSharedTx(), reason, mempool_sequence);
492 for (
const CTxIn &txin : it->GetTx().vin) {
493 mapNextTx.erase(txin.prevout);
499 totalTxSize -= it->GetTxSize();
500 m_total_fee -= it->GetFee();
501 cachedInnerUsage -= it->DynamicMemoryUsage();
517 if (setDescendants.count(entryit) == 0) {
518 stage.insert(entryit);
523 while (!stage.empty()) {
524 txiter it = *stage.begin();
525 setDescendants.insert(it);
526 stage.erase(stage.begin());
529 it->GetMemPoolChildrenConst();
531 txiter childiter = mapTx.iterator_to(child);
532 if (!setDescendants.count(childiter)) {
533 stage.insert(childiter);
545 if (origit != mapTx.end()) {
546 txToRemove.insert(origit);
553 while (it != mapNextTx.end() &&
554 it->first->GetTxId() == origTx.
GetId()) {
555 txiter nextit = mapTx.find(it->second->GetId());
556 assert(nextit != mapTx.end());
557 txToRemove.insert(nextit);
563 for (
txiter it : txToRemove) {
574 auto it = mapNextTx.find(txin.
prevout);
575 if (it != mapNextTx.end()) {
577 if (txConflict != tx) {
592 if (mapTx.empty() && mapDeltas.empty()) {
607 if (it != mapTx.end()) {
618 disconnectpool.
clear();
620 lastRollingFeeUpdate =
GetTime();
621 blockSinceLastRollingFeeBump =
true;
629 cachedInnerUsage = 0;
630 lastRollingFeeUpdate =
GetTime();
631 blockSinceLastRollingFeeBump =
false;
632 rollingMinimumFeeRate = 0;
642 int64_t spendheight)
const {
654 "Checking mempool with %u transactions and %u inputs\n",
655 (
unsigned int)mapTx.size(), (
unsigned int)mapNextTx.size());
657 uint64_t checkTotal = 0;
659 uint64_t innerUsage = 0;
665 checkTotal += entry.GetTxSize();
666 check_total_fee += entry.GetFee();
667 innerUsage += entry.DynamicMemoryUsage();
677 if (parentIt != mapTx.end()) {
681 setParentCheck.insert(*parentIt);
684 assert(parentIt->GetEntryId() < entry.GetEntryId());
692 auto prevoutNextIt = mapNextTx.find(txin.
prevout);
693 assert(prevoutNextIt != mapNextTx.end());
695 assert(prevoutNextIt->second == &tx);
699 return a.
GetTx().
GetId() == b.GetTx().GetId();
701 assert(setParentCheck.size() == entry.GetMemPoolParentsConst().size());
702 assert(std::equal(setParentCheck.begin(), setParentCheck.end(),
703 entry.GetMemPoolParentsConst().begin(), comp));
714 uint64_t nCountCheck = setAncestors.size() + 1;
715 uint64_t nSizeCheck = entry.GetTxSize();
716 Amount nFeesCheck = entry.GetModifiedFee();
717 int64_t nSigChecksCheck = entry.GetSigChecks();
719 for (
txiter ancestorIt : setAncestors) {
720 nSizeCheck += ancestorIt->GetTxSize();
721 nFeesCheck += ancestorIt->GetModifiedFee();
722 nSigChecksCheck += ancestorIt->GetSigChecks();
725 assert(entry.GetCountWithAncestors() == nCountCheck);
726 assert(entry.GetSizeWithAncestors() == nSizeCheck);
727 assert(entry.GetSigChecksWithAncestors() == nSigChecksCheck);
728 assert(entry.GetModFeesWithAncestors() == nFeesCheck);
732 for (
const auto &ancestor : setAncestors) {
733 assert(ancestor->GetEntryId() < entry.GetEntryId());
738 auto iter = mapNextTx.lower_bound(
COutPoint(entry.GetTx().GetId(), 0));
739 uint64_t child_sizes = 0;
740 int64_t child_sigChecks = 0;
741 for (; iter != mapNextTx.end() &&
742 iter->first->GetTxId() == entry.GetTx().GetId();
744 txiter childIt = mapTx.find(iter->second->GetId());
746 assert(childIt != mapTx.end());
747 if (setChildrenCheck.insert(*childIt).second) {
748 child_sizes += childIt->GetTxSize();
749 child_sigChecks += childIt->GetSigChecks();
752 assert(setChildrenCheck.size() ==
753 entry.GetMemPoolChildrenConst().size());
754 assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(),
755 entry.GetMemPoolChildrenConst().begin(), comp));
760 assert(entry.GetSizeWithDescendants() >=
761 child_sizes + entry.GetTxSize());
762 assert(entry.GetSigChecksWithDescendants() >=
763 child_sigChecks + entry.GetSigChecks());
771 spendheight, txfee));
772 for (
const auto &input : tx.
vin) {
773 mempoolDuplicate.SpendCoin(input.prevout);
775 AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
778 for (
auto &[
_, nextTx] : mapNextTx) {
779 txiter it = mapTx.find(nextTx->GetId());
780 assert(it != mapTx.end());
781 assert(&it->GetTx() == nextTx);
784 assert(totalTxSize == checkTotal);
785 assert(m_total_fee == check_total_fee);
786 assert(innerUsage == cachedInnerUsage);
790 const TxId &txidb)
const {
792 auto it1 = mapTx.find(txida);
793 if (it1 == mapTx.end()) {
796 auto it2 = mapTx.find(txidb);
797 if (it2 == mapTx.end()) {
800 return it1->GetEntryId() < it2->GetEntryId();
807 vtxid.reserve(mapTx.size());
809 for (
const auto &entry : mapTx.get<
entry_id>()) {
810 vtxid.push_back(entry.GetTx().GetId());
815 GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
816 return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(),
817 it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
823 std::vector<TxMempoolInfo> ret;
824 ret.reserve(mapTx.size());
826 const auto &index = mapTx.get<
entry_id>();
827 for (
auto it = index.begin(); it != index.end(); ++it) {
828 ret.push_back(
GetInfo(mapTx.project<0>(it)));
836 indexed_transaction_set::const_iterator i = mapTx.find(txid);
837 if (i == mapTx.end()) {
841 return i->GetSharedTx();
846 indexed_transaction_set::const_iterator i = mapTx.find(txid);
847 if (i == mapTx.end()) {
857 uint64_t maxMempoolSize =
870 Amount &delta = mapDeltas[txid];
872 txiter it = mapTx.find(txid);
873 if (it != mapTx.end()) {
883 for (
txiter ancestorIt : setAncestors) {
884 mapTx.modify(ancestorIt,
891 setDescendants.erase(it);
892 for (
txiter descendantIt : setDescendants) {
893 mapTx.modify(descendantIt,
906 std::map<TxId, Amount>::const_iterator pos = mapDeltas.find(txid);
907 if (pos == mapDeltas.end()) {
911 nFeeDelta += pos->second;
916 mapDeltas.erase(txid);
920 const auto it = mapNextTx.find(prevout);
921 return it == mapNextTx.end() ? nullptr : it->second;
925 auto it = mapTx.find(txid);
926 if (it != mapTx.end()) {
935 for (
const auto &txid : txids) {
972 if (outpoint.
GetN() < ptx->vout.size()) {
982 for (uint32_t n = 0; n < tx->vout.size(); ++n) {
993 12 *
sizeof(
void *)) *
1002 if (m_unbroadcast_txids.erase(txid)) {
1006 (unchecked ?
" before confirmation that txn was sent out" :
""));
1014 for (
txiter it : stage) {
1021 indexed_transaction_set::index<entry_time>::type::iterator it =
1024 while (it != mapTx.get<
entry_time>().end() && it->GetTime() < time) {
1025 toremove.insert(mapTx.project<0>(it));
1030 for (
txiter removeit : toremove) {
1035 return stage.size();
1039 std::chrono::seconds age) {
1042 int expired =
Expire(GetTime<std::chrono::seconds>() - age);
1045 "Expired %i transactions from the memory pool\n", expired);
1048 std::vector<COutPoint> vNoSpendsRemaining;
1050 for (
const COutPoint &removed : vNoSpendsRemaining) {
1068 if (add && entry->GetMemPoolChildren().insert(*child).second) {
1070 }
else if (!add && entry->GetMemPoolChildren().erase(*child)) {
1078 if (add && entry->GetMemPoolParents().insert(*parent).second) {
1080 }
else if (!add && entry->GetMemPoolParents().erase(*parent)) {
1087 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0) {
1092 if (time > lastRollingFeeUpdate + 10) {
1100 rollingMinimumFeeRate =
1101 rollingMinimumFeeRate /
1102 pow(2.0, (time - lastRollingFeeUpdate) / halflife);
1103 lastRollingFeeUpdate = time;
1112 blockSinceLastRollingFeeBump =
false;
1117 std::vector<COutPoint> *pvNoSpendsRemaining) {
1120 unsigned nTxnRemoved = 0;
1131 CFeeRate removed = it->GetModifiedFeeRate();
1135 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
1139 nTxnRemoved += stage.size();
1141 if (pvNoSpendsRemaining) {
1142 for (
const txiter &iter : stage) {
1143 for (
const CTxIn &txin : iter->GetTx().vin) {
1145 pvNoSpendsRemaining->push_back(txin.
prevout);
1156 "Removed %u txn, rolling minimum fee bumped to %s\n",
1157 nTxnRemoved, maxFeeRateRemoved.
ToString());
1164 std::vector<txiter> candidates;
1166 candidates.push_back(entry);
1167 uint64_t maximum = 0;
1168 while (candidates.size()) {
1169 txiter candidate = candidates.back();
1170 candidates.pop_back();
1171 if (!counted.insert(candidate).second) {
1175 candidate->GetMemPoolParentsConst();
1176 if (parents.size() == 0) {
1177 maximum = std::max(maximum, candidate->GetCountWithDescendants());
1180 candidates.push_back(mapTx.iterator_to(i));
1188 size_t &descendants,
1189 size_t *
const ancestorsize,
1190 Amount *
const ancestorfees)
const {
1192 auto it = mapTx.find(txid);
1193 ancestors = descendants = 0;
1194 if (it != mapTx.end()) {
1195 ancestors = it->GetCountWithAncestors();
1197 *ancestorsize = it->GetSizeWithAncestors();
1200 *ancestorfees = it->GetModFeesWithAncestors();
1213 m_is_loaded = loaded;
1220 const std::vector<CTransactionRef> &vtx,
CTxMemPool &pool) {
1233 std::unordered_set<TxId, SaltedTxIdHasher> parents;
1241 while (parents.size() > 0) {
1242 std::unordered_set<TxId, SaltedTxIdHasher> worklist(
1243 std::move(parents));
1246 for (
const TxId &txid : worklist) {
1261 for (
const CTxIn &in : ptx->vin) {
1289 std::vector<CTransactionRef> vtx;
1291 vtx.reserve(pool.mapTx.
size());
1294 vtx.push_back(e.GetSharedTx());
1297 txInfo.try_emplace(e.GetTx().GetId(), e.GetTime(),
1298 e.GetModifiedFee() - e.GetFee(), e.GetHeight());
1329 if (
auto it = txInfo.find(tx->
GetId()); it != txInfo.end()) {
1342 if (fAddToMempool) {
1356 bool hasFeeDelta =
false;
1360 pool.mapDeltas[tx->
GetId()] = ptxInfo->feeDelta;
1365 config, active_chainstate, tx,
1366 ptxInfo ? ptxInfo->time.count() :
GetTime(),
1368 ptxInfo ? ptxInfo->height : 0);
1369 if (result.m_result_type !=
1373 pool.mapDeltas.erase(tx->
GetId());
1385 std::chrono::hours{gArgs.GetIntArg(
"-mempoolexpiry",
1386 DEFAULT_MEMPOOL_EXPIRY)});
static constexpr Amount SATOSHI
RecursiveMutex cs_main
Global state.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
An in-memory indexed chain of blocks.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
CCoinsView backed by another CCoinsView.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Abstract view on the open txout dataset.
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
std::unordered_map< COutPoint, Coin, SaltedOutpointHasher > m_temp_added
Coins made available by transactions being validated.
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
void PackageAddTransaction(const CTransactionRef &tx)
Add the coins created by this transaction.
const CTxMemPool & mempool
Fee rate in satoshis per kilobyte: Amount / kB.
std::string ToString() const
Amount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
void TransactionRemovedFromMempool(const CTransactionRef &, MemPoolRemovalReason, uint64_t mempool_sequence)
An outpoint - a combination of a transaction hash and an index n into its vout.
const TxId & GetTxId() const
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxOut > vout
const std::vector< CTxIn > vin
An input of a transaction.
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
std::set< CTxMemPoolEntryRef, CompareIteratorById > Parents
uint64_t GetVirtualSizeWithDescendants() const
int64_t nSigChecksWithDescendants
... and sichecks
const CTransaction & GetTx() const
const Parents & GetMemPoolParentsConst() const
void UpdateAncestorState(int64_t modifySize, Amount modifyFee, int64_t modifyCount, int64_t modifySigChecks)
const size_t nTxSize
... and avoid recomputing tx size
void UpdateLockPoints(const LockPoints &lp)
uint64_t GetVirtualSizeWithAncestors() const
Amount nModFeesWithAncestors
void UpdateFeeDelta(Amount feeDelta)
void SetEntryId(uint64_t eid)
This should only be set by addUnchecked() before entry insertion into mempool.
int64_t nSigChecksWithAncestors
uint64_t nCountWithDescendants
number of descendant transactions
Amount feeDelta
Used for determining the priority of the transaction for mining in a block.
CTxMemPoolEntry(const CTransactionRef &_tx, const Amount fee, int64_t time, unsigned int entry_height, bool spends_coinbase, int64_t sigchecks, LockPoints lp)
Amount nModFeesWithDescendants
... and total fees (all including us)
uint64_t nSizeWithDescendants
... and size
uint64_t nCountWithAncestors
size_t GetTxVirtualSize() const
void UpdateDescendantState(int64_t modifySize, Amount modifyFee, int64_t modifyCount, int64_t modifySigChecks)
LockPoints lockPoints
Track the height and time at which tx was final.
uint64_t nSizeWithAncestors
std::set< CTxMemPoolEntryRef, CompareIteratorById > Children
const int64_t sigChecks
Total sigChecks.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs)
CFeeRate estimateFee() const
bool HasNoInputsOf(const CTransaction &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Check that none of this transactions inputs are in the mempool, and thus the tx is not dependent on o...
void ClearPrioritisation(const TxId &txid) EXCLUSIVE_LOCKS_REQUIRED(cs)
std::set< txiter, CompareIteratorById > setEntries
void RemoveUnbroadcastTx(const TxId &txid, const bool unchecked=false)
Removes a transaction from the unbroadcast set.
void UpdateParentsOf(bool add, txiter it, const setEntries *setAncestors=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Update parents of it to add/remove it as a child transaction.
void UpdateEntryForAncestors(txiter it, const setEntries *setAncestors) EXCLUSIVE_LOCKS_REQUIRED(cs)
Set ancestor state for an entry.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
void trackPackageRemoved(const CFeeRate &rate) EXCLUSIVE_LOCKS_REQUIRED(cs)
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
const int m_check_ratio
Value n means that 1 times in n we check.
void TrimToSize(size_t sizelimit, std::vector< COutPoint > *pvNoSpendsRemaining=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove transactions from the mempool until its dynamic size is <= sizelimit.
void AddTransactionsUpdated(unsigned int n)
void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs)
Sever link between specified transaction and direct children.
bool CompareTopologically(const TxId &txida, const TxId &txidb) const
TxMempoolInfo info(const TxId &txid) const
void getAllTxIds(std::vector< TxId > &vtxid) const
std::atomic< uint32_t > nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
setEntries GetIterSet(const std::set< TxId > &txids) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Translate a set of txids into a set of pool iterators to avoid repeated lookups.
size_t DynamicMemoryUsage() const
std::vector< TxMempoolInfo > infoAll() const
void SetIsLoaded(bool loaded)
Sets the current loaded state.
void UpdateParent(txiter entry, txiter parent, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
void removeUnchecked(txiter entry, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Before calling removeUnchecked for a given transaction, UpdateForRemoveFromMempool must be called on ...
void removeForBlock(const std::vector< CTransactionRef > &vtx) EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
int Expire(std::chrono::seconds time) EXCLUSIVE_LOCKS_REQUIRED(cs)
Expire all transaction (and their dependencies) in the mempool older than time.
bool exists(const TxId &txid) const
bool CheckPackageLimits(const Package &package, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, 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...
CTxMemPool(int check_ratio=0)
Create a new CTxMemPool.
void LimitSize(CCoinsViewCache &coins_cache, size_t limit, std::chrono::seconds age) EXCLUSIVE_LOCKS_REQUIRED(cs
Reduce the size of the mempool by expiring and then trimming the mempool.
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.
static const int ROLLING_FEE_HALFLIFE
void GetTransactionAncestry(const TxId &txid, size_t &ancestors, size_t &descendants, size_t *ancestorsize=nullptr, Amount *ancestorfees=nullptr) const
Calculate the ancestor and descendant count for the given transaction.
CTransactionRef get(const TxId &txid) const
void PrioritiseTransaction(const TxId &txid, const Amount nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
uint64_t GetAndIncrementSequence() const EXCLUSIVE_LOCKS_REQUIRED(cs)
Guards this internal counter for external reporting.
void UpdateChild(txiter entry, txiter child, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs)
std::atomic< bool > wellingtonLatched
Wellington activation latch.
const CTransaction * GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
void RemoveStaged(const setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove a set of transactions from the mempool.
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
unsigned long size() const
void ApplyDelta(const TxId &txid, Amount &nFeeDelta) 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.
std::optional< txiter > GetIter(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given txid, if found.
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void cs_main
bool CalculateAncestorsAndCheckLimits(size_t entry_size, size_t entry_count, setEntries &setAncestors, CTxMemPoolEntry::Parents &staged_ancestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Helper function to calculate all in-mempool ancestors of staged_ancestors and apply ancestor and desc...
uint64_t CalculateDescendantMaximum(txiter entry) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove after wellington activates as this will be inaccurate.
bool isSpent(const COutPoint &outpoint) const
unsigned int GetTransactionsUpdated() const
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...
void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs)
Chainstate stores and provides an API to update our local knowledge of the current best chain.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
void updateMempoolForReorg(const Config &config, Chainstate &active_chainstate, bool fAddToMempool, CTxMemPool &pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Make mempool consistent after a reorg, by re-adding or recursively erasing disconnected block transac...
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
indexed_disconnected_transactions queuedTx
TxInfoMap txInfo
populated by importMempool(); the original tx entry times and feeDeltas
uint64_t cachedInnerUsage
size_t DynamicMemoryUsage() const
const TxInfo * getTxInfo(const CTransactionRef &tx) const
void addTransaction(const CTransactionRef &tx)
const indexed_disconnected_transactions & GetQueuedTx() const
void addForBlock(const std::vector< CTransactionRef > &vtx, CTxMemPool &pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
void importMempool(CTxMemPool &pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
std::string ToString() const
std::string GetHex() const
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
static const uint64_t DEFAULT_MAX_BLOCK_SIZE
Default setting for maximum allowed size for a block, in bytes.
static size_t RecursiveDynamicUsage(const CScript &script)
#define LogPrint(category,...)
std::string FormatMoney(const Amount amt)
Do not use these functions to represent or parse monetary amounts to or from JSON but use AmountFromV...
bool CheckTxInputs(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, Amount &txfee)
Check whether all inputs of this transaction are valid (no double spends and amounts).
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
static size_t IncrementalDynamicUsage(const std::set< X, Y > &s)
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
int64_t GetVirtualTransactionSize(int64_t nSize, int64_t nSigChecks, unsigned int bytes_per_sigCheck)
Compute the virtual transaction size (size, or more if sigChecks are too dense).
static const CFeeRate MEMPOOL_FULL_FEE_INCREMENT(1000 *SATOSHI)
Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP...
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
std::shared_ptr< const CTransaction > CTransactionRef
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
reverse_range< T > reverse_iterate(T &x)
static constexpr Amount zero()
CBlockIndex * maxInputBlock
@ VALID
Fully validated, valid.
A TxId is the identifier of a transaction.
Information about a mempool transaction.
void operator()(CTxMemPoolEntry &e)
update_ancestor_state(int64_t _modifySize, Amount _modifyFee, int64_t _modifyCount, int64_t _modifySigChecks)
void operator()(CTxMemPoolEntry &e)
update_descendant_state(int64_t _modifySize, Amount _modifyFee, int64_t _modifyCount, int64_t _modifySigChecks)
T GetTime()
Return system time (or mocked time, if set)
bilingual_str _(const char *psz)
Translation function.
bool TestLockPointValidity(const CChain &active_chain, const LockPoints &lp)
Test whether the LockPoints height and time are still valid on the current chain.
static const size_t MAX_DISCONNECTED_TX_POOL_SIZE
Maximum bytes for transactions to store for processing during reorg.
constexpr uint64_t nNoLimit
Used in various places in this file to signify "no limit" for CalculateMemPoolAncestors.
static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it)
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
@ SIZELIMIT
Removed in size limiting.
@ BLOCK
Removed for block.
@ EXPIRY
Expired from mempool.
@ CONFLICT
Removed for conflict with in-block transaction.
@ REORG
Removed for reorganization.
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coins to signify they are only in the memory pool(since 0....
MempoolAcceptResult AcceptToMemoryPool(const Config &config, Chainstate &active_chainstate, const CTransactionRef &tx, int64_t accept_time, bool bypass_limits, bool test_accept, unsigned int heightOverride)
Try to add a transaction to the mempool.
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
CMainSignals & GetMainSignals()