Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.0] Signal accepted_block after it is marked valid #1769

Merged
merged 2 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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{} );
greg7mdp marked this conversation as resolved.
Show resolved Hide resolved
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;
linh2931 marked this conversation as resolved.
Show resolved Hide resolved
});

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

auto trace_ptr = chain.create_account("hello"_n);
linh2931 marked this conversation as resolved.
Show resolved Hide resolved
chain.produce_block();
validator.push_block(accepted_bsp->block);

} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_SUITE_END()
Loading