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) { @@ -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::HaveCoins(const uint256 &txid) { return false; }
uint256 CCoinsView::GetBestBlock() { return uint256(0); }
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return uint256(0); }
bool CCoinsView::SetBestBlock(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) { }
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::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); }
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
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()) {}
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)) {
coins = cacheCoins[txid];
return true;
@ -99,19 +99,29 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) { @@ -99,19 +99,29 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
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) {
CCoinsMap::iterator it = FetchCoins(txid);
assert(it != cacheCoins.end());
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) {
cacheCoins[txid] = coins;
return true;
}
bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
CCoinsMap::iterator it = FetchCoins(txid);
bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
CCoinsMap::const_iterator it = FetchCoins(txid);
// 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
// in a reorganization (which wipes vout entirely, as opposed to spending
@ -119,7 +129,7 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) { @@ -119,7 +129,7 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) {
return (it != cacheCoins.end() && !it->second.vout.empty());
}
uint256 CCoinsViewCache::GetBestBlock() {
uint256 CCoinsViewCache::GetBestBlock() const {
if (hashBlock == uint256(0))
hashBlock = base->GetBestBlock();
return hashBlock;
@ -146,18 +156,18 @@ bool CCoinsViewCache::Flush() { @@ -146,18 +156,18 @@ bool CCoinsViewCache::Flush() {
return fOk;
}
unsigned int CCoinsViewCache::GetCacheSize() {
unsigned int CCoinsViewCache::GetCacheSize() const {
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);
assert(coins.IsAvailable(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())
return 0;
@ -169,7 +179,7 @@ int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx) @@ -169,7 +179,7 @@ int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx)
return nResult;
}
bool CCoinsViewCache::HaveInputs(const CTransaction& tx)
bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
if (!tx.IsCoinBase()) {
// first check whether information about the prevout hash is available
@ -190,7 +200,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) @@ -190,7 +200,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx)
return true;
}
double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight)
double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
{
if (tx.IsCoinBase())
return 0.0;

41
src/coins.h

@ -276,17 +276,17 @@ class CCoinsView @@ -276,17 +276,17 @@ class CCoinsView
{
public:
// 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
virtual bool SetCoins(const uint256 &txid, const CCoins &coins);
// Just check whether we have data for a given txid.
// 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
virtual uint256 GetBestBlock();
virtual uint256 GetBestBlock() const;
// Modify the currently active block hash
virtual bool SetBestBlock(const uint256 &hashBlock);
@ -296,7 +296,7 @@ public: @@ -296,7 +296,7 @@ public:
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
// 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
virtual ~CCoinsView() {}
@ -311,14 +311,14 @@ protected: @@ -311,14 +311,14 @@ protected:
public:
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 HaveCoins(const uint256 &txid);
uint256 GetBestBlock();
bool HaveCoins(const uint256 &txid) const;
uint256 GetBestBlock() const;
bool SetBestBlock(const uint256 &hashBlock);
void SetBackend(CCoinsView &viewIn);
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
bool GetStats(CCoinsStats &stats);
bool GetStats(CCoinsStats &stats) const;
};
@ -326,17 +326,20 @@ public: @@ -326,17 +326,20 @@ public:
class CCoinsViewCache : public CCoinsViewBacked
{
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:
CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false);
// 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 HaveCoins(const uint256 &txid);
uint256 GetBestBlock();
bool HaveCoins(const uint256 &txid) const;
uint256 GetBestBlock() const;
bool SetBestBlock(const uint256 &hashBlock);
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
@ -344,6 +347,7 @@ public: @@ -344,6 +347,7 @@ public:
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce
// copying.
CCoins &GetCoins(const uint256 &txid);
const CCoins &GetCoins(const uint256 &txid) const;
// Push the modifications applied to this cache to its base.
// Failure to call this method before destruction will cause the changes to be forgotten.
@ -351,7 +355,7 @@ public: @@ -351,7 +355,7 @@ public:
bool Flush();
// 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
Note that lightweight clients may not know anything besides the hash of previous transactions,
@ -360,18 +364,19 @@ public: @@ -360,18 +364,19 @@ public:
@param[in] tx transaction for which we are checking input total
@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
bool HaveInputs(const CTransaction& tx);
bool HaveInputs(const CTransaction& tx) const;
// 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:
CCoinsMap::iterator FetchCoins(const uint256 &txid);
CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const;
};
#endif

