1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2013 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
11 CTxMemPoolEntry::CTxMemPoolEntry()
13 nHeight
= MEMPOOL_HEIGHT
;
16 CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction
& _tx
, int64_t _nFee
,
17 int64_t _nTime
, double _dPriority
,
18 unsigned int _nHeight
):
19 tx(_tx
), nFee(_nFee
), nTime(_nTime
), dPriority(_dPriority
), nHeight(_nHeight
)
21 nTxSize
= ::GetSerializeSize(tx
, SER_NETWORK
, PROTOCOL_VERSION
);
24 CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry
& other
)
30 CTxMemPoolEntry::GetPriority(unsigned int currentHeight
) const
32 int64_t nValueIn
= tx
.GetValueOut()+nFee
;
33 double deltaPriority
= ((double)(currentHeight
-nHeight
)*nValueIn
)/nTxSize
;
34 double dResult
= dPriority
+ deltaPriority
;
38 CTxMemPool::CTxMemPool()
40 // Sanity checks off by default for performance, because otherwise
41 // accepting transactions becomes O(N^2) where N is the number
42 // of transactions in the pool
46 void CTxMemPool::pruneSpent(const uint256
&hashTx
, CCoins
&coins
)
50 std::map
<COutPoint
, CInPoint
>::iterator it
= mapNextTx
.lower_bound(COutPoint(hashTx
, 0));
52 // iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
53 while (it
!= mapNextTx
.end() && it
->first
.hash
== hashTx
) {
54 coins
.Spend(it
->first
.n
); // and remove those outputs from coins
59 unsigned int CTxMemPool::GetTransactionsUpdated() const
62 return nTransactionsUpdated
;
65 void CTxMemPool::AddTransactionsUpdated(unsigned int n
)
68 nTransactionsUpdated
+= n
;
72 bool CTxMemPool::addUnchecked(const uint256
& hash
, const CTxMemPoolEntry
&entry
)
74 // Add to memory pool without checking anything.
75 // Used by main.cpp AcceptToMemoryPool(), which DOES do
76 // all the appropriate checks.
80 const CTransaction
& tx
= mapTx
[hash
].GetTx();
81 for (unsigned int i
= 0; i
< tx
.vin
.size(); i
++)
82 mapNextTx
[tx
.vin
[i
].prevout
] = CInPoint(&tx
, i
);
83 nTransactionsUpdated
++;
89 void CTxMemPool::remove(const CTransaction
&tx
, std::list
<CTransaction
>& removed
, bool fRecursive
)
91 // Remove transaction from memory pool
94 uint256 hash
= tx
.GetHash();
96 for (unsigned int i
= 0; i
< tx
.vout
.size(); i
++) {
97 std::map
<COutPoint
, CInPoint
>::iterator it
= mapNextTx
.find(COutPoint(hash
, i
));
98 if (it
== mapNextTx
.end())
100 remove(*it
->second
.ptx
, removed
, true);
103 if (mapTx
.count(hash
))
105 removed
.push_front(tx
);
106 BOOST_FOREACH(const CTxIn
& txin
, tx
.vin
)
107 mapNextTx
.erase(txin
.prevout
);
109 nTransactionsUpdated
++;
114 void CTxMemPool::removeConflicts(const CTransaction
&tx
, std::list
<CTransaction
>& removed
)
116 // Remove transactions which depend on inputs of tx, recursively
117 list
<CTransaction
> result
;
119 BOOST_FOREACH(const CTxIn
&txin
, tx
.vin
) {
120 std::map
<COutPoint
, CInPoint
>::iterator it
= mapNextTx
.find(txin
.prevout
);
121 if (it
!= mapNextTx
.end()) {
122 const CTransaction
&txConflict
= *it
->second
.ptx
;
123 if (txConflict
!= tx
)
125 remove(txConflict
, removed
, true);
131 void CTxMemPool::clear()
136 ++nTransactionsUpdated
;
139 void CTxMemPool::check(CCoinsViewCache
*pcoins
) const
144 LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx
.size(), (unsigned int)mapNextTx
.size());
147 for (std::map
<uint256
, CTxMemPoolEntry
>::const_iterator it
= mapTx
.begin(); it
!= mapTx
.end(); it
++) {
149 const CTransaction
& tx
= it
->second
.GetTx();
150 BOOST_FOREACH(const CTxIn
&txin
, tx
.vin
) {
151 // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
152 std::map
<uint256
, CTxMemPoolEntry
>::const_iterator it2
= mapTx
.find(txin
.prevout
.hash
);
153 if (it2
!= mapTx
.end()) {
154 const CTransaction
& tx2
= it2
->second
.GetTx();
155 assert(tx2
.vout
.size() > txin
.prevout
.n
&& !tx2
.vout
[txin
.prevout
.n
].IsNull());
157 CCoins
&coins
= pcoins
->GetCoins(txin
.prevout
.hash
);
158 assert(coins
.IsAvailable(txin
.prevout
.n
));
160 // Check whether its inputs are marked in mapNextTx.
161 std::map
<COutPoint
, CInPoint
>::const_iterator it3
= mapNextTx
.find(txin
.prevout
);
162 assert(it3
!= mapNextTx
.end());
163 assert(it3
->second
.ptx
== &tx
);
164 assert(it3
->second
.n
== i
);
168 for (std::map
<COutPoint
, CInPoint
>::const_iterator it
= mapNextTx
.begin(); it
!= mapNextTx
.end(); it
++) {
169 uint256 hash
= it
->second
.ptx
->GetHash();
170 map
<uint256
, CTxMemPoolEntry
>::const_iterator it2
= mapTx
.find(hash
);
171 const CTransaction
& tx
= it2
->second
.GetTx();
172 assert(it2
!= mapTx
.end());
173 assert(&tx
== it
->second
.ptx
);
174 assert(tx
.vin
.size() > it
->second
.n
);
175 assert(it
->first
== it
->second
.ptx
->vin
[it
->second
.n
].prevout
);
179 void CTxMemPool::queryHashes(vector
<uint256
>& vtxid
)
184 vtxid
.reserve(mapTx
.size());
185 for (map
<uint256
, CTxMemPoolEntry
>::iterator mi
= mapTx
.begin(); mi
!= mapTx
.end(); ++mi
)
186 vtxid
.push_back((*mi
).first
);
189 bool CTxMemPool::lookup(uint256 hash
, CTransaction
& result
) const
192 map
<uint256
, CTxMemPoolEntry
>::const_iterator i
= mapTx
.find(hash
);
193 if (i
== mapTx
.end()) return false;
194 result
= i
->second
.GetTx();
198 CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView
&baseIn
, CTxMemPool
&mempoolIn
) : CCoinsViewBacked(baseIn
), mempool(mempoolIn
) { }
200 bool CCoinsViewMemPool::GetCoins(const uint256
&txid
, CCoins
&coins
) {
201 if (base
->GetCoins(txid
, coins
))
204 if (mempool
.lookup(txid
, tx
)) {
205 coins
= CCoins(tx
, MEMPOOL_HEIGHT
);
211 bool CCoinsViewMemPool::HaveCoins(const uint256
&txid
) {
212 return mempool
.exists(txid
) || base
->HaveCoins(txid
);