From 966d9fd7453e247113301287cf93e1dc3ba90a81 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 25 Apr 2019 11:54:37 -0400 Subject: [PATCH] properly shutdown from database_guard_exception during irreversible blocks replay --- libraries/chain/controller.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 1b1f914db2d..5f75d8205cc 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -453,17 +453,22 @@ struct controller_impl { auto start_block_num = head->block_num + 1; auto start = fc::time_point::now(); + std::exception_ptr except_ptr; + if( start_block_num <= blog_head->block_num() ) { ilog( "existing block log, attempting to replay from ${s} to ${n} blocks", ("s", start_block_num)("n", blog_head->block_num()) ); - while( auto next = blog.read_block_by_num( head->block_num + 1 ) ) { - replay_push_block( next, controller::block_status::irreversible ); - if( next->block_num() % 500 == 0 ) { - ilog( "${n} of ${head}", ("n", next->block_num())("head", blog_head->block_num()) ); - if( shutdown() ) break; + try { + while( auto next = blog.read_block_by_num( head->block_num + 1 ) ) { + replay_push_block( next, controller::block_status::irreversible ); + if( next->block_num() % 500 == 0 ) { + ilog( "${n} of ${head}", ("n", next->block_num())("head", blog_head->block_num()) ); + if( shutdown() ) break; + } } + } catch( const database_guard_exception& e ) { + except_ptr = std::current_exception(); } - std::cerr<< "\n"; ilog( "${n} irreversible blocks replayed", ("n", 1 + head->block_num - start_block_num) ); auto pending_head = fork_db.pending_head(); @@ -488,18 +493,24 @@ struct controller_impl { ilog( "no irreversible blocks need to be replayed" ); } - int rev = 0; - while( auto obj = reversible_blocks.find(head->block_num+1) ) { - ++rev; - replay_push_block( obj->get_block(), controller::block_status::validated ); + if( !except_ptr && !shutdown() ) { + int rev = 0; + while( auto obj = reversible_blocks.find(head->block_num+1) ) { + ++rev; + replay_push_block( obj->get_block(), controller::block_status::validated ); + } + ilog( "${n} reversible blocks replayed", ("n",rev) ); } - ilog( "${n} reversible blocks replayed", ("n",rev) ); auto end = fc::time_point::now(); ilog( "replayed ${n} blocks in ${duration} seconds, ${mspb} ms/block", ("n", head->block_num + 1 - start_block_num)("duration", (end-start).count()/1000000) ("mspb", ((end-start).count()/1000.0)/(head->block_num-start_block_num)) ); replay_head_time.reset(); + + if( except_ptr ) { + std::rethrow_exception( except_ptr ); + } } void init(std::function shutdown, const snapshot_reader_ptr& snapshot) {