From a0052d4bd35f2a0882a051a44b5b9f656317b9e3 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Thu, 13 Jul 2017 20:26:35 +0200 Subject: [PATCH] Enable undo + fork database for final blocks in a replay Dont remove blocks from block db when popping blocks, handle edge case in replay wrt fork_db, adapted unit tests --- libraries/chain/db_block.cpp | 1 - libraries/chain/db_management.cpp | 40 ++++++++++++++++++------------- tests/tests/block_tests.cpp | 6 ++++- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 9b2c7f36..ad4ad1a0 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -506,7 +506,6 @@ void database::pop_block() GRAPHENE_ASSERT( head_block.valid(), pop_empty_chain, "there are no blocks to pop" ); _fork_db.pop_block(); - _block_id_to_block.remove( head_id ); pop_undo(); _popped_tx.insert( _popped_tx.begin(), head_block->transactions.begin(), head_block->transactions.end() ); diff --git a/libraries/chain/db_management.cpp b/libraries/chain/db_management.cpp index ca4004e6..1a60520a 100644 --- a/libraries/chain/db_management.cpp +++ b/libraries/chain/db_management.cpp @@ -64,11 +64,16 @@ void database::reindex( fc::path data_dir ) uint32_t undo_point = last_block_num - 50; ilog( "Replaying blocks..." ); - // Right now, we leave undo_db enabled when replaying when the bookie plugin is - // enabled. It depends on new/changed/removed object notifications, and those are - // only fired when the undo_db is enabled - if (!_slow_replays) - _undo_db.disable(); + if( head_block_num() >= undo_point ) + _fork_db.start_block( *fetch_block_by_number( head_block_num() ) ); + else + { + // Right now, we leave undo_db enabled when replaying when the bookie plugin is + // enabled. It depends on new/changed/removed object notifications, and those are + // only fired when the undo_db is enabled + if (!_slow_replays) + _undo_db.disable(); + } for( uint32_t i = head_block_num() + 1; i <= last_block_num; ++i ) { if( i % 10000 == 0 ) std::cerr << " " << double(i*100)/last_block_num << "% "< block = _block_id_to_block.fetch_by_number(i); if( !block.valid() ) { @@ -100,21 +103,26 @@ void database::reindex( fc::path data_dir ) wlog( "Dropped ${n} blocks from after the gap", ("n", dropped_count) ); break; } - if (_slow_replays) - push_block(*block, skip_fork_db | - skip_witness_signature | - skip_transaction_signatures | - skip_transaction_dupe_check | - skip_tapos_check | - skip_witness_schedule_check | - skip_authority_check); - else + if( i < undo_point && !_slow_replays) + { apply_block(*block, skip_witness_signature | skip_transaction_signatures | skip_transaction_dupe_check | skip_tapos_check | skip_witness_schedule_check | skip_authority_check); + } + else + { + if (!_slow_replays) + _undo_db.enable(); + push_block(*block, skip_witness_signature | + skip_transaction_signatures | + skip_transaction_dupe_check | + skip_tapos_check | + skip_witness_schedule_check | + skip_authority_check); + } } if (!_slow_replays) _undo_db.enable(); diff --git a/tests/tests/block_tests.cpp b/tests/tests/block_tests.cpp index 5990b12b..daa0734b 100644 --- a/tests/tests/block_tests.cpp +++ b/tests/tests/block_tests.cpp @@ -136,6 +136,7 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) // TODO: Don't generate this here auto init_account_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key")) ); signed_block cutoff_block; + uint32_t last_block; { database db; db.open(data_dir.path(), make_genesis, "TEST" ); @@ -155,6 +156,7 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) if( cutoff_height >= 200 ) { cutoff_block = *(db.fetch_block_by_number( cutoff_height )); + last_block = db.head_block_num(); break; } } @@ -163,7 +165,9 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks ) { database db; db.open(data_dir.path(), []{return genesis_state_type();}, "TEST"); - BOOST_CHECK_EQUAL( db.head_block_num(), cutoff_block.block_num() ); + BOOST_CHECK_EQUAL( db.head_block_num(), last_block ); + while( db.head_block_num() > cutoff_block.block_num() ) + db.pop_block(); b = cutoff_block; for( uint32_t i = 0; i < 200; ++i ) {