Changeset View
Changeset View
Standalone View
Standalone View
src/test/coins_tests.cpp
Show First 20 Lines • Show All 587 Lines • ▼ Show 20 Lines | try { | ||||
Coin c5; | Coin c5; | ||||
ss5 >> c5; | ss5 >> c5; | ||||
BOOST_CHECK_MESSAGE(false, "We should have thrown"); | BOOST_CHECK_MESSAGE(false, "We should have thrown"); | ||||
} catch (const std::ios_base::failure &) { | } catch (const std::ios_base::failure &) { | ||||
} | } | ||||
} | } | ||||
static const COutPoint OUTPOINT; | static const COutPoint OUTPOINT; | ||||
static const Amount PRUNED(-1 * SATOSHI); | static const Amount SPENT(-1 * SATOSHI); | ||||
static const Amount ABSENT(-2 * SATOSHI); | static const Amount ABSENT(-2 * SATOSHI); | ||||
static const Amount FAIL(-3 * SATOSHI); | static const Amount FAIL(-3 * SATOSHI); | ||||
static const Amount VALUE1(100 * SATOSHI); | static const Amount VALUE1(100 * SATOSHI); | ||||
static const Amount VALUE2(200 * SATOSHI); | static const Amount VALUE2(200 * SATOSHI); | ||||
static const Amount VALUE3(300 * SATOSHI); | static const Amount VALUE3(300 * SATOSHI); | ||||
static const char DIRTY = CCoinsCacheEntry::DIRTY; | static const char DIRTY = CCoinsCacheEntry::DIRTY; | ||||
static const char FRESH = CCoinsCacheEntry::FRESH; | static const char FRESH = CCoinsCacheEntry::FRESH; | ||||
static const char NO_ENTRY = -1; | static const char NO_ENTRY = -1; | ||||
static const auto FLAGS = {char(0), FRESH, DIRTY, char(DIRTY | FRESH)}; | static const auto FLAGS = {char(0), FRESH, DIRTY, char(DIRTY | FRESH)}; | ||||
static const auto CLEAN_FLAGS = {char(0), FRESH}; | static const auto CLEAN_FLAGS = {char(0), FRESH}; | ||||
static const auto ABSENT_FLAGS = {NO_ENTRY}; | static const auto ABSENT_FLAGS = {NO_ENTRY}; | ||||
static void SetCoinValue(const Amount value, Coin &coin) { | static void SetCoinValue(const Amount value, Coin &coin) { | ||||
assert(value != ABSENT); | assert(value != ABSENT); | ||||
coin.Clear(); | coin.Clear(); | ||||
assert(coin.IsSpent()); | assert(coin.IsSpent()); | ||||
if (value != PRUNED) { | if (value != SPENT) { | ||||
CTxOut out; | CTxOut out; | ||||
out.nValue = value; | out.nValue = value; | ||||
coin = Coin(std::move(out), 1, false); | coin = Coin(std::move(out), 1, false); | ||||
assert(!coin.IsSpent()); | assert(!coin.IsSpent()); | ||||
} | } | ||||
} | } | ||||
static size_t InsertCoinMapEntry(CCoinsMap &map, const Amount value, | static size_t InsertCoinMapEntry(CCoinsMap &map, const Amount value, | ||||
Show All 13 Lines | |||||
void GetCoinMapEntry(const CCoinsMap &map, Amount &value, char &flags) { | void GetCoinMapEntry(const CCoinsMap &map, Amount &value, char &flags) { | ||||
auto it = map.find(OUTPOINT); | auto it = map.find(OUTPOINT); | ||||
if (it == map.end()) { | if (it == map.end()) { | ||||
value = ABSENT; | value = ABSENT; | ||||
flags = NO_ENTRY; | flags = NO_ENTRY; | ||||
} else { | } else { | ||||
if (it->second.coin.IsSpent()) { | if (it->second.coin.IsSpent()) { | ||||
value = PRUNED; | value = SPENT; | ||||
} else { | } else { | ||||
value = it->second.coin.GetTxOut().nValue; | value = it->second.coin.GetTxOut().nValue; | ||||
} | } | ||||
flags = it->second.flags; | flags = it->second.flags; | ||||
assert(flags != NO_ENTRY); | assert(flags != NO_ENTRY); | ||||
} | } | ||||
} | } | ||||
Show All 36 Lines | BOOST_AUTO_TEST_CASE(coin_access) { | ||||
/* Check AccessCoin behavior, requesting a coin from a cache view layered on | /* Check AccessCoin behavior, requesting a coin from a cache view layered on | ||||
* top of a base view, and checking the resulting entry in the cache after | * top of a base view, and checking the resulting entry in the cache after | ||||
* the access. | * the access. | ||||
* | * | ||||
* Base Cache Result Cache Result | * Base Cache Result Cache Result | ||||
* Value Value Value Flags Flags | * Value Value Value Flags Flags | ||||
*/ | */ | ||||
CheckAccessCoin(ABSENT, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY); | CheckAccessCoin(ABSENT, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY); | ||||
CheckAccessCoin(ABSENT, PRUNED, PRUNED, 0, 0); | CheckAccessCoin(ABSENT, SPENT, SPENT, 0, 0); | ||||
CheckAccessCoin(ABSENT, PRUNED, PRUNED, FRESH, FRESH); | CheckAccessCoin(ABSENT, SPENT, SPENT, FRESH, FRESH); | ||||
CheckAccessCoin(ABSENT, PRUNED, PRUNED, DIRTY, DIRTY); | CheckAccessCoin(ABSENT, SPENT, SPENT, DIRTY, DIRTY); | ||||
CheckAccessCoin(ABSENT, PRUNED, PRUNED, DIRTY | FRESH, DIRTY | FRESH); | CheckAccessCoin(ABSENT, SPENT, SPENT, DIRTY | FRESH, DIRTY | FRESH); | ||||
CheckAccessCoin(ABSENT, VALUE2, VALUE2, 0, 0); | CheckAccessCoin(ABSENT, VALUE2, VALUE2, 0, 0); | ||||
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, ABSENT, NO_ENTRY, NO_ENTRY); | CheckAccessCoin(SPENT, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY); | ||||
CheckAccessCoin(PRUNED, PRUNED, PRUNED, 0, 0); | CheckAccessCoin(SPENT, SPENT, SPENT, 0, 0); | ||||
CheckAccessCoin(PRUNED, PRUNED, PRUNED, FRESH, FRESH); | CheckAccessCoin(SPENT, SPENT, SPENT, FRESH, FRESH); | ||||
CheckAccessCoin(PRUNED, PRUNED, PRUNED, DIRTY, DIRTY); | CheckAccessCoin(SPENT, SPENT, SPENT, DIRTY, DIRTY); | ||||
CheckAccessCoin(PRUNED, PRUNED, PRUNED, DIRTY | FRESH, DIRTY | FRESH); | CheckAccessCoin(SPENT, SPENT, SPENT, DIRTY | FRESH, DIRTY | FRESH); | ||||
CheckAccessCoin(PRUNED, VALUE2, VALUE2, 0, 0); | CheckAccessCoin(SPENT, VALUE2, VALUE2, 0, 0); | ||||
CheckAccessCoin(PRUNED, VALUE2, VALUE2, FRESH, FRESH); | CheckAccessCoin(SPENT, VALUE2, VALUE2, FRESH, FRESH); | ||||
CheckAccessCoin(PRUNED, VALUE2, VALUE2, DIRTY, DIRTY); | CheckAccessCoin(SPENT, VALUE2, VALUE2, DIRTY, DIRTY); | ||||
CheckAccessCoin(PRUNED, VALUE2, VALUE2, DIRTY | FRESH, DIRTY | FRESH); | CheckAccessCoin(SPENT, VALUE2, VALUE2, DIRTY | FRESH, DIRTY | FRESH); | ||||
CheckAccessCoin(VALUE1, ABSENT, VALUE1, NO_ENTRY, 0); | CheckAccessCoin(VALUE1, ABSENT, VALUE1, NO_ENTRY, 0); | ||||
CheckAccessCoin(VALUE1, PRUNED, PRUNED, 0, 0); | CheckAccessCoin(VALUE1, SPENT, SPENT, 0, 0); | ||||
CheckAccessCoin(VALUE1, PRUNED, PRUNED, FRESH, FRESH); | CheckAccessCoin(VALUE1, SPENT, SPENT, FRESH, FRESH); | ||||
CheckAccessCoin(VALUE1, PRUNED, PRUNED, DIRTY, DIRTY); | CheckAccessCoin(VALUE1, SPENT, SPENT, DIRTY, DIRTY); | ||||
CheckAccessCoin(VALUE1, PRUNED, PRUNED, DIRTY | FRESH, DIRTY | FRESH); | CheckAccessCoin(VALUE1, SPENT, SPENT, DIRTY | FRESH, DIRTY | FRESH); | ||||
CheckAccessCoin(VALUE1, VALUE2, VALUE2, 0, 0); | CheckAccessCoin(VALUE1, VALUE2, VALUE2, 0, 0); | ||||
CheckAccessCoin(VALUE1, VALUE2, VALUE2, FRESH, FRESH); | CheckAccessCoin(VALUE1, VALUE2, VALUE2, FRESH, FRESH); | ||||
CheckAccessCoin(VALUE1, VALUE2, VALUE2, DIRTY, DIRTY); | CheckAccessCoin(VALUE1, VALUE2, VALUE2, DIRTY, DIRTY); | ||||
CheckAccessCoin(VALUE1, VALUE2, VALUE2, DIRTY | FRESH, DIRTY | FRESH); | CheckAccessCoin(VALUE1, VALUE2, VALUE2, DIRTY | FRESH, DIRTY | FRESH); | ||||
} | } | ||||
static void CheckSpendCoin(Amount base_value, Amount cache_value, | static void CheckSpendCoin(Amount base_value, Amount cache_value, | ||||
Amount expected_value, char cache_flags, | Amount expected_value, char cache_flags, | ||||
Show All 14 Lines | BOOST_AUTO_TEST_CASE(coin_spend) { | ||||
* Check SpendCoin behavior, requesting a coin from a cache view layered on | * Check SpendCoin behavior, requesting a coin from a cache view layered on | ||||
* top of a base view, spending, and then checking the resulting entry in | * top of a base view, spending, and then checking the resulting entry in | ||||
* the cache after the modification. | * the cache after the modification. | ||||
* | * | ||||
* Base Cache Result Cache Result | * Base Cache Result Cache Result | ||||
* Value Value Value Flags Flags | * Value Value Value Flags Flags | ||||
*/ | */ | ||||
CheckSpendCoin(ABSENT, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY); | CheckSpendCoin(ABSENT, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY); | ||||
CheckSpendCoin(ABSENT, PRUNED, PRUNED, 0, DIRTY); | CheckSpendCoin(ABSENT, SPENT, SPENT, 0, DIRTY); | ||||
CheckSpendCoin(ABSENT, PRUNED, ABSENT, FRESH, NO_ENTRY); | CheckSpendCoin(ABSENT, SPENT, ABSENT, FRESH, NO_ENTRY); | ||||
CheckSpendCoin(ABSENT, PRUNED, PRUNED, DIRTY, DIRTY); | CheckSpendCoin(ABSENT, SPENT, SPENT, DIRTY, DIRTY); | ||||
CheckSpendCoin(ABSENT, PRUNED, ABSENT, DIRTY | FRESH, NO_ENTRY); | CheckSpendCoin(ABSENT, SPENT, ABSENT, DIRTY | FRESH, NO_ENTRY); | ||||
CheckSpendCoin(ABSENT, VALUE2, PRUNED, 0, DIRTY); | CheckSpendCoin(ABSENT, VALUE2, SPENT, 0, DIRTY); | ||||
CheckSpendCoin(ABSENT, VALUE2, ABSENT, FRESH, NO_ENTRY); | CheckSpendCoin(ABSENT, VALUE2, ABSENT, FRESH, NO_ENTRY); | ||||
CheckSpendCoin(ABSENT, VALUE2, PRUNED, DIRTY, DIRTY); | CheckSpendCoin(ABSENT, VALUE2, SPENT, DIRTY, DIRTY); | ||||
CheckSpendCoin(ABSENT, VALUE2, ABSENT, DIRTY | FRESH, NO_ENTRY); | CheckSpendCoin(ABSENT, VALUE2, ABSENT, DIRTY | FRESH, NO_ENTRY); | ||||
CheckSpendCoin(PRUNED, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY); | CheckSpendCoin(SPENT, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY); | ||||
CheckSpendCoin(PRUNED, PRUNED, PRUNED, 0, DIRTY); | CheckSpendCoin(SPENT, SPENT, SPENT, 0, DIRTY); | ||||
CheckSpendCoin(PRUNED, PRUNED, ABSENT, FRESH, NO_ENTRY); | CheckSpendCoin(SPENT, SPENT, ABSENT, FRESH, NO_ENTRY); | ||||
CheckSpendCoin(PRUNED, PRUNED, PRUNED, DIRTY, DIRTY); | CheckSpendCoin(SPENT, SPENT, SPENT, DIRTY, DIRTY); | ||||
CheckSpendCoin(PRUNED, PRUNED, ABSENT, DIRTY | FRESH, NO_ENTRY); | CheckSpendCoin(SPENT, SPENT, ABSENT, DIRTY | FRESH, NO_ENTRY); | ||||
CheckSpendCoin(PRUNED, VALUE2, PRUNED, 0, DIRTY); | CheckSpendCoin(SPENT, VALUE2, SPENT, 0, DIRTY); | ||||
CheckSpendCoin(PRUNED, VALUE2, ABSENT, FRESH, NO_ENTRY); | CheckSpendCoin(SPENT, VALUE2, ABSENT, FRESH, NO_ENTRY); | ||||
CheckSpendCoin(PRUNED, VALUE2, PRUNED, DIRTY, DIRTY); | CheckSpendCoin(SPENT, VALUE2, SPENT, DIRTY, DIRTY); | ||||
CheckSpendCoin(PRUNED, VALUE2, ABSENT, DIRTY | FRESH, NO_ENTRY); | CheckSpendCoin(SPENT, VALUE2, ABSENT, DIRTY | FRESH, NO_ENTRY); | ||||
CheckSpendCoin(VALUE1, ABSENT, PRUNED, NO_ENTRY, DIRTY); | CheckSpendCoin(VALUE1, ABSENT, SPENT, NO_ENTRY, DIRTY); | ||||
CheckSpendCoin(VALUE1, PRUNED, PRUNED, 0, DIRTY); | CheckSpendCoin(VALUE1, SPENT, SPENT, 0, DIRTY); | ||||
CheckSpendCoin(VALUE1, PRUNED, ABSENT, FRESH, NO_ENTRY); | CheckSpendCoin(VALUE1, SPENT, ABSENT, FRESH, NO_ENTRY); | ||||
CheckSpendCoin(VALUE1, PRUNED, PRUNED, DIRTY, DIRTY); | CheckSpendCoin(VALUE1, SPENT, SPENT, DIRTY, DIRTY); | ||||
CheckSpendCoin(VALUE1, PRUNED, ABSENT, DIRTY | FRESH, NO_ENTRY); | CheckSpendCoin(VALUE1, SPENT, ABSENT, DIRTY | FRESH, NO_ENTRY); | ||||
CheckSpendCoin(VALUE1, VALUE2, PRUNED, 0, DIRTY); | CheckSpendCoin(VALUE1, VALUE2, SPENT, 0, DIRTY); | ||||
CheckSpendCoin(VALUE1, VALUE2, ABSENT, FRESH, NO_ENTRY); | CheckSpendCoin(VALUE1, VALUE2, ABSENT, FRESH, NO_ENTRY); | ||||
CheckSpendCoin(VALUE1, VALUE2, PRUNED, DIRTY, DIRTY); | CheckSpendCoin(VALUE1, VALUE2, SPENT, DIRTY, DIRTY); | ||||
CheckSpendCoin(VALUE1, VALUE2, ABSENT, DIRTY | FRESH, NO_ENTRY); | CheckSpendCoin(VALUE1, VALUE2, ABSENT, DIRTY | FRESH, NO_ENTRY); | ||||
} | } | ||||
static void CheckAddCoinBase(Amount base_value, Amount cache_value, | static void CheckAddCoinBase(Amount base_value, Amount cache_value, | ||||
Amount modify_value, Amount expected_value, | Amount modify_value, Amount expected_value, | ||||
char cache_flags, char expected_flags, | char cache_flags, char expected_flags, | ||||
bool coinbase) { | bool coinbase) { | ||||
SingleEntryCacheTest test(base_value, cache_value, cache_flags); | SingleEntryCacheTest test(base_value, cache_value, cache_flags); | ||||
Show All 17 Lines | |||||
} | } | ||||
// Simple wrapper for CheckAddCoinBase function above that loops through | // Simple wrapper for CheckAddCoinBase function above that loops through | ||||
// different possible base_values, making sure each one gives the same results. | // different possible base_values, making sure each one gives the same results. | ||||
// This wrapper lets the coin_add test below be shorter and less repetitive, | // This wrapper lets the coin_add test below be shorter and less repetitive, | ||||
// while still verifying that the CoinsViewCache::AddCoin implementation ignores | // while still verifying that the CoinsViewCache::AddCoin implementation ignores | ||||
// base values. | // base values. | ||||
template <typename... Args> static void CheckAddCoin(Args &&... args) { | template <typename... Args> static void CheckAddCoin(Args &&... args) { | ||||
for (const Amount &base_value : {ABSENT, PRUNED, VALUE1}) { | for (const Amount &base_value : {ABSENT, SPENT, VALUE1}) { | ||||
CheckAddCoinBase(base_value, std::forward<Args>(args)...); | CheckAddCoinBase(base_value, std::forward<Args>(args)...); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(coin_add) { | BOOST_AUTO_TEST_CASE(coin_add) { | ||||
/** | /** | ||||
* Check AddCoin behavior, requesting a new coin from a cache view, writing | * Check AddCoin behavior, requesting a new coin from a cache view, writing | ||||
* a modification to the coin, and then checking the resulting entry in the | * a modification to the coin, and then checking the resulting entry in the | ||||
* cache after the modification. Verify behavior with the with the AddCoin | * cache after the modification. Verify behavior with the with the AddCoin | ||||
* potential_overwrite argument set to false, and to true. | * potential_overwrite argument set to false, and to true. | ||||
* | * | ||||
* Cache Write Result Cache Result potential_overwrite | * Cache Write Result Cache Result potential_overwrite | ||||
* Value Value Value Flags Flags | * Value Value Value Flags Flags | ||||
*/ | */ | ||||
CheckAddCoin(ABSENT, VALUE3, VALUE3, NO_ENTRY, DIRTY | FRESH, false); | CheckAddCoin(ABSENT, VALUE3, VALUE3, NO_ENTRY, DIRTY | FRESH, false); | ||||
CheckAddCoin(ABSENT, VALUE3, VALUE3, NO_ENTRY, DIRTY, true); | CheckAddCoin(ABSENT, VALUE3, VALUE3, NO_ENTRY, DIRTY, true); | ||||
CheckAddCoin(PRUNED, VALUE3, VALUE3, 0, DIRTY | FRESH, false); | CheckAddCoin(SPENT, VALUE3, VALUE3, 0, DIRTY | FRESH, false); | ||||
CheckAddCoin(PRUNED, VALUE3, VALUE3, 0, DIRTY, true); | CheckAddCoin(SPENT, VALUE3, VALUE3, 0, DIRTY, true); | ||||
CheckAddCoin(PRUNED, VALUE3, VALUE3, FRESH, DIRTY | FRESH, false); | CheckAddCoin(SPENT, VALUE3, VALUE3, FRESH, DIRTY | FRESH, false); | ||||
CheckAddCoin(PRUNED, VALUE3, VALUE3, FRESH, DIRTY | FRESH, true); | CheckAddCoin(SPENT, VALUE3, VALUE3, FRESH, DIRTY | FRESH, true); | ||||
CheckAddCoin(PRUNED, VALUE3, VALUE3, DIRTY, DIRTY, false); | CheckAddCoin(SPENT, VALUE3, VALUE3, DIRTY, DIRTY, false); | ||||
CheckAddCoin(PRUNED, VALUE3, VALUE3, DIRTY, DIRTY, true); | CheckAddCoin(SPENT, VALUE3, VALUE3, DIRTY, DIRTY, true); | ||||
CheckAddCoin(PRUNED, VALUE3, VALUE3, DIRTY | FRESH, DIRTY | FRESH, false); | CheckAddCoin(SPENT, VALUE3, VALUE3, DIRTY | FRESH, DIRTY | FRESH, false); | ||||
CheckAddCoin(PRUNED, VALUE3, VALUE3, DIRTY | FRESH, DIRTY | FRESH, true); | CheckAddCoin(SPENT, VALUE3, VALUE3, DIRTY | FRESH, DIRTY | FRESH, true); | ||||
CheckAddCoin(VALUE2, VALUE3, FAIL, 0, NO_ENTRY, false); | CheckAddCoin(VALUE2, VALUE3, FAIL, 0, NO_ENTRY, false); | ||||
CheckAddCoin(VALUE2, VALUE3, VALUE3, 0, DIRTY, true); | CheckAddCoin(VALUE2, VALUE3, VALUE3, 0, DIRTY, true); | ||||
CheckAddCoin(VALUE2, VALUE3, FAIL, FRESH, NO_ENTRY, false); | CheckAddCoin(VALUE2, VALUE3, FAIL, FRESH, NO_ENTRY, false); | ||||
CheckAddCoin(VALUE2, VALUE3, VALUE3, FRESH, DIRTY | FRESH, true); | CheckAddCoin(VALUE2, VALUE3, VALUE3, FRESH, DIRTY | FRESH, true); | ||||
CheckAddCoin(VALUE2, VALUE3, FAIL, DIRTY, NO_ENTRY, false); | CheckAddCoin(VALUE2, VALUE3, FAIL, DIRTY, NO_ENTRY, false); | ||||
CheckAddCoin(VALUE2, VALUE3, VALUE3, DIRTY, DIRTY, true); | CheckAddCoin(VALUE2, VALUE3, VALUE3, DIRTY, DIRTY, true); | ||||
CheckAddCoin(VALUE2, VALUE3, FAIL, DIRTY | FRESH, NO_ENTRY, false); | CheckAddCoin(VALUE2, VALUE3, FAIL, DIRTY | FRESH, NO_ENTRY, false); | ||||
CheckAddCoin(VALUE2, VALUE3, VALUE3, DIRTY | FRESH, DIRTY | FRESH, true); | CheckAddCoin(VALUE2, VALUE3, VALUE3, DIRTY | FRESH, DIRTY | FRESH, true); | ||||
Show All 23 Lines | BOOST_AUTO_TEST_CASE(coin_write) { | ||||
/* Check BatchWrite behavior, flushing one entry from a child cache to a | /* Check BatchWrite behavior, flushing one entry from a child cache to a | ||||
* parent cache, and checking the resulting entry in the parent cache | * parent cache, and checking the resulting entry in the parent cache | ||||
* after the write. | * after the write. | ||||
* | * | ||||
* Parent Child Result Parent Child Result | * Parent Child Result Parent Child Result | ||||
* Value Value Value Flags Flags Flags | * Value Value Value Flags Flags Flags | ||||
*/ | */ | ||||
CheckWriteCoin(ABSENT, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY, NO_ENTRY); | CheckWriteCoin(ABSENT, ABSENT, ABSENT, NO_ENTRY, NO_ENTRY, NO_ENTRY); | ||||
CheckWriteCoin(ABSENT, PRUNED, PRUNED, NO_ENTRY, DIRTY, DIRTY); | CheckWriteCoin(ABSENT, SPENT, SPENT, NO_ENTRY, DIRTY, DIRTY); | ||||
CheckWriteCoin(ABSENT, PRUNED, ABSENT, NO_ENTRY, DIRTY | FRESH, NO_ENTRY); | CheckWriteCoin(ABSENT, SPENT, ABSENT, NO_ENTRY, DIRTY | FRESH, NO_ENTRY); | ||||
CheckWriteCoin(ABSENT, VALUE2, VALUE2, NO_ENTRY, DIRTY, DIRTY); | CheckWriteCoin(ABSENT, VALUE2, VALUE2, NO_ENTRY, DIRTY, DIRTY); | ||||
CheckWriteCoin(ABSENT, VALUE2, VALUE2, NO_ENTRY, DIRTY | FRESH, | CheckWriteCoin(ABSENT, VALUE2, VALUE2, NO_ENTRY, DIRTY | FRESH, | ||||
DIRTY | FRESH); | DIRTY | FRESH); | ||||
CheckWriteCoin(PRUNED, ABSENT, PRUNED, 0, NO_ENTRY, 0); | CheckWriteCoin(SPENT, ABSENT, SPENT, 0, NO_ENTRY, 0); | ||||
CheckWriteCoin(PRUNED, ABSENT, PRUNED, FRESH, NO_ENTRY, FRESH); | CheckWriteCoin(SPENT, ABSENT, SPENT, FRESH, NO_ENTRY, FRESH); | ||||
CheckWriteCoin(PRUNED, ABSENT, PRUNED, DIRTY, NO_ENTRY, DIRTY); | CheckWriteCoin(SPENT, ABSENT, SPENT, DIRTY, NO_ENTRY, DIRTY); | ||||
CheckWriteCoin(PRUNED, ABSENT, PRUNED, DIRTY | FRESH, NO_ENTRY, | CheckWriteCoin(SPENT, ABSENT, SPENT, DIRTY | FRESH, NO_ENTRY, | ||||
DIRTY | FRESH); | DIRTY | FRESH); | ||||
CheckWriteCoin(PRUNED, PRUNED, PRUNED, 0, DIRTY, DIRTY); | CheckWriteCoin(SPENT, SPENT, SPENT, 0, DIRTY, DIRTY); | ||||
CheckWriteCoin(PRUNED, PRUNED, PRUNED, 0, DIRTY | FRESH, DIRTY); | CheckWriteCoin(SPENT, SPENT, SPENT, 0, DIRTY | FRESH, DIRTY); | ||||
CheckWriteCoin(PRUNED, PRUNED, ABSENT, FRESH, DIRTY, NO_ENTRY); | CheckWriteCoin(SPENT, SPENT, ABSENT, FRESH, DIRTY, NO_ENTRY); | ||||
CheckWriteCoin(PRUNED, PRUNED, ABSENT, FRESH, DIRTY | FRESH, NO_ENTRY); | CheckWriteCoin(SPENT, SPENT, ABSENT, FRESH, DIRTY | FRESH, NO_ENTRY); | ||||
CheckWriteCoin(PRUNED, PRUNED, PRUNED, DIRTY, DIRTY, DIRTY); | CheckWriteCoin(SPENT, SPENT, SPENT, DIRTY, DIRTY, DIRTY); | ||||
CheckWriteCoin(PRUNED, PRUNED, PRUNED, DIRTY, DIRTY | FRESH, DIRTY); | CheckWriteCoin(SPENT, SPENT, SPENT, DIRTY, DIRTY | FRESH, DIRTY); | ||||
CheckWriteCoin(PRUNED, PRUNED, ABSENT, DIRTY | FRESH, DIRTY, NO_ENTRY); | CheckWriteCoin(SPENT, SPENT, ABSENT, DIRTY | FRESH, DIRTY, NO_ENTRY); | ||||
CheckWriteCoin(PRUNED, PRUNED, ABSENT, DIRTY | FRESH, DIRTY | FRESH, | CheckWriteCoin(SPENT, SPENT, ABSENT, DIRTY | FRESH, DIRTY | FRESH, | ||||
NO_ENTRY); | NO_ENTRY); | ||||
CheckWriteCoin(PRUNED, VALUE2, VALUE2, 0, DIRTY, DIRTY); | CheckWriteCoin(SPENT, VALUE2, VALUE2, 0, DIRTY, DIRTY); | ||||
CheckWriteCoin(PRUNED, VALUE2, VALUE2, 0, DIRTY | FRESH, DIRTY); | CheckWriteCoin(SPENT, VALUE2, VALUE2, 0, DIRTY | FRESH, DIRTY); | ||||
CheckWriteCoin(PRUNED, VALUE2, VALUE2, FRESH, DIRTY, DIRTY | FRESH); | CheckWriteCoin(SPENT, VALUE2, VALUE2, FRESH, DIRTY, DIRTY | FRESH); | ||||
CheckWriteCoin(PRUNED, VALUE2, VALUE2, FRESH, DIRTY | FRESH, DIRTY | FRESH); | CheckWriteCoin(SPENT, VALUE2, VALUE2, FRESH, DIRTY | FRESH, DIRTY | FRESH); | ||||
CheckWriteCoin(PRUNED, VALUE2, VALUE2, DIRTY, DIRTY, DIRTY); | CheckWriteCoin(SPENT, VALUE2, VALUE2, DIRTY, DIRTY, DIRTY); | ||||
CheckWriteCoin(PRUNED, VALUE2, VALUE2, DIRTY, DIRTY | FRESH, DIRTY); | CheckWriteCoin(SPENT, VALUE2, VALUE2, DIRTY, DIRTY | FRESH, DIRTY); | ||||
CheckWriteCoin(PRUNED, VALUE2, VALUE2, DIRTY | FRESH, DIRTY, DIRTY | FRESH); | CheckWriteCoin(SPENT, VALUE2, VALUE2, DIRTY | FRESH, DIRTY, DIRTY | FRESH); | ||||
CheckWriteCoin(PRUNED, VALUE2, VALUE2, DIRTY | FRESH, DIRTY | FRESH, | CheckWriteCoin(SPENT, VALUE2, VALUE2, DIRTY | FRESH, DIRTY | FRESH, | ||||
DIRTY | FRESH); | DIRTY | FRESH); | ||||
CheckWriteCoin(VALUE1, ABSENT, VALUE1, 0, NO_ENTRY, 0); | CheckWriteCoin(VALUE1, ABSENT, VALUE1, 0, NO_ENTRY, 0); | ||||
CheckWriteCoin(VALUE1, ABSENT, VALUE1, FRESH, NO_ENTRY, FRESH); | CheckWriteCoin(VALUE1, ABSENT, VALUE1, FRESH, NO_ENTRY, FRESH); | ||||
CheckWriteCoin(VALUE1, ABSENT, VALUE1, DIRTY, NO_ENTRY, DIRTY); | CheckWriteCoin(VALUE1, ABSENT, VALUE1, DIRTY, NO_ENTRY, DIRTY); | ||||
CheckWriteCoin(VALUE1, ABSENT, VALUE1, DIRTY | FRESH, NO_ENTRY, | CheckWriteCoin(VALUE1, ABSENT, VALUE1, DIRTY | FRESH, NO_ENTRY, | ||||
DIRTY | FRESH); | DIRTY | FRESH); | ||||
CheckWriteCoin(VALUE1, PRUNED, PRUNED, 0, DIRTY, DIRTY); | CheckWriteCoin(VALUE1, SPENT, SPENT, 0, DIRTY, DIRTY); | ||||
CheckWriteCoin(VALUE1, PRUNED, FAIL, 0, DIRTY | FRESH, NO_ENTRY); | CheckWriteCoin(VALUE1, SPENT, FAIL, 0, DIRTY | FRESH, NO_ENTRY); | ||||
CheckWriteCoin(VALUE1, PRUNED, ABSENT, FRESH, DIRTY, NO_ENTRY); | CheckWriteCoin(VALUE1, SPENT, ABSENT, FRESH, DIRTY, NO_ENTRY); | ||||
CheckWriteCoin(VALUE1, PRUNED, FAIL, FRESH, DIRTY | FRESH, NO_ENTRY); | CheckWriteCoin(VALUE1, SPENT, FAIL, FRESH, DIRTY | FRESH, NO_ENTRY); | ||||
CheckWriteCoin(VALUE1, PRUNED, PRUNED, DIRTY, DIRTY, DIRTY); | CheckWriteCoin(VALUE1, SPENT, SPENT, DIRTY, DIRTY, DIRTY); | ||||
CheckWriteCoin(VALUE1, PRUNED, FAIL, DIRTY, DIRTY | FRESH, NO_ENTRY); | CheckWriteCoin(VALUE1, SPENT, FAIL, DIRTY, DIRTY | FRESH, NO_ENTRY); | ||||
CheckWriteCoin(VALUE1, PRUNED, ABSENT, DIRTY | FRESH, DIRTY, NO_ENTRY); | CheckWriteCoin(VALUE1, SPENT, ABSENT, DIRTY | FRESH, DIRTY, NO_ENTRY); | ||||
CheckWriteCoin(VALUE1, PRUNED, FAIL, DIRTY | FRESH, DIRTY | FRESH, | CheckWriteCoin(VALUE1, SPENT, FAIL, DIRTY | FRESH, DIRTY | FRESH, NO_ENTRY); | ||||
NO_ENTRY); | |||||
CheckWriteCoin(VALUE1, VALUE2, VALUE2, 0, DIRTY, DIRTY); | CheckWriteCoin(VALUE1, VALUE2, VALUE2, 0, DIRTY, DIRTY); | ||||
CheckWriteCoin(VALUE1, VALUE2, FAIL, 0, DIRTY | FRESH, NO_ENTRY); | CheckWriteCoin(VALUE1, VALUE2, FAIL, 0, DIRTY | FRESH, NO_ENTRY); | ||||
CheckWriteCoin(VALUE1, VALUE2, VALUE2, FRESH, DIRTY, DIRTY | FRESH); | CheckWriteCoin(VALUE1, VALUE2, VALUE2, FRESH, DIRTY, DIRTY | FRESH); | ||||
CheckWriteCoin(VALUE1, VALUE2, FAIL, FRESH, DIRTY | FRESH, NO_ENTRY); | CheckWriteCoin(VALUE1, VALUE2, FAIL, FRESH, DIRTY | FRESH, NO_ENTRY); | ||||
CheckWriteCoin(VALUE1, VALUE2, VALUE2, DIRTY, DIRTY, DIRTY); | CheckWriteCoin(VALUE1, VALUE2, VALUE2, DIRTY, DIRTY, DIRTY); | ||||
CheckWriteCoin(VALUE1, VALUE2, FAIL, DIRTY, DIRTY | FRESH, NO_ENTRY); | CheckWriteCoin(VALUE1, VALUE2, FAIL, DIRTY, DIRTY | FRESH, NO_ENTRY); | ||||
CheckWriteCoin(VALUE1, VALUE2, VALUE2, DIRTY | FRESH, DIRTY, DIRTY | FRESH); | CheckWriteCoin(VALUE1, VALUE2, VALUE2, DIRTY | FRESH, DIRTY, DIRTY | FRESH); | ||||
CheckWriteCoin(VALUE1, VALUE2, FAIL, DIRTY | FRESH, DIRTY | FRESH, | CheckWriteCoin(VALUE1, VALUE2, FAIL, DIRTY | FRESH, DIRTY | FRESH, | ||||
NO_ENTRY); | NO_ENTRY); | ||||
// The checks above omit cases where the child flags are not DIRTY, since | // The checks above omit cases where the child flags are not DIRTY, since | ||||
// they would be too repetitive (the parent cache is never updated in these | // they would be too repetitive (the parent cache is never updated in these | ||||
// cases). The loop below covers these cases and makes sure the parent cache | // cases). The loop below covers these cases and makes sure the parent cache | ||||
// is always left unchanged. | // is always left unchanged. | ||||
for (const Amount &parent_value : {ABSENT, PRUNED, VALUE1}) { | for (const Amount &parent_value : {ABSENT, SPENT, VALUE1}) { | ||||
for (const Amount &child_value : {ABSENT, PRUNED, VALUE2}) { | for (const Amount &child_value : {ABSENT, SPENT, VALUE2}) { | ||||
for (const char parent_flags : | for (const char parent_flags : | ||||
parent_value == ABSENT ? ABSENT_FLAGS : FLAGS) { | parent_value == ABSENT ? ABSENT_FLAGS : FLAGS) { | ||||
for (const char child_flags : | for (const char child_flags : | ||||
child_value == ABSENT ? ABSENT_FLAGS : CLEAN_FLAGS) { | child_value == ABSENT ? ABSENT_FLAGS : CLEAN_FLAGS) { | ||||
CheckWriteCoin(parent_value, child_value, parent_value, | CheckWriteCoin(parent_value, child_value, parent_value, | ||||
parent_flags, child_flags, parent_flags); | parent_flags, child_flags, parent_flags); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |