]>
Commit | Line | Data |
---|---|---|
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 |
bc909a7a | 4 | // file COPYING or https://www.opensource.org/licenses/mit-license.php . |
093303a8 | 5 | |
319b1160 GA |
6 | #ifndef BITCOIN_TXMEMPOOL_H |
7 | #define BITCOIN_TXMEMPOOL_H | |
8 | ||
93a18a36 GA |
9 | #include <list> |
10 | ||
8b78a819 T |
11 | #include "addressindex.h" |
12 | #include "spentindex.h" | |
eda37330 | 13 | #include "amount.h" |
a0fa20a1 | 14 | #include "coins.h" |
d2270111 | 15 | #include "primitives/transaction.h" |
51ed9ec9 | 16 | #include "sync.h" |
68e174e2 | 17 | #include "addressindex.h" |
86b23f37 | 18 | #include "spentindex.h" |
319b1160 | 19 | |
e328fa32 AH |
20 | #undef foreach |
21 | #include "boost/multi_index_container.hpp" | |
22 | #include "boost/multi_index/ordered_index.hpp" | |
23 | ||
41f170fd MT |
24 | #include "pbaas/reserves.h" |
25 | ||
fa736190 CF |
26 | class CAutoFile; |
27 | ||
c1c9d5b4 CL |
28 | inline double AllowFreeThreshold() |
29 | { | |
30 | return COIN * 144 / 250; | |
31 | } | |
32 | ||
171ca774 GA |
33 | inline bool AllowFree(double dPriority) |
34 | { | |
35 | // Large (in bytes) low-priority (new, small-coin) transactions | |
36 | // need a fee. | |
c1c9d5b4 | 37 | return dPriority > AllowFreeThreshold(); |
171ca774 GA |
38 | } |
39 | ||
a0fa20a1 PW |
40 | /** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */ |
41 | static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF; | |
42 | ||
7329fdd1 | 43 | /** |
4d707d51 GA |
44 | * CTxMemPool stores these: |
45 | */ | |
46 | class CTxMemPoolEntry | |
47 | { | |
48 | private: | |
49 | CTransaction tx; | |
7329fdd1 MF |
50 | CAmount nFee; //! Cached to avoid expensive parent-transaction lookups |
51 | size_t nTxSize; //! ... and avoid recomputing tx size | |
52 | size_t nModSize; //! ... and modified size for priority | |
bde5c8b0 | 53 | size_t nUsageSize; //! ... and total memory usage |
e328fa32 | 54 | CFeeRate feeRate; //! ... and fee per kB |
7329fdd1 MF |
55 | int64_t nTime; //! Local time when entering the mempool |
56 | double dPriority; //! Priority when entering the mempool | |
57 | unsigned int nHeight; //! Chain height when entering the mempool | |
b649e039 | 58 | bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool |
a4b25180 | 59 | bool spendsCoinbase; //! keep track of transactions that spend a coinbase |
88d014d0 | 60 | bool hasReserve; //! keep track of transactions that hold reserve currency |
34a64fe0 | 61 | uint32_t nBranchId; //! Branch ID this transaction is known to commit to, cached for efficiency |
4d707d51 GA |
62 | |
63 | public: | |
a372168e | 64 | CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, |
a4b25180 | 65 | int64_t _nTime, double _dPriority, unsigned int _nHeight, |
41f170fd | 66 | bool poolHasNoInputsOf, bool spendsCoinbase, uint32_t nBranchId, bool hasreserve=false); |
4d707d51 GA |
67 | CTxMemPoolEntry(); |
68 | CTxMemPoolEntry(const CTxMemPoolEntry& other); | |
69 | ||
70 | const CTransaction& GetTx() const { return this->tx; } | |
71 | double GetPriority(unsigned int currentHeight) const; | |
a372168e | 72 | CAmount GetFee() const { return nFee; } |
e328fa32 | 73 | CFeeRate GetFeeRate() const { return feeRate; } |
4d707d51 GA |
74 | size_t GetTxSize() const { return nTxSize; } |
75 | int64_t GetTime() const { return nTime; } | |
76 | unsigned int GetHeight() const { return nHeight; } | |
b649e039 | 77 | bool WasClearAtEntry() const { return hadNoDependencies; } |
bde5c8b0 | 78 | size_t DynamicMemoryUsage() const { return nUsageSize; } |
a4b25180 SD |
79 | |
80 | bool GetSpendsCoinbase() const { return spendsCoinbase; } | |
34a64fe0 | 81 | uint32_t GetValidatedBranchId() const { return nBranchId; } |
4d707d51 GA |
82 | }; |
83 | ||
e328fa32 AH |
84 | // extracts a TxMemPoolEntry's transaction hash |
85 | struct mempoolentry_txid | |
86 | { | |
87 | typedef uint256 result_type; | |
88 | result_type operator() (const CTxMemPoolEntry &entry) const | |
89 | { | |
90 | return entry.GetTx().GetHash(); | |
91 | } | |
92 | }; | |
93 | ||
94 | class CompareTxMemPoolEntryByFee | |
95 | { | |
96 | public: | |
97 | bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) | |
98 | { | |
99 | if (a.GetFeeRate() == b.GetFeeRate()) | |
100 | return a.GetTime() < b.GetTime(); | |
101 | return a.GetFeeRate() > b.GetFeeRate(); | |
102 | } | |
4d707d51 GA |
103 | }; |
104 | ||
b649e039 | 105 | class CBlockPolicyEstimator; |
171ca774 | 106 | |
e8ea0fd1 | 107 | /** An inpoint - a combination of a transaction and an index n into its vin */ |
108 | class CInPoint | |
109 | { | |
110 | public: | |
111 | const CTransaction* ptx; | |
112 | uint32_t n; | |
113 | ||
114 | CInPoint() { SetNull(); } | |
115 | CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; } | |
116 | void SetNull() { ptx = NULL; n = (uint32_t) -1; } | |
117 | bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); } | |
bde5c8b0 | 118 | size_t DynamicMemoryUsage() const { return 0; } |
e8ea0fd1 | 119 | }; |
120 | ||
7329fdd1 | 121 | /** |
319b1160 GA |
122 | * CTxMemPool stores valid-according-to-the-current-best-chain |
123 | * transactions that may be included in the next block. | |
124 | * | |
125 | * Transactions are added when they are seen on the network | |
126 | * (or created by the local node), but not all transactions seen | |
127 | * are added to the pool: if a new transaction double-spends | |
128 | * an input of a transaction in the pool, it is dropped, | |
129 | * as are non-standard transactions. | |
130 | */ | |
131 | class CTxMemPool | |
132 | { | |
133 | private: | |
98f30100 | 134 | uint32_t nCheckFrequency; //!< Value n means that n times in 2^32 we check. |
319b1160 | 135 | unsigned int nTransactionsUpdated; |
b649e039 | 136 | CBlockPolicyEstimator* minerPolicyEstimator; |
319b1160 | 137 | |
98f30100 M |
138 | uint64_t totalTxSize = 0; //!< sum of all mempool tx' byte sizes |
139 | uint64_t cachedInnerUsage; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves) | |
13fc83c7 | 140 | |
3ff68c50 | 141 | std::map<uint256, const CTransaction*> mapRecentlyAddedTx; |
9d8322a3 JG |
142 | uint64_t nRecentlyAddedSequence = 0; |
143 | uint64_t nNotifiedSequence = 0; | |
13fc83c7 | 144 | |
9669920f | 145 | std::map<uint256, const CTransaction*> mapSproutNullifiers; |
685e936c EOW |
146 | std::map<uint256, const CTransaction*> mapSaplingNullifiers; |
147 | ||
41f170fd MT |
148 | std::map<uint256, std::pair<double, CAmount> > mapDeltas; |
149 | std::map<uint256, CReserveTransactionDescriptor> mapReserveTransactions; // all reserve transactions in the mempool go here | |
150 | ||
28d20bdb | 151 | void checkNullifiers(ShieldedType type) const; |
685e936c | 152 | |
319b1160 | 153 | public: |
e328fa32 AH |
154 | typedef boost::multi_index_container< |
155 | CTxMemPoolEntry, | |
156 | boost::multi_index::indexed_by< | |
157 | // sorted by txid | |
158 | boost::multi_index::ordered_unique<mempoolentry_txid>, | |
159 | // sorted by fee rate | |
160 | boost::multi_index::ordered_non_unique< | |
161 | boost::multi_index::identity<CTxMemPoolEntry>, | |
162 | CompareTxMemPoolEntryByFee | |
163 | > | |
164 | > | |
165 | > indexed_transaction_set; | |
166 | ||
319b1160 | 167 | mutable CCriticalSection cs; |
e328fa32 | 168 | indexed_transaction_set mapTx; |
8b78a819 T |
169 | |
170 | private: | |
68e174e2 LR |
171 | std::map<CMempoolAddressDeltaKey, CMempoolAddressDelta, CMempoolAddressDeltaKeyCompare> mapAddress; |
172 | std::map<uint256, std::vector<CMempoolAddressDeltaKey> > mapAddressInserted; | |
86b23f37 LR |
173 | std::map<CSpentIndexKey, CSpentIndexValue, CSpentIndexKeyCompare> mapSpent; |
174 | std::map<uint256, std::vector<CSpentIndexKey>> mapSpentInserted; | |
8b78a819 T |
175 | |
176 | public: | |
319b1160 GA |
177 | std::map<COutPoint, CInPoint> mapNextTx; |
178 | ||
13fc83c7 | 179 | CTxMemPool(const CFeeRate& _minRelayFee); |
171ca774 | 180 | ~CTxMemPool(); |
319b1160 | 181 | |
7329fdd1 | 182 | /** |
319b1160 GA |
183 | * If sanity-checking is turned on, check makes sure the pool is |
184 | * consistent (does not contain two transactions that spend the same inputs, | |
185 | * all inputs are in the mapNextTx array). If sanity-checking is turned off, | |
186 | * check does nothing. | |
187 | */ | |
d0867acb | 188 | void check(const CCoinsViewCache *pcoins) const; |
a0c977ca | 189 | void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = static_cast<uint32_t>(dFrequency * 4294967295.0); } |
319b1160 | 190 | |
b649e039 | 191 | bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); |
8b78a819 | 192 | void addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); |
88d014d0 | 193 | bool getAddressIndex(const std::vector<std::pair<uint160, int> > &addresses, std::vector<std::pair<CMempoolAddressDeltaKey, CMempoolAddressDelta> > &results); |
8b78a819 T |
194 | bool removeAddressIndex(const uint256 txhash); |
195 | ||
196 | void addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view); | |
86b23f37 | 197 | bool getSpentIndex(const CSpentIndexKey &key, CSpentIndexValue &value); |
8b78a819 | 198 | bool removeSpentIndex(const uint256 txhash); |
93a18a36 | 199 | void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false); |
98d2f090 | 200 | void removeWithAnchor(const uint256 &invalidRoot, ShieldedType type); |
233c9eb6 | 201 | void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); |
22adf258 | 202 | bool checkNameConflicts(const CTransaction &tx, std::list<CTransaction> &conflicting); |
93a18a36 | 203 | void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed); |
9bb37bf0 | 204 | void removeExpired(unsigned int nBlockHeight); |
171ca774 | 205 | void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight, |
b649e039 | 206 | std::list<CTransaction>& conflicts, bool fCurrentEstimate = true); |
34a64fe0 | 207 | void removeWithoutBranchId(uint32_t nMemPoolBranchId); |
319b1160 GA |
208 | void clear(); |
209 | void queryHashes(std::vector<uint256>& vtxid); | |
210 | void pruneSpent(const uint256& hash, CCoins &coins); | |
211 | unsigned int GetTransactionsUpdated() const; | |
212 | void AddTransactionsUpdated(unsigned int n); | |
b649e039 AM |
213 | /** |
214 | * Check that none of this transactions inputs are in the mempool, and thus | |
215 | * the tx is not dependent on other mempool transactions to be included in a block. | |
216 | */ | |
217 | bool HasNoInputsOf(const CTransaction& tx) const; | |
319b1160 | 218 | |
2a72d459 | 219 | /** Affect CreateNewBlock prioritisation of transactions */ |
41f170fd | 220 | void PrioritiseTransaction(const uint256 &hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta); |
c8c677c9 | 221 | bool PrioritiseReserveTransaction(const CReserveTransactionDescriptor &txDesc, const CCurrencyState ¤cyState); |
47aecf2f | 222 | bool IsKnownReserveTransaction(const uint256 &hash, CReserveTransactionDescriptor &txDesc); // know to be reserve transaction, get descriptor, update mempool |
a372168e | 223 | void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta); |
2a72d459 LD |
224 | void ClearPrioritisation(const uint256 hash); |
225 | ||
28d20bdb | 226 | bool nullifierExists(const uint256& nullifier, ShieldedType type) const; |
685e936c | 227 | |
3ff68c50 | 228 | void NotifyRecentlyAdded(); |
9d8322a3 | 229 | bool IsFullyNotified(); |
3ff68c50 | 230 | |
319b1160 GA |
231 | unsigned long size() |
232 | { | |
233 | LOCK(cs); | |
234 | return mapTx.size(); | |
235 | } | |
bde5c8b0 | 236 | |
6f2c26a4 JG |
237 | uint64_t GetTotalTxSize() |
238 | { | |
239 | LOCK(cs); | |
240 | return totalTxSize; | |
241 | } | |
319b1160 | 242 | |
b649e039 | 243 | bool exists(uint256 hash) const |
319b1160 GA |
244 | { |
245 | LOCK(cs); | |
246 | return (mapTx.count(hash) != 0); | |
247 | } | |
248 | ||
249 | bool lookup(uint256 hash, CTransaction& result) const; | |
171ca774 | 250 | |
7329fdd1 | 251 | /** Estimate fee rate needed to get into the next nBlocks */ |
171ca774 | 252 | CFeeRate estimateFee(int nBlocks) const; |
7329fdd1 MF |
253 | |
254 | /** Estimate priority needed to get into the next nBlocks */ | |
171ca774 | 255 | double estimatePriority(int nBlocks) const; |
7329fdd1 MF |
256 | |
257 | /** Write/Read estimates to disk */ | |
171ca774 GA |
258 | bool WriteFeeEstimates(CAutoFile& fileout) const; |
259 | bool ReadFeeEstimates(CAutoFile& filein); | |
bde5c8b0 PW |
260 | |
261 | size_t DynamicMemoryUsage() const; | |
a0c977ca S |
262 | |
263 | /** Return nCheckFrequency */ | |
264 | uint32_t GetCheckFrequency() const { | |
265 | return nCheckFrequency; | |
266 | } | |
319b1160 GA |
267 | }; |
268 | ||
7329fdd1 MF |
269 | /** |
270 | * CCoinsView that brings transactions from a memorypool into view. | |
271 | * It does not check for spendings by memory pool transactions. | |
272 | */ | |
a0fa20a1 PW |
273 | class CCoinsViewMemPool : public CCoinsViewBacked |
274 | { | |
275 | protected: | |
276 | CTxMemPool &mempool; | |
277 | ||
278 | public: | |
7c70438d | 279 | CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn); |
28d20bdb | 280 | bool GetNullifier(const uint256 &txid, ShieldedType type) const; |
a3dc587a DK |
281 | bool GetCoins(const uint256 &txid, CCoins &coins) const; |
282 | bool HaveCoins(const uint256 &txid) const; | |
a0fa20a1 PW |
283 | }; |
284 | ||
093303a8 | 285 | #endif // BITCOIN_TXMEMPOOL_H |