Changeset View
Changeset View
Standalone View
Standalone View
src/test/coins_tests.cpp
Show First 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { | ||||
const Coin &entry = | const Coin &entry = | ||||
(InsecureRandRange(500) == 0) | (InsecureRandRange(500) == 0) | ||||
? AccessByTxid(*stack.back(), txid) | ? AccessByTxid(*stack.back(), txid) | ||||
: stack.back()->AccessCoin(COutPoint(txid, 0)); | : stack.back()->AccessCoin(COutPoint(txid, 0)); | ||||
BOOST_CHECK(coin == entry); | BOOST_CHECK(coin == entry); | ||||
if (InsecureRandRange(5) == 0 || coin.IsSpent()) { | if (InsecureRandRange(5) == 0 || coin.IsSpent()) { | ||||
CTxOut txout; | CTxOut txout; | ||||
txout.nValue = int64_t(insecure_rand()) * SATOSHI; | txout.nValue = int64_t(InsecureRand32()) * SATOSHI; | ||||
if (InsecureRandRange(16) == 0 && coin.IsSpent()) { | if (InsecureRandRange(16) == 0 && coin.IsSpent()) { | ||||
txout.scriptPubKey.assign(1 + InsecureRandBits(6), | txout.scriptPubKey.assign(1 + InsecureRandBits(6), | ||||
OP_RETURN); | OP_RETURN); | ||||
BOOST_CHECK(txout.scriptPubKey.IsUnspendable()); | BOOST_CHECK(txout.scriptPubKey.IsUnspendable()); | ||||
added_an_unspendable_entry = true; | added_an_unspendable_entry = true; | ||||
} else { | } else { | ||||
// Random sizes so we can test memory usage accounting | // Random sizes so we can test memory usage accounting | ||||
txout.scriptPubKey.assign(InsecureRandBits(6), 0); | txout.scriptPubKey.assign(InsecureRandBits(6), 0); | ||||
(coin.IsSpent() ? added_an_entry : updated_an_entry) = true; | (coin.IsSpent() ? added_an_entry : updated_an_entry) = true; | ||||
coin = Coin(txout, 1, false); | coin = Coin(txout, 1, false); | ||||
} | } | ||||
Coin newcoin(txout, 1, false); | Coin newcoin(txout, 1, false); | ||||
stack.back()->AddCoin(COutPoint(txid, 0), newcoin, | stack.back()->AddCoin(COutPoint(txid, 0), newcoin, | ||||
!coin.IsSpent() || insecure_rand() & 1); | !coin.IsSpent() || InsecureRand32() & 1); | ||||
} else { | } else { | ||||
removed_an_entry = true; | removed_an_entry = true; | ||||
coin.Clear(); | coin.Clear(); | ||||
stack.back()->SpendCoin(COutPoint(txid, 0)); | stack.back()->SpendCoin(COutPoint(txid, 0)); | ||||
} | } | ||||
} | } | ||||
// One every 10 iterations, remove a random entry from the cache | // One every 10 iterations, remove a random entry from the cache | ||||
if (InsecureRandRange(10) == 0) { | if (InsecureRandRange(10) == 0) { | ||||
COutPoint out(txids[insecure_rand() % txids.size()], 0); | COutPoint out(txids[InsecureRand32() % txids.size()], 0); | ||||
int cacheid = insecure_rand() % stack.size(); | int cacheid = InsecureRand32() % stack.size(); | ||||
stack[cacheid]->Uncache(out); | stack[cacheid]->Uncache(out); | ||||
uncached_an_entry |= !stack[cacheid]->HaveCoinInCache(out); | uncached_an_entry |= !stack[cacheid]->HaveCoinInCache(out); | ||||
} | } | ||||
// Once every 1000 iterations and at the end, verify the full cache. | // Once every 1000 iterations and at the end, verify the full cache. | ||||
if (InsecureRandRange(1000) == 1 || | if (InsecureRandRange(1000) == 1 || | ||||
i == NUM_SIMULATION_ITERATIONS - 1) { | i == NUM_SIMULATION_ITERATIONS - 1) { | ||||
for (const auto &entry : result) { | for (const auto &entry : result) { | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) { | ||||
// Track the txids we've used in various sets | // Track the txids we've used in various sets | ||||
std::set<COutPoint> coinbase_coins; | std::set<COutPoint> coinbase_coins; | ||||
std::set<COutPoint> disconnected_coins; | std::set<COutPoint> disconnected_coins; | ||||
std::set<COutPoint> duplicate_coins; | std::set<COutPoint> duplicate_coins; | ||||
std::set<COutPoint> utxoset; | std::set<COutPoint> utxoset; | ||||
for (int64_t i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { | for (int64_t i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { | ||||
uint32_t randiter = insecure_rand(); | uint32_t randiter = InsecureRand32(); | ||||
// 19/20 txs add a new transaction | // 19/20 txs add a new transaction | ||||
if (randiter % 20 < 19) { | if (randiter % 20 < 19) { | ||||
CMutableTransaction tx; | CMutableTransaction tx; | ||||
tx.vin.resize(1); | tx.vin.resize(1); | ||||
tx.vout.resize(1); | tx.vout.resize(1); | ||||
// Keep txs unique unless intended to duplicate. | // Keep txs unique unless intended to duplicate. | ||||
tx.vout[0].nValue = i * SATOSHI; | tx.vout[0].nValue = i * SATOSHI; | ||||
// Random sizes so we can test memory usage accounting | // Random sizes so we can test memory usage accounting | ||||
tx.vout[0].scriptPubKey.assign(insecure_rand() & 0x3F, 0); | tx.vout[0].scriptPubKey.assign(InsecureRand32() & 0x3F, 0); | ||||
unsigned int height = insecure_rand(); | unsigned int height = InsecureRand32(); | ||||
Coin old_coin; | Coin old_coin; | ||||
// 2/20 times create a new coinbase | // 2/20 times create a new coinbase | ||||
if (randiter % 20 < 2 || coinbase_coins.size() < 10) { | if (randiter % 20 < 2 || coinbase_coins.size() < 10) { | ||||
// 1/10 of those times create a duplicate coinbase | // 1/10 of those times create a duplicate coinbase | ||||
if (InsecureRandRange(10) == 0 && coinbase_coins.size()) { | if (InsecureRandRange(10) == 0 && coinbase_coins.size()) { | ||||
auto utxod = FindRandomFrom(coinbase_coins); | auto utxod = FindRandomFrom(coinbase_coins); | ||||
// Reuse the exact same coinbase | // Reuse the exact same coinbase | ||||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | for (int64_t i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { | ||||
const Coin &coin = stack.back()->AccessCoin(entry.first); | const Coin &coin = stack.back()->AccessCoin(entry.first); | ||||
BOOST_CHECK(have == !coin.IsSpent()); | BOOST_CHECK(have == !coin.IsSpent()); | ||||
BOOST_CHECK(coin == entry.second); | BOOST_CHECK(coin == entry.second); | ||||
} | } | ||||
} | } | ||||
// One every 10 iterations, remove a random entry from the cache | // One every 10 iterations, remove a random entry from the cache | ||||
if (utxoset.size() > 1 && InsecureRandRange(30) == 0) { | if (utxoset.size() > 1 && InsecureRandRange(30) == 0) { | ||||
stack[insecure_rand() % stack.size()]->Uncache( | stack[InsecureRand32() % stack.size()]->Uncache( | ||||
FindRandomFrom(utxoset)->first); | FindRandomFrom(utxoset)->first); | ||||
} | } | ||||
if (disconnected_coins.size() > 1 && InsecureRandRange(30) == 0) { | if (disconnected_coins.size() > 1 && InsecureRandRange(30) == 0) { | ||||
stack[insecure_rand() % stack.size()]->Uncache( | stack[InsecureRand32() % stack.size()]->Uncache( | ||||
FindRandomFrom(disconnected_coins)->first); | FindRandomFrom(disconnected_coins)->first); | ||||
} | } | ||||
if (duplicate_coins.size() > 1 && InsecureRandRange(30) == 0) { | if (duplicate_coins.size() > 1 && InsecureRandRange(30) == 0) { | ||||
stack[insecure_rand() % stack.size()]->Uncache( | stack[InsecureRand32() % stack.size()]->Uncache( | ||||
FindRandomFrom(duplicate_coins)->first); | FindRandomFrom(duplicate_coins)->first); | ||||
} | } | ||||
if (InsecureRandRange(100) == 0) { | if (InsecureRandRange(100) == 0) { | ||||
// Every 100 iterations, flush an intermediate cache | // Every 100 iterations, flush an intermediate cache | ||||
if (stack.size() > 1 && InsecureRandBool() == 0) { | if (stack.size() > 1 && InsecureRandBool() == 0) { | ||||
unsigned int flushIndex = InsecureRandRange(stack.size() - 1); | unsigned int flushIndex = InsecureRandRange(stack.size() - 1); | ||||
stack[flushIndex]->Flush(); | stack[flushIndex]->Flush(); | ||||
▲ Show 20 Lines • Show All 433 Lines • Show Last 20 Lines |