PRCYCoin  2.0.0.7rc1
P2P Digital Currency
txmempool.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2015-2018 The PIVX developers
4 // Copyright (c) 2018-2020 The DAPS Project developers
5 // Distributed under the MIT software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 
8 #include "txmempool.h"
9 
10 #include "clientversion.h"
11 #include "main.h"
12 #include "streams.h"
13 #include "util.h"
14 #include "utilmoneystr.h"
15 #include "version.h"
16 
17 #include <boost/circular_buffer.hpp>
18 
19 
20 CTxMemPoolEntry::CTxMemPoolEntry() : nFee(0), nTxSize(0), nModSize(0), nTime(0), dPriority(0.0)
21 {
22  nHeight = MEMPOOL_HEIGHT;
23 }
24 
25 CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _dPriority, unsigned int _nHeight) : tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight)
26 {
27  nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
28 
30 }
31 
33 {
34  *this = other;
35 }
36 
37 double
38 CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
39 {
40  return ::GetPriority(tx, currentHeight);
41 }
42 
47 {
48 private:
49  boost::circular_buffer<CFeeRate> feeSamples;
50  boost::circular_buffer<double> prioritySamples;
51 
52  template <typename T>
53  std::vector<T> buf2vec(boost::circular_buffer<T> buf) const
54  {
55  std::vector<T> vec(buf.begin(), buf.end());
56  return vec;
57  }
58 
59 public:
61 
62  void RecordFee(const CFeeRate& feeRate)
63  {
64  feeSamples.push_back(feeRate);
65  }
66 
67  void RecordPriority(double priority)
68  {
69  prioritySamples.push_back(priority);
70  }
71 
72  size_t FeeSamples() const { return feeSamples.size(); }
73  size_t GetFeeSamples(std::vector<CFeeRate>& insertInto) const
74  {
75  for (const CFeeRate& f : feeSamples)
76  insertInto.push_back(f);
77  return feeSamples.size();
78  }
79  size_t PrioritySamples() const { return prioritySamples.size(); }
80  size_t GetPrioritySamples(std::vector<double>& insertInto) const
81  {
82  for (double d : prioritySamples)
83  insertInto.push_back(d);
84  return prioritySamples.size();
85  }
86 
91  static bool AreSane(const CFeeRate fee, const CFeeRate& minRelayFee)
92  {
93  if (fee < CFeeRate(0))
94  return false;
95  if (fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000)
96  return false;
97  return true;
98  }
99  static bool AreSane(const std::vector<CFeeRate>& vecFee, const CFeeRate& minRelayFee)
100  {
101  for (CFeeRate fee : vecFee) {
102  if (!AreSane(fee, minRelayFee))
103  return false;
104  }
105  return true;
106  }
107  static bool AreSane(const double priority)
108  {
109  return priority >= 0;
110  }
111  static bool AreSane(const std::vector<double> vecPriority)
112  {
113  for (double priority : vecPriority) {
114  if (!AreSane(priority))
115  return false;
116  }
117  return true;
118  }
119 
120  void Write(CAutoFile& fileout) const
121  {
122  std::vector<CFeeRate> vecFee = buf2vec(feeSamples);
123  fileout << vecFee;
124  std::vector<double> vecPriority = buf2vec(prioritySamples);
125  fileout << vecPriority;
126  }
127 
128  void Read(CAutoFile& filein, const CFeeRate& minRelayFee)
129  {
130  std::vector<CFeeRate> vecFee;
131  filein >> vecFee;
132  if (AreSane(vecFee, minRelayFee))
133  feeSamples.insert(feeSamples.end(), vecFee.begin(), vecFee.end());
134  else
135  throw std::runtime_error("Corrupt fee value in estimates file.");
136  std::vector<double> vecPriority;
137  filein >> vecPriority;
138  if (AreSane(vecPriority))
139  prioritySamples.insert(prioritySamples.end(), vecPriority.begin(), vecPriority.end());
140  else
141  throw std::runtime_error("Corrupt priority value in estimates file.");
142  if (feeSamples.size() + prioritySamples.size() > 0)
143  LogPrint(BCLog::ESTIMATEFEE, "Read %d fee samples and %d priority samples\n",
144  feeSamples.size(), prioritySamples.size());
145  }
146 };
147 
149 {
150 private:
155  std::vector<CBlockAverage> history;
156  std::vector<CFeeRate> sortedFeeSamples;
157  std::vector<double> sortedPrioritySamples;
158 
160 
165  void seenTxConfirm(const CFeeRate& feeRate, const CFeeRate& minRelayFee, double dPriority, int nBlocksAgo)
166  {
167  // Last entry records "everything else".
168  int nBlocksTruncated = std::min(nBlocksAgo, (int)history.size() - 1);
169  assert(nBlocksTruncated >= 0);
170 
171  // We need to guess why the transaction was included in a block-- either
172  // because it is high-priority or because it has sufficient fees.
173  bool sufficientFee = (feeRate > minRelayFee);
174  bool sufficientPriority = AllowFree(dPriority);
175  const char* assignedTo = "unassigned";
176  if (sufficientFee && !sufficientPriority && CBlockAverage::AreSane(feeRate, minRelayFee)) {
177  history[nBlocksTruncated].RecordFee(feeRate);
178  assignedTo = "fee";
179  } else if (sufficientPriority && !sufficientFee && CBlockAverage::AreSane(dPriority)) {
180  history[nBlocksTruncated].RecordPriority(dPriority);
181  assignedTo = "priority";
182  } else {
183  // Neither or both fee and priority sufficient to get confirmed:
184  // don't know why they got confirmed.
185  }
186  LogPrint(BCLog::ESTIMATEFEE, "Seen TX confirm: %s : %s fee/%g priority, took %d blocks\n",
187  assignedTo, feeRate.ToString(), dPriority, nBlocksAgo);
188  }
189 
190 public:
192  {
193  history.resize(nEntries);
194  }
195 
196  void seenBlock(const std::vector<CTxMemPoolEntry>& entries, int nBlockHeight, const CFeeRate minRelayFee)
197  {
198  if (nBlockHeight <= nBestSeenHeight) {
199  // Ignore side chains and re-orgs; assuming they are random
200  // they don't affect the estimate.
201  // And if an attacker can re-org the chain at will, then
202  // you've got much bigger problems than "attacker can influence
203  // transaction fees."
204  return;
205  }
206  nBestSeenHeight = nBlockHeight;
207 
208  // Fill up the history buckets based on how long transactions took
209  // to confirm.
210  std::vector<std::vector<const CTxMemPoolEntry*> > entriesByConfirmations;
211  entriesByConfirmations.resize(history.size());
212  for (const CTxMemPoolEntry& entry : entries) {
213  // How many blocks did it take for miners to include this transaction?
214  int delta = nBlockHeight - entry.GetHeight();
215  if (delta <= 0) {
216  // Re-org made us lose height, this should only happen if we happen
217  // to re-org on a difficulty transition point: very rare!
218  continue;
219  }
220  if ((delta - 1) >= (int)history.size())
221  delta = history.size(); // Last bucket is catch-all
222  entriesByConfirmations.at(delta - 1).push_back(&entry);
223  }
224  for (size_t i = 0; i < entriesByConfirmations.size(); i++) {
225  std::vector<const CTxMemPoolEntry*>& e = entriesByConfirmations.at(i);
226  // Insert at most 10 random entries per bucket, otherwise a single block
227  // can dominate an estimate:
228  if (e.size() > 10) {
229  std::random_shuffle(e.begin(), e.end());
230  e.resize(10);
231  }
232  for (const CTxMemPoolEntry* entry : e) {
233  // Fees are stored and reported as BTC-per-kb:
234  CFeeRate feeRate(entry->GetFee(), entry->GetTxSize());
235  double dPriority = entry->GetPriority(entry->GetHeight()); // Want priority when it went IN
236  seenTxConfirm(feeRate, minRelayFee, dPriority, i);
237  }
238  }
239 
240  //After new samples are added, we have to clear the sorted lists,
241  //so they'll be resorted the next time someone asks for an estimate
242  sortedFeeSamples.clear();
243  sortedPrioritySamples.clear();
244 
245  for (size_t i = 0; i < history.size(); i++) {
246  if (history[i].FeeSamples() + history[i].PrioritySamples() > 0)
247  LogPrint(BCLog::ESTIMATEFEE, "estimates: for confirming within %d blocks based on %d/%d samples, fee=%s, prio=%g\n",
248  i,
249  history[i].FeeSamples(), history[i].PrioritySamples(),
250  estimateFee(i + 1).ToString(), estimatePriority(i + 1));
251  }
252  }
253 
257  CFeeRate estimateFee(int nBlocksToConfirm)
258  {
259  nBlocksToConfirm--;
260 
261  if (nBlocksToConfirm < 0 || nBlocksToConfirm >= (int)history.size())
262  return CFeeRate(0);
263 
264  if (sortedFeeSamples.size() == 0) {
265  for (size_t i = 0; i < history.size(); i++)
266  history.at(i).GetFeeSamples(sortedFeeSamples);
267  std::sort(sortedFeeSamples.begin(), sortedFeeSamples.end(),
268  std::greater<CFeeRate>());
269  }
270  if (sortedFeeSamples.size() < 11) {
271  // Eleven is Gavin's Favorite Number
272  // ... but we also take a maximum of 10 samples per block so eleven means
273  // we're getting samples from at least two different blocks
274  return CFeeRate(0);
275  }
276 
277  int nBucketSize = history.at(nBlocksToConfirm).FeeSamples();
278 
279  // Estimates should not increase as number of confirmations goes up,
280  // but the estimates are noisy because confirmations happen discretely
281  // in blocks. To smooth out the estimates, use all samples in the history
282  // and use the nth highest where n is (number of samples in previous bucket +
283  // half the samples in nBlocksToConfirm bucket):
284  size_t nPrevSize = 0;
285  for (int i = 0; i < nBlocksToConfirm; i++)
286  nPrevSize += history.at(i).FeeSamples();
287  size_t index = std::min(nPrevSize + nBucketSize / 2, sortedFeeSamples.size() - 1);
288  return sortedFeeSamples[index];
289  }
290  double estimatePriority(int nBlocksToConfirm)
291  {
292  nBlocksToConfirm--;
293 
294  if (nBlocksToConfirm < 0 || nBlocksToConfirm >= (int)history.size())
295  return -1;
296 
297  if (sortedPrioritySamples.size() == 0) {
298  for (size_t i = 0; i < history.size(); i++)
299  history.at(i).GetPrioritySamples(sortedPrioritySamples);
300  std::sort(sortedPrioritySamples.begin(), sortedPrioritySamples.end(),
301  std::greater<double>());
302  }
303  if (sortedPrioritySamples.size() < 11)
304  return -1.0;
305 
306  int nBucketSize = history.at(nBlocksToConfirm).PrioritySamples();
307 
308  // Estimates should not increase as number of confirmations needed goes up,
309  // but the estimates are noisy because confirmations happen discretely
310  // in blocks. To smooth out the estimates, use all samples in the history
311  // and use the nth highest where n is (number of samples in previous buckets +
312  // half the samples in nBlocksToConfirm bucket).
313  size_t nPrevSize = 0;
314  for (int i = 0; i < nBlocksToConfirm; i++)
315  nPrevSize += history.at(i).PrioritySamples();
316  size_t index = std::min(nPrevSize + nBucketSize / 2, sortedPrioritySamples.size() - 1);
317  return sortedPrioritySamples[index];
318  }
319 
320  void Write(CAutoFile& fileout) const
321  {
322  fileout << nBestSeenHeight;
323  fileout << (uint32_t)history.size();
324  for (const CBlockAverage& entry : history) {
325  entry.Write(fileout);
326  }
327  }
328 
329  void Read(CAutoFile& filein, const CFeeRate& minRelayFee)
330  {
331  int nFileBestSeenHeight;
332  filein >> nFileBestSeenHeight;
333  uint32_t numEntries;
334  filein >> numEntries;
335  if (numEntries <= 0 || numEntries > 10000)
336  throw std::runtime_error("Corrupt estimates file. Must have between 1 and 10k entries.");
337 
338  std::vector<CBlockAverage> fileHistory;
339 
340  for (size_t i = 0; i < numEntries; i++) {
341  CBlockAverage entry;
342  entry.Read(filein, minRelayFee);
343  fileHistory.push_back(entry);
344  }
345 
346  // Now that we've processed the entire fee estimate data file and not
347  // thrown any errors, we can copy it to our history
348  nBestSeenHeight = nFileBestSeenHeight;
349  history = fileHistory;
350  assert(history.size() > 0);
351  }
352 };
353 
354 
355 CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) : nTransactionsUpdated(0),
356  minRelayFee(_minRelayFee)
357 {
358  // Sanity checks off by default for performance, because otherwise
359  // accepting transactions becomes O(N^2) where N is the number
360  // of transactions in the pool
361  fSanityCheck = false;
362 
363  // 25 blocks is a compromise between using a lot of disk/memory and
364  // trying to give accurate estimates to people who might be willing
365  // to wait a day or two to save a fraction of a penny in fees.
366  // Confirmation times for very-low-fee transactions that take more
367  // than an hour or three to confirm are highly variable.
369 }
370 
372 {
373  delete minerPolicyEstimator;
374 }
375 
376 void CTxMemPool::pruneSpent(const uint256& hashTx, CCoins& coins)
377 {
378  LOCK(cs);
379 
380  std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(hashTx, 0));
381 
382  // iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
383  while (it != mapNextTx.end() && it->first.hash == hashTx) {
384  coins.Spend(it->first.n); // and remove those outputs from coins
385  it++;
386  }
387 }
388 
390 {
391  LOCK(cs);
392  return nTransactionsUpdated;
393 }
394 
396 {
397  LOCK(cs);
399 }
400 
401 
402 bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry& entry)
403 {
404  // Add to memory pool without checking anything.
405  // Used by main.cpp AcceptToMemoryPool(), which DOES do
406  // all the appropriate checks.
407  LOCK(cs);
408  {
409  mapTx[hash] = entry;
410  const CTransaction& tx = mapTx[hash].GetTx();
411  {
412  if (tx.IsCoinStake()) {
413  for (unsigned int i = 0; i < tx.vin.size(); i++)
414  mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
415  }
416  }
418  totalTxSize += entry.GetTxSize();
419  }
420  return true;
421 }
422 
423 
424 void CTxMemPool::remove(const CTransaction& origTx, std::list<CTransaction>& removed, bool fRecursive)
425 {
426  // Remove transaction from memory pool
427  {
428  LOCK(cs);
429  std::deque<uint256> txToRemove;
430  txToRemove.push_back(origTx.GetHash());
431  if (fRecursive && !mapTx.count(origTx.GetHash())) {
432  // If recursively removing but origTx isn't in the mempool
433  // be sure to remove any children that are in the pool. This can
434  // happen during chain re-orgs if origTx isn't re-accepted into
435  // the mempool for any reason.
436  for (unsigned int i = 0; i < origTx.vout.size(); i++) {
437  std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
438  if (it == mapNextTx.end())
439  continue;
440  txToRemove.push_back(it->second.ptx->GetHash());
441  }
442  }
443  while (!txToRemove.empty()) {
444  uint256 hash = txToRemove.front();
445  txToRemove.pop_front();
446  if (!mapTx.count(hash))
447  continue;
448  const CTransaction& tx = mapTx[hash].GetTx();
449  if (fRecursive) {
450  for (unsigned int i = 0; i < tx.vout.size(); i++) {
451  std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i));
452  if (it == mapNextTx.end())
453  continue;
454  txToRemove.push_back(it->second.ptx->GetHash());
455  }
456  }
457  for (const CTxIn& txin : tx.vin)
458  mapNextTx.erase(txin.prevout);
459 
460  removed.push_back(tx);
461  totalTxSize -= mapTx[hash].GetTxSize();
462  mapTx.erase(hash);
464  }
465  }
466 }
467 
468 void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache* pcoins, unsigned int nMemPoolHeight)
469 {
470  // Remove transactions spending a coinbase which are now immature
471  LOCK(cs);
472  std::list<CTransaction> transactionsToRemove;
473  for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
474  const CTransaction& tx = it->second.GetTx();
475  for (const CTxIn& txin : tx.vin) {
476  std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
477  if (it2 != mapTx.end())
478  continue;
479  const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
480  if (fSanityCheck) assert(coins);
481  if (!coins || ((coins->IsCoinBase() || coins->IsCoinStake()) && nMemPoolHeight - coins->nHeight < (unsigned)Params().COINBASE_MATURITY())) {
482  transactionsToRemove.push_back(tx);
483  break;
484  }
485  }
486  }
487  for (const CTransaction& tx : transactionsToRemove) {
488  std::list<CTransaction> removed;
489  remove(tx, removed, true);
490  }
491 }
492 
493 void CTxMemPool::removeConflicts(const CTransaction& tx, std::list<CTransaction>& removed)
494 {
495  // Remove transactions which depend on inputs of tx, recursively
496  std::list<CTransaction> result;
497  LOCK(cs);
498  for (const CTxIn& txin : tx.vin) {
499  std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout);
500  if (it != mapNextTx.end()) {
501  const CTransaction& txConflict = *it->second.ptx;
502  if (txConflict != tx) {
503  remove(txConflict, removed, true);
504  }
505  }
506  }
507 }
508 
512 void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight, std::list<CTransaction>& conflicts)
513 {
514  LOCK(cs);
515  std::vector<CTxMemPoolEntry> entries;
516  for (const CTransaction& tx : vtx) {
517  uint256 hash = tx.GetHash();
518  if (mapTx.count(hash))
519  entries.push_back(mapTx[hash]);
520  }
521  minerPolicyEstimator->seenBlock(entries, nBlockHeight, minRelayFee);
522  for (const CTransaction& tx : vtx) {
523  std::list<CTransaction> dummy;
524  remove(tx, dummy, false);
525  removeConflicts(tx, conflicts);
526  ClearPrioritisation(tx.GetHash());
527  }
528 }
529 
530 
532 {
533  LOCK(cs);
534  mapTx.clear();
535  mapNextTx.clear();
536  totalTxSize = 0;
538 }
539 
540 void CTxMemPool::check(const CCoinsViewCache* pcoins) const
541 {
542  if (!fSanityCheck)
543  return;
544 
545  LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
546 
547  uint64_t checkTotal = 0;
548 
549  CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
550 
551  LOCK(cs);
552  std::list<const CTxMemPoolEntry*> waitingOnDependants;
553  for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
554  unsigned int i = 0;
555  checkTotal += it->second.GetTxSize();
556  const CTransaction& tx = it->second.GetTx();
557  bool fDependsWait = false;
558  for (const CTxIn& txin : tx.vin) {
559  // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
560  std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
561  if (it2 != mapTx.end()) {
562  const CTransaction& tx2 = it2->second.GetTx();
563  assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
564  fDependsWait = true;
565  } else {
566  const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
567  assert(coins && coins->IsAvailable(txin.prevout.n));
568  }
569  // Check whether its inputs are marked in mapNextTx.
570  std::map<COutPoint, CInPoint>::const_iterator it3 = mapNextTx.find(txin.prevout);
571  assert(it3 != mapNextTx.end());
572  assert(it3->second.ptx == &tx);
573  assert(it3->second.n == i);
574  i++;
575  }
576  if (fDependsWait)
577  waitingOnDependants.push_back(&it->second);
578  else {
579  CValidationState state;
580  CTxUndo undo;
581  assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL));
582  UpdateCoins(tx, mempoolDuplicate, undo, 1000000);
583  }
584  }
585  unsigned int stepsSinceLastRemove = 0;
586  while (!waitingOnDependants.empty()) {
587  const CTxMemPoolEntry* entry = waitingOnDependants.front();
588  waitingOnDependants.pop_front();
589  CValidationState state;
590  if (!CheckHaveInputs(mempoolDuplicate, entry->GetTx())) {
591  waitingOnDependants.push_back(entry);
592  stepsSinceLastRemove++;
593  assert(stepsSinceLastRemove < waitingOnDependants.size());
594  } else {
595  assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL));
596  CTxUndo undo;
597  UpdateCoins(entry->GetTx(), mempoolDuplicate, undo, 1000000);
598  stepsSinceLastRemove = 0;
599  }
600  }
601  for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) {
602  uint256 hash = it->second.ptx->GetHash();
603  std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(hash);
604  const CTransaction& tx = it2->second.GetTx();
605  assert(it2 != mapTx.end());
606  assert(&tx == it->second.ptx);
607  assert(tx.vin.size() > it->second.n);
608  assert(it->first == it->second.ptx->vin[it->second.n].prevout);
609  }
610 
611  assert(totalTxSize == checkTotal);
612 }
613 
614 void CTxMemPool::queryHashes(std::vector<uint256>& vtxid)
615 {
616  vtxid.clear();
617 
618  LOCK(cs);
619  vtxid.reserve(mapTx.size());
620  for (std::map<uint256, CTxMemPoolEntry>::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi)
621  vtxid.push_back((*mi).first);
622 }
623 
624 bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const
625 {
626  LOCK(cs);
627  std::map<uint256, CTxMemPoolEntry>::const_iterator i = mapTx.find(hash);
628  if (i == mapTx.end()) return false;
629  result = i->second.GetTx();
630  return true;
631 }
632 
634 {
635  LOCK(cs);
636  return minerPolicyEstimator->estimateFee(nBlocks);
637 }
638 double CTxMemPool::estimatePriority(int nBlocks) const
639 {
640  LOCK(cs);
641  return minerPolicyEstimator->estimatePriority(nBlocks);
642 }
643 
645 {
646  try {
647  LOCK(cs);
648  fileout << 120000; // version required to read: 0.12.00 or later
649  fileout << CLIENT_VERSION; // version that wrote the file
650  minerPolicyEstimator->Write(fileout);
651  } catch (const std::exception&) {
652  LogPrintf("CTxMemPool::WriteFeeEstimates() : unable to write policy estimator data (non-fatal)\n");
653  return false;
654  }
655  return true;
656 }
657 
659 {
660  try {
661  int nVersionRequired, nVersionThatWrote;
662  filein >> nVersionRequired >> nVersionThatWrote;
663  if (nVersionRequired > CLIENT_VERSION)
664  return error("CTxMemPool::ReadFeeEstimates() : up-version (%d) fee estimate file", nVersionRequired);
665 
666  LOCK(cs);
668  } catch (const std::exception&) {
669  LogPrintf("CTxMemPool::ReadFeeEstimates() : unable to read policy estimator data (non-fatal)\n");
670  return false;
671  }
672  return true;
673 }
674 
675 void CTxMemPool::PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta)
676 {
677  {
678  LOCK(cs);
679  std::pair<double, CAmount>& deltas = mapDeltas[hash];
680  deltas.first += dPriorityDelta;
681  deltas.second += nFeeDelta;
682  }
683  LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta));
684 }
685 
686 void CTxMemPool::ApplyDeltas(const uint256 hash, double& dPriorityDelta, CAmount& nFeeDelta)
687 {
688  LOCK(cs);
689  std::map<uint256, std::pair<double, CAmount> >::iterator pos = mapDeltas.find(hash);
690  if (pos == mapDeltas.end())
691  return;
692  const std::pair<double, CAmount>& deltas = pos->second;
693  dPriorityDelta += deltas.first;
694  nFeeDelta += deltas.second;
695 }
696 
698 {
699  LOCK(cs);
700  mapDeltas.erase(hash);
701 }
702 
703 
705 
706 bool CCoinsViewMemPool::GetCoins(const uint256& txid, CCoins& coins) const
707 {
708  // If an entry in the mempool exists, always return that one, as it's guaranteed to never
709  // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
710  // transactions. First checking the underlying cache risks returning a pruned entry instead.
711  CTransaction tx;
712  if (mempool.lookup(txid, tx)) {
713  coins = CCoins(tx, MEMPOOL_HEIGHT);
714  return true;
715  }
716  return (base->GetCoins(txid, coins) && !coins.IsPruned());
717 }
718 
719 bool CCoinsViewMemPool::HaveCoins(const uint256& txid) const
720 {
721  return mempool.exists(txid) || base->HaveCoins(txid);
722 }
CBlockAverage::GetFeeSamples
size_t GetFeeSamples(std::vector< CFeeRate > &insertInto) const
Definition: txmempool.cpp:73
CTxIn
An input of a transaction.
Definition: transaction.h:83
CCoinsViewMemPool::GetCoins
bool GetCoins(const uint256 &txid, CCoins &coins) const
Retrieve the CCoins (unspent transaction outputs) for a given txid.
Definition: txmempool.cpp:706
CTxMemPool::AddTransactionsUpdated
void AddTransactionsUpdated(unsigned int n)
Definition: txmempool.cpp:395
CTxMemPool::pruneSpent
void pruneSpent(const uint256 &hash, CCoins &coins)
Definition: txmempool.cpp:376
CTxMemPool::removeCoinbaseSpends
void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight)
Definition: txmempool.cpp:468
CTxUndo
Undo information for a CTransaction.
Definition: undo.h:63
streams.h
CTxMemPool::minRelayFee
CFeeRate minRelayFee
Definition: txmempool.h:104
CBlockAverage::AreSane
static bool AreSane(const std::vector< CFeeRate > &vecFee, const CFeeRate &minRelayFee)
Definition: txmempool.cpp:99
AllowFree
bool AllowFree(double dPriority)
Definition: txmempool.h:26
COutPoint::hash
uint256 hash
Definition: transaction.h:39
CTxMemPool
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:97
CheckHaveInputs
bool CheckHaveInputs(const CCoinsViewCache &view, const CTransaction &tx)
Find the best known block, and make it the tip of the block chain.
Definition: main.cpp:1521
CTxMemPool::exists
bool exists(uint256 hash)
Definition: txmempool.h:179
CCoins::IsAvailable
bool IsAvailable(unsigned int nPos) const
check whether a particular output is still available
Definition: coins.h:275
CTxMemPool::ReadFeeEstimates
bool ReadFeeEstimates(CAutoFile &filein)
Definition: txmempool.cpp:658
CheckInputs
bool CheckInputs(const CTransaction &tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector< CScriptCheck > *pvChecks)
Check whether all inputs of this transaction are valid (no double spends, scripts & sigs,...
Definition: main.cpp:2766
UpdateCoins
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
Apply the effects of this transaction on the UTXO set represented by view.
Definition: main.cpp:2706
clientversion.h
GetSerializeSize
unsigned int GetSerializeSize(char a, int, int=0)
Definition: serialize.h:194
CCoins::nHeight
int nHeight
at which height this transaction was included in the active block chain
Definition: coins.h:88
CMinerPolicyEstimator::estimateFee
CFeeRate estimateFee(int nBlocksToConfirm)
Can return CFeeRate(0) if we don't have any data for that many blocks back.
Definition: txmempool.cpp:257
CMinerPolicyEstimator::Write
void Write(CAutoFile &fileout) const
Definition: txmempool.cpp:320
CBlockAverage::prioritySamples
boost::circular_buffer< double > prioritySamples
Definition: txmempool.cpp:50
FormatMoney
std::string FormatMoney(const CAmount &n, bool fPlus)
Money parsing/formatting utilities.
Definition: utilmoneystr.cpp:13
CBlockAverage::AreSane
static bool AreSane(const std::vector< double > vecPriority)
Definition: txmempool.cpp:111
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:159
CTxMemPool::GetTransactionsUpdated
unsigned int GetTransactionsUpdated() const
Definition: txmempool.cpp:389
CTxMemPool::check
void check(const CCoinsViewCache *pcoins) const
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
Definition: txmempool.cpp:540
CInPoint
An inpoint - a combination of a transaction and an index n into its vin.
Definition: txmempool.h:67
version.h
BCLog::ESTIMATEFEE
@ ESTIMATEFEE
Definition: logging.h:48
CFeeRate
Fee rate in PRCY per kilobyte: CAmount / kB.
Definition: amount.h:39
CMinerPolicyEstimator::sortedPrioritySamples
std::vector< double > sortedPrioritySamples
Definition: txmempool.cpp:157
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:269
CBlockAverage::Read
void Read(CAutoFile &filein, const CFeeRate &minRelayFee)
Definition: txmempool.cpp:128
CCoinsViewBacked::base
CCoinsView * base
Definition: coins.h:375
CTxMemPool::~CTxMemPool
~CTxMemPool()
Definition: txmempool.cpp:371
txmempool.h
CCoinsView
Abstract view on the open txout dataset.
Definition: coins.h:346
CAutoFile
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:303
CBlockAverage::feeSamples
boost::circular_buffer< CFeeRate > feeSamples
Definition: txmempool.cpp:49
CCoinsView::GetCoins
virtual bool GetCoins(const uint256 &txid, CCoins &coins) const
Retrieve the CCoins (unspent transaction outputs) for a given txid.
Definition: coins.cpp:66
CMinerPolicyEstimator::Read
void Read(CAutoFile &filein, const CFeeRate &minRelayFee)
Definition: txmempool.cpp:329
CCoinsViewMemPool::CCoinsViewMemPool
CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn)
Definition: txmempool.cpp:704
CBlockAverage::PrioritySamples
size_t PrioritySamples() const
Definition: txmempool.cpp:79
CTxMemPool::cs
RecursiveMutex cs
sum of all mempool tx' byte sizes
Definition: txmempool.h:135
CCoins::IsCoinStake
bool IsCoinStake() const
Definition: coins.h:173
CBlockAverage
Keep track of fee/priority for transactions confirmed within N blocks.
Definition: txmempool.cpp:46
CTxMemPool::removeForBlock
void removeForBlock(const std::vector< CTransaction > &vtx, unsigned int nBlockHeight, std::list< CTransaction > &conflicts)
Called when a block is connected.
Definition: txmempool.cpp:512
CTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:286
CTxMemPool::PrioritiseTransaction
void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
Definition: txmempool.cpp:675
CTxMemPool::remove
void remove(const CTransaction &tx, std::list< CTransaction > &removed, bool fRecursive=false)
Definition: txmempool.cpp:424
CMinerPolicyEstimator::seenBlock
void seenBlock(const std::vector< CTxMemPoolEntry > &entries, int nBlockHeight, const CFeeRate minRelayFee)
Definition: txmempool.cpp:196
CBlockAverage::AreSane
static bool AreSane(const CFeeRate fee, const CFeeRate &minRelayFee)
Used as belt-and-suspenders check when reading to detect file corruption.
Definition: txmempool.cpp:91
LogPrintf
#define LogPrintf(...)
Definition: logging.h:147
CAmount
int64_t CAmount
Amount in PRCY (Can be negative)
Definition: amount.h:17
CCoinsViewMemPool::mempool
CTxMemPool & mempool
Definition: txmempool.h:205
mempool
CTxMemPool mempool(::minRelayTxFee)
CTxMemPool::lookup
bool lookup(uint256 hash, CTransaction &result) const
Definition: txmempool.cpp:624
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
uint256::GetHash
uint64_t GetHash(const uint256 &salt) const
Definition: uint256.cpp:99
CMinerPolicyEstimator::sortedFeeSamples
std::vector< CFeeRate > sortedFeeSamples
Definition: txmempool.cpp:156
CTxMemPool::minerPolicyEstimator
CMinerPolicyEstimator * minerPolicyEstimator
Definition: txmempool.h:102
CTxMemPool::totalTxSize
uint64_t totalTxSize
Passed to constructor to avoid dependency on main.
Definition: txmempool.h:105
LogPrint
#define LogPrint(category,...)
Definition: logging.h:162
CMinerPolicyEstimator::CMinerPolicyEstimator
CMinerPolicyEstimator(int nEntries)
Definition: txmempool.cpp:191
CBlockAverage::AreSane
static bool AreSane(const double priority)
Definition: txmempool.cpp:107
GetPriority
double GetPriority(const CTransaction &tx, int nHeight)
Return priority of tx at height nHeight.
Definition: main.cpp:259
CTxMemPoolEntry::tx
CTransaction tx
Definition: txmempool.h:43
CCoinsViewCache::AccessCoins
const CCoins * AccessCoins(const uint256 &txid) const
Return a pointer to CCoins in the cache, or NULL if not found.
Definition: coins.cpp:145
CBlockAverage::buf2vec
std::vector< T > buf2vec(boost::circular_buffer< T > buf) const
Definition: txmempool.cpp:53
CCoins::IsCoinBase
bool IsCoinBase() const
Definition: coins.h:168
CTxMemPool::addUnchecked
bool addUnchecked(const uint256 &hash, const CTxMemPoolEntry &entry)
Definition: txmempool.cpp:402
CMinerPolicyEstimator::nBestSeenHeight
int nBestSeenHeight
Definition: txmempool.cpp:159
CTxMemPool::queryHashes
void queryHashes(std::vector< uint256 > &vtxid)
Definition: txmempool.cpp:614
CTxMemPool::WriteFeeEstimates
bool WriteFeeEstimates(CAutoFile &fileout) const
Write/Read estimates to disk.
Definition: txmempool.cpp:644
CTxMemPool::mapNextTx
std::map< COutPoint, CInPoint > mapNextTx
Definition: txmempool.h:137
BCLog::MEMPOOL
@ MEMPOOL
Definition: logging.h:42
CCoinsViewCache
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:414
CMinerPolicyEstimator
Definition: txmempool.cpp:148
CCoinsViewBacked
CCoinsView backed by another CCoinsView.
Definition: coins.h:372
utilmoneystr.h
main.h
CTxMemPoolEntry::nTxSize
size_t nTxSize
Cached to avoid expensive parent-transaction lookups.
Definition: txmempool.h:45
CCoinsViewMemPool::HaveCoins
bool HaveCoins(const uint256 &txid) const
Just check whether we have data for a given txid.
Definition: txmempool.cpp:719
COutPoint::n
uint32_t n
Definition: transaction.h:40
CTxMemPool::CTxMemPool
CTxMemPool(const CFeeRate &_minRelayFee)
Definition: txmempool.cpp:355
CTransaction::vin
std::vector< CTxIn > vin
Definition: transaction.h:285
CTxMemPoolEntry
CTxMemPool stores these:
Definition: txmempool.h:40
CTxMemPool::mapTx
std::map< uint256, CTxMemPoolEntry > mapTx
Definition: txmempool.h:136
LOCK
#define LOCK(cs)
Definition: sync.h:182
CTxMemPoolEntry::GetPriority
double GetPriority(unsigned int currentHeight) const
Definition: txmempool.cpp:38
CTxMemPool::estimateFee
CFeeRate estimateFee(int nBlocks) const
Estimate fee rate needed to get into the next nBlocks.
Definition: txmempool.cpp:633
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:86
CTransaction::CalculateModifiedSize
unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const
Definition: transaction.cpp:199
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:463
CTxMemPool::ApplyDeltas
void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta)
Definition: txmempool.cpp:686
CBlockAverage::Write
void Write(CAutoFile &fileout) const
Definition: txmempool.cpp:120
CFeeRate::ToString
std::string ToString() const
Definition: amount.cpp:30
CTxMemPoolEntry::nModSize
size_t nModSize
... and avoid recomputing tx size
Definition: txmempool.h:46
CCoins
Definition: coins.h:77
CTxMemPool::mapDeltas
std::map< uint256, std::pair< double, CAmount > > mapDeltas
Definition: txmempool.h:138
CTxMemPoolEntry::GetTxSize
size_t GetTxSize() const
Definition: txmempool.h:59
CTransaction::GetHash
const uint256 & GetHash() const
Definition: transaction.h:342
CTxMemPool::nTransactionsUpdated
unsigned int nTransactionsUpdated
Normally false, true if -checkmempool or -regtest.
Definition: txmempool.h:101
CTxMemPoolEntry::nHeight
unsigned int nHeight
Priority when entering the mempool.
Definition: txmempool.h:49
COutPoint
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:36
CTxMemPool::removeConflicts
void removeConflicts(const CTransaction &tx, std::list< CTransaction > &removed)
Definition: txmempool.cpp:493
CCoins::Spend
bool Spend(const COutPoint &out, CTxInUndo &undo)
mark an outpoint spent, and construct undo information
Definition: coins.cpp:38
CMinerPolicyEstimator::seenTxConfirm
void seenTxConfirm(const CFeeRate &feeRate, const CFeeRate &minRelayFee, double dPriority, int nBlocksAgo)
nBlocksAgo is 0 based, i.e.
Definition: txmempool.cpp:165
CBlockAverage::CBlockAverage
CBlockAverage()
Definition: txmempool.cpp:60
CTxMemPoolEntry::CTxMemPoolEntry
CTxMemPoolEntry()
Definition: txmempool.cpp:20
CFeeRate::GetFeePerK
CAmount GetFeePerK() const
Definition: amount.h:50
CMinerPolicyEstimator::estimatePriority
double estimatePriority(int nBlocksToConfirm)
Definition: txmempool.cpp:290
CCoinsView::HaveCoins
virtual bool HaveCoins(const uint256 &txid) const
Just check whether we have data for a given txid.
Definition: coins.cpp:67
CBlockAverage::FeeSamples
size_t FeeSamples() const
Definition: txmempool.cpp:72
CTxMemPool::clear
void clear()
Definition: txmempool.cpp:531
CValidationState
Capture information about block/transaction validation.
Definition: validation.h:23
util.h
CBlockAverage::RecordPriority
void RecordPriority(double priority)
Definition: txmempool.cpp:67
CBlockAverage::RecordFee
void RecordFee(const CFeeRate &feeRate)
Definition: txmempool.cpp:62
CTxMemPool::estimatePriority
double estimatePriority(int nBlocks) const
Estimate priority needed to get into the next nBlocks.
Definition: txmempool.cpp:638
CBlockAverage::GetPrioritySamples
size_t GetPrioritySamples(std::vector< double > &insertInto) const
Definition: txmempool.cpp:80
CMinerPolicyEstimator::history
std::vector< CBlockAverage > history
Records observed averages transactions that confirmed within one block, two blocks,...
Definition: txmempool.cpp:155
error
bool error(const char *fmt, const Args &... args)
Definition: util.h:61
CTxMemPool::ClearPrioritisation
void ClearPrioritisation(const uint256 hash)
Definition: txmempool.cpp:697
CCoins::IsPruned
bool IsPruned() const
check whether the entire CCoins is spent note that only !IsPruned() CCoins can be serialized
Definition: coins.h:282
CTxMemPoolEntry::GetTx
const CTransaction & GetTx() const
Definition: txmempool.h:56
CTransaction::IsCoinStake
bool IsCoinStake() const
Definition: transaction.cpp:143
CTxMemPool::fSanityCheck
bool fSanityCheck
Definition: txmempool.h:100