From 21180ff73436e198b6828c312ddfd0a1195447b2 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 13 Jun 2017 12:17:30 -0700 Subject: Simplify return values of GetCoin/HaveCoin(InCache) This removes the possibility for GetCoin/HaveCoin/HaveCoinInCache to return true while the respective coin is spent. By doing it across all calls, some extra checks can be eliminated. coins_tests is modified to call HaveCoin sometimes before and sometimes after AccessCoin. A further change is needed because the semantics for GetCoin slightly changed, causing a pruned entry in the parent cache to not be pulled into the child in FetchCoin. --- src/test/coins_tests.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/test') diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 622b157621..e24431528a 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -50,12 +50,6 @@ public: return true; } - bool HaveCoin(const COutPoint& outpoint) const override - { - Coin coin; - return GetCoin(outpoint, coin); - } - uint256 GetBestBlock() const override { return hashBestBlock_; } 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. 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)); 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()) { Coin newcoin; @@ -628,7 +636,7 @@ BOOST_AUTO_TEST_CASE(ccoins_access) CheckAccessCoin(ABSENT, VALUE2, VALUE2, FRESH , FRESH ); CheckAccessCoin(ABSENT, VALUE2, VALUE2, DIRTY , DIRTY ); 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, FRESH , FRESH ); CheckAccessCoin(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); -- cgit v1.2.3