]> Git Repo - VerusCoin.git/blame - src/txmempool.cpp
Update libzerocash ref
[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
319b1160
GA
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
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"
ad49c256 14#include "util.h"
a372168e 15#include "utilmoneystr.h"
85c579e3 16#include "version.h"
319b1160
GA
17
18using namespace std;
19
8bdd2877 20CTxMemPoolEntry::CTxMemPoolEntry():
b649e039 21 nFee(0), nTxSize(0), nModSize(0), nTime(0), dPriority(0.0), hadNoDependencies(false)
4d707d51
GA
22{
23 nHeight = MEMPOOL_HEIGHT;
24}
25
a372168e 26CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
4d707d51 27 int64_t _nTime, double _dPriority,
b649e039
AM
28 unsigned int _nHeight, bool poolHasNoInputsOf):
29 tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight),
30 hadNoDependencies(poolHasNoInputsOf)
4d707d51
GA
31{
32 nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
c26649f9 33 nModSize = tx.CalculateModifiedSize(nTxSize);
4d707d51
GA
34}
35
36CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
37{
38 *this = other;
39}
40
41double
42CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
43{
a372168e 44 CAmount nValueIn = tx.GetValueOut()+nFee;
c26649f9 45 double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize;
4d707d51
GA
46 double dResult = dPriority + deltaPriority;
47 return dResult;
48}
49
8bdd2877 50CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
b649e039 51 nTransactionsUpdated(0)
319b1160
GA
52{
53 // Sanity checks off by default for performance, because otherwise
54 // accepting transactions becomes O(N^2) where N is the number
55 // of transactions in the pool
56 fSanityCheck = false;
171ca774 57
b649e039 58 minerPolicyEstimator = new CBlockPolicyEstimator(_minRelayFee);
171ca774
GA
59}
60
61CTxMemPool::~CTxMemPool()
62{
63 delete minerPolicyEstimator;
319b1160
GA
64}
65
66void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins)
67{
68 LOCK(cs);
69
70 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(hashTx, 0));
71
72 // iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
73 while (it != mapNextTx.end() && it->first.hash == hashTx) {
74 coins.Spend(it->first.n); // and remove those outputs from coins
75 it++;
76 }
77}
78
79unsigned int CTxMemPool::GetTransactionsUpdated() const
80{
81 LOCK(cs);
82 return nTransactionsUpdated;
83}
84
85void CTxMemPool::AddTransactionsUpdated(unsigned int n)
86{
87 LOCK(cs);
88 nTransactionsUpdated += n;
89}
90
91
b649e039 92bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate)
319b1160
GA
93{
94 // Add to memory pool without checking anything.
95 // Used by main.cpp AcceptToMemoryPool(), which DOES do
96 // all the appropriate checks.
97 LOCK(cs);
b649e039
AM
98 mapTx[hash] = entry;
99 const CTransaction& tx = mapTx[hash].GetTx();
100 for (unsigned int i = 0; i < tx.vin.size(); i++)
101 mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
102 nTransactionsUpdated++;
103 totalTxSize += entry.GetTxSize();
104 minerPolicyEstimator->processTransaction(entry, fCurrentEstimate);
105
319b1160
GA
106 return true;
107}
108
109
7fd6219a 110void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive)
319b1160
GA
111{
112 // Remove transaction from memory pool
113 {
114 LOCK(cs);
7fd6219a
MC
115 std::deque<uint256> txToRemove;
116 txToRemove.push_back(origTx.GetHash());
ad9e86dc
GA
117 if (fRecursive && !mapTx.count(origTx.GetHash())) {
118 // If recursively removing but origTx isn't in the mempool
119 // be sure to remove any children that are in the pool. This can
120 // happen during chain re-orgs if origTx isn't re-accepted into
121 // the mempool for any reason.
122 for (unsigned int i = 0; i < origTx.vout.size(); i++) {
123 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
124 if (it == mapNextTx.end())
125 continue;
126 txToRemove.push_back(it->second.ptx->GetHash());
127 }
128 }
7fd6219a 129 while (!txToRemove.empty())
319b1160 130 {
7fd6219a
MC
131 uint256 hash = txToRemove.front();
132 txToRemove.pop_front();
133 if (!mapTx.count(hash))
134 continue;
135 const CTransaction& tx = mapTx[hash].GetTx();
136 if (fRecursive) {
137 for (unsigned int i = 0; i < tx.vout.size(); i++) {
138 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i));
139 if (it == mapNextTx.end())
140 continue;
141 txToRemove.push_back(it->second.ptx->GetHash());
142 }
143 }
319b1160
GA
144 BOOST_FOREACH(const CTxIn& txin, tx.vin)
145 mapNextTx.erase(txin.prevout);
6f2c26a4 146
7fd6219a 147 removed.push_back(tx);
6f2c26a4 148 totalTxSize -= mapTx[hash].GetTxSize();
319b1160
GA
149 mapTx.erase(hash);
150 nTransactionsUpdated++;
b649e039 151 minerPolicyEstimator->removeTx(hash);
319b1160
GA
152 }
153 }
319b1160
GA
154}
155
723d12c0
MC
156void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight)
157{
158 // Remove transactions spending a coinbase which are now immature
159 LOCK(cs);
160 list<CTransaction> transactionsToRemove;
161 for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
162 const CTransaction& tx = it->second.GetTx();
163 BOOST_FOREACH(const CTxIn& txin, tx.vin) {
164 std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
165 if (it2 != mapTx.end())
166 continue;
167 const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
168 if (fSanityCheck) assert(coins);
169 if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) {
170 transactionsToRemove.push_back(tx);
171 break;
172 }
173 }
174 }
175 BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
176 list<CTransaction> removed;
177 remove(tx, removed, true);
178 }
179}
180
93a18a36 181void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed)
319b1160
GA
182{
183 // Remove transactions which depend on inputs of tx, recursively
98e84aae 184 list<CTransaction> result;
319b1160
GA
185 LOCK(cs);
186 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
187 std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout);
188 if (it != mapNextTx.end()) {
189 const CTransaction &txConflict = *it->second.ptx;
190 if (txConflict != tx)
93a18a36
GA
191 {
192 remove(txConflict, removed, true);
193 }
319b1160
GA
194 }
195 }
319b1160
GA
196}
197
7329fdd1
MF
198/**
199 * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
200 */
171ca774 201void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
b649e039 202 std::list<CTransaction>& conflicts, bool fCurrentEstimate)
171ca774
GA
203{
204 LOCK(cs);
205 std::vector<CTxMemPoolEntry> entries;
206 BOOST_FOREACH(const CTransaction& tx, vtx)
207 {
208 uint256 hash = tx.GetHash();
209 if (mapTx.count(hash))
210 entries.push_back(mapTx[hash]);
211 }
171ca774
GA
212 BOOST_FOREACH(const CTransaction& tx, vtx)
213 {
214 std::list<CTransaction> dummy;
215 remove(tx, dummy, false);
216 removeConflicts(tx, conflicts);
2a72d459 217 ClearPrioritisation(tx.GetHash());
171ca774 218 }
b649e039
AM
219 // After the txs in the new block have been removed from the mempool, update policy estimates
220 minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate);
171ca774
GA
221}
222
319b1160
GA
223void CTxMemPool::clear()
224{
225 LOCK(cs);
226 mapTx.clear();
227 mapNextTx.clear();
6f2c26a4 228 totalTxSize = 0;
319b1160
GA
229 ++nTransactionsUpdated;
230}
231
d0867acb 232void CTxMemPool::check(const CCoinsViewCache *pcoins) const
319b1160
GA
233{
234 if (!fSanityCheck)
235 return;
236
237 LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
238
6f2c26a4
JG
239 uint64_t checkTotal = 0;
240
b7b4318f
MC
241 CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
242
319b1160 243 LOCK(cs);
b7b4318f 244 list<const CTxMemPoolEntry*> waitingOnDependants;
4d707d51 245 for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
319b1160 246 unsigned int i = 0;
6f2c26a4 247 checkTotal += it->second.GetTxSize();
4d707d51 248 const CTransaction& tx = it->second.GetTx();
b7b4318f 249 bool fDependsWait = false;
4d707d51 250 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
319b1160 251 // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
4d707d51 252 std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
319b1160 253 if (it2 != mapTx.end()) {
4d707d51
GA
254 const CTransaction& tx2 = it2->second.GetTx();
255 assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
b7b4318f 256 fDependsWait = true;
319b1160 257 } else {
629d75fa
PW
258 const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
259 assert(coins && coins->IsAvailable(txin.prevout.n));
319b1160
GA
260 }
261 // Check whether its inputs are marked in mapNextTx.
262 std::map<COutPoint, CInPoint>::const_iterator it3 = mapNextTx.find(txin.prevout);
263 assert(it3 != mapNextTx.end());
4d707d51 264 assert(it3->second.ptx == &tx);
319b1160
GA
265 assert(it3->second.n == i);
266 i++;
267 }
b7b4318f
MC
268 if (fDependsWait)
269 waitingOnDependants.push_back(&it->second);
270 else {
d7621ccf 271 CValidationState state;
b7b4318f 272 assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL));
d7621ccf 273 UpdateCoins(tx, state, mempoolDuplicate, 1000000);
b7b4318f
MC
274 }
275 }
276 unsigned int stepsSinceLastRemove = 0;
277 while (!waitingOnDependants.empty()) {
278 const CTxMemPoolEntry* entry = waitingOnDependants.front();
279 waitingOnDependants.pop_front();
280 CValidationState state;
281 if (!mempoolDuplicate.HaveInputs(entry->GetTx())) {
282 waitingOnDependants.push_back(entry);
283 stepsSinceLastRemove++;
284 assert(stepsSinceLastRemove < waitingOnDependants.size());
285 } else {
286 assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL));
d7621ccf 287 UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000);
b7b4318f
MC
288 stepsSinceLastRemove = 0;
289 }
319b1160
GA
290 }
291 for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) {
292 uint256 hash = it->second.ptx->GetHash();
4d707d51
GA
293 map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(hash);
294 const CTransaction& tx = it2->second.GetTx();
319b1160 295 assert(it2 != mapTx.end());
4d707d51
GA
296 assert(&tx == it->second.ptx);
297 assert(tx.vin.size() > it->second.n);
319b1160
GA
298 assert(it->first == it->second.ptx->vin[it->second.n].prevout);
299 }
6f2c26a4
JG
300
301 assert(totalTxSize == checkTotal);
319b1160
GA
302}
303
4d707d51 304void CTxMemPool::queryHashes(vector<uint256>& vtxid)
319b1160
GA
305{
306 vtxid.clear();
307
308 LOCK(cs);
309 vtxid.reserve(mapTx.size());
4d707d51 310 for (map<uint256, CTxMemPoolEntry>::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi)
319b1160
GA
311 vtxid.push_back((*mi).first);
312}
313
314bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const
315{
316 LOCK(cs);
4d707d51 317 map<uint256, CTxMemPoolEntry>::const_iterator i = mapTx.find(hash);
319b1160 318 if (i == mapTx.end()) return false;
4d707d51 319 result = i->second.GetTx();
319b1160
GA
320 return true;
321}
a0fa20a1 322
171ca774
GA
323CFeeRate CTxMemPool::estimateFee(int nBlocks) const
324{
325 LOCK(cs);
326 return minerPolicyEstimator->estimateFee(nBlocks);
327}
328double CTxMemPool::estimatePriority(int nBlocks) const
329{
330 LOCK(cs);
331 return minerPolicyEstimator->estimatePriority(nBlocks);
332}
333
334bool
335CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
336{
337 try {
338 LOCK(cs);
b649e039 339 fileout << 109900; // version required to read: 0.10.99 or later
171ca774
GA
340 fileout << CLIENT_VERSION; // version that wrote the file
341 minerPolicyEstimator->Write(fileout);
342 }
27df4123 343 catch (const std::exception&) {
7ff9d122 344 LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)\n");
171ca774
GA
345 return false;
346 }
347 return true;
348}
349
350bool
351CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
352{
353 try {
354 int nVersionRequired, nVersionThatWrote;
355 filein >> nVersionRequired >> nVersionThatWrote;
356 if (nVersionRequired > CLIENT_VERSION)
5262fde0 357 return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired);
171ca774
GA
358
359 LOCK(cs);
b649e039 360 minerPolicyEstimator->Read(filein);
171ca774 361 }
27df4123 362 catch (const std::exception&) {
7ff9d122 363 LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n");
171ca774
GA
364 return false;
365 }
366 return true;
367}
368
a372168e 369void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, const CAmount& nFeeDelta)
2a72d459
LD
370{
371 {
372 LOCK(cs);
a372168e 373 std::pair<double, CAmount> &deltas = mapDeltas[hash];
2a72d459
LD
374 deltas.first += dPriorityDelta;
375 deltas.second += nFeeDelta;
376 }
a372168e 377 LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta));
2a72d459
LD
378}
379
a372168e 380void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta)
2a72d459
LD
381{
382 LOCK(cs);
a372168e 383 std::map<uint256, std::pair<double, CAmount> >::iterator pos = mapDeltas.find(hash);
2a72d459
LD
384 if (pos == mapDeltas.end())
385 return;
a372168e 386 const std::pair<double, CAmount> &deltas = pos->second;
2a72d459
LD
387 dPriorityDelta += deltas.first;
388 nFeeDelta += deltas.second;
389}
390
391void CTxMemPool::ClearPrioritisation(const uint256 hash)
392{
393 LOCK(cs);
394 mapDeltas.erase(hash);
395}
396
b649e039
AM
397bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
398{
399 for (unsigned int i = 0; i < tx.vin.size(); i++)
400 if (exists(tx.vin[i].prevout.hash))
401 return false;
402 return true;
403}
171ca774 404
7c70438d 405CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
a0fa20a1 406
a3dc587a 407bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
ad08d0b9
PW
408 // If an entry in the mempool exists, always return that one, as it's guaranteed to never
409 // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
410 // transactions. First checking the underlying cache risks returning a pruned entry instead.
a0fa20a1
PW
411 CTransaction tx;
412 if (mempool.lookup(txid, tx)) {
413 coins = CCoins(tx, MEMPOOL_HEIGHT);
414 return true;
415 }
ad08d0b9 416 return (base->GetCoins(txid, coins) && !coins.IsPruned());
a0fa20a1
PW
417}
418
a3dc587a 419bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const {
a0fa20a1
PW
420 return mempool.exists(txid) || base->HaveCoins(txid);
421}
This page took 0.197385 seconds and 4 git commands to generate.