2013-08-26 22:51:57 -07:00
|
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
2014-12-16 17:47:57 -08:00
|
|
|
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
2014-11-16 18:29:09 -08:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2013-08-26 22:51:57 -07:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2014-08-28 13:21:03 -07:00
|
|
|
|
2013-08-26 22:51:57 -07:00
|
|
|
#ifndef BITCOIN_TXMEMPOOL_H
|
|
|
|
#define BITCOIN_TXMEMPOOL_H
|
|
|
|
|
2014-02-15 13:38:28 -08:00
|
|
|
#include <list>
|
|
|
|
|
2014-10-22 17:05:11 -07:00
|
|
|
#include "amount.h"
|
2013-11-04 17:47:07 -08:00
|
|
|
#include "coins.h"
|
2014-11-18 13:03:02 -08:00
|
|
|
#include "primitives/transaction.h"
|
2013-04-12 22:13:08 -07:00
|
|
|
#include "sync.h"
|
2013-08-26 22:51:57 -07:00
|
|
|
|
2015-06-24 01:32:20 -07:00
|
|
|
#undef foreach
|
|
|
|
#include "boost/multi_index_container.hpp"
|
|
|
|
#include "boost/multi_index/ordered_index.hpp"
|
|
|
|
|
2014-10-22 12:08:30 -07:00
|
|
|
class CAutoFile;
|
|
|
|
|
2014-11-01 16:14:47 -07:00
|
|
|
inline double AllowFreeThreshold()
|
|
|
|
{
|
|
|
|
return COIN * 144 / 250;
|
|
|
|
}
|
|
|
|
|
2014-03-17 05:19:54 -07:00
|
|
|
inline bool AllowFree(double dPriority)
|
|
|
|
{
|
|
|
|
// Large (in bytes) low-priority (new, small-coin) transactions
|
|
|
|
// need a fee.
|
2014-11-01 16:14:47 -07:00
|
|
|
return dPriority > AllowFreeThreshold();
|
2014-03-17 05:19:54 -07:00
|
|
|
}
|
|
|
|
|
2013-11-04 17:47:07 -08:00
|
|
|
/** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */
|
|
|
|
static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF;
|
|
|
|
|
2014-11-16 18:29:09 -08:00
|
|
|
/**
|
2013-11-10 23:35:14 -08:00
|
|
|
* CTxMemPool stores these:
|
|
|
|
*/
|
|
|
|
class CTxMemPoolEntry
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
CTransaction tx;
|
2014-11-16 18:29:09 -08:00
|
|
|
CAmount nFee; //! Cached to avoid expensive parent-transaction lookups
|
|
|
|
size_t nTxSize; //! ... and avoid recomputing tx size
|
|
|
|
size_t nModSize; //! ... and modified size for priority
|
2015-07-09 10:56:31 -07:00
|
|
|
size_t nUsageSize; //! ... and total memory usage
|
2015-06-24 01:32:20 -07:00
|
|
|
CFeeRate feeRate; //! ... and fee per kB
|
2014-11-16 18:29:09 -08:00
|
|
|
int64_t nTime; //! Local time when entering the mempool
|
|
|
|
double dPriority; //! Priority when entering the mempool
|
|
|
|
unsigned int nHeight; //! Chain height when entering the mempool
|
2014-08-26 13:28:32 -07:00
|
|
|
bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool
|
2015-10-29 11:06:13 -07:00
|
|
|
bool spendsCoinbase; //! keep track of transactions that spend a coinbase
|
2018-02-09 15:16:55 -08:00
|
|
|
uint32_t nBranchId; //! Branch ID this transaction is known to commit to, cached for efficiency
|
2013-11-10 23:35:14 -08:00
|
|
|
|
|
|
|
public:
|
2014-04-22 15:46:19 -07:00
|
|
|
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
|
2015-10-29 11:06:13 -07:00
|
|
|
int64_t _nTime, double _dPriority, unsigned int _nHeight,
|
2018-02-09 15:16:55 -08:00
|
|
|
bool poolHasNoInputsOf, bool spendsCoinbase, uint32_t nBranchId);
|
2013-11-10 23:35:14 -08:00
|
|
|
CTxMemPoolEntry();
|
|
|
|
CTxMemPoolEntry(const CTxMemPoolEntry& other);
|
|
|
|
|
|
|
|
const CTransaction& GetTx() const { return this->tx; }
|
|
|
|
double GetPriority(unsigned int currentHeight) const;
|
2014-04-22 15:46:19 -07:00
|
|
|
CAmount GetFee() const { return nFee; }
|
2015-06-24 01:32:20 -07:00
|
|
|
CFeeRate GetFeeRate() const { return feeRate; }
|
2013-11-10 23:35:14 -08:00
|
|
|
size_t GetTxSize() const { return nTxSize; }
|
|
|
|
int64_t GetTime() const { return nTime; }
|
|
|
|
unsigned int GetHeight() const { return nHeight; }
|
2014-08-26 13:28:32 -07:00
|
|
|
bool WasClearAtEntry() const { return hadNoDependencies; }
|
2015-07-09 10:56:31 -07:00
|
|
|
size_t DynamicMemoryUsage() const { return nUsageSize; }
|
2015-10-29 11:06:13 -07:00
|
|
|
|
|
|
|
bool GetSpendsCoinbase() const { return spendsCoinbase; }
|
2018-02-09 15:16:55 -08:00
|
|
|
uint32_t GetValidatedBranchId() const { return nBranchId; }
|
2013-11-10 23:35:14 -08:00
|
|
|
};
|
|
|
|
|
2015-06-24 01:32:20 -07:00
|
|
|
// extracts a TxMemPoolEntry's transaction hash
|
|
|
|
struct mempoolentry_txid
|
|
|
|
{
|
|
|
|
typedef uint256 result_type;
|
|
|
|
result_type operator() (const CTxMemPoolEntry &entry) const
|
|
|
|
{
|
|
|
|
return entry.GetTx().GetHash();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class CompareTxMemPoolEntryByFee
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
|
|
|
|
{
|
|
|
|
if (a.GetFeeRate() == b.GetFeeRate())
|
|
|
|
return a.GetTime() < b.GetTime();
|
|
|
|
return a.GetFeeRate() > b.GetFeeRate();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-08-26 13:28:32 -07:00
|
|
|
class CBlockPolicyEstimator;
|
2014-03-17 05:19:54 -07:00
|
|
|
|
2014-10-16 16:58:43 -07:00
|
|
|
/** An inpoint - a combination of a transaction and an index n into its vin */
|
|
|
|
class CInPoint
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
const CTransaction* ptx;
|
|
|
|
uint32_t n;
|
|
|
|
|
|
|
|
CInPoint() { SetNull(); }
|
|
|
|
CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; }
|
|
|
|
void SetNull() { ptx = NULL; n = (uint32_t) -1; }
|
|
|
|
bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); }
|
2015-07-09 10:56:31 -07:00
|
|
|
size_t DynamicMemoryUsage() const { return 0; }
|
2014-10-16 16:58:43 -07:00
|
|
|
};
|
|
|
|
|
2014-11-16 18:29:09 -08:00
|
|
|
/**
|
2013-08-26 22:51:57 -07:00
|
|
|
* CTxMemPool stores valid-according-to-the-current-best-chain
|
|
|
|
* transactions that may be included in the next block.
|
|
|
|
*
|
|
|
|
* Transactions are added when they are seen on the network
|
|
|
|
* (or created by the local node), but not all transactions seen
|
|
|
|
* are added to the pool: if a new transaction double-spends
|
|
|
|
* an input of a transaction in the pool, it is dropped,
|
|
|
|
* as are non-standard transactions.
|
|
|
|
*/
|
|
|
|
class CTxMemPool
|
|
|
|
{
|
|
|
|
private:
|
2015-10-07 14:34:55 -07:00
|
|
|
uint32_t nCheckFrequency; //! Value n means that n times in 2^32 we check.
|
2013-08-26 22:51:57 -07:00
|
|
|
unsigned int nTransactionsUpdated;
|
2014-08-26 13:28:32 -07:00
|
|
|
CBlockPolicyEstimator* minerPolicyEstimator;
|
2013-08-26 22:51:57 -07:00
|
|
|
|
2016-10-20 11:28:22 -07:00
|
|
|
uint64_t totalTxSize = 0; //! sum of all mempool tx' byte sizes
|
2015-07-09 10:56:31 -07:00
|
|
|
uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves)
|
2014-07-03 11:25:32 -07:00
|
|
|
|
2018-04-25 10:26:38 -07:00
|
|
|
std::map<uint256, const CTransaction*> mapSproutNullifiers;
|
2018-04-18 12:18:57 -07:00
|
|
|
std::map<uint256, const CTransaction*> mapSaplingNullifiers;
|
|
|
|
|
2018-04-25 16:55:33 -07:00
|
|
|
void checkNullifiers(ShieldedType type) const;
|
2018-04-18 12:18:57 -07:00
|
|
|
|
2013-08-26 22:51:57 -07:00
|
|
|
public:
|
2015-06-24 01:32:20 -07:00
|
|
|
typedef boost::multi_index_container<
|
|
|
|
CTxMemPoolEntry,
|
|
|
|
boost::multi_index::indexed_by<
|
|
|
|
// sorted by txid
|
|
|
|
boost::multi_index::ordered_unique<mempoolentry_txid>,
|
|
|
|
// sorted by fee rate
|
|
|
|
boost::multi_index::ordered_non_unique<
|
|
|
|
boost::multi_index::identity<CTxMemPoolEntry>,
|
|
|
|
CompareTxMemPoolEntryByFee
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> indexed_transaction_set;
|
|
|
|
|
2013-08-26 22:51:57 -07:00
|
|
|
mutable CCriticalSection cs;
|
2015-06-24 01:32:20 -07:00
|
|
|
indexed_transaction_set mapTx;
|
2013-08-26 22:51:57 -07:00
|
|
|
std::map<COutPoint, CInPoint> mapNextTx;
|
2014-04-22 15:46:19 -07:00
|
|
|
std::map<uint256, std::pair<double, CAmount> > mapDeltas;
|
2018-04-25 10:26:38 -07:00
|
|
|
|
2014-07-03 11:25:32 -07:00
|
|
|
CTxMemPool(const CFeeRate& _minRelayFee);
|
2014-03-17 05:19:54 -07:00
|
|
|
~CTxMemPool();
|
2013-08-26 22:51:57 -07:00
|
|
|
|
2014-11-16 18:29:09 -08:00
|
|
|
/**
|
2013-08-26 22:51:57 -07:00
|
|
|
* If sanity-checking is turned on, check makes sure the pool is
|
|
|
|
* consistent (does not contain two transactions that spend the same inputs,
|
|
|
|
* all inputs are in the mapNextTx array). If sanity-checking is turned off,
|
|
|
|
* check does nothing.
|
|
|
|
*/
|
2014-07-19 08:14:23 -07:00
|
|
|
void check(const CCoinsViewCache *pcoins) const;
|
2018-04-10 20:45:36 -07:00
|
|
|
void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = static_cast<uint32_t>(dFrequency * 4294967295.0); }
|
2013-08-26 22:51:57 -07:00
|
|
|
|
2014-08-26 13:28:32 -07:00
|
|
|
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true);
|
2014-02-15 13:38:28 -08:00
|
|
|
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
|
2018-05-06 23:16:14 -07:00
|
|
|
void removeWithAnchor(const uint256 &invalidRoot, ShieldedType type);
|
2015-11-23 13:06:12 -08:00
|
|
|
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
|
2014-02-15 13:38:28 -08:00
|
|
|
void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed);
|
2018-02-21 20:21:06 -08:00
|
|
|
void removeExpired(unsigned int nBlockHeight);
|
2014-03-17 05:19:54 -07:00
|
|
|
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
|
2014-08-26 13:28:32 -07:00
|
|
|
std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);
|
2018-02-09 15:16:55 -08:00
|
|
|
void removeWithoutBranchId(uint32_t nMemPoolBranchId);
|
2013-08-26 22:51:57 -07:00
|
|
|
void clear();
|
|
|
|
void queryHashes(std::vector<uint256>& vtxid);
|
|
|
|
void pruneSpent(const uint256& hash, CCoins &coins);
|
|
|
|
unsigned int GetTransactionsUpdated() const;
|
|
|
|
void AddTransactionsUpdated(unsigned int n);
|
2014-08-26 13:28:32 -07:00
|
|
|
/**
|
|
|
|
* Check that none of this transactions inputs are in the mempool, and thus
|
|
|
|
* the tx is not dependent on other mempool transactions to be included in a block.
|
|
|
|
*/
|
|
|
|
bool HasNoInputsOf(const CTransaction& tx) const;
|
2013-08-26 22:51:57 -07:00
|
|
|
|
2012-07-11 11:52:41 -07:00
|
|
|
/** Affect CreateNewBlock prioritisation of transactions */
|
2014-04-22 15:46:19 -07:00
|
|
|
void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta);
|
|
|
|
void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta);
|
2012-07-11 11:52:41 -07:00
|
|
|
void ClearPrioritisation(const uint256 hash);
|
|
|
|
|
2018-04-25 16:55:33 -07:00
|
|
|
bool nullifierExists(const uint256& nullifier, ShieldedType type) const;
|
2018-04-18 12:18:57 -07:00
|
|
|
|
2013-08-26 22:51:57 -07:00
|
|
|
unsigned long size()
|
|
|
|
{
|
|
|
|
LOCK(cs);
|
|
|
|
return mapTx.size();
|
|
|
|
}
|
2015-07-09 10:56:31 -07:00
|
|
|
|
2014-08-06 20:58:19 -07:00
|
|
|
uint64_t GetTotalTxSize()
|
|
|
|
{
|
|
|
|
LOCK(cs);
|
|
|
|
return totalTxSize;
|
|
|
|
}
|
2013-08-26 22:51:57 -07:00
|
|
|
|
2014-08-26 13:28:32 -07:00
|
|
|
bool exists(uint256 hash) const
|
2013-08-26 22:51:57 -07:00
|
|
|
{
|
|
|
|
LOCK(cs);
|
|
|
|
return (mapTx.count(hash) != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool lookup(uint256 hash, CTransaction& result) const;
|
2014-03-17 05:19:54 -07:00
|
|
|
|
2014-11-16 18:29:09 -08:00
|
|
|
/** Estimate fee rate needed to get into the next nBlocks */
|
2014-03-17 05:19:54 -07:00
|
|
|
CFeeRate estimateFee(int nBlocks) const;
|
2014-11-16 18:29:09 -08:00
|
|
|
|
|
|
|
/** Estimate priority needed to get into the next nBlocks */
|
2014-03-17 05:19:54 -07:00
|
|
|
double estimatePriority(int nBlocks) const;
|
2014-11-16 18:29:09 -08:00
|
|
|
|
|
|
|
/** Write/Read estimates to disk */
|
2014-03-17 05:19:54 -07:00
|
|
|
bool WriteFeeEstimates(CAutoFile& fileout) const;
|
|
|
|
bool ReadFeeEstimates(CAutoFile& filein);
|
2015-07-09 10:56:31 -07:00
|
|
|
|
|
|
|
size_t DynamicMemoryUsage() const;
|
2018-04-10 20:45:36 -07:00
|
|
|
|
|
|
|
/** Return nCheckFrequency */
|
|
|
|
uint32_t GetCheckFrequency() const {
|
|
|
|
return nCheckFrequency;
|
|
|
|
}
|
2013-08-26 22:51:57 -07:00
|
|
|
};
|
|
|
|
|
2014-11-16 18:29:09 -08:00
|
|
|
/**
|
|
|
|
* CCoinsView that brings transactions from a memorypool into view.
|
|
|
|
* It does not check for spendings by memory pool transactions.
|
|
|
|
*/
|
2013-11-04 17:47:07 -08:00
|
|
|
class CCoinsViewMemPool : public CCoinsViewBacked
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
CTxMemPool &mempool;
|
|
|
|
|
|
|
|
public:
|
2014-09-23 18:19:04 -07:00
|
|
|
CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn);
|
2018-04-25 16:55:33 -07:00
|
|
|
bool GetNullifier(const uint256 &txid, ShieldedType type) const;
|
2014-07-19 07:42:48 -07:00
|
|
|
bool GetCoins(const uint256 &txid, CCoins &coins) const;
|
|
|
|
bool HaveCoins(const uint256 &txid) const;
|
2013-11-04 17:47:07 -08:00
|
|
|
};
|
|
|
|
|
2014-08-28 13:21:03 -07:00
|
|
|
#endif // BITCOIN_TXMEMPOOL_H
|