Skip to content

Commit

Permalink
Merge pull request #1061 from AntelopeIO/GH-1053-irr-shutdown-1.0
Browse files Browse the repository at this point in the history
[1.0.4] Fast shutdown in irreversible mode
  • Loading branch information
heifner authored Dec 11, 2024
2 parents fbe8949 + c070108 commit 790584e
Showing 1 changed file with 28 additions and 15 deletions.
43 changes: 28 additions & 15 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1308,8 +1308,6 @@ struct controller_impl {
// When in IRREVERSIBLE mode fork_db blocks are applied and marked valid when they become irreversible
template<typename ForkDB, typename BSP>
bool apply_irreversible_block(ForkDB& forkdb, const BSP& bsp) {
if (read_mode != db_read_mode::IRREVERSIBLE)
return true; // ignore
controller::block_report br;
if constexpr (std::is_same_v<block_state_legacy_ptr, std::decay_t<decltype(bsp)>>) {
// before transition to savanna
Expand Down Expand Up @@ -1493,6 +1491,8 @@ struct controller_impl {
if( new_lib_num <= lib_num )
return;

const fc::time_point start = fc::time_point::now();

auto mark_branch_irreversible = [&, this](auto& forkdb) {
assert(!irreversible_mode() || forkdb.head());
const auto& head_id = irreversible_mode() ? forkdb.head()->id() : chain_head.id();
Expand All @@ -1512,27 +1512,39 @@ struct controller_impl {
// irreversible. Instead, this moves irreversible as much as possible and allows the next maybe_switch_forks call to apply these
// non-validated blocks. After the maybe_switch_forks call (before next produced block or on next received block), irreversible
// can then move forward on the then validated blocks.
return read_mode == db_read_mode::IRREVERSIBLE || bsp->is_valid();
// In irreversible mode, break every ~500ms to allow other tasks (e.g. get_info, SHiP) opportunity to run. There is a post
// for every incoming blocks; enough posted tasks to apply all blocks queued to the fork db.
if (irreversible_mode()) {
if (!replaying && fc::time_point::now() - start > fc::milliseconds(500))
return false;
return true;
}
return bsp->is_valid();
};

std::vector<std::future<std::vector<char>>> v;
v.reserve( branch.size() );
for( auto bitr = branch.rbegin(); bitr != branch.rend() && should_process(*bitr); ++bitr ) {

v.emplace_back( post_async_task( thread_pool.get_executor(), [b=(*bitr)->block]() { return fc::raw::pack(*b); } ) );
using packed_block_future = std::future<std::vector<char>>;
std::vector<packed_block_future> v;
if (!irreversible_mode()) {
v.reserve( branch.size() );
for( auto bitr = branch.rbegin(); bitr != branch.rend() && should_process(*bitr); ++bitr ) {
v.emplace_back( post_async_task( thread_pool.get_executor(), [b=(*bitr)->block]() { return fc::raw::pack(*b); } ) );
}
}
auto it = v.begin();

for( auto bitr = branch.rbegin(); bitr != branch.rend() && should_process(*bitr); ++bitr ) {
if (!apply_irreversible_block(forkdb, *bitr))
break;
packed_block_future f;
if (irreversible_mode()) {
f = post_async_task( thread_pool.get_executor(), [b=(*bitr)->block]() { return fc::raw::pack(*b); } );
if (!apply_irreversible_block(forkdb, *bitr))
break;
}

emit( irreversible_block, std::tie((*bitr)->block, (*bitr)->id()), __FILE__, __LINE__ );

// blog.append could fail due to failures like running out of space.
// Do it before commit so that in case it throws, DB can be rolled back.
blog.append( (*bitr)->block, (*bitr)->id(), it->get() );
++it;
blog.append( (*bitr)->block, (*bitr)->id(), irreversible_mode() ? f.get() : it++->get() );

db.commit( (*bitr)->block_num() );
root_id = (*bitr)->id();
Expand All @@ -1544,13 +1556,14 @@ struct controller_impl {
}
} catch( const std::exception& e ) {
try {
elog("Caught exception while logging irreversible: ${e}", ("e", e.what()));
if (root_id != forkdb.root()->id()) {
forkdb.advance_root(root_id);
}
} catch( const fc::exception& e2 ) {
wlog("Caught exception ${e2}, while processing exception ${e}", ("e2", e2.to_detail_string())("e", e.what()));
elog("Caught exception ${e2}, while processing exception ${e}", ("e2", e2.to_detail_string())("e", e.what()));
} catch( const std::exception& e2 ) {
wlog("Caught exception ${e2}, while processing exception ${e}", ("e2", e2.what())("e", e.what()));
elog("Caught exception ${e2}, while processing exception ${e}", ("e2", e2.what())("e", e.what()));
}
throw;
}
Expand Down Expand Up @@ -4985,7 +4998,7 @@ struct controller_impl {
}

bool should_terminate() const {
return should_terminate(chain_head.block_num());
return should_terminate(chain_head.block_num()) || check_shutdown();
}

bool is_builtin_activated( builtin_protocol_feature_t f )const {
Expand Down

0 comments on commit 790584e

Please sign in to comment.