Browse Source

Merge pull request #4561

d0867ac Use const CCoinsView's at some places. (Daniel Kraft)
a3dc587 Make appropriate getter-routines "const" in CCoinsView. (Daniel Kraft)
ffb4c21 Mark LevelDB "Read" and "Exists" functions as const. (Daniel Kraft)
0.10
Pieter Wuille 10 years ago
parent
commit
790911ff0a
No known key found for this signature in database
GPG Key ID: 8F653255C87992E0
  1. 44
      src/coins.cpp
  2. 41
      src/coins.h
  3. 4
      src/leveldbwrapper.h
  4. 6
      src/main.cpp
  5. 6
      src/main.h
  6. 13
      src/txdb.cpp
  7. 8
      src/txdb.h
  8. 8
      src/txmempool.cpp
  9. 6
      src/txmempool.h

44
src/coins.cpp

@ -52,30 +52,30 @@ bool CCoins::Spend(int nPos) {
} }
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) { return false; } bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; } bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; }
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
uint256 CCoinsView::GetBestBlock() { return uint256(0); } uint256 CCoinsView::GetBestBlock() const { return uint256(0); }
bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; } bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
bool CCoinsView::GetStats(CCoinsStats &stats) { return false; } bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; }
CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { } CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { }
bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) { return base->GetCoins(txid, coins); } bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); } bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); }
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); } bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); } uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); } bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); } bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); }
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { } CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { }
bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) { bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
if (cacheCoins.count(txid)) { if (cacheCoins.count(txid)) {
coins = cacheCoins[txid]; coins = cacheCoins[txid];
return true; return true;
@ -99,19 +99,29 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
return ret; return ret;
} }
CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const {
/* Avoid redundant implementation with the const-cast. */
return const_cast<CCoinsViewCache*>(this)->FetchCoins(txid);
}
CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) { CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) {
CCoinsMap::iterator it = FetchCoins(txid); CCoinsMap::iterator it = FetchCoins(txid);
assert(it != cacheCoins.end()); assert(it != cacheCoins.end());
return it->second; return it->second;
} }
const CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) const {
/* Avoid redundant implementation with the const-cast. */
return const_cast<CCoinsViewCache*>(this)->GetCoins(txid);
}
bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) { bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) {
cacheCoins[txid] = coins; cacheCoins[txid] = coins;
return true; return true;
} }
bool CCoinsViewCache::HaveCoins(const uint256 &txid) { bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
CCoinsMap::iterator it = FetchCoins(txid); CCoinsMap::const_iterator it = FetchCoins(txid);
// We're using vtx.empty() instead of IsPruned here for performance reasons, // We're using vtx.empty() instead of IsPruned here for performance reasons,
// as we only care about the case where an transaction was replaced entirely // as we only care about the case where an transaction was replaced entirely
// in a reorganization (which wipes vout entirely, as opposed to spending // in a reorganization (which wipes vout entirely, as opposed to spending
@ -119,7 +129,7 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
return (it != cacheCoins.end() && !it->second.vout.empty()); return (it != cacheCoins.end() && !it->second.vout.empty());
} }
uint256 CCoinsViewCache::GetBestBlock() { uint256 CCoinsViewCache::GetBestBlock() const {
if (hashBlock == uint256(0)) if (hashBlock == uint256(0))
hashBlock = base->GetBestBlock(); hashBlock = base->GetBestBlock();
return hashBlock; return hashBlock;
@ -146,18 +156,18 @@ bool CCoinsViewCache::Flush() {
return fOk; return fOk;
} }
unsigned int CCoinsViewCache::GetCacheSize() { unsigned int CCoinsViewCache::GetCacheSize() const {
return cacheCoins.size(); return cacheCoins.size();
} }
const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const
{ {
const CCoins &coins = GetCoins(input.prevout.hash); const CCoins &coins = GetCoins(input.prevout.hash);
assert(coins.IsAvailable(input.prevout.n)); assert(coins.IsAvailable(input.prevout.n));
return coins.vout[input.prevout.n]; return coins.vout[input.prevout.n];
} }
int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx) int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx) const
{ {
if (tx.IsCoinBase()) if (tx.IsCoinBase())
return 0; return 0;
@ -169,7 +179,7 @@ int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx)
return nResult; return nResult;
} }
bool CCoinsViewCache::HaveInputs(const CTransaction& tx) bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{ {
if (!tx.IsCoinBase()) { if (!tx.IsCoinBase()) {
// first check whether information about the prevout hash is available // first check whether information about the prevout hash is available
@ -190,7 +200,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx)
return true; return true;
} }
double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
{ {
if (tx.IsCoinBase()) if (tx.IsCoinBase())
return 0.0; return 0.0;

41
src/coins.h

@ -276,17 +276,17 @@ class CCoinsView
{ {
public: public:
// Retrieve the CCoins (unspent transaction outputs) for a given txid // Retrieve the CCoins (unspent transaction outputs) for a given txid
virtual bool GetCoins(const uint256 &txid, CCoins &coins); virtual bool GetCoins(const uint256 &txid, CCoins &coins) const;
// Modify the CCoins for a given txid // Modify the CCoins for a given txid
virtual bool SetCoins(const uint256 &txid, const CCoins &coins); virtual bool SetCoins(const uint256 &txid, const CCoins &coins);
// Just check whether we have data for a given txid. // Just check whether we have data for a given txid.
// This may (but cannot always) return true for fully spent transactions // This may (but cannot always) return true for fully spent transactions
virtual bool HaveCoins(const uint256 &txid); virtual bool HaveCoins(const uint256 &txid) const;
// Retrieve the block hash whose state this CCoinsView currently represents // Retrieve the block hash whose state this CCoinsView currently represents
virtual uint256 GetBestBlock(); virtual uint256 GetBestBlock() const;
// Modify the currently active block hash // Modify the currently active block hash
virtual bool SetBestBlock(const uint256 &hashBlock); virtual bool SetBestBlock(const uint256 &hashBlock);
@ -296,7 +296,7 @@ public:
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
// Calculate statistics about the unspent transaction output set // Calculate statistics about the unspent transaction output set
virtual bool GetStats(CCoinsStats &stats); virtual bool GetStats(CCoinsStats &stats) const;
// As we use CCoinsViews polymorphically, have a virtual destructor // As we use CCoinsViews polymorphically, have a virtual destructor
virtual ~CCoinsView() {} virtual ~CCoinsView() {}
@ -311,14 +311,14 @@ protected:
public: public:
CCoinsViewBacked(CCoinsView &viewIn); CCoinsViewBacked(CCoinsView &viewIn);
bool GetCoins(const uint256 &txid, CCoins &coins); bool GetCoins(const uint256 &txid, CCoins &coins) const;
bool SetCoins(const uint256 &txid, const CCoins &coins); bool SetCoins(const uint256 &txid, const CCoins &coins);
bool HaveCoins(const uint256 &txid); bool HaveCoins(const uint256 &txid) const;
uint256 GetBestBlock(); uint256 GetBestBlock() const;
bool SetBestBlock(const uint256 &hashBlock); bool SetBestBlock(const uint256 &hashBlock);
void SetBackend(CCoinsView &viewIn); void SetBackend(CCoinsView &viewIn);
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
bool GetStats(CCoinsStats &stats); bool GetStats(CCoinsStats &stats) const;
}; };
@ -326,17 +326,20 @@ public:
class CCoinsViewCache : public CCoinsViewBacked class CCoinsViewCache : public CCoinsViewBacked
{ {
protected: protected:
uint256 hashBlock;
CCoinsMap cacheCoins; /* Make mutable so that we can "fill the cache" even from Get-methods
declared as "const". */
mutable uint256 hashBlock;
mutable CCoinsMap cacheCoins;
public: public:
CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false); CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false);
// Standard CCoinsView methods // Standard CCoinsView methods
bool GetCoins(const uint256 &txid, CCoins &coins); bool GetCoins(const uint256 &txid, CCoins &coins) const;
bool SetCoins(const uint256 &txid, const CCoins &coins); bool SetCoins(const uint256 &txid, const CCoins &coins);
bool HaveCoins(const uint256 &txid); bool HaveCoins(const uint256 &txid) const;
uint256 GetBestBlock(); uint256 GetBestBlock() const;
bool SetBestBlock(const uint256 &hashBlock); bool SetBestBlock(const uint256 &hashBlock);
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
@ -344,6 +347,7 @@ public:
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce // Many methods explicitly require a CCoinsViewCache because of this method, to reduce
// copying. // copying.
CCoins &GetCoins(const uint256 &txid); CCoins &GetCoins(const uint256 &txid);
const CCoins &GetCoins(const uint256 &txid) const;
// Push the modifications applied to this cache to its base. // Push the modifications applied to this cache to its base.
// Failure to call this method before destruction will cause the changes to be forgotten. // Failure to call this method before destruction will cause the changes to be forgotten.
@ -351,7 +355,7 @@ public:
bool Flush(); bool Flush();
// Calculate the size of the cache (in number of transactions) // Calculate the size of the cache (in number of transactions)
unsigned int GetCacheSize(); unsigned int GetCacheSize() const;
/** Amount of bitcoins coming in to a transaction /** Amount of bitcoins coming in to a transaction
Note that lightweight clients may not know anything besides the hash of previous transactions, Note that lightweight clients may not know anything besides the hash of previous transactions,
@ -360,18 +364,19 @@ public:
@param[in] tx transaction for which we are checking input total @param[in] tx transaction for which we are checking input total
@return Sum of value of all inputs (scriptSigs) @return Sum of value of all inputs (scriptSigs)
*/ */
int64_t GetValueIn(const CTransaction& tx); int64_t GetValueIn(const CTransaction& tx) const;
// Check whether all prevouts of the transaction are present in the UTXO set represented by this view // Check whether all prevouts of the transaction are present in the UTXO set represented by this view
bool HaveInputs(const CTransaction& tx); bool HaveInputs(const CTransaction& tx) const;
// Return priority of tx at height nHeight // Return priority of tx at height nHeight
double GetPriority(const CTransaction &tx, int nHeight); double GetPriority(const CTransaction &tx, int nHeight) const;
const CTxOut &GetOutputFor(const CTxIn& input); const CTxOut &GetOutputFor(const CTxIn& input) const;
private: private:
CCoinsMap::iterator FetchCoins(const uint256 &txid); CCoinsMap::iterator FetchCoins(const uint256 &txid);
CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const;
}; };
#endif #endif

4
src/leveldbwrapper.h

@ -82,7 +82,7 @@ public:
CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory = false, bool fWipe = false); CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
~CLevelDBWrapper(); ~CLevelDBWrapper();
template<typename K, typename V> bool Read(const K& key, V& value) throw(leveldb_error) { template<typename K, typename V> bool Read(const K& key, V& value) const throw(leveldb_error) {
CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key; ssKey << key;
@ -111,7 +111,7 @@ public:
return WriteBatch(batch, fSync); return WriteBatch(batch, fSync);
} }
template<typename K> bool Exists(const K& key) throw(leveldb_error) { template<typename K> bool Exists(const K& key) const throw(leveldb_error) {
CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(ssKey.GetSerializeSize(key)); ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key; ssKey << key;

6
src/main.cpp

@ -644,7 +644,7 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
// 2. P2SH scripts with a crazy number of expensive // 2. P2SH scripts with a crazy number of expensive
// CHECKSIG/CHECKMULTISIG operations // CHECKSIG/CHECKMULTISIG operations
// //
bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs) bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{ {
if (tx.IsCoinBase()) if (tx.IsCoinBase())
return true; // Coinbases don't use vin normally return true; // Coinbases don't use vin normally
@ -717,7 +717,7 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx)
return nSigOps; return nSigOps;
} }
unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& inputs) unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
{ {
if (tx.IsCoinBase()) if (tx.IsCoinBase())
return 0; return 0;
@ -1470,7 +1470,7 @@ bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned in
return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)(); return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)();
} }
bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks) bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks)
{ {
if (!tx.IsCoinBase()) if (!tx.IsCoinBase())
{ {

6
src/main.h

@ -265,7 +265,7 @@ int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
@param[in] mapInputs Map of previous transactions that have outputs we're spending @param[in] mapInputs Map of previous transactions that have outputs we're spending
@return True if all inputs (scriptSigs) use only standard transaction forms @return True if all inputs (scriptSigs) use only standard transaction forms
*/ */
bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs); bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
/** Count ECDSA signature operations the old-fashioned (pre-0.6) way /** Count ECDSA signature operations the old-fashioned (pre-0.6) way
@return number of sigops this transaction's outputs will produce when spent @return number of sigops this transaction's outputs will produce when spent
@ -279,13 +279,13 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx);
@return maximum number of sigops required to validate this transaction's inputs @return maximum number of sigops required to validate this transaction's inputs
@see CTransaction::FetchInputs @see CTransaction::FetchInputs
*/ */
unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& mapInputs); unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs);
// Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) // Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
// This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it // This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
// instead of being performed inline. // instead of being performed inline.
bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCache &view, bool fScriptChecks = true, bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks = true,
unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS, unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS,
std::vector<CScriptCheck> *pvChecks = NULL); std::vector<CScriptCheck> *pvChecks = NULL);

