From f978fd91831acc7944c667cddbe27fd1d8bb8fae Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Tue, 24 Jul 2018 16:55:25 -0400 Subject: [PATCH] Resolve stalling producer schedule upgrade due to speculation The producer_plugin was calculating the "next time to produce" for a producer taking into account the effects of the current speculative block on the producer schedule. As that block is speculative, it may not happen. In the case where it did not happen this calculated value would be wrong potentially causing a producer to sleep through its rightful time to produce. If all of the producers that could provide the last confirming block for a pending->active upgrade were in this state the upgrade stalled out. In normal operation, you can predict wake up assuming the block is _not_ going to arrive because when the block arrives we recalculate. --- plugins/producer_plugin/producer_plugin.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 51d6d5d1b..d4be760a0 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -769,9 +769,11 @@ producer_plugin::greylist_params producer_plugin::get_greylist() const { optional producer_plugin_impl::calculate_next_block_time(const account_name& producer_name) const { chain::controller& chain = app().get_plugin().chain(); + const auto& hbs = chain.head_block_state(); + const auto& active_schedule = hbs->active_schedule.producers; + const auto& pbs = chain.pending_block_state(); - const auto& active_schedule = pbs->active_schedule.producers; - const auto& hbt = pbs->header.timestamp; + const auto& pbt = pbs->header.timestamp; // determine if this producer is in the active schedule and if so, where auto itr = std::find_if(active_schedule.begin(), active_schedule.end(), [&](const auto& asp){ return asp.producer_name == producer_name; }); @@ -798,7 +800,7 @@ optional producer_plugin_impl::calculate_next_block_time(const a } // this producers next opportuity to produce is the next time its slot arrives after or at the calculated minimum - uint32_t minimum_slot = hbt.slot + minimum_offset; + uint32_t minimum_slot = pbt.slot + minimum_offset; size_t minimum_slot_producer_index = (minimum_slot % (active_schedule.size() * config::producer_repetitions)) / config::producer_repetitions; if ( producer_index == minimum_slot_producer_index ) { // this is the producer for the minimum slot, go with that -- GitLab