24 int64_t _nTime,
unsigned int _entryHeight,
25 bool _spendsCoinbase, int64_t _sigOpsCost,
LockPoints lp):
26 tx(_tx), nFee(_nFee), nTime(_nTime), entryHeight(_entryHeight),
27 spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp)
48 feeDelta = newFeeDelta;
67 stageEntries = GetMemPoolChildren(updateIt);
69 while (!stageEntries.empty()) {
70 const txiter cit = *stageEntries.begin();
71 setAllDescendants.insert(cit);
72 stageEntries.erase(cit);
73 const setEntries &setChildren = GetMemPoolChildren(cit);
74 for (
const txiter childEntry : setChildren) {
75 cacheMap::iterator cacheIt = cachedDescendants.find(childEntry);
76 if (cacheIt != cachedDescendants.end()) {
79 for (
const txiter cacheEntry : cacheIt->second) {
80 setAllDescendants.insert(cacheEntry);
82 }
else if (!setAllDescendants.count(childEntry)) {
84 stageEntries.insert(childEntry);
90 int64_t modifySize = 0;
92 int64_t modifyCount = 0;
93 for (
txiter cit : setAllDescendants) {
94 if (!setExclude.count(cit->GetTx().GetHash())) {
95 modifySize += cit->GetTxSize();
96 modifyFee += cit->GetModifiedFee();
98 cachedDescendants[updateIt].insert(cit);
100 mapTx.modify(cit,
update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost()));
117 cacheMap mapMemPoolDescendantsToUpdate;
121 std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end());
132 txiter it = mapTx.find(hash);
133 if (it == mapTx.end()) {
136 auto iter = mapNextTx.lower_bound(
COutPoint(hash, 0));
139 for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) {
140 const uint256 &childHash = iter->second->GetHash();
141 txiter childIter = mapTx.find(childHash);
142 assert(childIter != mapTx.end());
145 if (setChildren.insert(childIter).second && !setAlreadyIncluded.count(childHash)) {
146 UpdateChild(it, childIter,
true);
147 UpdateParent(childIter, it,
true);
150 UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded);
161 if (fSearchForParents) {
165 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
166 txiter piter = mapTx.find(tx.
vin[i].prevout.hash);
167 if (piter != mapTx.end()) {
168 parentHashes.insert(piter);
169 if (parentHashes.size() + 1 > limitAncestorCount) {
170 errString =
strprintf(
"too many unconfirmed parents [limit: %u]", limitAncestorCount);
178 txiter it = mapTx.iterator_to(entry);
179 parentHashes = GetMemPoolParents(it);
182 size_t totalSizeWithAncestors = entry.
GetTxSize();
184 while (!parentHashes.empty()) {
185 txiter stageit = *parentHashes.begin();
187 setAncestors.insert(stageit);
188 parentHashes.erase(stageit);
189 totalSizeWithAncestors += stageit->GetTxSize();
191 if (stageit->GetSizeWithDescendants() + entry.
GetTxSize() > limitDescendantSize) {
192 errString =
strprintf(
"exceeds descendant size limit for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantSize);
194 }
else if (stageit->GetCountWithDescendants() + 1 > limitDescendantCount) {
195 errString =
strprintf(
"too many descendants for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantCount);
197 }
else if (totalSizeWithAncestors > limitAncestorSize) {
198 errString =
strprintf(
"exceeds ancestor size limit [limit: %u]", limitAncestorSize);
202 const setEntries & setMemPoolParents = GetMemPoolParents(stageit);
203 for (
const txiter &phash : setMemPoolParents) {
205 if (setAncestors.count(phash) == 0) {
206 parentHashes.insert(phash);
208 if (parentHashes.size() + setAncestors.size() + 1 > limitAncestorCount) {
209 errString =
strprintf(
"too many unconfirmed ancestors [limit: %u]", limitAncestorCount);
220 setEntries parentIters = GetMemPoolParents(it);
222 for (
txiter piter : parentIters) {
223 UpdateChild(piter, it, add);
225 const int64_t updateCount = (add ? 1 : -1);
226 const int64_t updateSize = updateCount * it->GetTxSize();
227 const CAmount updateFee = updateCount * it->GetModifiedFee();
228 for (
txiter ancestorIt : setAncestors) {
235 int64_t updateCount = setAncestors.size();
236 int64_t updateSize = 0;
238 int64_t updateSigOpsCost = 0;
239 for (
txiter ancestorIt : setAncestors) {
240 updateSize += ancestorIt->GetTxSize();
241 updateFee += ancestorIt->GetModifiedFee();
242 updateSigOpsCost += ancestorIt->GetSigOpCost();
249 const setEntries &setMemPoolChildren = GetMemPoolChildren(it);
250 for (
txiter updateIt : setMemPoolChildren) {
251 UpdateParent(updateIt, it,
false);
259 const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
260 if (updateDescendants) {
267 for (
txiter removeIt : entriesToRemove) {
269 CalculateDescendants(removeIt, setDescendants);
270 setDescendants.erase(removeIt);
271 int64_t modifySize = -((int64_t)removeIt->GetTxSize());
272 CAmount modifyFee = -removeIt->GetModifiedFee();
273 int modifySigOps = -removeIt->GetSigOpCost();
274 for (
txiter dit : setDescendants) {
279 for (
txiter removeIt : entriesToRemove) {
300 CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy,
false);
303 UpdateAncestorsOf(
false, removeIt, setAncestors);
308 for (
txiter removeIt : entriesToRemove) {
309 UpdateChildrenForRemoval(removeIt);
334 nTransactionsUpdated(0), minerPolicyEstimator(estimator)
369 indexed_transaction_set::iterator newit =
mapTx.insert(entry).first;
375 std::map<uint256, CAmount>::const_iterator pos =
mapDeltas.find(hash);
377 const CAmount &delta = pos->second;
389 std::set<uint256> setParentTransactions;
390 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
392 setParentTransactions.insert(tx.
vin[i].prevout.hash);
402 for (
const uint256 &phash : setParentTransactions) {
404 if (pit !=
mapTx.end()) {
416 newit->vTxHashesIdx =
vTxHashes.size() - 1;
425 std::vector<CMempoolAddressDeltaKey> inserted;
428 for (
unsigned int j = 0; j < tx.
vin.size(); j++) {
435 mapAddress.insert(std::make_pair(key, delta));
436 inserted.push_back(key);
441 mapAddress.insert(std::make_pair(key, delta));
442 inserted.push_back(key);
447 mapAddress.insert(std::make_pair(key, delta));
448 inserted.push_back(key);
453 std::string assetName;
458 mapAddress.insert(std::make_pair(key, delta));
459 inserted.push_back(key);
466 for (
unsigned int k = 0; k < tx.
vout.size(); k++) {
472 inserted.push_back(key);
475 std::pair<addressDeltaMap::iterator,bool> ret;
478 inserted.push_back(key);
481 std::pair<addressDeltaMap::iterator,bool> ret;
484 inserted.push_back(key);
489 std::string assetName;
492 std::pair<addressDeltaMap::iterator, bool> ret;
495 inserted.push_back(key);
506 std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> > &results)
509 for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
512 while (ait !=
mapAddress.end() && (*ait).first.addressBytes == (*it).first && (*ait).first.type == (*it).second
513 && (*ait).first.asset == assetName) {
514 results.push_back(*ait);
522 std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> > &results)
525 for (std::vector<std::pair<uint160, int> >::iterator it = addresses.begin(); it != addresses.end(); it++) {
527 while (ait !=
mapAddress.end() && (*ait).first.addressBytes == (*it).first && (*ait).first.type == (*it).second) {
528 results.push_back(*ait);
541 std::vector<CMempoolAddressDeltaKey> keys = (*it).second;
542 for (std::vector<CMempoolAddressDeltaKey>::iterator mit = keys.begin(); mit != keys.end(); mit++) {
556 std::vector<CSpentIndexKey> inserted;
559 for (
unsigned int j = 0; j < tx.
vin.size(); j++) {
582 mapSpent.insert(std::make_pair(key, value));
583 inserted.push_back(key);
593 mapSpentIndex::iterator it;
609 std::vector<CSpentIndexKey> keys = (*it).second;
610 for (std::vector<CSpentIndexKey>::iterator mit = keys.begin(); mit != keys.end(); mit++) {
622 const uint256 hash = it->GetTx().GetHash();
623 for (
const CTxIn& txin : it->GetTx().vin)
628 vTxHashes[it->vTxHashesIdx].second->vTxHashesIdx = it->vTxHashesIdx;
696 if (setDescendants.count(entryit) == 0) {
697 stage.insert(entryit);
702 while (!stage.empty()) {
703 txiter it = *stage.begin();
704 setDescendants.insert(it);
708 for (
const txiter &childiter : setChildren) {
709 if (!setDescendants.count(childiter)) {
710 stage.insert(childiter);
723 if (origit !=
mapTx.end()) {
724 txToRemove.insert(origit);
730 for (
unsigned int i = 0; i < origTx.
vout.size(); i++) {
735 assert(nextit !=
mapTx.end());
736 txToRemove.insert(nextit);
740 for (
txiter it : txToRemove) {
753 for (indexed_transaction_set::const_iterator it =
mapTx.begin(); it !=
mapTx.end(); it++) {
760 txToRemove.insert(it);
761 }
else if (it->GetSpendsCoinbase()) {
763 indexed_transaction_set::const_iterator it2 =
mapTx.find(txin.
prevout.
hash);
764 if (it2 !=
mapTx.end())
769 txToRemove.insert(it);
779 for (
txiter it : txToRemove) {
793 if (txConflict != tx)
818 std::set<uint256> setAlreadyRemoving;
820 std::vector<const CTxMemPoolEntry*> entries;
821 for (
const auto& tx : vtx)
825 indexed_transaction_set::iterator i =
mapTx.find(hash);
826 if (i !=
mapTx.end())
827 entries.push_back(&*i);
832 std::vector<CTransaction> trans;
836 if (i !=
mapTx.end()) {
837 entries.push_back(&*i);
838 trans.emplace_back(i->GetTx());
847 indexed_transaction_set::iterator i =
mapTx.find(hash);
848 if (i !=
mapTx.end()) {
851 entries.push_back(&*i);
852 trans.emplace_back(i->GetTx());
853 setAlreadyRemoving.insert(hash);
863 indexed_transaction_set::iterator i =
mapTx.find(hash);
864 if (i !=
mapTx.end()) {
867 entries.push_back(&*i);
868 trans.emplace_back(i->GetTx());
869 setAlreadyRemoving.insert(hash);
880 indexed_transaction_set::iterator i =
mapTx.find(hash);
881 if (i !=
mapTx.end()) {
884 entries.push_back(&*i);
885 trans.emplace_back(i->GetTx());
886 setAlreadyRemoving.insert(hash);
896 auto pair = std::make_pair(it.address, it.assetName);
899 indexed_transaction_set::iterator i =
mapTx.find(hash);
900 if (i !=
mapTx.end()) {
902 std::vector<std::pair<std::string, uint256>> vReissueAssets;
904 entries.push_back(&*i);
905 trans.emplace_back(i->GetTx());
906 setAlreadyRemoving.insert(hash);
917 for (
const auto& tx : vtx)
920 if (it !=
mapTx.end()) {
931 for (
auto tx : trans)
934 if (it !=
mapTx.end()) {
984 std::vector<std::pair<std::string, uint256>> vReissueAssets;
986 assert(fCheckResult && fCheckAssets);
988 assert(fCheckResult);
1003 uint64_t checkTotal = 0;
1004 uint64_t innerUsage = 0;
1006 CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
1010 std::list<const CTxMemPoolEntry*> waitingOnDependants;
1011 for (indexed_transaction_set::const_iterator it =
mapTx.begin(); it !=
mapTx.end(); it++) {
1013 checkTotal += it->GetTxSize();
1014 innerUsage += it->DynamicMemoryUsage();
1016 txlinksMap::const_iterator linksiter =
mapLinks.find(it);
1017 assert(linksiter !=
mapLinks.end());
1018 const TxLinks &links = linksiter->second;
1019 innerUsage += memusage::DynamicUsage(links.parents) + memusage::DynamicUsage(links.children);
1020 bool fDependsWait =
false;
1022 int64_t parentSizes = 0;
1023 int64_t parentSigOpCost = 0;
1026 indexed_transaction_set::const_iterator it2 =
mapTx.find(txin.
prevout.
hash);
1027 if (it2 !=
mapTx.end()) {
1030 fDependsWait =
true;
1031 if (setParentCheck.insert(it2).second) {
1032 parentSizes += it2->GetTxSize();
1033 parentSigOpCost += it2->GetSigOpCost();
1041 assert(it3->first == &txin.
prevout);
1042 assert(it3->second == &tx);
1048 uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
1051 uint64_t nCountCheck = setAncestors.size() + 1;
1052 uint64_t nSizeCheck = it->GetTxSize();
1053 CAmount nFeesCheck = it->GetModifiedFee();
1054 int64_t nSigOpCheck = it->GetSigOpCost();
1056 for (
txiter ancestorIt : setAncestors) {
1057 nSizeCheck += ancestorIt->GetTxSize();
1058 nFeesCheck += ancestorIt->GetModifiedFee();
1059 nSigOpCheck += ancestorIt->GetSigOpCost();
1062 assert(it->GetCountWithAncestors() == nCountCheck);
1063 assert(it->GetSizeWithAncestors() == nSizeCheck);
1064 assert(it->GetSigOpCostWithAncestors() == nSigOpCheck);
1065 assert(it->GetModFeesWithAncestors() == nFeesCheck);
1070 int64_t childSizes = 0;
1071 for (; iter !=
mapNextTx.
end() && iter->first->hash == it->GetTx().GetHash(); ++iter) {
1072 txiter childit =
mapTx.find(iter->second->GetHash());
1073 assert(childit !=
mapTx.end());
1074 if (setChildrenCheck.insert(childit).second) {
1075 childSizes += childit->GetTxSize();
1081 assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize());
1084 waitingOnDependants.push_back(&(*it));
1086 CheckInputsAndUpdateCoins(tx, mempoolDuplicate, spendheight);
1089 unsigned int stepsSinceLastRemove = 0;
1090 while (!waitingOnDependants.empty()) {
1092 waitingOnDependants.pop_front();
1095 waitingOnDependants.push_back(entry);
1096 stepsSinceLastRemove++;
1097 assert(stepsSinceLastRemove < waitingOnDependants.size());
1099 CheckInputsAndUpdateCoins(entry->
GetTx(), mempoolDuplicate, spendheight);
1100 stepsSinceLastRemove = 0;
1104 uint256 hash = it->second->GetHash();
1105 indexed_transaction_set::const_iterator it2 =
mapTx.find(hash);
1107 assert(it2 !=
mapTx.end());
1108 assert(&tx == it->second);
1118 indexed_transaction_set::const_iterator i =
mapTx.find(hasha);
1119 if (i ==
mapTx.end())
return false;
1120 indexed_transaction_set::const_iterator j =
mapTx.find(hashb);
1121 if (j ==
mapTx.end())
return true;
1122 uint64_t counta = i->GetCountWithAncestors();
1123 uint64_t countb = j->GetCountWithAncestors();
1124 if (counta == countb) {
1127 return counta < countb;
1131 class DepthAndScoreComparator
1134 bool operator()(
const CTxMemPool::indexed_transaction_set::const_iterator& a,
const CTxMemPool::indexed_transaction_set::const_iterator& b)
1136 uint64_t counta = a->GetCountWithAncestors();
1137 uint64_t countb = b->GetCountWithAncestors();
1138 if (counta == countb) {
1141 return counta < countb;
1148 std::vector<indexed_transaction_set::const_iterator> iters;
1151 iters.reserve(
mapTx.size());
1153 for (indexed_transaction_set::iterator mi =
mapTx.begin(); mi !=
mapTx.end(); ++mi) {
1154 iters.push_back(mi);
1156 std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
1166 vtxid.reserve(
mapTx.size());
1168 for (
auto it : iters) {
1169 vtxid.push_back(it->GetTx().GetHash());
1173 static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
1174 return TxMempoolInfo{it->GetSharedTx(), it->GetTime(),
CFeeRate(it->GetFee(), it->GetTxSize()), it->GetModifiedFee() - it->
GetFee()};
1182 std::vector<TxMempoolInfo> ret;
1183 ret.reserve(
mapTx.size());
1184 for (
auto it : iters) {
1185 ret.push_back(GetInfo(it));
1194 indexed_transaction_set::const_iterator i =
mapTx.find(hash);
1195 if (i ==
mapTx.end())
1197 return i->GetSharedTx();
1203 indexed_transaction_set::const_iterator i =
mapTx.find(hash);
1204 if (i ==
mapTx.end())
1216 if (it !=
mapTx.end()) {
1220 uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
1223 for (
txiter ancestorIt : setAncestors) {
1229 setDescendants.erase(it);
1230 for (
txiter descendantIt : setDescendants) {
1242 std::map<uint256, CAmount>::const_iterator pos =
mapDeltas.find(hash);
1245 const CAmount &delta = pos->second;
1257 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
1271 if (outpoint.
n < ptx->vout.size()) {
1272 coin =
Coin(ptx->vout[outpoint.
n], MEMPOOL_HEIGHT,
false);
1284 return memusage::MallocUsage(
sizeof(
CTxMemPoolEntry) + 15 *
sizeof(
void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage;
1289 UpdateForRemoveFromMempool(stage, updateDescendants);
1290 for (
const txiter& it : stage) {
1291 removeUnchecked(it, reason);
1297 indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get<
entry_time>().begin();
1299 while (it != mapTx.get<
entry_time>().end() && it->GetTime() < time) {
1300 toremove.insert(mapTx.project<0>(it));
1304 for (
txiter removeit : toremove) {
1305 CalculateDescendants(removeit, stage);
1308 return stage.size();
1315 uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
1317 CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
1318 return addUnchecked(hash, entry, setAncestors, validFeeEstimate);
1324 if (add && mapLinks[entry].children.insert(child).second) {
1325 cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
1326 }
else if (!add && mapLinks[entry].children.erase(child)) {
1327 cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
1334 if (add && mapLinks[entry].parents.insert(parent).second) {
1335 cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
1336 }
else if (!add && mapLinks[entry].parents.erase(parent)) {
1337 cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
1343 assert (entry != mapTx.end());
1344 txlinksMap::const_iterator it = mapLinks.find(entry);
1345 assert(it != mapLinks.end());
1346 return it->second.parents;
1351 assert (entry != mapTx.end());
1352 txlinksMap::const_iterator it = mapLinks.find(entry);
1353 assert(it != mapLinks.end());
1354 return it->second.children;
1359 if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0)
1360 return CFeeRate(llround(rollingMinimumFeeRate));
1363 if (time > lastRollingFeeUpdate + 10) {
1364 double halflife = ROLLING_FEE_HALFLIFE;
1365 if (DynamicMemoryUsage() < sizelimit / 4)
1367 else if (DynamicMemoryUsage() < sizelimit / 2)
1370 rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
1371 lastRollingFeeUpdate = time;
1374 rollingMinimumFeeRate = 0;
1383 if (rate.
GetFeePerK() > rollingMinimumFeeRate) {
1385 blockSinceLastRollingFeeBump =
false;
1392 unsigned nTxnRemoved = 0;
1394 while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) {
1395 indexed_transaction_set::index<descendant_score>::type::iterator it = mapTx.get<
descendant_score>().begin();
1401 CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants());
1403 trackPackageRemoved(removed);
1404 maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
1407 CalculateDescendants(mapTx.project<0>(it), stage);
1408 nTxnRemoved += stage.size();
1410 std::vector<CTransaction> txn;
1411 if (pvNoSpendsRemaining) {
1412 txn.reserve(stage.size());
1413 for (
txiter iter : stage)
1414 txn.push_back(iter->GetTx());
1417 if (pvNoSpendsRemaining) {
1421 pvNoSpendsRemaining->push_back(txin.
prevout);
1427 if (maxFeeRateRemoved >
CFeeRate(0)) {
1434 auto it = mapTx.find(txid);
1435 return it == mapTx.end() || (it->GetCountWithAncestors() < chainLimit &&
1436 it->GetCountWithDescendants() < chainLimit);
addressDeltaMapInserted mapAddressInserted
size_type count(const K &key) const
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
Compute the virtual transaction size (weight reinterpreted as bytes).
Information about a mempool transaction.
int Expire(int64_t time)
Expire all transaction (and their dependencies) in the mempool older than time.
void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors)
Set ancestor state for an entry.
CAmount nModFeesWithDescendants
... and total fees (all including us)
void UpdateLockPoints(const LockPoints &lp)
void addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view)
std::set< CAssetCacheNewAsset > newAssetsToAdd
void removeConflicts(const CTransaction &tx)
size_t nTxWeight
... and avoid recomputing tx weight (also used for GetTxSize())
uint256 GetWitnessHash() const
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
std::vector< TxMempoolInfo > infoAll() const
std::map< uint256, std::set< std::string > > mapHashQualifiersChanged
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or a pruned one if not found.
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason=MemPoolRemovalReason::UNKNOWN)
void trackPackageRemoved(const CFeeRate &rate)
addressDeltaMap mapAddress
boost::signals2::signal< void(CTransactionRef)> NotifyEntryAdded
bool IsPayToScriptHash() const
size_t DynamicMemoryUsage() const
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
bool isSpent(const COutPoint &outpoint)
bool removeTx(uint256 hash, bool inBlock)
Remove a transaction from the mempool tracking stats.
reverse_range< T > reverse_iterate(T &x)
TxMempoolInfo info(const uint256 &hash) const
const_iterator cend() const
std::map< uint256, std::set< std::string > > mapHashVerifierChanged
std::map< uint256, std::set< std::string > > mapHashMarkedGlobalFrozen
CTxOut out
unspent transaction output
CTxMemPool(CBlockPolicyEstimator *estimator=nullptr)
Create a new CTxMemPool.
std::set< CAssetCacheRestrictedGlobal > newGlobalRestrictionsToAdd
bool HasNoInputsOf(const CTransaction &tx) const
Check that none of this transactions inputs are in the mempool, and thus the tx is not dependent on o...
std::set< CAssetCacheRestrictedAddress > newAddressRestrictionsToAdd
const_iterator cbegin() const
std::set< txiter, CompareIteratorByHash > setEntries
void queryHashes(std::vector< uint256 > &vtxid)
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
int64_t sigOpCost
Total sigop cost.
bool getAddressIndex(std::vector< std::pair< uint160, int > > &addresses, std::string assetName, std::vector< std::pair< CMempoolAddressDeltaKey, CMempoolAddressDelta > > &results)
uint160 Hash160(const T1 pbegin, const T1 pend)
Compute the 160-bit hash an object.
void TrimToSize(size_t sizelimit, std::vector< COutPoint > *pvNoSpendsRemaining=nullptr)
Remove transactions from the mempool until its dynamic size is <= sizelimit.
bool HaveInputs(const CTransaction &tx) const
Check whether all prevouts of the transaction are present in the UTXO set represented by this view...
std::shared_ptr< const CTransaction > CTransactionRef
uint64_t nCountWithDescendants
number of descendant transactions
int64_t lastRollingFeeUpdate
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight, ConnectedBlockAssetData &connectedBlockData)
Called when a block is connected.
CAmount nFee
Cached to avoid expensive parent-transaction lookups.
indirectmap< COutPoint, const CTransaction * > mapNextTx
const std::vector< CTxIn > vin
void UpdateTransactionsFromBlock(const std::vector< uint256 > &vHashesToUpdate)
When adding transactions from a disconnected block back to the mempool, new mempool entries may have ...
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...
indexed_transaction_set mapTx
int64_t CAmount
Amount in corbies (Can be negative)
bool blockSinceLastRollingFeeBump
#define AssertLockHeld(cs)
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
Removed in size limiting.
int64_t nSigOpCostWithAncestors
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
bool IsPayToPublicKey() const
RVN END.
std::vector< std::pair< uint256, txiter > > vTxHashes
All tx witness hashes/entries in mapTx, in random order.
void UpdateFeeDelta(int64_t feeDelta)
std::map< uint256, std::string > mapHashToAsset
bool CheckFinalTx(const CTransaction &tx, int flags)
Transaction validation functions.
size_t nUsageSize
... and total memory usage
bool AreAssetsDeployed()
RVN START.
int GetSpendHeight(const CCoinsViewCache &inputs)
RVN END.
uint64_t nSizeWithAncestors
int64_t feeDelta
Used for determining the priority of the transaction for mining in a block.
Abstract view on the open txout dataset.
size_t DynamicMemoryUsage() const
void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const
std::pair< iterator, bool > insert(const value_type &value)
An input of a transaction.
bool removeAddressIndex(const uint256 txhash)
We want to be able to estimate feerates that are needed on tx's to be included in a certain number of...
iterator lower_bound(const K &key)
bool CheckTxInputs(const CTransaction &tx, CValidationState &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...
const uint256 & GetHash() const
std::vector< indexed_transaction_set::const_iterator > GetSortedDepthAndScore() const
CTransactionRef GetSharedTx() const
Removed for reorganization.
void UpdateParent(txiter entry, txiter parent, bool add)
std::map< std::string, uint256 > mapReissuedAssets
std::map< uint256, CAmount > mapDeltas
void CalculateDescendants(txiter it, setEntries &setDescendants)
Populate setDescendants with all in-mempool descendants of hash.
bool ParseAssetScript(CScript scriptPubKey, uint160 &hashBytes, std::string &assetName, CAmount &assetAmount)
Helper method for extracting address bytes, asset name and amount from an asset script.
const setEntries & GetMemPoolChildren(txiter entry) const
const std::vector< CTxOut > vout
std::map< std::string, std::set< uint256 > > mapAssetVerifierChanged
std::map< std::string, std::set< uint256 > > mapAddressesQualifiersChanged
uint64_t cachedInnerUsage
sum of dynamic memory usage of all the map elements (NOT the maps themselves)
bool exists(uint256 hash) const
bool TestLockPointValidity(const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
An output of a transaction.
CAmount nModFeesWithAncestors
std::string ToString() const
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
Try to calculate all in-mempool ancestors of entry.
unsigned int nTransactionsUpdated
Used by getblocktemplate to trigger CreateNewBlock() invocation.
void UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int modifySigOps)
Manually removed or unknown reason.
An outpoint - a combination of a transaction hash and an index n into its vout.
uint64_t nSizeWithDescendants
... and size
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...
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints *lp, bool useExistingLockPoints)
Check if transaction will be BIP 68 final in the next block to be created.
uint64_t totalTxSize
sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discount...
indexed_transaction_set::nth_index< 0 >::type::iterator txiter
bool removeSpentIndex(const uint256 txhash)
std::map< std::pair< std::string, std::string >, std::set< uint256 > > mapAddressesMarkedFrozen
Restricted assets maps.
bool TransactionWithinChainLimit(const uint256 &txid, size_t chainLimit) const
Returns false if the transaction is in the mempool and not within the chain limit specified...
#define LogPrint(category,...)
CAssetsCache * passets
Global variable that point to the active assets (protected by cs_main)
void UpdateChildrenForRemoval(txiter entry)
Sever link between specified transaction and direct children.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
std::map< uint256, std::set< std::pair< std::string, std::string > > > mapHashToAddressMarkedFrozen
bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb)
void processBlock(unsigned int nBlockHeight, std::vector< const CTxMemPoolEntry *> &entries)
Process all the transactions that have been included in a block.
std::map< txiter, setEntries, CompareIteratorByHash > cacheMap
std::map< std::string, uint256 > mapAssetToHash
LockPoints lockPoints
Track the height and time at which tx was final.
uint32_t nCheckFrequency
Value n means that n times in 2^32 we check.
std::set< CAssetCacheQualifierAddress > newQualifiersToAdd
void UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount)
const CTransaction & GetTx() const
std::map< uint256, std::string > mapReissuedTx
void UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants)
For each transaction being removed, update ancestors and any direct children.
uint64_t nCountWithAncestors
Fee rate in satoshis per kilobyte: CAmount / kB.
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, uint256 blockHash, CAssetsCache *assetCache, std::pair< std::string, CBlockAssetUndo > *undoAssetData)
void UpdateChild(txiter entry, txiter child, bool add)
unsigned int GetTransactionsUpdated() const
bool CheckTransaction(const CTransaction &tx, CValidationState &state, bool fCheckDuplicateInputs)
Transaction validation functions.
const setEntries & GetMemPoolParents(txiter entry) const
std::set< CAssetCacheRestrictedVerifiers > newVerifiersToAdd
bool CheckTxAssets(const CTransaction &tx, CValidationState &state, const CCoinsViewCache &inputs, CAssetsCache *assetCache, bool fCheckMempool, std::vector< std::pair< std::string, uint256 > > &vPairReissueAssets, const bool fRunningUnitTests=false, std::set< CMessage > *setMessages=nullptr, int64_t nBlocktime=0)
RVN START.
void ClearPrioritisation(const uint256 hash)
CTransactionRef get(const uint256 &hash) const
bool getSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors)
Update ancestors of hash to add/remove it as a descendant transaction.
boost::signals2::signal< void(CTransactionRef, MemPoolRemovalReason)> NotifyEntryRemoved
bool addUnchecked(const uint256 &hash, const CTxMemPoolEntry &entry, bool validFeeEstimate=true)
mapSpentIndexInserted mapSpentInserted
CCoinsViewMemPool(CCoinsView *baseIn, const CTxMemPool &mempoolIn)
std::map< std::string, std::set< uint256 > > mapAssetMarkedGlobalFrozen
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
std::string ToString() const
The basic transaction that is broadcasted on the network and contained in blocks. ...
CCoinsView backed by another CCoinsView.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Sort by score of entry ((fee+delta)/size) in descending order.
const CTxMemPool & mempool
void addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view)
CBlockPolicyEstimator * minerPolicyEstimator
double rollingMinimumFeeRate
minimum fee to get into the pool, decreases exponentially
CFeeRate incrementalRelayFee
bool IsPayToPublicKeyHash() const
iterator find(const K &key)
CTxMemPoolEntry(const CTransactionRef &_tx, const CAmount &_nFee, int64_t _nTime, unsigned int _entryHeight, bool spendsCoinbase, int64_t nSigOpsCost, LockPoints lp)
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags)
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
void removeUnchecked(txiter entry, MemPoolRemovalReason reason=MemPoolRemovalReason::UNKNOWN)
Before calling removeUnchecked for a given transaction, UpdateForRemoveFromMempool must be called on ...
void RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason=MemPoolRemovalReason::UNKNOWN)
Remove a set of transactions from the mempool.
uint64_t GetRand(uint64_t nMax)
void processTransaction(const CTxMemPoolEntry &entry, bool validFeeEstimate)
Process a transaction accepted to the mempool.
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
void UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, const std::set< uint256 > &setExclude)
UpdateForDescendants is used by UpdateTransactionsFromBlock to update the descendants for a single tr...
size_type erase(const K &key)