|
|
|
@ -43,7 +43,7 @@ public:
@@ -43,7 +43,7 @@ public:
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
coin = it->second; |
|
|
|
|
if (coin.IsSpent() && insecure_rand() % 2 == 0) { |
|
|
|
|
if (coin.IsSpent() && insecure_randrange(2) == 0) { |
|
|
|
|
// Randomly return false in case of an empty entry.
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
@ -64,7 +64,7 @@ public:
@@ -64,7 +64,7 @@ public:
|
|
|
|
|
if (it->second.flags & CCoinsCacheEntry::DIRTY) { |
|
|
|
|
// Same optimization used in CCoinsViewDB is to only write dirty entries.
|
|
|
|
|
map_[it->first] = it->second.coin; |
|
|
|
|
if (it->second.coin.IsSpent() && insecure_rand() % 3 == 0) { |
|
|
|
|
if (it->second.coin.IsSpent() && insecure_randrange(3) == 0) { |
|
|
|
|
// Randomly delete empty entries on write.
|
|
|
|
|
map_.erase(it->first); |
|
|
|
|
} |
|
|
|
@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
@@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
|
|
|
|
|
std::vector<uint256> txids; |
|
|
|
|
txids.resize(NUM_SIMULATION_ITERATIONS / 8); |
|
|
|
|
for (unsigned int i = 0; i < txids.size(); i++) { |
|
|
|
|
txids[i] = GetRandHash(); |
|
|
|
|
txids[i] = insecure_rand256(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { |
|
|
|
@ -147,14 +147,14 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
@@ -147,14 +147,14 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
|
|
|
|
|
{ |
|
|
|
|
uint256 txid = txids[insecure_rand() % txids.size()]; // txid we're going to modify in this iteration.
|
|
|
|
|
Coin& coin = result[COutPoint(txid, 0)]; |
|
|
|
|
const Coin& entry = (insecure_rand() % 500 == 0) ? AccessByTxid(*stack.back(), txid) : stack.back()->AccessCoin(COutPoint(txid, 0)); |
|
|
|
|
const Coin& entry = (insecure_randrange(500) == 0) ? AccessByTxid(*stack.back(), txid) : stack.back()->AccessCoin(COutPoint(txid, 0)); |
|
|
|
|
BOOST_CHECK(coin == entry); |
|
|
|
|
|
|
|
|
|
if (insecure_rand() % 5 == 0 || coin.IsSpent()) { |
|
|
|
|
if (insecure_randrange(5) == 0 || coin.IsSpent()) { |
|
|
|
|
Coin newcoin; |
|
|
|
|
newcoin.out.nValue = insecure_rand(); |
|
|
|
|
newcoin.nHeight = 1; |
|
|
|
|
if (insecure_rand() % 16 == 0 && coin.IsSpent()) { |
|
|
|
|
if (insecure_randrange(16) == 0 && coin.IsSpent()) { |
|
|
|
|
newcoin.out.scriptPubKey.assign(1 + (insecure_rand() & 0x3F), OP_RETURN); |
|
|
|
|
BOOST_CHECK(newcoin.out.scriptPubKey.IsUnspendable()); |
|
|
|
|
added_an_unspendable_entry = true; |
|
|
|
@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
@@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// One every 10 iterations, remove a random entry from the cache
|
|
|
|
|
if (insecure_rand() % 10 == 0) { |
|
|
|
|
if (insecure_randrange(10) == 0) { |
|
|
|
|
COutPoint out(txids[insecure_rand() % txids.size()], 0); |
|
|
|
|
int cacheid = insecure_rand() % stack.size(); |
|
|
|
|
stack[cacheid]->Uncache(out); |
|
|
|
@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
@@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Once every 1000 iterations and at the end, verify the full cache.
|
|
|
|
|
if (insecure_rand() % 1000 == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { |
|
|
|
|
if (insecure_randrange(1000) == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { |
|
|
|
|
for (auto it = result.begin(); it != result.end(); it++) { |
|
|
|
|
bool have = stack.back()->HaveCoin(it->first); |
|
|
|
|
const Coin& coin = stack.back()->AccessCoin(it->first); |
|
|
|
@ -198,22 +198,22 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
@@ -198,22 +198,22 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (insecure_rand() % 100 == 0) { |
|
|
|
|
if (insecure_randrange(100) == 0) { |
|
|
|
|
// Every 100 iterations, flush an intermediate cache
|
|
|
|
|
if (stack.size() > 1 && insecure_rand() % 2 == 0) { |
|
|
|
|
if (stack.size() > 1 && insecure_randrange(2) == 0) { |
|
|
|
|
unsigned int flushIndex = insecure_rand() % (stack.size() - 1); |
|
|
|
|
stack[flushIndex]->Flush(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (insecure_rand() % 100 == 0) { |
|
|
|
|
if (insecure_randrange(100) == 0) { |
|
|
|
|
// Every 100 iterations, change the cache stack.
|
|
|
|
|
if (stack.size() > 0 && insecure_rand() % 2 == 0) { |
|
|
|
|
if (stack.size() > 0 && insecure_randrange(2) == 0) { |
|
|
|
|
//Remove the top cache
|
|
|
|
|
stack.back()->Flush(); |
|
|
|
|
delete stack.back(); |
|
|
|
|
stack.pop_back(); |
|
|
|
|
} |
|
|
|
|
if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) { |
|
|
|
|
if (stack.size() == 0 || (stack.size() < 4 && insecure_randrange(2))) { |
|
|
|
|
//Add a new cache
|
|
|
|
|
CCoinsView* tip = &base; |
|
|
|
|
if (stack.size() > 0) { |
|
|
|
@ -253,7 +253,7 @@ UtxoData utxoData;
@@ -253,7 +253,7 @@ UtxoData utxoData;
|
|
|
|
|
|
|
|
|
|
UtxoData::iterator FindRandomFrom(const std::set<COutPoint> &utxoSet) { |
|
|
|
|
assert(utxoSet.size()); |
|
|
|
|
auto utxoSetIt = utxoSet.lower_bound(COutPoint(GetRandHash(), 0)); |
|
|
|
|
auto utxoSetIt = utxoSet.lower_bound(COutPoint(insecure_rand256(), 0)); |
|
|
|
|
if (utxoSetIt == utxoSet.end()) { |
|
|
|
|
utxoSetIt = utxoSet.begin(); |
|
|
|
|
} |
|
|
|
@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
@@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
|
|
|
|
|
// 2/20 times create a new coinbase
|
|
|
|
|
if (randiter % 20 < 2 || coinbase_coins.size() < 10) { |
|
|
|
|
// 1/10 of those times create a duplicate coinbase
|
|
|
|
|
if (insecure_rand() % 10 == 0 && coinbase_coins.size()) { |
|
|
|
|
if (insecure_randrange(10) == 0 && coinbase_coins.size()) { |
|
|
|
|
auto utxod = FindRandomFrom(coinbase_coins); |
|
|
|
|
// Reuse the exact same coinbase
|
|
|
|
|
tx = std::get<0>(utxod->second); |
|
|
|
@ -411,7 +411,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
@@ -411,7 +411,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Once every 1000 iterations and at the end, verify the full cache.
|
|
|
|
|
if (insecure_rand() % 1000 == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { |
|
|
|
|
if (insecure_randrange(1000) == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { |
|
|
|
|
for (auto it = result.begin(); it != result.end(); it++) { |
|
|
|
|
bool have = stack.back()->HaveCoin(it->first); |
|
|
|
|
const Coin& coin = stack.back()->AccessCoin(it->first); |
|
|
|
@ -421,31 +421,31 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
@@ -421,31 +421,31 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// One every 10 iterations, remove a random entry from the cache
|
|
|
|
|
if (utxoset.size() > 1 && insecure_rand() % 30 == 0) { |
|
|
|
|
if (utxoset.size() > 1 && insecure_randrange(30) == 0) { |
|
|
|
|
stack[insecure_rand() % stack.size()]->Uncache(FindRandomFrom(utxoset)->first); |
|
|
|
|
} |
|
|
|
|
if (disconnected_coins.size() > 1 && insecure_rand() % 30 == 0) { |
|
|
|
|
if (disconnected_coins.size() > 1 && insecure_randrange(30) == 0) { |
|
|
|
|
stack[insecure_rand() % stack.size()]->Uncache(FindRandomFrom(disconnected_coins)->first); |
|
|
|
|
} |
|
|
|
|
if (duplicate_coins.size() > 1 && insecure_rand() % 30 == 0) { |
|
|
|
|
if (duplicate_coins.size() > 1 && insecure_randrange(30) == 0) { |
|
|
|
|
stack[insecure_rand() % stack.size()]->Uncache(FindRandomFrom(duplicate_coins)->first); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (insecure_rand() % 100 == 0) { |
|
|
|
|
if (insecure_randrange(100) == 0) { |
|
|
|
|
// Every 100 iterations, flush an intermediate cache
|
|
|
|
|
if (stack.size() > 1 && insecure_rand() % 2 == 0) { |
|
|
|
|
if (stack.size() > 1 && insecure_randrange(2) == 0) { |
|
|
|
|
unsigned int flushIndex = insecure_rand() % (stack.size() - 1); |
|
|
|
|
stack[flushIndex]->Flush(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (insecure_rand() % 100 == 0) { |
|
|
|
|
if (insecure_randrange(100) == 0) { |
|
|
|
|
// Every 100 iterations, change the cache stack.
|
|
|
|
|
if (stack.size() > 0 && insecure_rand() % 2 == 0) { |
|
|
|
|
if (stack.size() > 0 && insecure_randrange(2) == 0) { |
|
|
|
|
stack.back()->Flush(); |
|
|
|
|
delete stack.back(); |
|
|
|
|
stack.pop_back(); |
|
|
|
|
} |
|
|
|
|
if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) { |
|
|
|
|
if (stack.size() == 0 || (stack.size() < 4 && insecure_randrange(2))) { |
|
|
|
|
CCoinsView* tip = &base; |
|
|
|
|
if (stack.size() > 0) { |
|
|
|
|
tip = stack.back(); |
|
|
|
|