diff --git a/libraries/chain/chain_controller.cpp b/libraries/chain/chain_controller.cpp index e44e47321a8fee7b72aa3dafddf960c4bcfc544a..0e7e2c3e458296e9953b17745735936571bda4dc 100644 --- a/libraries/chain/chain_controller.cpp +++ b/libraries/chain/chain_controller.cpp @@ -1290,7 +1290,12 @@ void chain_controller::update_last_irreversible_block() return a->last_confirmed_block_num < b->last_confirmed_block_num; }); - uint32_t new_last_irreversible_block_num = producer_objs[offset]->last_confirmed_block_num - 1; + uint32_t new_last_irreversible_block_num = producer_objs[offset]->last_confirmed_block_num; + // TODO: right now the code cannot handle the head block being irreversible for reasons that are purely + // implementation details. We can and should remove this special case once the rest of the logic is fixed. + if (producer_objs.size() == 1) { + new_last_irreversible_block_num -= 1; + } if (new_last_irreversible_block_num > dpo.last_irreversible_block_num) { diff --git a/libraries/chain/include/eosio/chain/producer_schedule.hpp b/libraries/chain/include/eosio/chain/producer_schedule.hpp index b2a2fe6d6b2d1bfe01b4a8eaf1147ae16b8584e0..9892ba5a25a3bd3bfcf1b0b19711d27d06d5a79d 100644 --- a/libraries/chain/include/eosio/chain/producer_schedule.hpp +++ b/libraries/chain/include/eosio/chain/producer_schedule.hpp @@ -33,6 +33,7 @@ namespace eosio { namespace chain { shared_producer_schedule_type& operator=( const producer_schedule_type& a ) { version = a.version; + producers.clear(); producers.reserve( a.producers.size() ); for( const auto& p : a.producers ) producers.push_back(p); diff --git a/tests/tests/database_tests.cpp b/tests/tests/database_tests.cpp index 9ff03aca3cbbbcade49f2d06d1c6709532444fc5..d03ba98aa713046f9ba4500aaaab4292ab57ca78 100644 --- a/tests/tests/database_tests.cpp +++ b/tests/tests/database_tests.cpp @@ -58,12 +58,17 @@ BOOST_AUTO_TEST_SUITE(database_tests) } // Utility function to check expected irreversible block - auto calc_exp_last_irr_block_num = [&](uint32_t head_block_num) { + auto calc_exp_last_irr_block_num = [&](uint32_t head_block_num) -> uint32_t { const global_property_object &gpo = test.control->get_global_properties(); const auto producers_size = gpo.active_producers.producers.size(); - const auto min_producers = EOS_PERCENT(producers_size, config::irreversible_threshold_percent); - return head_block_num - (((min_producers - 1) * config::producer_repititions) + 1 + - (head_block_num % config::producer_repititions)); + const auto max_reversible_rounds = EOS_PERCENT(producers_size, config::percent_100 - config::irreversible_threshold_percent); + if( max_reversible_rounds == 0) { + return head_block_num - 1; + } else { + const auto current_round = head_block_num / config::producer_repititions; + const auto irreversible_round = current_round - max_reversible_rounds; + return (irreversible_round + 1) * config::producer_repititions - 1; + } }; // Check the last irreversible block number is set correctly