@@ -317,6 +317,67 @@ void remove_block_log_part( fc::path& data_dir, uint32_t part_number )
317317 fc::remove_all ( part_path_str );
318318}
319319
320+ bool is_block_link_broken ( fc::exception const & ex )
321+ {
322+ std::string s ( ex.what () );
323+ return ( s.rfind (" Mismatch detected between block log part files" , 0 ) == 0 );
324+ }
325+
326+ BOOST_AUTO_TEST_CASE ( split_over_split )
327+ {
328+ try {
329+ ilog ( " Testing partial overriding of existing split block log." );
330+
331+ // Get dedicated temporary directory for database (shm) files
332+ // which is used to hide database from second (replay) run.
333+ fc::temp_directory shm_dir ( hive::utilities::temp_directory_path () );
334+
335+ fc::path data_dir;
336+ {
337+ // Generate longer (two-part) block log.
338+ hived_fixture fixture ( true /* remove blockchain*/ );
339+ INIT_FIXTURE_1 ( " block-log-split" , std::to_string ( MAX_FILES_OF_SPLIT_BLOCK_LOG ) );
340+
341+ for ( int i = 0 ; i < BLOCKS_IN_SPLIT_BLOCK_LOG_FILE +1 ; ++i )
342+ fixture.generate_block ();
343+
344+ data_dir = fixture.get_data_dir ();
345+ }
346+ // Store head (second) file of block log.
347+ fc::path temp_name ( data_dir / " temp_name.log" );
348+ fc::path temp_artifacts_name ( data_dir / " temp_name.artifacts.log" );
349+ std::string second_part_path_str = get_block_log_part_path ( data_dir, 2 );
350+ std::string second_part_artifacts_path_str = second_part_path_str + " .artifacts" ;
351+ fc::rename ( second_part_path_str, temp_name );
352+ fc::rename ( second_part_artifacts_path_str, temp_artifacts_name );
353+ {
354+ // Generate shorter (one-part) block log.
355+ hived_fixture fixture ( true /* remove blockchain*/ );
356+ INIT_FIXTURE_2 ( " block-log-split" , std::to_string ( MAX_FILES_OF_SPLIT_BLOCK_LOG ),
357+ " shared-file-dir" , shm_dir.path ().string () );
358+
359+ for ( int i = 0 ; i < BLOCKS_IN_SPLIT_BLOCK_LOG_FILE / 2 ; ++i )
360+ fixture.generate_block ();
361+ }
362+ // Restore head (second) file of block log.
363+ fc::rename ( temp_name, second_part_path_str );
364+ fc::rename ( temp_artifacts_name, second_part_artifacts_path_str );
365+ {
366+ // Fail before replay attempt, due to block log files consistency check.
367+ hived_fixture fixture ( false /* remove blockchain*/ );
368+ BOOST_CHECK_EXCEPTION (
369+ INIT_FIXTURE_2 ( " block-log-split" , std::to_string ( MAX_FILES_OF_SPLIT_BLOCK_LOG ),
370+ " replay-blockchain" , " " ),
371+ fc::exception,
372+ is_block_link_broken );
373+ }
374+
375+ } catch (fc::exception& e) {
376+ edump ((e.to_detail_string ()));
377+ throw ;
378+ }
379+ }
380+
320381void require_blocks ( hived_fixture& fixture, uint32_t block_num1, uint32_t block_num2 )
321382{
322383 const block_read_i& block_reader = fixture.get_chain_plugin ().block_reader ();
0 commit comments