Skip to content

Commit

Permalink
Merge pull request #894 from AntelopeIO/gh_869
Browse files Browse the repository at this point in the history
[1.0.3] Restart with ctrl-c during replay of forkdb spams log
  • Loading branch information
greg7mdp authored Oct 4, 2024
2 parents fb33083 + 6f814f9 commit 74d4565
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
1 change: 1 addition & 0 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2012,6 +2012,7 @@ struct controller_impl {
ilog( "applying branch from fork database ending with block: ${id}", ("id", pending_head->id()) );
controller::block_report br;
maybe_switch_forks( br, pending_head, controller::block_status::complete, {}, trx_meta_cache_lookup{} );
if( check_shutdown() ) return;
}
}
}
Expand Down
26 changes: 15 additions & 11 deletions unittests/savanna_cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,12 @@ namespace savanna_cluster {

template <class Node>
void push_blocks_to(Node& n, uint32_t block_num_limit = std::numeric_limits<uint32_t>::max()) const {
auto limit = std::min(fork_db_head().block_num(), block_num_limit);
while (n.fork_db_head().block_num() < limit) {
auto sb = control->fetch_block_by_number(n.fork_db_head().block_num() + 1);
n.push_block(sb);
if (fork_db_head().is_valid() && n.fork_db_head().is_valid()) {
auto limit = std::min(fork_db_head().block_num(), block_num_limit);
while (n.fork_db_head().block_num() < limit) {
auto sb = control->fetch_block_by_number(n.fork_db_head().block_num() + 1);
n.push_block(sb);
}
}
}

Expand Down Expand Up @@ -291,7 +293,7 @@ namespace savanna_cluster {

void remove_state() {
auto state_path = cfg.state_dir;
dlog("node ${i} - removing state data from: ${state_path}", ("i", _node_idx)("${state_path}", state_path));
dlog("node ${i} - removing state data from: ${state_path}", ("i", _node_idx)("state_path", state_path));
remove_all(state_path);
fs::create_directories(state_path);
}
Expand All @@ -309,7 +311,7 @@ namespace savanna_cluster {
for (auto const& dir_entry : std::filesystem::directory_iterator{path}) {
auto path = dir_entry.path();
if (path.filename().generic_string() != "reversible") {
dlog("node ${i} - removing : ${path}", ("i", _node_idx)("${path}", path));
dlog("node ${i} - removing : ${path}", ("i", _node_idx)("path", path));
remove_all(path);
}
}
Expand All @@ -336,7 +338,7 @@ namespace savanna_cluster {
void remove_blocks(bool rm_blocks_log) {
auto reversible_path = cfg.blocks_dir / config::reversible_blocks_dir_name;
auto& path = rm_blocks_log ? cfg.blocks_dir : reversible_path;
dlog("node ${i} - removing : ${path}", ("i", _node_idx)("${path}", path));
dlog("node ${i} - removing : ${path}", ("i", _node_idx)("path", path));
remove_all(path);
fs::create_directories(reversible_path);
}
Expand Down Expand Up @@ -519,11 +521,13 @@ namespace savanna_cluster {
auto& src = _nodes[src_idx];
assert(src.is_open() && _nodes[dst_idx].is_open());

auto end_block_num = src.fork_db_head().block_num();
if (src.fork_db_head().is_valid()) {
auto end_block_num = src.fork_db_head().block_num();

for (uint32_t i=start_block_num; i<=end_block_num; ++i) {
auto sb = src.control->fetch_block_by_number(i);
push_block(dst_idx, sb);
for (uint32_t i=start_block_num; i<=end_block_num; ++i) {
auto sb = src.control->fetch_block_by_number(i);
push_block(dst_idx, sb);
}
}
}

Expand Down
45 changes: 45 additions & 0 deletions unittests/savanna_misc_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,5 +1105,50 @@ BOOST_FIXTURE_TEST_CASE(finality_advancing_past_block_claimed_on_alternate_branc

} FC_LOG_AND_RETHROW()

// ------------------------------------------------------------------------------------
// Test that replays blocks from fork_db at startup, and simulating a Ctrl-C
// interruption of that replay.
// (the cluster starts with 9 final blocks and 1 reversible block after the transition
// to Savanna)
// ------------------------------------------------------------------------------------
BOOST_FIXTURE_TEST_CASE(replay_forkdb_at_startup, savanna_cluster::cluster_t) try {
auto& A=_nodes[0]; auto& C=_nodes[2]; auto& D=_nodes[3];

// at this point we have 9 final blocks and 1 reversible block

set_partition( { &C, &D } ); // partition so blocks aren't finalized
const size_t num_blocks = 20;

std::vector<signed_block_ptr> blocks;
blocks.reserve(num_blocks);
for (size_t i=0; i<num_blocks; ++i)
blocks.push_back(A.produce_block());

const size_t num_forkdb_blocks = A.control->fork_db_size();;
BOOST_REQUIRE_GT(num_forkdb_blocks, num_blocks); // A should have 20+ unfinalized blocks in its fork_db (actually 21)

controller::config copied_config = A.get_config();
auto genesis = block_log::extract_genesis_state(A.get_config().blocks_dir);

A.close();
A.remove_state();

A.open(make_protocol_feature_set(), genesis->compute_chain_id(), [genesis, &control=A.control]() {
auto check_shutdown = [](){
static size_t call_idx = 0;
return ++call_idx >= 15; // simulate Ctrl-C being hit on 15th call, so fewer than
// 21 blocks from fork_db will be replayed.
};

control->startup([]() {}, check_shutdown, *genesis);
} );

A.close();
A.open(); // open() the node again to make sure it restarts correctly
// after being interrupted.

BOOST_REQUIRE_EQUAL(A.control->fork_db_size(), num_forkdb_blocks);

} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 74d4565

Please sign in to comment.