Changeset View
Changeset View
Standalone View
Standalone View
src/test/coins_tests.cpp
// Copyright (c) 2014-2016 The Bitcoin Core developers | // Copyright (c) 2014-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <coins.h> | #include <coins.h> | ||||
#include <clientversion.h> | #include <clientversion.h> | ||||
#include <consensus/validation.h> | #include <consensus/validation.h> | ||||
#include <script/standard.h> | #include <script/standard.h> | ||||
#include <streams.h> | #include <streams.h> | ||||
#include <uint256.h> | |||||
#include <undo.h> | #include <undo.h> | ||||
#include <util/strencodings.h> | #include <util/strencodings.h> | ||||
#include <validation.h> | #include <validation.h> | ||||
#include <test/test_bitcoin.h> | #include <test/test_bitcoin.h> | ||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
Show All 9 Lines | if (a.IsSpent() && b.IsSpent()) { | ||||
return true; | return true; | ||||
} | } | ||||
return a.IsCoinBase() == b.IsCoinBase() && a.GetHeight() == b.GetHeight() && | return a.IsCoinBase() == b.IsCoinBase() && a.GetHeight() == b.GetHeight() && | ||||
a.GetTxOut() == b.GetTxOut(); | a.GetTxOut() == b.GetTxOut(); | ||||
} | } | ||||
class CCoinsViewTest : public CCoinsView { | class CCoinsViewTest : public CCoinsView { | ||||
uint256 hashBestBlock_; | BlockHash hashBestBlock_; | ||||
std::map<COutPoint, Coin> map_; | std::map<COutPoint, Coin> map_; | ||||
public: | public: | ||||
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override { | bool GetCoin(const COutPoint &outpoint, Coin &coin) const override { | ||||
std::map<COutPoint, Coin>::const_iterator it = map_.find(outpoint); | std::map<COutPoint, Coin>::const_iterator it = map_.find(outpoint); | ||||
if (it == map_.end()) { | if (it == map_.end()) { | ||||
return false; | return false; | ||||
} | } | ||||
coin = it->second; | coin = it->second; | ||||
if (coin.IsSpent() && InsecureRandBool() == 0) { | if (coin.IsSpent() && InsecureRandBool() == 0) { | ||||
// Randomly return false in case of an empty entry. | // Randomly return false in case of an empty entry. | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
uint256 GetBestBlock() const override { return hashBestBlock_; } | BlockHash GetBestBlock() const override { return hashBestBlock_; } | ||||
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override { | bool BatchWrite(CCoinsMap &mapCoins, const BlockHash &hashBlock) override { | ||||
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { | for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { | ||||
if (it->second.flags & CCoinsCacheEntry::DIRTY) { | if (it->second.flags & CCoinsCacheEntry::DIRTY) { | ||||
// Same optimization used in CCoinsViewDB is to only write dirty | // Same optimization used in CCoinsViewDB is to only write dirty | ||||
// entries. | // entries. | ||||
map_[it->first] = it->second.coin; | map_[it->first] = it->second.coin; | ||||
if (it->second.coin.IsSpent() && InsecureRandRange(3) == 0) { | if (it->second.coin.IsSpent() && InsecureRandRange(3) == 0) { | ||||
// Randomly delete empty entries on write. | // Randomly delete empty entries on write. | ||||
map_.erase(it->first); | map_.erase(it->first); | ||||
▲ Show 20 Lines • Show All 556 Lines • ▼ Show 20 Lines | if (it == map.end()) { | ||||
flags = it->second.flags; | flags = it->second.flags; | ||||
assert(flags != NO_ENTRY); | assert(flags != NO_ENTRY); | ||||
} | } | ||||
} | } | ||||
void WriteCoinViewEntry(CCoinsView &view, const Amount value, char flags) { | void WriteCoinViewEntry(CCoinsView &view, const Amount value, char flags) { | ||||
CCoinsMap map; | CCoinsMap map; | ||||
InsertCoinMapEntry(map, value, flags); | InsertCoinMapEntry(map, value, flags); | ||||
view.BatchWrite(map, {}); | view.BatchWrite(map, BlockHash()); | ||||
} | } | ||||
class SingleEntryCacheTest { | class SingleEntryCacheTest { | ||||
public: | public: | ||||
SingleEntryCacheTest(const Amount base_value, const Amount cache_value, | SingleEntryCacheTest(const Amount base_value, const Amount cache_value, | ||||
char cache_flags) { | char cache_flags) { | ||||
WriteCoinViewEntry(base, base_value, | WriteCoinViewEntry(base, base_value, | ||||
base_value == ABSENT ? NO_ENTRY : DIRTY); | base_value == ABSENT ? NO_ENTRY : DIRTY); | ||||
▲ Show 20 Lines • Show All 277 Lines • Show Last 20 Lines |