-
Notifications
You must be signed in to change notification settings - Fork 791
Description
This code skips updating total_missed in case witness_missed.owner == b.owner. To fix the bug, transform from:
if( witness_missed.owner != b.witness )
{
modify(witness_missed, [&](witness_object& w)
{
w.total_missed++;
if( has_hf_14 ) { if( last_old_enough ) { shutdown_witness } }
}
}
to:
modify(witness_missed, [&](witness_object& w)
{
w.total_missed++;
if( witness_missed.owner != b.witness )
{
if( has_hf_14 ) { if( last_old_enough ) { shutdown_witness } }
}
}
We can collapse these three checks to a single if statement with a conjunction (AND) of these three conditions, reordered any we like, and I like this ordering:
modify(witness_missed, [&](witness_object& w)
{
w.total_missed++;
if( last_old_enough
&& witness_missed.owner != b.witness
&& has_hf_14 )
{ shutdown_witness }
}
The idea behind this reordering is that, by deferring the hardfork check (involving an object lookup) until the last, we might well avoid it entirely if one of the other checks fails (the other two checks are both only integer arithmetic and reading fields from objects already available).
I'd really like to get rid of the witness_missed.owner != b.owner check, but I realized we cannot remove it, otherwise the network might be bricked if all of the witnesses miss enough blocks to get shut down, then start producing again.