Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Producer plugin #7791

Merged
merged 7 commits into from
Aug 26, 2019
Merged
Changes from 6 commits
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
31 changes: 15 additions & 16 deletions plugins/producer_plugin/producer_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1322,12 +1322,6 @@ fc::time_point producer_plugin_impl::calculate_block_deadline( const fc::time_po
return block_time + fc::microseconds(last_block ? _last_block_time_offset_us : _produce_time_offset_us);
}

enum class tx_category {
PERSISTED,
UNEXPIRED_UNPERSISTED
};


producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
chain::controller& chain = chain_plug->chain();

Expand All @@ -1336,17 +1330,18 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {

const auto& hbs = chain.head_block_state();

fc_dlog(_log, "Starting block ${n} at ${time}", ("n", hbs->block_num + 1)("time", fc::time_point::now()));

//Schedule for the next second's tick regardless of chain state
// If we would wait less than 50ms (1/10 of block_interval), wait for the whole block interval.
const fc::time_point now = fc::time_point::now();
const fc::time_point block_time = calculate_pending_block_time();

_pending_block_mode = pending_block_mode::producing;

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

fc_dlog(_log, "Starting block #${n} at ${time} producer ${p}",
("n", hbs->block_num + 1)("time", now)("p", scheduled_producer.producer_name));

auto current_watermark = get_watermark(scheduled_producer.producer_name);

size_t num_relevant_signatures = 0;
Expand Down Expand Up @@ -1597,7 +1592,6 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
continue; // do not allow schedule and execute in same block
}
if( scheduled_trx_deadline <= fc::time_point::now() ) {
exhausted = true;
break;
}

Expand Down Expand Up @@ -1625,7 +1619,6 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
}

if (scheduled_trx_deadline <= fc::time_point::now()) {
exhausted = true;
break;
}

Expand Down Expand Up @@ -1680,13 +1673,16 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
_incoming_trx_weight = 0.0;

if (!_pending_incoming_transactions.empty()) {
fc_dlog(_log, "Processing ${n} pending transactions", ("n", _pending_incoming_transactions.size()));
size_t processed = 0;
fc_dlog(_log, "Processing ${n} pending transactions", ("n", orig_pending_txn_size));
while (orig_pending_txn_size && _pending_incoming_transactions.size()) {
if (preprocess_deadline <= fc::time_point::now()) return start_block_result::exhausted;
auto e = _pending_incoming_transactions.pop_front();
--orig_pending_txn_size;
process_incoming_transaction_async(std::get<0>(e), std::get<1>(e), std::get<2>(e));
++processed;
}
fc_dlog(_log, "Processed ${n} pending transactions, ${p} left", ("n", processed)("p", _pending_incoming_transactions.size()));
}
return start_block_result::succeeded;
}
Expand Down Expand Up @@ -1750,9 +1746,13 @@ void producer_plugin_impl::schedule_production_loop() {
auto expect_time = chain.pending_block_time() - fc::microseconds(config::block_interval_us);
// ship this block off up to 1 block time earlier or immediately
if (fc::time_point::now() >= expect_time) {
_timer.expires_from_now( boost::posix_time::microseconds( 0 ));
fc_dlog(_log, "Scheduling Block Production on Exhausted Block #${num} immediately",
// produce block immediately
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I cannot find a direct reason this is an issue, there are a few implicit requirements that this may one day run-afoul of that I think we should attempt to make more explicit

  1. schedule_production_loop is almost always called from a destructor of an fc::scoped_exit which means it really shouldn't throw (maybe one day we should consider requiring noexcept qualifiers on lambdas for fc::scoped_exit). Right now, maybe_produce_block` appears to handle all of the exceptions and is clean but I'd be interested in how we make sure the implicit requirement that it not throw is made explicit.

  2. maybe_produce_block calls schedule_production_loop making this recursive. I don't think it can get into an infinite recursion because this branch is taken based on time but, there are a lot of variables and if this stays direct, perhaps we should "schedule" the call to schedule_production_loop in maybe_produce_block so that it at least clears the stack ?

at the least we should probably make the log messages the same (other than the notice about exhaustion) and turn the call and the fc_dlogcalls into a local lambda so that the messages are kept consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted this change as I think it is clearer and more consistent the way it was.

fc_dlog(_log, "Completing Block Production on Exhausted Block #${num} immediately",
("num", chain.head_block_num()+1));
fc_dlog( _log, "Produce block for ${num} running at ${time}", ("num", chain.head_block_num()+1)("time", fc::time_point::now()) );
auto res = maybe_produce_block();
fc_dlog( _log, "Producing Block #${num} returned: ${res}", ("num", chain.head_block_num()+1)( "res", res ) );
return;
} else {
_timer.expires_at(epoch + boost::posix_time::microseconds(expect_time.time_since_epoch().count()));
fc_dlog(_log, "Scheduling Block Production on Exhausted Block #${num} at ${time}",
Expand Down Expand Up @@ -1786,9 +1786,8 @@ void producer_plugin_impl::schedule_delayed_production_loop(const std::weak_ptr<
for (const auto&p: _producers) {
auto next_producer_block_time = calculate_next_block_time(p, current_block_time);
if (next_producer_block_time) {
auto producer_wake_up_time = *next_producer_block_time - fc::microseconds(config::block_interval_us);
auto producer_wake_up_time = *next_producer_block_time;
if (wake_up_time) {
// wake up with a full block interval to the deadline
wake_up_time = std::min<fc::time_point>(*wake_up_time, producer_wake_up_time);
} else {
wake_up_time = producer_wake_up_time;
Expand Down