13
src/txdb.cpp

@ -27,7 +27,7 @@ void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) { CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
} }
bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) { bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const {
return db.Read(make_pair('c', txid), coins); return db.Read(make_pair('c', txid), coins);
} }
@ -37,11 +37,11 @@ bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) {
return db.WriteBatch(batch); return db.WriteBatch(batch);
} }
bool CCoinsViewDB::HaveCoins(const uint256 &txid) { bool CCoinsViewDB::HaveCoins(const uint256 &txid) const {
return db.Exists(make_pair('c', txid)); return db.Exists(make_pair('c', txid));
} }
uint256 CCoinsViewDB::GetBestBlock() { uint256 CCoinsViewDB::GetBestBlock() const {
uint256 hashBestChain; uint256 hashBestChain;
if (!db.Read('B', hashBestChain)) if (!db.Read('B', hashBestChain))
return uint256(0); return uint256(0);
@ -105,8 +105,11 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
return Read('l', nFile); return Read('l', nFile);
} }
bool CCoinsViewDB::GetStats(CCoinsStats &stats) { bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
boost::scoped_ptr<leveldb::Iterator> pcursor(db.NewIterator()); /* It seems that there are no "const iterators" for LevelDB. Since we
only need read operations on it, use a const-cast to get around
that restriction. */
leveldb::Iterator *pcursor = const_cast<CLevelDBWrapper*>(&db)->NewIterator();
pcursor->SeekToFirst(); pcursor->SeekToFirst();
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);

