]> Git Repo - VerusCoin.git/blame - src/txmempool.cpp
Auto merge of #3926 - LarryRuane:3708-getaddressrpcs, r=str4d
[VerusCoin.git] / src / txmempool.cpp
CommitLineData
319b1160 1// Copyright (c) 2009-2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
7329fdd1 3// Distributed under the MIT software license, see the accompanying
bc909a7a 4// file COPYING or https://www.opensource.org/licenses/mit-license.php .
319b1160 5
319b1160 6#include "txmempool.h"
611116d4 7
71697f97 8#include "clientversion.h"
691161d4 9#include "consensus/consensus.h"
da29ecbc 10#include "consensus/validation.h"
b7b4318f 11#include "main.h"
b649e039 12#include "policy/fees.h"
fa736190 13#include "streams.h"
f5b35d23 14#include "timedata.h"
ad49c256 15#include "util.h"
a372168e 16#include "utilmoneystr.h"
85c579e3 17#include "version.h"
319b1160
GA
18
19using namespace std;
20
8bdd2877 21CTxMemPoolEntry::CTxMemPoolEntry():
a4b25180
SD
22 nFee(0), nTxSize(0), nModSize(0), nUsageSize(0), nTime(0), dPriority(0.0),
23 hadNoDependencies(false), spendsCoinbase(false)
4d707d51
GA
24{
25 nHeight = MEMPOOL_HEIGHT;
26}
27
a372168e 28CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
4d707d51 29 int64_t _nTime, double _dPriority,
a4b25180 30 unsigned int _nHeight, bool poolHasNoInputsOf,
34a64fe0 31 bool _spendsCoinbase, uint32_t _nBranchId):
b649e039 32 tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight),
a4b25180 33 hadNoDependencies(poolHasNoInputsOf),
34a64fe0 34 spendsCoinbase(_spendsCoinbase), nBranchId(_nBranchId)
4d707d51
GA
35{
36 nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
c26649f9 37 nModSize = tx.CalculateModifiedSize(nTxSize);
6bd1d60c 38 nUsageSize = RecursiveDynamicUsage(tx);
e328fa32 39 feeRate = CFeeRate(nFee, nTxSize);
4d707d51
GA
40}
41
42CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
43{
44 *this = other;
45}
46
47double
48CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
49{
a372168e 50 CAmount nValueIn = tx.GetValueOut()+nFee;
c26649f9 51 double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize;
4d707d51
GA
52 double dResult = dPriority + deltaPriority;
53 return dResult;
54}
55
8bdd2877 56CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
b649e039 57 nTransactionsUpdated(0)
319b1160
GA
58{
59 // Sanity checks off by default for performance, because otherwise
60 // accepting transactions becomes O(N^2) where N is the number
61 // of transactions in the pool
934fd197 62 nCheckFrequency = 0;
171ca774 63
b649e039 64 minerPolicyEstimator = new CBlockPolicyEstimator(_minRelayFee);
171ca774
GA
65}
66
67CTxMemPool::~CTxMemPool()
68{
69 delete minerPolicyEstimator;
319b1160
GA
70}
71
72void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins)
73{
74 LOCK(cs);
75
76 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(hashTx, 0));
77
78 // iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
79 while (it != mapNextTx.end() && it->first.hash == hashTx) {
80 coins.Spend(it->first.n); // and remove those outputs from coins
81 it++;
82 }
83}
84
85unsigned int CTxMemPool::GetTransactionsUpdated() const
86{
87 LOCK(cs);
88 return nTransactionsUpdated;
89}
90
91void CTxMemPool::AddTransactionsUpdated(unsigned int n)
92{
93 LOCK(cs);
94 nTransactionsUpdated += n;
95}
96
97
b649e039 98bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate)
319b1160
GA
99{
100 // Add to memory pool without checking anything.
101 // Used by main.cpp AcceptToMemoryPool(), which DOES do
102 // all the appropriate checks.
103 LOCK(cs);
e328fa32
AH
104 mapTx.insert(entry);
105 const CTransaction& tx = mapTx.find(hash)->GetTx();
b649e039
AM
106 for (unsigned int i = 0; i < tx.vin.size(); i++)
107 mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
f57f76d7 108 BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
22de1602 109 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
9669920f 110 mapSproutNullifiers[nf] = &tx;
d66877af
SB
111 }
112 }
cab341e1
EOW
113 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
114 mapSaplingNullifiers[spendDescription.nullifier] = &tx;
115 }
b649e039
AM
116 nTransactionsUpdated++;
117 totalTxSize += entry.GetTxSize();
bde5c8b0 118 cachedInnerUsage += entry.DynamicMemoryUsage();
b649e039
AM
119 minerPolicyEstimator->processTransaction(entry, fCurrentEstimate);
120
319b1160
GA
121 return true;
122}
123
68e174e2
LR
124void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view)
125{
126 LOCK(cs);
127 const CTransaction& tx = entry.GetTx();
128 std::vector<CMempoolAddressDeltaKey> inserted;
129
130 uint256 txhash = tx.GetHash();
131 for (unsigned int j = 0; j < tx.vin.size(); j++) {
132 const CTxIn input = tx.vin[j];
133 const CTxOut &prevout = view.GetOutputFor(input);
134 CScript::ScriptType type = prevout.scriptPubKey.GetType();
135 if (type == CScript::UNKNOWN)
136 continue;
137 CMempoolAddressDeltaKey key(type, prevout.scriptPubKey.AddressHash(), txhash, j, 1);
138 CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
139 mapAddress.insert(make_pair(key, delta));
140 inserted.push_back(key);
141 }
142
143 for (unsigned int j = 0; j < tx.vout.size(); j++) {
144 const CTxOut &out = tx.vout[j];
145 CScript::ScriptType type = out.scriptPubKey.GetType();
146 if (type == CScript::UNKNOWN)
147 continue;
148 CMempoolAddressDeltaKey key(type, out.scriptPubKey.AddressHash(), txhash, j, 0);
149 mapAddress.insert(make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
150 inserted.push_back(key);
151 }
152
153 mapAddressInserted.insert(make_pair(txhash, inserted));
154}
155
156void CTxMemPool::getAddressIndex(
157 const std::vector<std::pair<uint160, int>>& addresses,
158 std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta>>& results)
159{
160 LOCK(cs);
161 for (const auto& it : addresses) {
162 auto ait = mapAddress.lower_bound(CMempoolAddressDeltaKey(it.second, it.first));
163 while (ait != mapAddress.end() && (*ait).first.addressBytes == it.first && (*ait).first.type == it.second) {
164 results.push_back(*ait);
165 ait++;
166 }
167 }
168}
169
170void CTxMemPool::removeAddressIndex(const uint256& txhash)
171{
172 LOCK(cs);
173 auto it = mapAddressInserted.find(txhash);
174
175 if (it != mapAddressInserted.end()) {
176 std::vector<CMempoolAddressDeltaKey> keys = it->second;
177 for (const auto& mit : keys) {
178 mapAddress.erase(mit);
179 }
180 mapAddressInserted.erase(it);
181 }
182}
9669920f 183
7fd6219a 184void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive)
319b1160
GA
185{
186 // Remove transaction from memory pool
187 {
188 LOCK(cs);
7fd6219a 189 std::deque<uint256> txToRemove;
805344dc
S
190 txToRemove.push_back(origTx.GetHash());
191 if (fRecursive && !mapTx.count(origTx.GetHash())) {
ad9e86dc
GA
192 // If recursively removing but origTx isn't in the mempool
193 // be sure to remove any children that are in the pool. This can
194 // happen during chain re-orgs if origTx isn't re-accepted into
195 // the mempool for any reason.
196 for (unsigned int i = 0; i < origTx.vout.size(); i++) {
805344dc 197 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
ad9e86dc
GA
198 if (it == mapNextTx.end())
199 continue;
805344dc 200 txToRemove.push_back(it->second.ptx->GetHash());
ad9e86dc
GA
201 }
202 }
7fd6219a 203 while (!txToRemove.empty())
319b1160 204 {
7fd6219a
MC
205 uint256 hash = txToRemove.front();
206 txToRemove.pop_front();
207 if (!mapTx.count(hash))
208 continue;
e328fa32 209 const CTransaction& tx = mapTx.find(hash)->GetTx();
7fd6219a
MC
210 if (fRecursive) {
211 for (unsigned int i = 0; i < tx.vout.size(); i++) {
212 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i));
213 if (it == mapNextTx.end())
214 continue;
805344dc 215 txToRemove.push_back(it->second.ptx->GetHash());
7fd6219a
MC
216 }
217 }
319b1160
GA
218 BOOST_FOREACH(const CTxIn& txin, tx.vin)
219 mapNextTx.erase(txin.prevout);
f57f76d7 220 BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) {
22de1602 221 BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers) {
9669920f 222 mapSproutNullifiers.erase(nf);
d66877af
SB
223 }
224 }
cab341e1
EOW
225 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
226 mapSaplingNullifiers.erase(spendDescription.nullifier);
227 }
7fd6219a 228 removed.push_back(tx);
e328fa32
AH
229 totalTxSize -= mapTx.find(hash)->GetTxSize();
230 cachedInnerUsage -= mapTx.find(hash)->DynamicMemoryUsage();
319b1160
GA
231 mapTx.erase(hash);
232 nTransactionsUpdated++;
b649e039 233 minerPolicyEstimator->removeTx(hash);
68e174e2
LR
234 // insightexplorer
235 if (fAddressIndex)
236 removeAddressIndex(hash);
319b1160
GA
237 }
238 }
319b1160
GA
239}
240
233c9eb6 241void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags)
723d12c0 242{
c944d161 243 // Remove transactions spending a coinbase which are now immature and no-longer-final transactions
723d12c0
MC
244 LOCK(cs);
245 list<CTransaction> transactionsToRemove;
e328fa32
AH
246 for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
247 const CTransaction& tx = it->GetTx();
233c9eb6 248 if (!CheckFinalTx(tx, flags)) {
f5b35d23 249 transactionsToRemove.push_back(tx);
a4b25180 250 } else if (it->GetSpendsCoinbase()) {
f5b35d23
MC
251 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
252 indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
253 if (it2 != mapTx.end())
254 continue;
255 const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
256 if (nCheckFrequency != 0) assert(coins);
257 if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
258 transactionsToRemove.push_back(tx);
259 break;
260 }
723d12c0
MC
261 }
262 }
263 }
264 BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
265 list<CTransaction> removed;
266 remove(tx, removed, true);
267 }
268}
269
a8ac403d 270
98d2f090 271void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot, ShieldedType type)
a8ac403d
SB
272{
273 // If a block is disconnected from the tip, and the root changed,
274 // we must invalidate transactions from the mempool which spend
275 // from that root -- almost as though they were spending coinbases
276 // which are no longer valid to spend due to coinbase maturity.
277 LOCK(cs);
278 list<CTransaction> transactionsToRemove;
279
e328fa32
AH
280 for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
281 const CTransaction& tx = it->GetTx();
98d2f090
SB
282 switch (type) {
283 case SPROUT:
f57f76d7 284 BOOST_FOREACH(const JSDescription& joinsplit, tx.vJoinSplit) {
98d2f090
SB
285 if (joinsplit.anchor == invalidRoot) {
286 transactionsToRemove.push_back(tx);
287 break;
288 }
289 }
290 break;
291 case SAPLING:
292 BOOST_FOREACH(const SpendDescription& spendDescription, tx.vShieldedSpend) {
293 if (spendDescription.anchor == invalidRoot) {
294 transactionsToRemove.push_back(tx);
295 break;
296 }
297 }
298 break;
299 default:
8c57bbac 300 throw runtime_error("Unknown shielded type");
98d2f090 301 break;
a8ac403d
SB
302 }
303 }
304
305 BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
306 list<CTransaction> removed;
307 remove(tx, removed, true);
308 }
309}
310
93a18a36 311void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed)
319b1160
GA
312{
313 // Remove transactions which depend on inputs of tx, recursively
98e84aae 314 list<CTransaction> result;
319b1160
GA
315 LOCK(cs);
316 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
317 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout);
318 if (it != mapNextTx.end()) {
319 const CTransaction &txConflict = *it->second.ptx;
320 if (txConflict != tx)
93a18a36
GA
321 {
322 remove(txConflict, removed, true);
323 }
319b1160
GA
324 }
325 }
d66877af 326
f57f76d7 327 BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
22de1602 328 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
9669920f
EOW
329 std::map<uint256, const CTransaction*>::iterator it = mapSproutNullifiers.find(nf);
330 if (it != mapSproutNullifiers.end()) {
d66877af 331 const CTransaction &txConflict = *it->second;
9669920f 332 if (txConflict != tx) {
d66877af 333 remove(txConflict, removed, true);
9669920f 334 }
d66877af
SB
335 }
336 }
337 }
cab341e1
EOW
338 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
339 std::map<uint256, const CTransaction*>::iterator it = mapSaplingNullifiers.find(spendDescription.nullifier);
340 if (it != mapSaplingNullifiers.end()) {
341 const CTransaction &txConflict = *it->second;
9669920f 342 if (txConflict != tx) {
cab341e1 343 remove(txConflict, removed, true);
9669920f 344 }
cab341e1
EOW
345 }
346 }
319b1160
GA
347}
348
9bb37bf0
JG
349void CTxMemPool::removeExpired(unsigned int nBlockHeight)
350{
351 // Remove expired txs from the mempool
352 LOCK(cs);
353 list<CTransaction> transactionsToRemove;
354 for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++)
355 {
356 const CTransaction& tx = it->GetTx();
357 if (IsExpiredTx(tx, nBlockHeight)) {
358 transactionsToRemove.push_back(tx);
359 }
360 }
361 for (const CTransaction& tx : transactionsToRemove) {
362 list<CTransaction> removed;
363 remove(tx, removed, true);
eb138626 364 LogPrint("mempool", "Removing expired txid: %s\n", tx.GetHash().ToString());
9bb37bf0
JG
365 }
366}
367
7329fdd1
MF
368/**
369 * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
370 */
171ca774 371void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
b649e039 372 std::list<CTransaction>& conflicts, bool fCurrentEstimate)
171ca774
GA
373{
374 LOCK(cs);
375 std::vector<CTxMemPoolEntry> entries;
376 BOOST_FOREACH(const CTransaction& tx, vtx)
377 {
805344dc 378 uint256 hash = tx.GetHash();
e328fa32
AH
379
380 indexed_transaction_set::iterator i = mapTx.find(hash);
381 if (i != mapTx.end())
382 entries.push_back(*i);
171ca774 383 }
171ca774
GA
384 BOOST_FOREACH(const CTransaction& tx, vtx)
385 {
386 std::list<CTransaction> dummy;
387 remove(tx, dummy, false);
388 removeConflicts(tx, conflicts);
805344dc 389 ClearPrioritisation(tx.GetHash());
171ca774 390 }
b649e039
AM
391 // After the txs in the new block have been removed from the mempool, update policy estimates
392 minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate);
171ca774
GA
393}
394
34a64fe0
JG
395/**
396 * Called whenever the tip changes. Removes transactions which don't commit to
397 * the given branch ID from the mempool.
398 */
399void CTxMemPool::removeWithoutBranchId(uint32_t nMemPoolBranchId)
400{
401 LOCK(cs);
402 std::list<CTransaction> transactionsToRemove;
403
404 for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
405 const CTransaction& tx = it->GetTx();
406 if (it->GetValidatedBranchId() != nMemPoolBranchId) {
407 transactionsToRemove.push_back(tx);
408 }
409 }
410
411 for (const CTransaction& tx : transactionsToRemove) {
412 std::list<CTransaction> removed;
413 remove(tx, removed, true);
414 }
415}
416
319b1160
GA
417void CTxMemPool::clear()
418{
419 LOCK(cs);
420 mapTx.clear();
421 mapNextTx.clear();
6f2c26a4 422 totalTxSize = 0;
bde5c8b0 423 cachedInnerUsage = 0;
319b1160
GA
424 ++nTransactionsUpdated;
425}
426
d0867acb 427void CTxMemPool::check(const CCoinsViewCache *pcoins) const
319b1160 428{
934fd197
PW
429 if (nCheckFrequency == 0)
430 return;
431
432 if (insecure_rand() >= nCheckFrequency)
319b1160
GA
433 return;
434
435 LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
436
6f2c26a4 437 uint64_t checkTotal = 0;
bde5c8b0 438 uint64_t innerUsage = 0;
6f2c26a4 439
b7b4318f 440 CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
722d811f 441 const int64_t nSpendHeight = GetSpendHeight(mempoolDuplicate);
b7b4318f 442
319b1160 443 LOCK(cs);
b7b4318f 444 list<const CTxMemPoolEntry*> waitingOnDependants;
e328fa32 445 for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
319b1160 446 unsigned int i = 0;
e328fa32
AH
447 checkTotal += it->GetTxSize();
448 innerUsage += it->DynamicMemoryUsage();
449 const CTransaction& tx = it->GetTx();
b7b4318f 450 bool fDependsWait = false;
4d707d51 451 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
319b1160 452 // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
e328fa32 453 indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
319b1160 454 if (it2 != mapTx.end()) {
e328fa32 455 const CTransaction& tx2 = it2->GetTx();
4d707d51 456 assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
b7b4318f 457 fDependsWait = true;
319b1160 458 } else {
629d75fa
PW
459 const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
460 assert(coins && coins->IsAvailable(txin.prevout.n));
319b1160
GA
461 }
462 // Check whether its inputs are marked in mapNextTx.
463 std::map<COutPoint, CInPoint>::const_iterator it3 = mapNextTx.find(txin.prevout);
464 assert(it3 != mapNextTx.end());
4d707d51 465 assert(it3->second.ptx == &tx);
319b1160
GA
466 assert(it3->second.n == i);
467 i++;
468 }
a667caec 469
4fc309f0 470 boost::unordered_map<uint256, SproutMerkleTree, CCoinsKeyHasher> intermediates;
a667caec 471
f57f76d7 472 BOOST_FOREACH(const JSDescription &joinsplit, tx.vJoinSplit) {
22de1602 473 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
28d20bdb 474 assert(!pcoins->GetNullifier(nf, SPROUT));
d66877af
SB
475 }
476
4fc309f0 477 SproutMerkleTree tree;
b7e4abd6 478 auto it = intermediates.find(joinsplit.anchor);
a667caec
SB
479 if (it != intermediates.end()) {
480 tree = it->second;
481 } else {
008f4ee8 482 assert(pcoins->GetSproutAnchorAt(joinsplit.anchor, tree));
a667caec
SB
483 }
484
b7e4abd6 485 BOOST_FOREACH(const uint256& commitment, joinsplit.commitments)
a667caec
SB
486 {
487 tree.append(commitment);
488 }
489
490 intermediates.insert(std::make_pair(tree.root(), tree));
d66877af 491 }
cab341e1 492 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
4fc309f0 493 SaplingMerkleTree tree;
b4ff7076
SB
494
495 assert(pcoins->GetSaplingAnchorAt(spendDescription.anchor, tree));
28d20bdb 496 assert(!pcoins->GetNullifier(spendDescription.nullifier, SAPLING));
cab341e1 497 }
b7b4318f 498 if (fDependsWait)
e328fa32 499 waitingOnDependants.push_back(&(*it));
b7b4318f 500 else {
d7621ccf 501 CValidationState state;
722d811f
JT
502 bool fCheckResult = tx.IsCoinBase() ||
503 Consensus::CheckTxInputs(tx, state, mempoolDuplicate, nSpendHeight, Params().GetConsensus());
504 assert(fCheckResult);
8cb98d91 505 UpdateCoins(tx, mempoolDuplicate, 1000000);
b7b4318f
MC
506 }
507 }
508 unsigned int stepsSinceLastRemove = 0;
509 while (!waitingOnDependants.empty()) {
510 const CTxMemPoolEntry* entry = waitingOnDependants.front();
511 waitingOnDependants.pop_front();
512 CValidationState state;
513 if (!mempoolDuplicate.HaveInputs(entry->GetTx())) {
514 waitingOnDependants.push_back(entry);
515 stepsSinceLastRemove++;
516 assert(stepsSinceLastRemove < waitingOnDependants.size());
517 } else {
722d811f
JT
518 bool fCheckResult = entry->GetTx().IsCoinBase() ||
519 Consensus::CheckTxInputs(entry->GetTx(), state, mempoolDuplicate, nSpendHeight, Params().GetConsensus());
520 assert(fCheckResult);
8cb98d91 521 UpdateCoins(entry->GetTx(), mempoolDuplicate, 1000000);
b7b4318f
MC
522 stepsSinceLastRemove = 0;
523 }
319b1160
GA
524 }
525 for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) {
805344dc 526 uint256 hash = it->second.ptx->GetHash();
e328fa32
AH
527 indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
528 const CTransaction& tx = it2->GetTx();
319b1160 529 assert(it2 != mapTx.end());
4d707d51
GA
530 assert(&tx == it->second.ptx);
531 assert(tx.vin.size() > it->second.n);
319b1160
GA
532 assert(it->first == it->second.ptx->vin[it->second.n].prevout);
533 }
6f2c26a4 534
28d20bdb
SB
535 checkNullifiers(SPROUT);
536 checkNullifiers(SAPLING);
d66877af 537
6f2c26a4 538 assert(totalTxSize == checkTotal);
bde5c8b0 539 assert(innerUsage == cachedInnerUsage);
319b1160
GA
540}
541
28d20bdb 542void CTxMemPool::checkNullifiers(ShieldedType type) const
685e936c 543{
708c87f1
EOW
544 const std::map<uint256, const CTransaction*>* mapToUse;
545 switch (type) {
28d20bdb 546 case SPROUT:
9669920f 547 mapToUse = &mapSproutNullifiers;
708c87f1 548 break;
28d20bdb 549 case SAPLING:
708c87f1
EOW
550 mapToUse = &mapSaplingNullifiers;
551 break;
552 default:
1f9dfbb9 553 throw runtime_error("Unknown nullifier type");
708c87f1 554 }
685e936c
EOW
555 for (const auto& entry : *mapToUse) {
556 uint256 hash = entry.second->GetHash();
557 CTxMemPool::indexed_transaction_set::const_iterator findTx = mapTx.find(hash);
558 const CTransaction& tx = findTx->GetTx();
559 assert(findTx != mapTx.end());
560 assert(&tx == entry.second);
561 }
562}
563
4d707d51 564void CTxMemPool::queryHashes(vector<uint256>& vtxid)
319b1160
GA
565{
566 vtxid.clear();
567
568 LOCK(cs);
569 vtxid.reserve(mapTx.size());
e328fa32
AH
570 for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi)
571 vtxid.push_back(mi->GetTx().GetHash());
319b1160
GA
572}
573
574bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const
575{
576 LOCK(cs);
e328fa32 577 indexed_transaction_set::const_iterator i = mapTx.find(hash);
319b1160 578 if (i == mapTx.end()) return false;
e328fa32 579 result = i->GetTx();
319b1160
GA
580 return true;
581}
a0fa20a1 582
171ca774
GA
583CFeeRate CTxMemPool::estimateFee(int nBlocks) const
584{
585 LOCK(cs);
586 return minerPolicyEstimator->estimateFee(nBlocks);
587}
588double CTxMemPool::estimatePriority(int nBlocks) const
589{
590 LOCK(cs);
591 return minerPolicyEstimator->estimatePriority(nBlocks);
592}
593
594bool
595CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
596{
597 try {
598 LOCK(cs);
b649e039 599 fileout << 109900; // version required to read: 0.10.99 or later
171ca774
GA
600 fileout << CLIENT_VERSION; // version that wrote the file
601 minerPolicyEstimator->Write(fileout);
602 }
27df4123 603 catch (const std::exception&) {
7ff9d122 604 LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)\n");
171ca774
GA
605 return false;
606 }
607 return true;
608}
609
610bool
611CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
612{
613 try {
614 int nVersionRequired, nVersionThatWrote;
615 filein >> nVersionRequired >> nVersionThatWrote;
616 if (nVersionRequired > CLIENT_VERSION)
5262fde0 617 return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired);
171ca774
GA
618
619 LOCK(cs);
b649e039 620 minerPolicyEstimator->Read(filein);
171ca774 621 }
27df4123 622 catch (const std::exception&) {
7ff9d122 623 LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n");
171ca774
GA
624 return false;
625 }
626 return true;
627}
628
a372168e 629void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, const CAmount& nFeeDelta)
2a72d459
LD
630{
631 {
632 LOCK(cs);
a372168e 633 std::pair<double, CAmount> &deltas = mapDeltas[hash];
2a72d459
LD
634 deltas.first += dPriorityDelta;
635 deltas.second += nFeeDelta;
636 }
a372168e 637 LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta));
2a72d459
LD
638}
639
a372168e 640void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta)
2a72d459
LD
641{
642 LOCK(cs);
a372168e 643 std::map<uint256, std::pair<double, CAmount> >::iterator pos = mapDeltas.find(hash);
2a72d459
LD
644 if (pos == mapDeltas.end())
645 return;
a372168e 646 const std::pair<double, CAmount> &deltas = pos->second;
2a72d459
LD
647 dPriorityDelta += deltas.first;
648 nFeeDelta += deltas.second;
649}
650
651void CTxMemPool::ClearPrioritisation(const uint256 hash)
652{
653 LOCK(cs);
654 mapDeltas.erase(hash);
655}
656
b649e039
AM
657bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
658{
659 for (unsigned int i = 0; i < tx.vin.size(); i++)
660 if (exists(tx.vin[i].prevout.hash))
661 return false;
662 return true;
663}
171ca774 664
28d20bdb 665bool CTxMemPool::nullifierExists(const uint256& nullifier, ShieldedType type) const
685e936c 666{
708c87f1 667 switch (type) {
28d20bdb 668 case SPROUT:
9669920f 669 return mapSproutNullifiers.count(nullifier);
28d20bdb 670 case SAPLING:
708c87f1
EOW
671 return mapSaplingNullifiers.count(nullifier);
672 default:
1f9dfbb9 673 throw runtime_error("Unknown nullifier type");
708c87f1 674 }
685e936c 675}
a0fa20a1 676
685e936c 677CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
d66877af 678
28d20bdb 679bool CCoinsViewMemPool::GetNullifier(const uint256 &nf, ShieldedType type) const
685e936c 680{
708c87f1 681 return mempool.nullifierExists(nf, type) || base->GetNullifier(nf, type);
d66877af
SB
682}
683
a3dc587a 684bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
ad08d0b9
PW
685 // If an entry in the mempool exists, always return that one, as it's guaranteed to never
686 // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
687 // transactions. First checking the underlying cache risks returning a pruned entry instead.
a0fa20a1
PW
688 CTransaction tx;
689 if (mempool.lookup(txid, tx)) {
690 coins = CCoins(tx, MEMPOOL_HEIGHT);
691 return true;
692 }
ad08d0b9 693 return (base->GetCoins(txid, coins) && !coins.IsPruned());
a0fa20a1
PW
694}
695
a3dc587a 696bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const {
a0fa20a1
PW
697 return mempool.exists(txid) || base->HaveCoins(txid);
698}
bde5c8b0
PW
699
700size_t CTxMemPool::DynamicMemoryUsage() const {
701 LOCK(cs);
e328fa32
AH
702 // Estimate the overhead of mapTx to be 6 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented.
703 return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 6 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + cachedInnerUsage;
bde5c8b0 704}
This page took 0.269912 seconds and 4 git commands to generate.