17 #include <boost/circular_buffer.hpp>
53 std::vector<T>
buf2vec(boost::circular_buffer<T> buf)
const
55 std::vector<T> vec(buf.begin(), buf.end());
76 insertInto.push_back(f);
83 insertInto.push_back(d);
99 static bool AreSane(
const std::vector<CFeeRate>& vecFee,
const CFeeRate& minRelayFee)
102 if (!
AreSane(fee, minRelayFee))
109 return priority >= 0;
111 static bool AreSane(
const std::vector<double> vecPriority)
113 for (
double priority : vecPriority) {
125 fileout << vecPriority;
130 std::vector<CFeeRate> vecFee;
132 if (
AreSane(vecFee, minRelayFee))
135 throw std::runtime_error(
"Corrupt fee value in estimates file.");
136 std::vector<double> vecPriority;
137 filein >> vecPriority;
141 throw std::runtime_error(
"Corrupt priority value in estimates file.");
168 int nBlocksTruncated = std::min(nBlocksAgo, (
int)
history.size() - 1);
169 assert(nBlocksTruncated >= 0);
173 bool sufficientFee = (feeRate > minRelayFee);
174 bool sufficientPriority =
AllowFree(dPriority);
175 const char* assignedTo =
"unassigned";
177 history[nBlocksTruncated].RecordFee(feeRate);
180 history[nBlocksTruncated].RecordPriority(dPriority);
181 assignedTo =
"priority";
187 assignedTo, feeRate.
ToString(), dPriority, nBlocksAgo);
196 void seenBlock(
const std::vector<CTxMemPoolEntry>& entries,
int nBlockHeight,
const CFeeRate minRelayFee)
210 std::vector<std::vector<const CTxMemPoolEntry*> > entriesByConfirmations;
211 entriesByConfirmations.resize(
history.size());
214 int delta = nBlockHeight - entry.GetHeight();
220 if ((delta - 1) >= (
int)
history.size())
222 entriesByConfirmations.at(delta - 1).push_back(&entry);
224 for (
size_t i = 0; i < entriesByConfirmations.size(); i++) {
225 std::vector<const CTxMemPoolEntry*>& e = entriesByConfirmations.at(i);
229 std::random_shuffle(e.begin(), e.end());
234 CFeeRate feeRate(entry->GetFee(), entry->GetTxSize());
235 double dPriority = entry->GetPriority(entry->GetHeight());
245 for (
size_t i = 0; i <
history.size(); i++) {
261 if (nBlocksToConfirm < 0 || nBlocksToConfirm >= (
int)
history.size())
265 for (
size_t i = 0; i <
history.size(); i++)
268 std::greater<CFeeRate>());
277 int nBucketSize =
history.at(nBlocksToConfirm).FeeSamples();
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);
294 if (nBlocksToConfirm < 0 || nBlocksToConfirm >= (
int)
history.size())
298 for (
size_t i = 0; i <
history.size(); i++)
301 std::greater<double>());
306 int nBucketSize =
history.at(nBlocksToConfirm).PrioritySamples();
313 size_t nPrevSize = 0;
314 for (
int i = 0; i < nBlocksToConfirm; i++)
315 nPrevSize +=
history.at(i).PrioritySamples();
323 fileout << (uint32_t)
history.size();
325 entry.Write(fileout);
331 int nFileBestSeenHeight;
332 filein >> nFileBestSeenHeight;
334 filein >> numEntries;
335 if (numEntries <= 0 || numEntries > 10000)
336 throw std::runtime_error(
"Corrupt estimates file. Must have between 1 and 10k entries.");
338 std::vector<CBlockAverage> fileHistory;
340 for (
size_t i = 0; i < numEntries; i++) {
342 entry.
Read(filein, minRelayFee);
343 fileHistory.push_back(entry);
356 minRelayFee(_minRelayFee)
380 std::map<COutPoint, CInPoint>::iterator it =
mapNextTx.lower_bound(
COutPoint(hashTx, 0));
383 while (it !=
mapNextTx.end() && it->first.hash == hashTx) {
384 coins.
Spend(it->first.n);
413 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
429 std::deque<uint256> txToRemove;
430 txToRemove.push_back(origTx.
GetHash());
436 for (
unsigned int i = 0; i < origTx.
vout.size(); i++) {
440 txToRemove.push_back(it->second.ptx->GetHash());
443 while (!txToRemove.empty()) {
444 uint256 hash = txToRemove.front();
445 txToRemove.pop_front();
446 if (!
mapTx.count(hash))
450 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
454 txToRemove.push_back(it->second.ptx->GetHash());
460 removed.push_back(tx);
472 std::list<CTransaction> transactionsToRemove;
473 for (std::map<uint256, CTxMemPoolEntry>::const_iterator it =
mapTx.begin(); it !=
mapTx.end(); it++) {
476 std::map<uint256, CTxMemPoolEntry>::const_iterator it2 =
mapTx.find(txin.
prevout.
hash);
477 if (it2 !=
mapTx.end())
482 transactionsToRemove.push_back(tx);
488 std::list<CTransaction> removed;
489 remove(tx, removed,
true);
496 std::list<CTransaction> result;
502 if (txConflict != tx) {
503 remove(txConflict, removed,
true);
515 std::vector<CTxMemPoolEntry> entries;
518 if (
mapTx.count(hash))
519 entries.push_back(
mapTx[hash]);
523 std::list<CTransaction> dummy;
547 uint64_t checkTotal = 0;
552 std::list<const CTxMemPoolEntry*> waitingOnDependants;
553 for (std::map<uint256, CTxMemPoolEntry>::const_iterator it =
mapTx.begin(); it !=
mapTx.end(); it++) {
555 checkTotal += it->second.GetTxSize();
557 bool fDependsWait =
false;
560 std::map<uint256, CTxMemPoolEntry>::const_iterator it2 =
mapTx.find(txin.
prevout.
hash);
561 if (it2 !=
mapTx.end()) {
570 std::map<COutPoint, CInPoint>::const_iterator it3 =
mapNextTx.find(txin.
prevout);
572 assert(it3->second.ptx == &tx);
573 assert(it3->second.n == i);
577 waitingOnDependants.push_back(&it->second);
581 assert(
CheckInputs(tx, state, mempoolDuplicate,
false, 0,
false, NULL));
585 unsigned int stepsSinceLastRemove = 0;
586 while (!waitingOnDependants.empty()) {
588 waitingOnDependants.pop_front();
591 waitingOnDependants.push_back(entry);
592 stepsSinceLastRemove++;
593 assert(stepsSinceLastRemove < waitingOnDependants.size());
595 assert(
CheckInputs(entry->
GetTx(), state, mempoolDuplicate,
false, 0,
false, NULL));
598 stepsSinceLastRemove = 0;
601 for (std::map<COutPoint, CInPoint>::const_iterator it =
mapNextTx.begin(); it !=
mapNextTx.end(); it++) {
603 std::map<uint256, CTxMemPoolEntry>::const_iterator it2 =
mapTx.find(hash);
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);
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);
627 std::map<uint256, CTxMemPoolEntry>::const_iterator i =
mapTx.find(hash);
628 if (i ==
mapTx.end())
return false;
629 result = i->second.GetTx();
649 fileout << CLIENT_VERSION;
651 }
catch (
const std::exception&) {
652 LogPrintf(
"CTxMemPool::WriteFeeEstimates() : unable to write policy estimator data (non-fatal)\n");
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);
668 }
catch (
const std::exception&) {
669 LogPrintf(
"CTxMemPool::ReadFeeEstimates() : unable to read policy estimator data (non-fatal)\n");
679 std::pair<double, CAmount>& deltas =
mapDeltas[hash];
680 deltas.first += dPriorityDelta;
681 deltas.second += nFeeDelta;
683 LogPrintf(
"PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta,
FormatMoney(nFeeDelta));
689 std::map<uint256, std::pair<double, CAmount> >::iterator pos =
mapDeltas.find(hash);
692 const std::pair<double, CAmount>& deltas = pos->second;
693 dPriorityDelta += deltas.first;
694 nFeeDelta += deltas.second;
713 coins =
CCoins(tx, MEMPOOL_HEIGHT);