8
src/txdb.h

@ -32,13 +32,13 @@ protected:
public: public:
CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
bool GetCoins(const uint256 &txid, CCoins &coins); bool GetCoins(const uint256 &txid, CCoins &coins) const;
bool SetCoins(const uint256 &txid, const CCoins &coins); bool SetCoins(const uint256 &txid, const CCoins &coins);
bool HaveCoins(const uint256 &txid); bool HaveCoins(const uint256 &txid) const;
uint256 GetBestBlock(); uint256 GetBestBlock() const;
bool SetBestBlock(const uint256 &hashBlock); bool SetBestBlock(const uint256 &hashBlock);
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
bool GetStats(CCoinsStats &stats); bool GetStats(CCoinsStats &stats) const;
}; };
/** Access to the block database (blocks/index/) */ /** Access to the block database (blocks/index/) */

8
src/txmempool.cpp

@ -484,7 +484,7 @@ void CTxMemPool::clear()
++nTransactionsUpdated; ++nTransactionsUpdated;
} }
void CTxMemPool::check(CCoinsViewCache *pcoins) const void CTxMemPool::check(const CCoinsViewCache *pcoins) const
{ {
if (!fSanityCheck) if (!fSanityCheck)
return; return;
@ -505,7 +505,7 @@ void CTxMemPool::check(CCoinsViewCache *pcoins) const
const CTransaction& tx2 = it2->second.GetTx(); const CTransaction& tx2 = it2->second.GetTx();
assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
} else { } else {
CCoins &coins = pcoins->GetCoins(txin.prevout.hash); const CCoins &coins = pcoins->GetCoins(txin.prevout.hash);
assert(coins.IsAvailable(txin.prevout.n)); assert(coins.IsAvailable(txin.prevout.n));
} }
// Check whether its inputs are marked in mapNextTx. // Check whether its inputs are marked in mapNextTx.
@ -625,7 +625,7 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) { bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
// If an entry in the mempool exists, always return that one, as it's guaranteed to never // If an entry in the mempool exists, always return that one, as it's guaranteed to never
// conflict with the underlying cache, and it cannot have pruned entries (as it contains full) // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
// transactions. First checking the underlying cache risks returning a pruned entry instead. // transactions. First checking the underlying cache risks returning a pruned entry instead.
@ -637,7 +637,7 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
return (base->GetCoins(txid, coins) && !coins.IsPruned()); return (base->GetCoins(txid, coins) && !coins.IsPruned());
} }
bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) { bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const {
return mempool.exists(txid) || base->HaveCoins(txid); return mempool.exists(txid) || base->HaveCoins(txid);
} }

6
src/txmempool.h

@ -85,7 +85,7 @@ public:
* all inputs are in the mapNextTx array). If sanity-checking is turned off, * all inputs are in the mapNextTx array). If sanity-checking is turned off,
* check does nothing. * check does nothing.
*/ */
void check(CCoinsViewCache *pcoins) const; void check(const CCoinsViewCache *pcoins) const;
void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; } void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; }
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry); bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry);
@ -143,8 +143,8 @@ protected:
public: public:
CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn); CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn);
bool GetCoins(const uint256 &txid, CCoins &coins); bool GetCoins(const uint256 &txid, CCoins &coins) const;
bool HaveCoins(const uint256 &txid); bool HaveCoins(const uint256 &txid) const;
}; };
#endif /* BITCOIN_TXMEMPOOL_H */ #endif /* BITCOIN_TXMEMPOOL_H */

Loading…
Cancel
Save