Skip to content

Commit

Permalink
GH-1941 Remove controller::head_block_state()
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Dec 20, 2023
1 parent 60555a4 commit fffbe1e
Show file tree
Hide file tree
Showing 18 changed files with 110 additions and 111 deletions.
6 changes: 5 additions & 1 deletion libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3536,9 +3536,13 @@ account_name controller::head_block_producer()const {
const block_header& controller::head_block_header()const {
return my->head->header;
}
block_state_legacy_ptr controller::head_block_state()const {
block_state_legacy_ptr controller::head_block_state_legacy()const {
// TODO: return null after instant finality activated
return my->head;
}
const signed_block_ptr& controller::head_block()const {
return my->head->block;
}

block_state_legacy_ptr controller_impl::fork_db_head() const {
if( read_mode == db_read_mode::IRREVERSIBLE ) {
Expand Down
3 changes: 2 additions & 1 deletion libraries/chain/hotstuff/chain_pacemaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ namespace eosio::chain {
const auto& [ block, id ] = t;
on_irreversible_block( block );
} );
_head_block_state = chain->head_block_state();
// TODO: assuming this will be going away
_head_block_state = chain->head_block_state_legacy();
}

void chain_pacemaker::register_bcast_function(std::function<void(const std::optional<uint32_t>&, const hs_message&)> broadcast_hs_message) {
Expand Down
4 changes: 3 additions & 1 deletion libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ namespace eosio::chain {
block_id_type head_block_id()const;
account_name head_block_producer()const;
const block_header& head_block_header()const;
block_state_legacy_ptr head_block_state()const;
const signed_block_ptr& head_block()const;
// returns nullptr after instant finality enabled
block_state_legacy_ptr head_block_state_legacy()const;

uint32_t fork_db_head_block_num()const;
block_id_type fork_db_head_block_id()const;
Expand Down
7 changes: 7 additions & 0 deletions libraries/chain/include/eosio/chain/producer_schedule.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include <eosio/chain/config.hpp>
#include <eosio/chain/types.hpp>
#include <eosio/chain/block_timestamp.hpp>
#include <chainbase/chainbase.hpp>
#include <eosio/chain/authority.hpp>
#include <eosio/chain/snapshot.hpp>
Expand Down Expand Up @@ -249,6 +250,12 @@ namespace eosio { namespace chain {
uint32_t version = 0; ///< sequentially incrementing version number
vector<producer_authority> producers;

const producer_authority& get_scheduled_producer( block_timestamp_type t )const {
auto index = t.slot % (producers.size() * config::producer_repetitions);
index /= config::producer_repetitions;
return producers[index];
}

friend bool operator == ( const producer_authority_schedule& a, const producer_authority_schedule& b )
{
if( a.version != b.version ) return false;
Expand Down
4 changes: 2 additions & 2 deletions libraries/testing/include/eosio/testing/tester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ namespace eosio { namespace testing {
bool validate() {


auto hbh = control->head_block_state()->header;
auto vn_hbh = validating_node->head_block_state()->header;
const auto& hbh = control->head_block_header();
const auto& vn_hbh = validating_node->head_block_header();
bool ok = control->head_block_id() == validating_node->head_block_id() &&
hbh.previous == vn_hbh.previous &&
hbh.timestamp == vn_hbh.timestamp &&
Expand Down
18 changes: 9 additions & 9 deletions libraries/testing/tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,6 @@ namespace eosio { namespace testing {

signed_block_ptr base_tester::_produce_block( fc::microseconds skip_time, bool skip_pending_trxs,
bool no_throw, std::vector<transaction_trace_ptr>& traces ) {
auto head = control->head_block_state();
auto head_time = control->head_block_time();
auto next_time = head_time + skip_time;

Expand Down Expand Up @@ -438,7 +437,7 @@ namespace eosio { namespace testing {

void base_tester::_start_block(fc::time_point block_time) {
auto head_block_number = control->head_block_num();
auto producer = control->head_block_state()->get_scheduled_producer(block_time);
auto producer = control->active_producers().get_scheduled_producer(block_time);

auto last_produced_block_num = control->last_irreversible_block_num();
auto itr = last_produced_block.find(producer.producer_name);
Expand Down Expand Up @@ -473,16 +472,17 @@ namespace eosio { namespace testing {
signed_block_ptr base_tester::_finish_block() {
FC_ASSERT( control->is_building_block(), "must first start a block before it can be finished" );

auto producer = control->head_block_state()->get_scheduled_producer( control->pending_block_time() );
auto auth = control->pending_block_signing_authority();
auto producer_name = control->pending_block_producer();
vector<private_key_type> signing_keys;

auto default_active_key = get_public_key( producer.producer_name, "active");
producer.for_each_key([&](const public_key_type& key){
auto default_active_key = get_public_key( producer_name, "active");
producer_authority::for_each_key(auth, [&](const public_key_type& key){
const auto& iter = block_signing_private_keys.find(key);
if(iter != block_signing_private_keys.end()) {
signing_keys.push_back(iter->second);
} else if (key == default_active_key) {
signing_keys.emplace_back( get_private_key( producer.producer_name, "active") );
signing_keys.emplace_back( get_private_key( producer_name, "active") );
}
});

Expand All @@ -497,9 +497,9 @@ namespace eosio { namespace testing {
} );

control->commit_block();
last_produced_block[control->head_block_state()->header.producer] = control->head_block_state()->id();
last_produced_block[producer_name] = control->head_block_id();

return control->head_block_state()->block;
return control->head_block();
}

signed_block_ptr base_tester::produce_block( std::vector<transaction_trace_ptr>& traces ) {
Expand Down Expand Up @@ -547,7 +547,7 @@ namespace eosio { namespace testing {
void base_tester::produce_min_num_of_blocks_to_spend_time_wo_inactive_prod(const fc::microseconds target_elapsed_time) {
fc::microseconds elapsed_time;
while (elapsed_time < target_elapsed_time) {
for(uint32_t i = 0; i < control->head_block_state()->active_schedule.producers.size(); i++) {
for(uint32_t i = 0; i < control->active_producers().producers.size(); i++) {
const auto time_to_skip = fc::milliseconds(config::producer_repetitions * config::block_interval_ms);
produce_block(time_to_skip);
elapsed_time += time_to_skip;
Expand Down
61 changes: 30 additions & 31 deletions plugins/producer_plugin/producer_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,9 +734,9 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
handle_error(fc::std_exception_wrapper::from_current_exception(e));
}

const auto& hbs = chain.head_block_state();
const auto& hb = chain.head_block();
now = fc::time_point::now();
if (hbs->header.timestamp.next().to_time_point() >= now) {
if (hb->timestamp.next().to_time_point() >= now) {
_production_enabled = true;
}

Expand All @@ -747,13 +747,14 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
("count", block->transactions.size())("lib", chain.last_irreversible_block_num())
("net", br.total_net_usage)("cpu", br.total_cpu_usage_us)
("elapsed", br.total_elapsed_time)("time", br.total_time)("latency", (now - block->timestamp).count() / 1000));
if (chain.get_read_mode() != db_read_mode::IRREVERSIBLE && hbs->id() != id && hbs->block != nullptr) { // not applied to head
const auto& hb_id = chain.head_block_id();
if (chain.get_read_mode() != db_read_mode::IRREVERSIBLE && hb_id != id && hb != nullptr) { // not applied to head
ilog("Block not applied to head ${id}... #${n} @ ${t} signed by ${p} "
"[trxs: ${count}, lib: ${lib}, net: ${net}, cpu: ${cpu}, elapsed: ${elapsed}, time: ${time}, latency: ${latency} ms]",
("p", hbs->block->producer)("id", hbs->id().str().substr(8, 16))("n", hbs->block_num())("t", hbs->block->timestamp)
("count", hbs->block->transactions.size())("lib", chain.last_irreversible_block_num())
("p", hb->producer)("id", hb_id.str().substr(8, 16))("n", hb->block_num())("t", hb->timestamp)
("count", hb->transactions.size())("lib", chain.last_irreversible_block_num())
("net", br.total_net_usage)("cpu", br.total_cpu_usage_us)("elapsed", br.total_elapsed_time)("time", br.total_time)
("latency", (now - hbs->block->timestamp).count() / 1000));
("latency", (now - hb->timestamp).count() / 1000));
}
}
if (_update_incoming_block_metrics) {
Expand Down Expand Up @@ -1014,14 +1015,10 @@ void new_chain_banner(const eosio::chain::controller& db)
"*******************************\n"
"\n";

if( db.head_block_state()->header.timestamp.to_time_point() < (fc::time_point::now() - fc::milliseconds(200 * config::block_interval_ms)))
{
if( db.head_block_time() < (fc::time_point::now() - fc::milliseconds(200 * config::block_interval_ms))) {
std::cerr << "Your genesis seems to have an old timestamp\n"
"Please consider using the --genesis-timestamp option to give your genesis a recent timestamp\n"
"\n"
;
"Please consider using the --genesis-timestamp option to give your genesis a recent timestamp\n\n";
}
return;
}

producer_plugin::producer_plugin()
Expand Down Expand Up @@ -1776,7 +1773,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
if (!chain_plug->accept_transactions())
return start_block_result::waiting_for_block;

const auto& hbs = chain.head_block_state();
const auto& hb = chain.head_block();

if (chain.get_terminate_at_block() > 0 && chain.get_terminate_at_block() <= chain.head_block_num()) {
ilog("Reached configured maximum block ${num}; terminating", ("num", chain.get_terminate_at_block()));
Expand All @@ -1786,12 +1783,12 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {

const fc::time_point now = fc::time_point::now();
const block_timestamp_type block_time = calculate_pending_block_time();
const uint32_t pending_block_num = hbs->block_num() + 1;
const uint32_t pending_block_num = hb->block_num() + 1;

_pending_block_mode = pending_block_mode::producing;

// Not our turn
const auto& scheduled_producer = hbs->get_scheduled_producer(block_time);
const auto& scheduled_producer = chain.active_producers().get_scheduled_producer(block_time);

const auto current_watermark = _producer_watermarks.get_watermark(scheduled_producer.producer_name);

Expand Down Expand Up @@ -1827,10 +1824,10 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
// determine if our watermark excludes us from producing at this point
if (current_watermark) {
const block_timestamp_type block_timestamp{block_time};
if (current_watermark->first > hbs->block_num()) {
if (current_watermark->first > hb->block_num()) {
elog("Not producing block because \"${producer}\" signed a block at a higher block number (${watermark}) than the current "
"fork's head (${head_block_num})",
("producer", scheduled_producer.producer_name)("watermark", current_watermark->first)("head_block_num", hbs->block_num()));
("producer", scheduled_producer.producer_name)("watermark", current_watermark->first)("head_block_num", hb->block_num()));
_pending_block_mode = pending_block_mode::speculating;
} else if (current_watermark->second >= block_timestamp) {
elog("Not producing block because \"${producer}\" signed a block at the next block time or later (${watermark}) than the pending "
Expand Down Expand Up @@ -1881,22 +1878,23 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
try {
uint16_t blocks_to_confirm = 0;

if (in_producing_mode() && hbs->dpos_irreversible_blocknum != hs_dpos_irreversible_blocknum) { // only if hotstuff not enabled
auto block_state = chain.head_block_state_legacy(); // null means if is active
if (in_producing_mode() && block_state && block_state->dpos_irreversible_blocknum != hs_dpos_irreversible_blocknum) { // only if hotstuff not enabled
// determine how many blocks this producer can confirm
// 1) if it is not a producer from this node, assume no confirmations (we will discard this block anyway)
// 2) if it is a producer on this node that has never produced, the conservative approach is to assume no
// confirmations to make sure we don't double sign after a crash
// 3) if it is a producer on this node where this node knows the last block it produced, safely set it -UNLESS-
// 4) the producer on this node's last watermark is higher (meaning on a different fork)
if (current_watermark) {
auto watermark_bn = current_watermark->first;
if (watermark_bn < hbs->block_num()) {
blocks_to_confirm = (uint16_t)(std::min<uint32_t>(std::numeric_limits<uint16_t>::max(), (uint32_t)(hbs->block_num() - watermark_bn)));
uint32_t watermark_bn = current_watermark->first;
if (watermark_bn < hb->block_num()) {
blocks_to_confirm = (uint16_t)(std::min<uint32_t>(std::numeric_limits<uint16_t>::max(), (hb->block_num() - watermark_bn)));
}
}

// can not confirm irreversible blocks
blocks_to_confirm = (uint16_t)(std::min<uint32_t>(blocks_to_confirm, (uint32_t)(hbs->block_num() - hbs->dpos_irreversible_blocknum)));
blocks_to_confirm = (uint16_t)(std::min<uint32_t>(blocks_to_confirm, (hb->block_num() - block_state->dpos_irreversible_blocknum)));
}

abort_block();
Expand Down Expand Up @@ -1959,7 +1957,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {

try {
chain::subjective_billing& subjective_bill = chain.get_mutable_subjective_billing();
_account_fails.report_and_clear(hbs->block_num(), subjective_bill);
_account_fails.report_and_clear(pending_block_num, subjective_bill);

if (!remove_expired_trxs(preprocess_deadline))
return start_block_result::exhausted;
Expand Down Expand Up @@ -2498,7 +2496,7 @@ void producer_plugin_impl::schedule_production_loop() {
chain::controller& chain = chain_plug->chain();
fc_dlog(_log, "Waiting till another block is received and scheduling Speculative/Production Change");
auto wake_time = block_timing_util::calculate_producer_wake_up_time(_produce_block_cpu_effort, chain.head_block_num(), calculate_pending_block_time(),
_producers, chain.head_block_state()->active_schedule.producers,
_producers, chain.active_producers().producers,
_producer_watermarks);
schedule_delayed_production_loop(weak_from_this(), wake_time);
} else {
Expand All @@ -2517,7 +2515,7 @@ void producer_plugin_impl::schedule_production_loop() {
fc_dlog(_log, "Speculative Block Created; Scheduling Speculative/Production Change");
EOS_ASSERT(chain.is_building_block(), missing_pending_block_state, "speculating without pending_block_state");
auto wake_time = block_timing_util::calculate_producer_wake_up_time(fc::microseconds{config::block_interval_us}, chain.pending_block_num(), chain.pending_block_timestamp(),
_producers, chain.head_block_state()->active_schedule.producers,
_producers, chain.active_producers().producers,
_producer_watermarks);
if (wake_time && fc::time_point::now() > *wake_time) {
// if wake time has already passed then use the block deadline instead
Expand Down Expand Up @@ -2659,26 +2657,27 @@ void producer_plugin_impl::produce_block() {

chain.commit_block();

block_state_legacy_ptr new_bs = chain.head_block_state();
const auto& id = chain.head_block_id();
const auto& new_b = chain.head_block();
producer_plugin::produced_block_metrics metrics;

br.total_time += fc::time_point::now() - start;

ilog("Produced block ${id}... #${n} @ ${t} signed by ${p} "
"[trxs: ${count}, lib: ${lib}, confirmed: ${confs}, net: ${net}, cpu: ${cpu}, elapsed: ${et}, time: ${tt}]",
("p", new_bs->header.producer)("id", new_bs->id().str().substr(8, 16))("n", new_bs->block_num())("t", new_bs->header.timestamp)
("count", new_bs->block->transactions.size())("lib", chain.last_irreversible_block_num())("net", br.total_net_usage)
("cpu", br.total_cpu_usage_us)("et", br.total_elapsed_time)("tt", br.total_time)("confs", new_bs->header.confirmed));
("p", new_b->producer)("id", id.str().substr(8, 16))("n", new_b->block_num())("t", new_b->timestamp)
("count", new_b->transactions.size())("lib", chain.last_irreversible_block_num())("net", br.total_net_usage)
("cpu", br.total_cpu_usage_us)("et", br.total_elapsed_time)("tt", br.total_time)("confs", new_b->confirmed));

_time_tracker.add_other_time();
_time_tracker.report(new_bs->block_num(), new_bs->block->producer, metrics);
_time_tracker.report(new_b->block_num(), new_b->producer, metrics);
_time_tracker.clear();

if (_update_produced_block_metrics) {
metrics.unapplied_transactions_total = _unapplied_transactions.size();
metrics.subjective_bill_account_size_total = chain.get_subjective_billing().get_account_cache_size();
metrics.scheduled_trxs_total = chain.db().get_index<generated_transaction_multi_index, by_delay>().size();
metrics.trxs_produced_total = new_bs->block->transactions.size();
metrics.trxs_produced_total = new_b->transactions.size();
metrics.cpu_usage_us = br.total_cpu_usage_us;
metrics.total_elapsed_time_us = br.total_elapsed_time.count();
metrics.total_time_us = br.total_time.count();
Expand Down
7 changes: 4 additions & 3 deletions plugins/state_history_plugin/state_history_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,11 @@ void state_history_plugin_impl::plugin_startup() {
try {
const auto& chain = chain_plug->chain();
update_current();
auto bsp = chain.head_block_state();
if( bsp && chain_state_log && chain_state_log->empty() ) {
const auto& b = chain.head_block();
const auto& id = chain.head_block_id();
if( chain_state_log && chain_state_log->empty() ) {
fc_ilog( _log, "Storing initial state on startup, this can take a considerable amount of time" );
store_chain_state( bsp->id(), bsp->header, bsp->block_num() );
store_chain_state( id, *b, b->block_num() );
fc_ilog( _log, "Done storing initial state on startup" );
}
first_available_block = chain.earliest_available_block_num();
Expand Down
2 changes: 1 addition & 1 deletion tests/test_chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ class chain_plugin_tester : public validating_tester {
}
produce_blocks( 250 );

auto producer_keys = control->head_block_state()->active_schedule.producers;
auto producer_keys = control->active_producers().producers;
BOOST_CHECK_EQUAL( 21u, producer_keys.size() );
BOOST_CHECK_EQUAL( name("defproducera"), producer_keys[0].producer_name );

Expand Down
Loading

0 comments on commit fffbe1e

Please sign in to comment.