You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
5.5 KiB
167 lines
5.5 KiB
// Copyright (c) 2009-2010 Satoshi Nakamoto |
|
// Copyright (c) 2009-2013 The Bitcoin developers |
|
// Distributed under the MIT/X11 software license, see the accompanying |
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php. |
|
|
|
#ifndef BITCOIN_TXMEMPOOL_H |
|
#define BITCOIN_TXMEMPOOL_H |
|
|
|
#include <list> |
|
|
|
#include "coins.h" |
|
#include "core.h" |
|
#include "sync.h" |
|
|
|
class CAutoFile; |
|
|
|
inline bool AllowFree(double dPriority) |
|
{ |
|
// Large (in bytes) low-priority (new, small-coin) transactions |
|
// need a fee. |
|
return dPriority > COIN * 144 / 250; |
|
} |
|
|
|
/** 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; |
|
|
|
/* |
|
* CTxMemPool stores these: |
|
*/ |
|
class CTxMemPoolEntry |
|
{ |
|
private: |
|
CTransaction tx; |
|
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 |
|
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 |
|
|
|
public: |
|
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, |
|
int64_t _nTime, double _dPriority, unsigned int _nHeight); |
|
CTxMemPoolEntry(); |
|
CTxMemPoolEntry(const CTxMemPoolEntry& other); |
|
|
|
const CTransaction& GetTx() const { return this->tx; } |
|
double GetPriority(unsigned int currentHeight) const; |
|
CAmount GetFee() const { return nFee; } |
|
size_t GetTxSize() const { return nTxSize; } |
|
int64_t GetTime() const { return nTime; } |
|
unsigned int GetHeight() const { return nHeight; } |
|
}; |
|
|
|
class CMinerPolicyEstimator; |
|
|
|
/** 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); } |
|
}; |
|
|
|
/* |
|
* 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: |
|
bool fSanityCheck; // Normally false, true if -checkmempool or -regtest |
|
unsigned int nTransactionsUpdated; |
|
CMinerPolicyEstimator* minerPolicyEstimator; |
|
|
|
CFeeRate minRelayFee; // Passed to constructor to avoid dependency on main |
|
uint64_t totalTxSize; // sum of all mempool tx' byte sizes |
|
|
|
public: |
|
mutable CCriticalSection cs; |
|
std::map<uint256, CTxMemPoolEntry> mapTx; |
|
std::map<COutPoint, CInPoint> mapNextTx; |
|
std::map<uint256, std::pair<double, CAmount> > mapDeltas; |
|
|
|
CTxMemPool(const CFeeRate& _minRelayFee); |
|
~CTxMemPool(); |
|
|
|
/* |
|
* 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. |
|
*/ |
|
void check(const CCoinsViewCache *pcoins) const; |
|
void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; } |
|
|
|
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry); |
|
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false); |
|
void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed); |
|
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight, |
|
std::list<CTransaction>& conflicts); |
|
void clear(); |
|
void queryHashes(std::vector<uint256>& vtxid); |
|
void pruneSpent(const uint256& hash, CCoins &coins); |
|
unsigned int GetTransactionsUpdated() const; |
|
void AddTransactionsUpdated(unsigned int n); |
|
|
|
/** Affect CreateNewBlock prioritisation of transactions */ |
|
void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta); |
|
void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta); |
|
void ClearPrioritisation(const uint256 hash); |
|
|
|
unsigned long size() |
|
{ |
|
LOCK(cs); |
|
return mapTx.size(); |
|
} |
|
uint64_t GetTotalTxSize() |
|
{ |
|
LOCK(cs); |
|
return totalTxSize; |
|
} |
|
|
|
bool exists(uint256 hash) |
|
{ |
|
LOCK(cs); |
|
return (mapTx.count(hash) != 0); |
|
} |
|
|
|
bool lookup(uint256 hash, CTransaction& result) const; |
|
|
|
// Estimate fee rate needed to get into the next |
|
// nBlocks |
|
CFeeRate estimateFee(int nBlocks) const; |
|
// Estimate priority needed to get into the next |
|
// nBlocks |
|
double estimatePriority(int nBlocks) const; |
|
// Write/Read estimates to disk |
|
bool WriteFeeEstimates(CAutoFile& fileout) const; |
|
bool ReadFeeEstimates(CAutoFile& filein); |
|
}; |
|
|
|
/** CCoinsView that brings transactions from a memorypool into view. |
|
It does not check for spendings by memory pool transactions. */ |
|
class CCoinsViewMemPool : public CCoinsViewBacked |
|
{ |
|
protected: |
|
CTxMemPool &mempool; |
|
|
|
public: |
|
CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn); |
|
bool GetCoins(const uint256 &txid, CCoins &coins) const; |
|
bool HaveCoins(const uint256 &txid) const; |
|
}; |
|
|
|
#endif // BITCOIN_TXMEMPOOL_H
|
|
|