31
31
#include < silkworm/core/types/address.hpp>
32
32
#include < silkworm/core/types/block_body_for_storage.hpp>
33
33
#include < silkworm/core/types/evmc_bytes32.hpp>
34
+ #include < silkworm/db/snapshot_bundle_factory_impl.hpp>
34
35
#include < silkworm/db/snapshot_sync.hpp>
35
36
#include < silkworm/db/snapshots/bittorrent/client.hpp>
36
37
#include < silkworm/db/snapshots/body_index.hpp>
@@ -227,44 +228,48 @@ void decode_segment(const SnapSettings& settings, int repetitions) {
227
228
SILK_INFO << " Decode snapshot elapsed: " << duration_as<std::chrono::milliseconds>(elapsed) << " msec" ;
228
229
}
229
230
231
+ static std::unique_ptr<SnapshotBundleFactory> bundle_factory () {
232
+ return std::make_unique<silkworm::db::SnapshotBundleFactoryImpl>();
233
+ }
234
+
230
235
void count_bodies (const SnapSettings& settings, int repetitions) {
231
- SnapshotRepository snapshot_repo{settings};
236
+ SnapshotRepository snapshot_repo{settings, bundle_factory () };
232
237
snapshot_repo.reopen_folder ();
233
238
std::chrono::time_point start{std::chrono::steady_clock::now ()};
234
239
int num_bodies{0 };
235
240
uint64_t num_txns{0 };
236
241
for (int i{0 }; i < repetitions; ++i) {
237
- const bool success = snapshot_repo.for_each_body ([&](BlockNum number, const BlockBodyForStorage& b) -> bool {
238
- // If *system transactions* should not be counted, skip first and last tx in block body
239
- const auto base_txn_id{settings. skip_system_txs ? b. base_txn_id + 1 : b. base_txn_id };
240
- const auto txn_count {settings.skip_system_txs && b. txn_count >= 2 ? b.txn_count - 2 : b.txn_count };
241
- SILK_DEBUG << " Body number: " << number << " base_txn_id: " << base_txn_id << " txn_count: " << txn_count
242
- << " #ommers : " << b. ommers . size ();
243
- num_bodies++ ;
244
- num_txns += txn_count ;
245
- return true ;
246
- });
247
- ensure (success, " count_bodies: for_each_body failed " );
242
+ for ( const SnapshotBundle& bundle : snapshot_repo.view_bundles ()) {
243
+ for ( const BlockBodyForStorage& b : BodySnapshotReader{bundle. body_snapshot }) {
244
+ // If *system transactions* should not be counted, skip first and last tx in block body
245
+ const auto base_txn_id {settings.skip_system_txs ? b.base_txn_id + 1 : b.base_txn_id };
246
+ const auto txn_count{settings. skip_system_txs && b. txn_count >= 2 ? b. txn_count - 2 : b. txn_count };
247
+ SILK_TRACE << " Body number: " << num_bodies << " base_txn_id : " << base_txn_id << " txn_count: " << txn_count
248
+ << " #ommers: " << b. ommers . size () ;
249
+ num_bodies++ ;
250
+ num_txns += txn_count ;
251
+ }
252
+ }
248
253
}
249
254
std::chrono::duration elapsed{std::chrono::steady_clock::now () - start};
250
255
const auto duration = static_cast <uint64_t >(std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count ());
251
256
SILK_INFO << " How many bodies: " << num_bodies << " txs: " << num_txns << " duration: " << duration << " msec" ;
252
257
}
253
258
254
259
void count_headers (const SnapSettings& settings, int repetitions) {
255
- SnapshotRepository snapshot_repo{settings};
260
+ SnapshotRepository snapshot_repo{settings, bundle_factory () };
256
261
snapshot_repo.reopen_folder ();
257
262
std::chrono::time_point start{std::chrono::steady_clock::now ()};
258
263
int count{0 };
259
264
for (int i{0 }; i < repetitions; ++i) {
260
- const bool success = snapshot_repo.for_each_header ([&count](const BlockHeader& h) -> bool {
261
- ++count;
262
- if (h.number % 50'000 == 0 ) {
263
- SILK_INFO << " Header number: " << h.number << " hash: " << to_hex (h.hash ());
265
+ for (const SnapshotBundle& bundle : snapshot_repo.view_bundles ()) {
266
+ for (const BlockHeader& h : HeaderSnapshotReader{bundle.header_snapshot }) {
267
+ ++count;
268
+ if (h.number % 50'000 == 0 ) {
269
+ SILK_INFO << " Header number: " << h.number << " hash: " << to_hex (h.hash ());
270
+ }
264
271
}
265
- return true ;
266
- });
267
- ensure (success, " count_headers: for_each_header failed" );
272
+ }
268
273
}
269
274
std::chrono::duration elapsed{std::chrono::steady_clock::now () - start};
270
275
SILK_INFO << " How many headers: " << count << " duration: " << duration_as<std::chrono::milliseconds>(elapsed) << " msec" ;
@@ -405,16 +410,17 @@ void lookup_header_by_hash(const SnapSettings& settings) {
405
410
406
411
std::optional<SnapshotPath> matching_snapshot;
407
412
std::optional<BlockHeader> matching_header;
408
- SnapshotRepository snapshot_repository{settings};
413
+ SnapshotRepository snapshot_repository{settings, bundle_factory () };
409
414
snapshot_repository.reopen_folder ();
410
- snapshot_repository.view_header_segments ([&](SnapshotRepository::SnapshotAndIndex snapshot) -> bool {
411
- const auto header = HeaderFindByHashQuery{snapshot.snapshot , snapshot.index }.exec (*hash);
415
+ for (const SnapshotBundle& bundle : snapshot_repository.view_bundles_reverse ()) {
416
+ auto snapshot_and_index = bundle.snapshot_and_index (SnapshotType::headers);
417
+ const auto header = HeaderFindByHashQuery{snapshot_and_index}.exec (*hash);
412
418
if (header) {
413
419
matching_header = header;
414
- matching_snapshot = snapshot.snapshot .path ();
420
+ matching_snapshot = snapshot_and_index.snapshot .path ();
421
+ break ;
415
422
}
416
- return header.has_value ();
417
- });
423
+ }
418
424
if (matching_snapshot) {
419
425
SILK_INFO << " Lookup header hash: " << hash->to_hex () << " found in: " << matching_snapshot->filename ();
420
426
if (matching_header && settings.print ) {
@@ -433,16 +439,16 @@ void lookup_header_by_number(const SnapSettings& settings) {
433
439
SILK_INFO << " Lookup header number: " << block_number;
434
440
std::chrono::time_point start{std::chrono::steady_clock::now ()};
435
441
436
- SnapshotRepository snapshot_repository{settings};
442
+ SnapshotRepository snapshot_repository{settings, bundle_factory () };
437
443
snapshot_repository.reopen_folder ();
438
- const auto header_snapshot{ snapshot_repository.find_header_segment ( block_number)} ;
439
- if (header_snapshot ) {
440
- const auto header = HeaderFindByBlockNumQuery{header_snapshot-> snapshot , header_snapshot-> index }.exec (block_number);
444
+ const auto snapshot_and_index = snapshot_repository.find_segment (SnapshotType::headers, block_number);
445
+ if (snapshot_and_index ) {
446
+ const auto header = HeaderFindByBlockNumQuery{*snapshot_and_index }.exec (block_number);
441
447
ensure (header.has_value (),
442
- [&]() { return " lookup_header_by_number: " + std::to_string (block_number) + " NOT found in " + header_snapshot ->snapshot .path ().filename (); });
443
- SILK_INFO << " Lookup header number: " << block_number << " found in: " << header_snapshot ->snapshot .path ().filename ();
448
+ [&]() { return " lookup_header_by_number: " + std::to_string (block_number) + " NOT found in " + snapshot_and_index ->snapshot .path ().filename (); });
449
+ SILK_INFO << " Lookup header number: " << block_number << " found in: " << snapshot_and_index ->snapshot .path ().filename ();
444
450
if (settings.print ) {
445
- print_header (*header, header_snapshot ->snapshot .path ().filename ());
451
+ print_header (*header, snapshot_and_index ->snapshot .path ().filename ());
446
452
}
447
453
} else {
448
454
SILK_WARN << " Lookup header number: " << block_number << " NOT found" ;
@@ -479,7 +485,7 @@ void lookup_body_in_one(const SnapSettings& settings, BlockNum block_number, con
479
485
Index idx_body_number{snapshot_path->index_file ()};
480
486
idx_body_number.reopen_index ();
481
487
482
- const auto body = BodyFindByBlockNumQuery{body_snapshot, idx_body_number}.exec (block_number);
488
+ const auto body = BodyFindByBlockNumQuery{{ body_snapshot, idx_body_number} }.exec (block_number);
483
489
if (body) {
484
490
SILK_INFO << " Lookup body number: " << block_number << " found in: " << body_snapshot.path ().filename ();
485
491
if (settings.print ) {
@@ -493,18 +499,18 @@ void lookup_body_in_one(const SnapSettings& settings, BlockNum block_number, con
493
499
}
494
500
495
501
void lookup_body_in_all (const SnapSettings& settings, BlockNum block_number) {
496
- SnapshotRepository snapshot_repository{settings};
502
+ SnapshotRepository snapshot_repository{settings, bundle_factory () };
497
503
snapshot_repository.reopen_folder ();
498
504
499
505
std::chrono::time_point start{std::chrono::steady_clock::now ()};
500
- const auto body_snapshot{ snapshot_repository.find_body_segment ( block_number)} ;
501
- if (body_snapshot ) {
502
- const auto body = BodyFindByBlockNumQuery{body_snapshot-> snapshot , body_snapshot-> index }.exec (block_number);
506
+ const auto snapshot_and_index = snapshot_repository.find_segment (SnapshotType::bodies, block_number);
507
+ if (snapshot_and_index ) {
508
+ const auto body = BodyFindByBlockNumQuery{*snapshot_and_index }.exec (block_number);
503
509
ensure (body.has_value (),
504
- [&]() { return " lookup_body: " + std::to_string (block_number) + " NOT found in " + body_snapshot ->snapshot .path ().filename (); });
505
- SILK_INFO << " Lookup body number: " << block_number << " found in: " << body_snapshot ->snapshot .path ().filename ();
510
+ [&]() { return " lookup_body: " + std::to_string (block_number) + " NOT found in " + snapshot_and_index ->snapshot .path ().filename (); });
511
+ SILK_INFO << " Lookup body number: " << block_number << " found in: " << snapshot_and_index ->snapshot .path ().filename ();
506
512
if (settings.print ) {
507
- print_body (*body, body_snapshot ->snapshot .path ().filename ());
513
+ print_body (*body, snapshot_and_index ->snapshot .path ().filename ());
508
514
}
509
515
} else {
510
516
SILK_WARN << " Lookup body number: " << block_number << " NOT found" ;
@@ -585,7 +591,7 @@ void lookup_txn_by_hash_in_one(const SnapSettings& settings, const Hash& hash, c
585
591
Index idx_txn_hash{snapshot_path->index_file ()};
586
592
idx_txn_hash.reopen_index ();
587
593
588
- const auto transaction = TransactionFindByHashQuery{tx_snapshot, idx_txn_hash}.exec (hash);
594
+ const auto transaction = TransactionFindByHashQuery{{ tx_snapshot, idx_txn_hash} }.exec (hash);
589
595
if (transaction) {
590
596
SILK_INFO << " Lookup txn hash: " << hash.to_hex () << " found in: " << tx_snapshot.path ().filename ();
591
597
if (settings.print ) {
@@ -600,21 +606,22 @@ void lookup_txn_by_hash_in_one(const SnapSettings& settings, const Hash& hash, c
600
606
}
601
607
602
608
void lookup_txn_by_hash_in_all (const SnapSettings& settings, const Hash& hash) {
603
- SnapshotRepository snapshot_repository{settings};
609
+ SnapshotRepository snapshot_repository{settings, bundle_factory () };
604
610
snapshot_repository.reopen_folder ();
605
611
606
612
std::optional<SnapshotPath> matching_snapshot;
607
613
std::chrono::time_point start{std::chrono::steady_clock::now ()};
608
- snapshot_repository.view_tx_segments ([&](SnapshotRepository::SnapshotAndIndex snapshot) -> bool {
609
- const auto transaction = TransactionFindByHashQuery{snapshot.snapshot , snapshot.index }.exec (hash);
614
+ for (const SnapshotBundle& bundle : snapshot_repository.view_bundles_reverse ()) {
615
+ auto snapshot_and_index = bundle.snapshot_and_index (SnapshotType::transactions);
616
+ const auto transaction = TransactionFindByHashQuery{snapshot_and_index}.exec (hash);
610
617
if (transaction) {
611
- matching_snapshot = snapshot .snapshot .path ();
618
+ matching_snapshot = snapshot_and_index .snapshot .path ();
612
619
if (settings.print ) {
613
620
print_txn (*transaction, matching_snapshot->path ().filename ());
614
621
}
622
+ break ;
615
623
}
616
- return transaction.has_value ();
617
- });
624
+ }
618
625
std::chrono::duration elapsed{std::chrono::steady_clock::now () - start};
619
626
SILK_INFO << " Lookup txn elapsed: " << duration_as<std::chrono::microseconds>(elapsed) << " usec" ;
620
627
if (matching_snapshot) {
@@ -648,7 +655,7 @@ void lookup_txn_by_id_in_one(const SnapSettings& settings, uint64_t txn_id, cons
648
655
Index idx_txn_hash{snapshot_path->index_file ()};
649
656
idx_txn_hash.reopen_index ();
650
657
651
- const auto transaction = TransactionFindByIdQuery{tx_snapshot, idx_txn_hash}.exec (txn_id);
658
+ const auto transaction = TransactionFindByIdQuery{{ tx_snapshot, idx_txn_hash} }.exec (txn_id);
652
659
if (transaction) {
653
660
SILK_INFO << " Lookup txn ID: " << txn_id << " found in: " << tx_snapshot.path ().filename ();
654
661
if (settings.print ) {
@@ -663,21 +670,22 @@ void lookup_txn_by_id_in_one(const SnapSettings& settings, uint64_t txn_id, cons
663
670
}
664
671
665
672
void lookup_txn_by_id_in_all (const SnapSettings& settings, uint64_t txn_id) {
666
- SnapshotRepository snapshot_repository{settings};
673
+ SnapshotRepository snapshot_repository{settings, bundle_factory () };
667
674
snapshot_repository.reopen_folder ();
668
675
669
676
std::optional<SnapshotPath> matching_snapshot;
670
677
std::chrono::time_point start{std::chrono::steady_clock::now ()};
671
- snapshot_repository.view_tx_segments ([&](SnapshotRepository::SnapshotAndIndex snapshot) -> bool {
672
- const auto transaction = TransactionFindByIdQuery{snapshot.snapshot , snapshot.index }.exec (txn_id);
678
+ for (const SnapshotBundle& bundle : snapshot_repository.view_bundles_reverse ()) {
679
+ auto snapshot_and_index = bundle.snapshot_and_index (SnapshotType::transactions);
680
+ const auto transaction = TransactionFindByIdQuery{snapshot_and_index}.exec (txn_id);
673
681
if (transaction) {
674
- matching_snapshot = snapshot .snapshot .path ();
682
+ matching_snapshot = snapshot_and_index .snapshot .path ();
675
683
if (settings.print ) {
676
684
print_txn (*transaction, matching_snapshot->path ().filename ());
677
685
}
686
+ break ;
678
687
}
679
- return transaction.has_value ();
680
- });
688
+ }
681
689
std::chrono::duration elapsed{std::chrono::steady_clock::now () - start};
682
690
SILK_INFO << " Lookup txn elapsed: " << duration_as<std::chrono::milliseconds>(elapsed) << " msec" ;
683
691
if (matching_snapshot) {
@@ -708,7 +716,7 @@ void lookup_transaction(const SnapSettings& settings) {
708
716
709
717
void sync (const SnapSettings& settings) {
710
718
std::chrono::time_point start{std::chrono::steady_clock::now ()};
711
- SnapshotRepository snapshot_repository{settings};
719
+ SnapshotRepository snapshot_repository{settings, bundle_factory () };
712
720
db::SnapshotSync snapshot_sync{&snapshot_repository, kMainnetConfig };
713
721
std::vector<std::string> snapshot_file_names;
714
722
if (settings.snapshot_file_name ) {
0 commit comments