4
src/leveldbwrapper.h

@ -82,7 +82,7 @@ public: @@ -82,7 +82,7 @@ public:
CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
~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);
ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key;
@ -111,7 +111,7 @@ public: @@ -111,7 +111,7 @@ public:
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);
ssKey.reserve(ssKey.GetSerializeSize(key));
ssKey << key;

6
src/main.cpp

@ -644,7 +644,7 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) @@ -644,7 +644,7 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
// 2. P2SH scripts with a crazy number of expensive
// CHECKSIG/CHECKMULTISIG operations
//
bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs)
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
if (tx.IsCoinBase())
return true; // Coinbases don't use vin normally
@ -717,7 +717,7 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx) @@ -717,7 +717,7 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx)
return nSigOps;
}
unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& inputs)
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
{
if (tx.IsCoinBase())
return 0;
@ -1470,7 +1470,7 @@ bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned in @@ -1470,7 +1470,7 @@ bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned in
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())
{

6
src/main.h

@ -265,7 +265,7 @@ int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF @@ -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
@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
@return number of sigops this transaction's outputs will produce when spent
@ -279,13 +279,13 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx); @@ -279,13 +279,13 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx);
@return maximum number of sigops required to validate this transaction's inputs
@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)
// This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
// 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,
std::vector<CScriptCheck> *pvChecks = NULL);

13
src/txdb.cpp

@ -27,7 +27,7 @@ void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) { @@ -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) {
}
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);
}
@ -37,11 +37,11 @@ bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) { @@ -37,11 +37,11 @@ bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) {
return db.WriteBatch(batch);
}
bool CCoinsViewDB::HaveCoins(const uint256 &txid) {
bool CCoinsViewDB::HaveCoins(const uint256 &txid) const {
return db.Exists(make_pair('c', txid));
}
uint256 CCoinsViewDB::GetBestBlock() {
uint256 CCoinsViewDB::GetBestBlock() const {
uint256 hashBestChain;
if (!db.Read('B', hashBestChain))
return uint256(0);
@ -105,8 +105,11 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) { @@ -105,8 +105,11 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
return Read('l', nFile);
}
bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
boost::scoped_ptr<leveldb::Iterator> pcursor(db.NewIterator());
bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
/* 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();
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);

8
src/txdb.h

@ -32,13 +32,13 @@ protected: @@ -32,13 +32,13 @@ protected:
public:
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 HaveCoins(const uint256 &txid);
uint256 GetBestBlock();
bool HaveCoins(const uint256 &txid) const;
uint256 GetBestBlock() const;
bool SetBestBlock(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/) */

8
src/txmempool.cpp

@ -484,7 +484,7 @@ void CTxMemPool::clear() @@ -484,7 +484,7 @@ void CTxMemPool::clear()
++nTransactionsUpdated;
}
void CTxMemPool::check(CCoinsViewCache *pcoins) const
void CTxMemPool::check(const CCoinsViewCache *pcoins) const
{
if (!fSanityCheck)
return;
@ -505,7 +505,7 @@ void CTxMemPool::check(CCoinsViewCache *pcoins) const @@ -505,7 +505,7 @@ void CTxMemPool::check(CCoinsViewCache *pcoins) const
const CTransaction& tx2 = it2->second.GetTx();
assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
} else {
CCoins &coins = pcoins->GetCoins(txin.prevout.hash);
const CCoins &coins = pcoins->GetCoins(txin.prevout.hash);
assert(coins.IsAvailable(txin.prevout.n));
}
// Check whether its inputs are marked in mapNextTx.
@ -625,7 +625,7 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash) @@ -625,7 +625,7 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
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
// 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.
@ -637,7 +637,7 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) { @@ -637,7 +637,7 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
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);
}

6
src/txmempool.h

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

Loading…
Cancel
Save