@@ -154,171 +154,186 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
154
154
BOOST_CHECK_CLOSE (c2.m_coinsdb_cache_size_bytes , max_cache * 0.95 , 1 );
155
155
}
156
156
157
- // ! Test basic snapshot activation.
158
- BOOST_FIXTURE_TEST_CASE (chainstatemanager_activate_snapshot, TestChain100Setup )
159
- {
160
- ChainstateManager& chainman = *Assert (m_node.chainman );
157
+ struct SnapshotTestSetup : TestChain100Setup {
158
+ std::tuple<Chainstate*, Chainstate*> SetupSnapshot ( )
159
+ {
160
+ ChainstateManager& chainman = *Assert (m_node.chainman );
161
161
162
- size_t initial_size ;
163
- size_t initial_total_coins{ 100 } ;
162
+ BOOST_CHECK (!chainman. IsSnapshotActive ()) ;
163
+ WITH_LOCK (::cs_main, BOOST_CHECK (!chainman. IsSnapshotValidated ())) ;
164
164
165
- // Make some initial assertions about the contents of the chainstate.
166
- {
167
- LOCK (::cs_main);
168
- CCoinsViewCache& ibd_coinscache = chainman.ActiveChainstate ().CoinsTip ();
169
- initial_size = ibd_coinscache.GetCacheSize ();
170
- size_t total_coins{0 };
171
-
172
- for (CTransactionRef& txn : m_coinbase_txns) {
173
- COutPoint op{txn->GetHash (), 0 };
174
- BOOST_CHECK (ibd_coinscache.HaveCoin (op));
175
- total_coins++;
176
- }
165
+ size_t initial_size;
166
+ size_t initial_total_coins{100 };
177
167
178
- BOOST_CHECK_EQUAL (total_coins, initial_total_coins);
179
- BOOST_CHECK_EQUAL (initial_size, initial_total_coins);
180
- }
168
+ // Make some initial assertions about the contents of the chainstate.
169
+ {
170
+ LOCK (::cs_main);
171
+ CCoinsViewCache& ibd_coinscache = chainman.ActiveChainstate ().CoinsTip ();
172
+ initial_size = ibd_coinscache.GetCacheSize ();
173
+ size_t total_coins{0 };
181
174
182
- // Snapshot should refuse to load at this height.
183
- BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (m_node, m_path_root));
184
- BOOST_CHECK (!chainman.ActiveChainstate ().m_from_snapshot_blockhash );
185
- BOOST_CHECK (!chainman.SnapshotBlockhash ());
186
-
187
- // Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
188
- // be found.
189
- constexpr int snapshot_height = 110 ;
190
- mineBlocks (10 );
191
- initial_size += 10 ;
192
- initial_total_coins += 10 ;
193
-
194
- // Should not load malleated snapshots
195
- BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
196
- m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
197
- // A UTXO is missing but count is correct
198
- metadata.m_coins_count -= 1 ;
199
-
200
- COutPoint outpoint;
201
- Coin coin;
202
-
203
- auto_infile >> outpoint;
204
- auto_infile >> coin;
205
- }));
206
- BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
207
- m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
208
- // Coins count is larger than coins in file
209
- metadata.m_coins_count += 1 ;
210
- }));
211
- BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
212
- m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
213
- // Coins count is smaller than coins in file
214
- metadata.m_coins_count -= 1 ;
215
- }));
216
- BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
217
- m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
218
- // Wrong hash
219
- metadata.m_base_blockhash = uint256::ZERO;
220
- }));
221
- BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
222
- m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
223
- // Wrong hash
224
- metadata.m_base_blockhash = uint256::ONE;
225
- }));
226
-
227
- BOOST_REQUIRE (CreateAndActivateUTXOSnapshot (m_node, m_path_root));
228
-
229
- // Ensure our active chain is the snapshot chainstate.
230
- BOOST_CHECK (!chainman.ActiveChainstate ().m_from_snapshot_blockhash ->IsNull ());
231
- BOOST_CHECK_EQUAL (
232
- *chainman.ActiveChainstate ().m_from_snapshot_blockhash ,
233
- *chainman.SnapshotBlockhash ());
175
+ for (CTransactionRef& txn : m_coinbase_txns) {
176
+ COutPoint op{txn->GetHash (), 0 };
177
+ BOOST_CHECK (ibd_coinscache.HaveCoin (op));
178
+ total_coins++;
179
+ }
234
180
235
- {
236
- LOCK (::cs_main);
181
+ BOOST_CHECK_EQUAL (total_coins, initial_total_coins);
182
+ BOOST_CHECK_EQUAL (initial_size, initial_total_coins);
183
+ }
237
184
238
- // Note: WriteSnapshotBaseBlockhash() is implicitly tested above.
185
+ Chainstate& validation_chainstate = chainman.ActiveChainstate ();
186
+
187
+ // Snapshot should refuse to load at this height.
188
+ BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (m_node, m_path_root));
189
+ BOOST_CHECK (!chainman.ActiveChainstate ().m_from_snapshot_blockhash );
190
+ BOOST_CHECK (!chainman.SnapshotBlockhash ());
191
+
192
+ // Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can
193
+ // be found.
194
+ constexpr int snapshot_height = 110 ;
195
+ mineBlocks (10 );
196
+ initial_size += 10 ;
197
+ initial_total_coins += 10 ;
198
+
199
+ // Should not load malleated snapshots
200
+ BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
201
+ m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
202
+ // A UTXO is missing but count is correct
203
+ metadata.m_coins_count -= 1 ;
204
+
205
+ COutPoint outpoint;
206
+ Coin coin;
207
+
208
+ auto_infile >> outpoint;
209
+ auto_infile >> coin;
210
+ }));
211
+ BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
212
+ m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
213
+ // Coins count is larger than coins in file
214
+ metadata.m_coins_count += 1 ;
215
+ }));
216
+ BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
217
+ m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
218
+ // Coins count is smaller than coins in file
219
+ metadata.m_coins_count -= 1 ;
220
+ }));
221
+ BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
222
+ m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
223
+ // Wrong hash
224
+ metadata.m_base_blockhash = uint256::ZERO;
225
+ }));
226
+ BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (
227
+ m_node, m_path_root, [](AutoFile& auto_infile, SnapshotMetadata& metadata) {
228
+ // Wrong hash
229
+ metadata.m_base_blockhash = uint256::ONE;
230
+ }));
231
+
232
+ BOOST_REQUIRE (CreateAndActivateUTXOSnapshot (m_node, m_path_root));
233
+
234
+ // Ensure our active chain is the snapshot chainstate.
235
+ BOOST_CHECK (!chainman.ActiveChainstate ().m_from_snapshot_blockhash ->IsNull ());
239
236
BOOST_CHECK_EQUAL (
240
- *node::ReadSnapshotBaseBlockhash (m_args. GetDataDirNet () / " chainstate_snapshot " ) ,
237
+ *chainman. ActiveChainstate (). m_from_snapshot_blockhash ,
241
238
*chainman.SnapshotBlockhash ());
242
239
243
- // Ensure that the genesis block was not marked assumed-valid.
244
- BOOST_CHECK (!chainman.ActiveChain ().Genesis ()->IsAssumedValid ());
245
- }
240
+ Chainstate& snapshot_chainstate = chainman.ActiveChainstate ();
246
241
247
- const AssumeutxoData& au_data = * ExpectedAssumeutxo (snapshot_height, :: Params ());
248
- const CBlockIndex* tip = WITH_LOCK (chainman. GetMutex (), return chainman. ActiveTip () );
242
+ {
243
+ LOCK (::cs_main );
249
244
250
- BOOST_CHECK_EQUAL (tip->nChainTx , au_data.nChainTx );
245
+ // Note: WriteSnapshotBaseBlockhash() is implicitly tested above.
246
+ BOOST_CHECK_EQUAL (
247
+ *node::ReadSnapshotBaseBlockhash (m_args.GetDataDirNet () / " chainstate_snapshot" ),
248
+ *chainman.SnapshotBlockhash ());
251
249
252
- // To be checked against later when we try loading a subsequent snapshot.
253
- uint256 loaded_snapshot_blockhash{*chainman.SnapshotBlockhash ()};
250
+ // Ensure that the genesis block was not marked assumed-valid.
251
+ BOOST_CHECK (!chainman.ActiveChain ().Genesis ()->IsAssumedValid ());
252
+ }
254
253
255
- // Make some assertions about the both chainstates. These checks ensure the
256
- // legacy chainstate hasn't changed and that the newly created chainstate
257
- // reflects the expected content.
258
- {
259
- LOCK (::cs_main);
260
- int chains_tested{0 };
254
+ const AssumeutxoData& au_data = *ExpectedAssumeutxo (snapshot_height, ::Params ());
255
+ const CBlockIndex* tip = WITH_LOCK (chainman.GetMutex (), return chainman.ActiveTip ());
261
256
262
- for (Chainstate* chainstate : chainman.GetAll ()) {
263
- BOOST_TEST_MESSAGE (" Checking coins in " << chainstate->ToString ());
264
- CCoinsViewCache& coinscache = chainstate->CoinsTip ();
257
+ BOOST_CHECK_EQUAL (tip->nChainTx , au_data.nChainTx );
265
258
266
- // Both caches will be empty initially .
267
- BOOST_CHECK_EQUAL (( unsigned int ) 0 , coinscache. GetCacheSize ()) ;
259
+ // To be checked against later when we try loading a subsequent snapshot .
260
+ uint256 loaded_snapshot_blockhash{*chainman. SnapshotBlockhash ()} ;
268
261
269
- size_t total_coins{0 };
262
+ // Make some assertions about the both chainstates. These checks ensure the
263
+ // legacy chainstate hasn't changed and that the newly created chainstate
264
+ // reflects the expected content.
265
+ {
266
+ LOCK (::cs_main);
267
+ int chains_tested{0 };
270
268
271
- for (CTransactionRef& txn : m_coinbase_txns) {
272
- COutPoint op{txn->GetHash (), 0 };
273
- BOOST_CHECK (coinscache.HaveCoin (op));
274
- total_coins++;
275
- }
269
+ for (Chainstate* chainstate : chainman.GetAll ()) {
270
+ BOOST_TEST_MESSAGE (" Checking coins in " << chainstate->ToString ());
271
+ CCoinsViewCache& coinscache = chainstate->CoinsTip ();
276
272
277
- BOOST_CHECK_EQUAL (initial_size , coinscache.GetCacheSize ());
278
- BOOST_CHECK_EQUAL (total_coins, initial_total_coins);
279
- chains_tested++;
280
- }
273
+ // Both caches will be empty initially.
274
+ BOOST_CHECK_EQUAL ((unsigned int )0 , coinscache.GetCacheSize ());
281
275
282
- BOOST_CHECK_EQUAL (chains_tested, 2 );
283
- }
276
+ size_t total_coins{0 };
284
277
285
- // Mine some new blocks on top of the activated snapshot chainstate.
286
- constexpr size_t new_coins{100 };
287
- mineBlocks (new_coins); // Defined in TestChain100Setup.
278
+ for (CTransactionRef& txn : m_coinbase_txns) {
279
+ COutPoint op{txn->GetHash (), 0 };
280
+ BOOST_CHECK (coinscache.HaveCoin (op));
281
+ total_coins++;
282
+ }
288
283
289
- {
290
- LOCK (::cs_main);
291
- size_t coins_in_active{0 };
292
- size_t coins_in_background{0 };
293
- size_t coins_missing_from_background{0 };
284
+ BOOST_CHECK_EQUAL (initial_size , coinscache.GetCacheSize ());
285
+ BOOST_CHECK_EQUAL (total_coins, initial_total_coins);
286
+ chains_tested++;
287
+ }
294
288
295
- for (Chainstate* chainstate : chainman.GetAll ()) {
296
- BOOST_TEST_MESSAGE (" Checking coins in " << chainstate->ToString ());
297
- CCoinsViewCache& coinscache = chainstate->CoinsTip ();
298
- bool is_background = chainstate != &chainman.ActiveChainstate ();
289
+ BOOST_CHECK_EQUAL (chains_tested, 2 );
290
+ }
299
291
300
- for (CTransactionRef& txn : m_coinbase_txns) {
301
- COutPoint op{txn->GetHash (), 0 };
302
- if (coinscache.HaveCoin (op)) {
303
- (is_background ? coins_in_background : coins_in_active)++;
304
- } else if (is_background) {
305
- coins_missing_from_background++;
292
+ // Mine some new blocks on top of the activated snapshot chainstate.
293
+ constexpr size_t new_coins{100 };
294
+ mineBlocks (new_coins); // Defined in TestChain100Setup.
295
+
296
+ {
297
+ LOCK (::cs_main);
298
+ size_t coins_in_active{0 };
299
+ size_t coins_in_background{0 };
300
+ size_t coins_missing_from_background{0 };
301
+
302
+ for (Chainstate* chainstate : chainman.GetAll ()) {
303
+ BOOST_TEST_MESSAGE (" Checking coins in " << chainstate->ToString ());
304
+ CCoinsViewCache& coinscache = chainstate->CoinsTip ();
305
+ bool is_background = chainstate != &chainman.ActiveChainstate ();
306
+
307
+ for (CTransactionRef& txn : m_coinbase_txns) {
308
+ COutPoint op{txn->GetHash (), 0 };
309
+ if (coinscache.HaveCoin (op)) {
310
+ (is_background ? coins_in_background : coins_in_active)++;
311
+ } else if (is_background) {
312
+ coins_missing_from_background++;
313
+ }
306
314
}
307
315
}
316
+
317
+ BOOST_CHECK_EQUAL (coins_in_active, initial_total_coins + new_coins);
318
+ BOOST_CHECK_EQUAL (coins_in_background, initial_total_coins);
319
+ BOOST_CHECK_EQUAL (coins_missing_from_background, new_coins);
308
320
}
309
321
310
- BOOST_CHECK_EQUAL (coins_in_active, initial_total_coins + new_coins);
311
- BOOST_CHECK_EQUAL (coins_in_background, initial_total_coins);
312
- BOOST_CHECK_EQUAL (coins_missing_from_background, new_coins);
313
- }
322
+ // Snapshot should refuse to load after one has already loaded.
323
+ BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (m_node, m_path_root));
314
324
315
- // Snapshot should refuse to load after one has already loaded.
316
- BOOST_REQUIRE (!CreateAndActivateUTXOSnapshot (m_node, m_path_root));
325
+ // Snapshot blockhash should be unchanged.
326
+ BOOST_CHECK_EQUAL (
327
+ *chainman.ActiveChainstate ().m_from_snapshot_blockhash ,
328
+ loaded_snapshot_blockhash);
329
+ return std::make_tuple (&validation_chainstate, &snapshot_chainstate);
330
+ }
331
+ };
317
332
318
- // Snapshot blockhash should be unchanged .
319
- BOOST_CHECK_EQUAL (
320
- *chainman. ActiveChainstate (). m_from_snapshot_blockhash ,
321
- loaded_snapshot_blockhash );
333
+ // ! Test basic snapshot activation .
334
+ BOOST_FIXTURE_TEST_CASE (chainstatemanager_activate_snapshot, SnapshotTestSetup)
335
+ {
336
+ this -> SetupSnapshot ( );
322
337
}
323
338
324
339
// ! Test LoadBlockIndex behavior when multiple chainstates are in use.
0 commit comments