Skip to content

Commit

Permalink
GH-1275 Signal accepted_block after it is marked valid
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Oct 13, 2023
1 parent e3f11c4 commit 03d53b7
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 21 deletions.
28 changes: 11 additions & 17 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,6 @@ struct controller_impl {
if( read_mode == db_read_mode::IRREVERSIBLE ) {
controller::block_report br;
apply_block( br, *bitr, controller::block_status::complete, trx_meta_cache_lookup{} );
head = (*bitr);
fork_db.mark_valid( head );
}

emit( self.irreversible_block, *bitr );
Expand Down Expand Up @@ -1934,7 +1932,7 @@ struct controller_impl {
/**
* @post regardless of the success of commit block there is no active pending block
*/
void commit_block( bool add_to_fork_db ) {
void commit_block( controller::block_status s ) {
auto reset_pending_on_exit = fc::make_scoped_exit([this]{
pending.reset();
});
Expand All @@ -1943,24 +1941,26 @@ struct controller_impl {
EOS_ASSERT( std::holds_alternative<completed_block>(pending->_block_stage), block_validate_exception,
"cannot call commit_block until pending block is completed" );

auto bsp = std::get<completed_block>(pending->_block_stage)._block_state;
const auto& bsp = std::get<completed_block>(pending->_block_stage)._block_state;

if( add_to_fork_db ) {
if( s == controller::block_status::incomplete ) {
fork_db.add( bsp );
fork_db.mark_valid( bsp );
emit( self.accepted_block_header, bsp );
head = fork_db.head();
EOS_ASSERT( bsp == head, fork_database_exception, "committed block did not become the new head in fork database");
EOS_ASSERT( bsp == fork_db.head(), fork_database_exception, "committed block did not become the new head in fork database");
} else if (s != controller::block_status::irreversible) {
fork_db.mark_valid( bsp );
}
head = bsp;

// at block level, no transaction specific logging is possible
if (auto dm_logger = get_deep_mind_logger(false)) {
if (auto* dm_logger = get_deep_mind_logger(false)) {
dm_logger->on_accepted_block(bsp);
}

emit( self.accepted_block, bsp );

if( add_to_fork_db ) {
if( s == controller::block_status::incomplete ) {
log_irreversible();
}
} catch (...) {
Expand Down Expand Up @@ -2160,7 +2160,7 @@ struct controller_impl {
pending->_block_stage = completed_block{ bsp };

br = pending->_block_report; // copy before commit block destroys pending
commit_block(false);
commit_block(s);
br.total_time = fc::time_point::now() - start;
return;
} catch ( const std::bad_alloc& ) {
Expand Down Expand Up @@ -2312,7 +2312,6 @@ struct controller_impl {
controller::block_report br;
if( s == controller::block_status::irreversible ) {
apply_block( br, bsp, s, trx_meta_cache_lookup{} );
head = bsp;

// On replay, log_irreversible is not called and so no irreversible_block signal is emitted.
// So emit it explicitly here.
Expand All @@ -2338,8 +2337,6 @@ struct controller_impl {
if( new_head->header.previous == head->id ) {
try {
apply_block( br, new_head, s, trx_lookup );
fork_db.mark_valid( new_head );
head = new_head;
} catch ( const std::exception& e ) {
fork_db.remove( new_head->id );
throw;
Expand Down Expand Up @@ -2372,8 +2369,6 @@ struct controller_impl {
br = controller::block_report{};
apply_block( br, *ritr, (*ritr)->is_valid() ? controller::block_status::validated
: controller::block_status::complete, trx_lookup );
fork_db.mark_valid( *ritr );
head = *ritr;
} catch ( const std::bad_alloc& ) {
throw;
} catch ( const boost::interprocess::bad_alloc& ) {
Expand Down Expand Up @@ -2404,7 +2399,6 @@ struct controller_impl {
for( auto ritr = branches.second.rbegin(); ritr != branches.second.rend(); ++ritr ) {
br = controller::block_report{};
apply_block( br, *ritr, controller::block_status::validated /* we previously validated these blocks*/, trx_lookup );
head = *ritr;
}
std::rethrow_exception(except);
} // end if exception
Expand Down Expand Up @@ -2994,7 +2988,7 @@ block_state_ptr controller::finalize_block( block_report& br, const signer_callb

void controller::commit_block() {
validate_db_available_size();
my->commit_block(true);
my->commit_block(block_status::incomplete);
}

deque<transaction_metadata_ptr> controller::abort_block() {
Expand Down
41 changes: 41 additions & 0 deletions unittests/chain_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,45 @@ BOOST_AUTO_TEST_CASE( decompressed_size_under_limit ) try {

} FC_LOG_AND_RETHROW()

// verify accepted_block signals validated blocks
BOOST_AUTO_TEST_CASE( signal_validated_blocks ) try {
tester chain;
tester validator;

block_state_ptr accepted_bsp;
auto c = chain.control->accepted_block.connect([&](const block_state_ptr& b) {
BOOST_CHECK(b);
BOOST_CHECK(chain.control->fetch_block_state_by_id(b->id) == b);
BOOST_CHECK(chain.control->fetch_block_state_by_number(b->block_num) == b); // verify it can be found (has to be validated)
BOOST_CHECK(chain.control->fetch_block_by_id(b->id) == b->block);
BOOST_CHECK(chain.control->fetch_block_by_number(b->block_num) == b->block);
BOOST_REQUIRE(chain.control->fetch_block_header_by_number(b->block_num));
BOOST_CHECK(chain.control->fetch_block_header_by_number(b->block_num)->calculate_id() == b->id);
BOOST_REQUIRE(chain.control->fetch_block_header_by_id(b->id));
BOOST_CHECK(chain.control->fetch_block_header_by_id(b->id)->calculate_id() == b->id);
accepted_bsp = b;
});
block_state_ptr validated_bsp;
auto c2 = validator.control->accepted_block.connect([&](const block_state_ptr& b) {
BOOST_CHECK(b);
BOOST_CHECK(validator.control->fetch_block_state_by_id(b->id) == b);
BOOST_CHECK(validator.control->fetch_block_state_by_number(b->block_num) == b); // verify it can be found (has to be validated)
BOOST_CHECK(validator.control->fetch_block_by_id(b->id) == b->block);
BOOST_CHECK(validator.control->fetch_block_by_number(b->block_num) == b->block);
BOOST_REQUIRE(validator.control->fetch_block_header_by_number(b->block_num));
BOOST_CHECK(validator.control->fetch_block_header_by_number(b->block_num)->calculate_id() == b->id);
BOOST_REQUIRE(validator.control->fetch_block_header_by_id(b->id));
BOOST_CHECK(validator.control->fetch_block_header_by_id(b->id)->calculate_id() == b->id);
validated_bsp = b;
});

chain.produce_blocks(1);
validator.push_block(accepted_bsp->block);

auto trace_ptr = chain.create_account("hello"_n);
chain.produce_block();
validator.push_block(accepted_bsp->block);

} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit 03d53b7

Please sign in to comment.