Merge #10581: Simplify return values of GetCoin/HaveCoin(InCache)
21180ff
Simplify return values of GetCoin/HaveCoin(InCache) (Pieter Wuille)
Tree-SHA512: eae0aa64fa1308191100cdc7cdc790c825f33b066c200a18b5895d7d5806cee1cc4caba1766ef3379a7cf93dde4bbae2bc9be92947935f5741f5c126d3ee991b
This commit is contained in:
commit
78783531b7
5 changed files with 28 additions and 19 deletions
|
@ -11,11 +11,15 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
|
bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
|
||||||
bool CCoinsView::HaveCoin(const COutPoint &outpoint) const { return false; }
|
|
||||||
uint256 CCoinsView::GetBestBlock() const { return uint256(); }
|
uint256 CCoinsView::GetBestBlock() const { return uint256(); }
|
||||||
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
|
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
|
||||||
CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }
|
CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }
|
||||||
|
|
||||||
|
bool CCoinsView::HaveCoin(const COutPoint &outpoint) const
|
||||||
|
{
|
||||||
|
Coin coin;
|
||||||
|
return GetCoin(outpoint, coin);
|
||||||
|
}
|
||||||
|
|
||||||
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
|
CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
|
||||||
bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); }
|
bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); }
|
||||||
|
@ -55,7 +59,7 @@ bool CCoinsViewCache::GetCoin(const COutPoint &outpoint, Coin &coin) const {
|
||||||
CCoinsMap::const_iterator it = FetchCoin(outpoint);
|
CCoinsMap::const_iterator it = FetchCoin(outpoint);
|
||||||
if (it != cacheCoins.end()) {
|
if (it != cacheCoins.end()) {
|
||||||
coin = it->second.coin;
|
coin = it->second.coin;
|
||||||
return true;
|
return !coin.IsSpent();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,11 +145,13 @@ private:
|
||||||
class CCoinsView
|
class CCoinsView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Retrieve the Coin (unspent transaction output) for a given outpoint.
|
/** Retrieve the Coin (unspent transaction output) for a given outpoint.
|
||||||
|
* Returns true only when an unspent coin was found, which is returned in coin.
|
||||||
|
* When false is returned, coin's value is unspecified.
|
||||||
|
*/
|
||||||
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
|
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
|
||||||
|
|
||||||
//! Just check whether we have data for a given outpoint.
|
//! Just check whether a given outpoint is unspent.
|
||||||
//! This may (but cannot always) return true for spent outputs.
|
|
||||||
virtual bool HaveCoin(const COutPoint &outpoint) const;
|
virtual bool HaveCoin(const COutPoint &outpoint) const;
|
||||||
|
|
||||||
//! Retrieve the block hash whose state this CCoinsView currently represents
|
//! Retrieve the block hash whose state this CCoinsView currently represents
|
||||||
|
|
|
@ -50,12 +50,6 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HaveCoin(const COutPoint& outpoint) const override
|
|
||||||
{
|
|
||||||
Coin coin;
|
|
||||||
return GetCoin(outpoint, coin);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint256 GetBestBlock() const override { return hashBestBlock_; }
|
uint256 GetBestBlock() const override { return hashBestBlock_; }
|
||||||
|
|
||||||
bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock) override
|
bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock) override
|
||||||
|
@ -147,8 +141,22 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
|
||||||
{
|
{
|
||||||
uint256 txid = txids[InsecureRandRange(txids.size())]; // txid we're going to modify in this iteration.
|
uint256 txid = txids[InsecureRandRange(txids.size())]; // txid we're going to modify in this iteration.
|
||||||
Coin& coin = result[COutPoint(txid, 0)];
|
Coin& coin = result[COutPoint(txid, 0)];
|
||||||
|
|
||||||
|
// Determine whether to test HaveCoin before or after Access* (or both). As these functions
|
||||||
|
// can influence each other's behaviour by pulling things into the cache, all combinations
|
||||||
|
// are tested.
|
||||||
|
bool test_havecoin_before = InsecureRandBits(2) == 0;
|
||||||
|
bool test_havecoin_after = InsecureRandBits(2) == 0;
|
||||||
|
|
||||||
|
bool result_havecoin = test_havecoin_before ? stack.back()->HaveCoin(COutPoint(txid, 0)) : false;
|
||||||
const Coin& entry = (InsecureRandRange(500) == 0) ? AccessByTxid(*stack.back(), txid) : stack.back()->AccessCoin(COutPoint(txid, 0));
|
const Coin& entry = (InsecureRandRange(500) == 0) ? AccessByTxid(*stack.back(), txid) : stack.back()->AccessCoin(COutPoint(txid, 0));
|
||||||
BOOST_CHECK(coin == entry);
|
BOOST_CHECK(coin == entry);
|
||||||
|
BOOST_CHECK(!test_havecoin_before || result_havecoin == !entry.IsSpent());
|
||||||
|
|
||||||
|
if (test_havecoin_after) {
|
||||||
|
bool ret = stack.back()->HaveCoin(COutPoint(txid, 0));
|
||||||
|
BOOST_CHECK(ret == !entry.IsSpent());
|
||||||
|
}
|
||||||
|
|
||||||
if (InsecureRandRange(5) == 0 || coin.IsSpent()) {
|
if (InsecureRandRange(5) == 0 || coin.IsSpent()) {
|
||||||
Coin newcoin;
|
Coin newcoin;
|
||||||
|
@ -628,7 +636,7 @@ BOOST_AUTO_TEST_CASE(ccoins_access)
|
||||||
CheckAccessCoin(ABSENT, VALUE2, VALUE2, FRESH , FRESH );
|
CheckAccessCoin(ABSENT, VALUE2, VALUE2, FRESH , FRESH );
|
||||||
CheckAccessCoin(ABSENT, VALUE2, VALUE2, DIRTY , DIRTY );
|
CheckAccessCoin(ABSENT, VALUE2, VALUE2, DIRTY , DIRTY );
|
||||||
CheckAccessCoin(ABSENT, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH);
|
CheckAccessCoin(ABSENT, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH);
|
||||||
CheckAccessCoin(PRUNED, ABSENT, PRUNED, NO_ENTRY , FRESH );
|
CheckAccessCoin(PRUNED, ABSENT, ABSENT, NO_ENTRY , NO_ENTRY );
|
||||||
CheckAccessCoin(PRUNED, PRUNED, PRUNED, 0 , 0 );
|
CheckAccessCoin(PRUNED, PRUNED, PRUNED, 0 , 0 );
|
||||||
CheckAccessCoin(PRUNED, PRUNED, PRUNED, FRESH , FRESH );
|
CheckAccessCoin(PRUNED, PRUNED, PRUNED, FRESH , FRESH );
|
||||||
CheckAccessCoin(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY );
|
CheckAccessCoin(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY );
|
||||||
|
|
|
@ -903,11 +903,7 @@ bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (base->GetCoin(outpoint, coin) && !coin.IsSpent());
|
return base->GetCoin(outpoint, coin);
|
||||||
}
|
|
||||||
|
|
||||||
bool CCoinsViewMemPool::HaveCoin(const COutPoint &outpoint) const {
|
|
||||||
return mempool.exists(outpoint) || base->HaveCoin(outpoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CTxMemPool::DynamicMemoryUsage() const {
|
size_t CTxMemPool::DynamicMemoryUsage() const {
|
||||||
|
|
|
@ -684,8 +684,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn);
|
CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn);
|
||||||
bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
|
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
|
||||||
bool HaveCoin(const COutPoint &outpoint) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue