@@ -258,12 +258,12 @@ std::shared_ptr<full_block_type> block_log_wrapper::get_block_by_number( uint32_
258
258
return std::shared_ptr<full_block_type>();
259
259
260
260
const block_log_ptr_t log = get_block_log_corresponding_to ( block_num );
261
- if ( _block_log_split < MAX_FILES_OF_SPLIT_BLOCK_LOG )
261
+ if ( _block_log_split <= MAX_FILES_OF_SPLIT_BLOCK_LOG )
262
262
{
263
263
FC_ASSERT ( log ,
264
264
" Block ${num} has been pruned (oldest stored block is ${old}). "
265
265
" Consider disabling pruning or increasing block-log-split value (currently ${part_count})." ,
266
- (" num" , block_num)(" old" , get_tail_block_num ())(" part_count" , _block_log_split) );
266
+ (" num" , block_num)(" old" , get_actual_tail_block_num ())(" part_count" , _block_log_split) );
267
267
}
268
268
else
269
269
{
@@ -392,6 +392,7 @@ block_id_type block_log_wrapper::read_block_id_by_num( uint32_t block_num ) cons
392
392
const block_log_wrapper::block_log_ptr_t block_log_wrapper::get_block_log_corresponding_to (
393
393
uint32_t block_num ) const
394
394
{
395
+ FC_ASSERT ( get_head_log (), " Using unopened block log?" );
395
396
uint32_t request_part_number = get_part_number_for_block ( block_num, _max_blocks_in_log_file );
396
397
if ( request_part_number > _logs.size () )
397
398
return block_log_ptr_t ();
@@ -410,7 +411,12 @@ block_log_wrapper::full_block_range_t block_log_wrapper::read_block_range_by_num
410
411
if ( not current_log )
411
412
return result;
412
413
413
- auto part_result = current_log->read_block_range_by_num ( starting_block_num, count );
414
+ FC_ASSERT ( current_log->head (), " Empty or unopened log! ${io}" , (" io" , current_log->is_open () ) );
415
+
416
+ // block_log class is not prepared for over-the-head count parameter.
417
+ uint32_t actual_count =
418
+ std::min<uint32_t >( count, current_log->head ()->get_block_num () - starting_block_num +1 );
419
+ auto part_result = current_log->read_block_range_by_num ( starting_block_num, actual_count );
414
420
size_t part_result_count = part_result.size ();
415
421
if ( part_result_count == 0 )
416
422
return result;
@@ -584,27 +590,13 @@ void block_log_wrapper::common_open_and_init( bool read_only, bool allow_splitti
584
590
if ( _block_log_split == LEGACY_SINGLE_FILE_BLOCK_LOG )
585
591
{
586
592
auto single_part_log = std::make_shared<block_log>( _app );
587
- internal_open_and_init ( single_part_log,
588
- _open_args. data_dir / block_log_file_name_info::_legacy_file_name,
589
- read_only );
593
+ auto log_file_path = _open_args. data_dir / block_log_file_name_info::_legacy_file_name;
594
+ ilog ( " Opening monolithic block log file ${log_file_path} " , (log_file_path));
595
+ internal_open_and_init ( single_part_log, log_file_path, read_only );
590
596
_logs.push_back ( single_part_log );
591
597
return ;
592
598
}
593
599
594
- uint32_t actual_tail_number_needed = 0 ;
595
- if ( _open_args.load_snapshot || _open_args.force_replay )
596
- {
597
- // When hard replay is in cards, ignore current state head (will be overridden anyway),
598
- // and split as many parts as it's possible from the source log.
599
- actual_tail_number_needed = 1 ;
600
- }
601
- else if ( _open_args.replay && not _open_args.force_replay && state_head_block )
602
- {
603
- // For regular replay require all parts beginning from state head block to be present & opened.
604
- actual_tail_number_needed =
605
- get_part_number_for_block ( state_head_block->get_block_num (), _max_blocks_in_log_file );
606
- }
607
-
608
600
// Any log file created on previous run?
609
601
part_file_names_t part_file_names;
610
602
look_for_part_files ( part_file_names );
@@ -656,26 +648,42 @@ void block_log_wrapper::common_open_and_init( bool read_only, bool allow_splitti
656
648
657
649
// Make sure all parts required by configuration are there.
658
650
uint32_t head_part_number = part_file_names.crbegin ()->part_number ;
659
- // Determine actual needed tail part number (if not set earlier).
660
- if ( actual_tail_number_needed == 0 )
651
+ // Determine actual needed tail part number.
652
+ uint32_t actual_tail_number_needed = head_part_number;
653
+ if ( _open_args.load_snapshot || _open_args.force_replay ||
654
+ head_part_number <= (unsigned int )_block_log_split )
655
+ {
656
+ // When hard replay is in cards, ignore current state head (will be overridden anyway),
657
+ // and split as many parts as it's possible from the source log.
658
+ // Do the same when block log is effectively not pruned (yet).
659
+ actual_tail_number_needed = 1 ;
660
+ }
661
+ else
661
662
{
662
- // Is block log not pruned or effectively not pruned (yet)?
663
- if ( _block_log_split == MAX_FILES_OF_SPLIT_BLOCK_LOG ||
664
- head_part_number <= (unsigned int )_block_log_split )
663
+ if ( _open_args.replay && not _open_args.force_replay && state_head_block )
665
664
{
666
- // Expected tail part is obviously 1 - we need each part.
667
- actual_tail_number_needed = 1 ;
665
+ // For regular replay require all parts beginning from state head block to be present & opened.
666
+ actual_tail_number_needed =
667
+ get_part_number_for_block ( state_head_block->get_block_num (), _max_blocks_in_log_file );
668
668
}
669
- else // pruned log here
669
+
670
+ if ( head_part_number > (uint32_t )_block_log_split )
670
671
{
671
- // not all parts are needed here, i.e. head_part_number > _block_log_split
672
- actual_tail_number_needed = head_part_number - _block_log_split;
672
+ // Make sure that we require sufficient number of parts.
673
+ actual_tail_number_needed =
674
+ std::min<uint32_t >( actual_tail_number_needed, head_part_number - _block_log_split);
673
675
}
674
676
}
675
677
force_parts_exist ( head_part_number, actual_tail_number_needed, part_file_names,
676
678
allow_splitting_monolithic_log, state_head_block );
677
679
678
680
// Open all needed parts.
681
+ if ( actual_tail_number_needed < head_part_number )
682
+ ilog ( " Opening split block log files numbered ${from} to ${to}" ,
683
+ (" from" , actual_tail_number_needed)(" to" , head_part_number) );
684
+ else
685
+ ilog ( " Opening single split block log file numbered ${to}" , (" to" , head_part_number) );
686
+
679
687
_logs.resize ( head_part_number, block_log_ptr_t () );
680
688
for ( auto cit = part_file_names.cbegin (); cit != part_file_names.cend (); ++cit )
681
689
{
@@ -766,16 +774,31 @@ void block_log_wrapper::internal_append( uint32_t block_num, append_t do_appendi
766
774
}
767
775
}
768
776
769
- uint32_t block_log_wrapper::get_tail_block_num () const
777
+ uint32_t block_log_wrapper::get_actual_tail_block_num () const
770
778
{
771
- if ( _block_log_split == LEGACY_SINGLE_FILE_BLOCK_LOG ||
772
- _block_log_split == MAX_FILES_OF_SPLIT_BLOCK_LOG )
779
+ // FC_ASSERT( get_head_log(), "Using unopened block log?" );
780
+ size_t log_number = _logs.size ();
781
+ FC_ASSERT ( log_number > 0 , " Uninitialized block_log_wrapper object?" );
782
+ FC_ASSERT ( std::atomic_load ( &(_logs[log_number -1 ]) ), " Head log not initialized?" );
783
+
784
+ uint32_t block_num = 0 ;
785
+ do
773
786
{
774
- return 1 ;
787
+ block_num = 1 + (log_number-1 ) * BLOCKS_IN_SPLIT_BLOCK_LOG_FILE;
788
+ --log_number;
789
+ } while ( log_number > 0 && std::atomic_load ( &(_logs[log_number -1 ]) ) );
790
+
791
+ return block_num;
792
+
793
+ /* uint32_t block_num = 1;
794
+ block_log_ptr_t another_log;
795
+ for(; not another_log; block_num += BLOCKS_IN_SPLIT_BLOCK_LOG_FILE )
796
+ {
797
+ another_log = get_block_log_corresponding_to( block_num );
775
798
}
799
+ while( not another_log ); // Will finally happen, see initial assertion.
776
800
777
- int oldest_available_part = std::max<int >( _logs.size () - _block_log_split, 1 );
778
- return (oldest_available_part -1 ) * BLOCKS_IN_SPLIT_BLOCK_LOG_FILE + 1 ;
801
+ return block_num;*/
779
802
}
780
803
781
804
} } // hive::chain
0 commit comments