You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rebroadcast immediately once a round threshold is met (#1003)
* Rebroadcast immediately once a round threshold is met
The original GPBFT protocol dictates that the rebroadcast only gets
triggered after the phase timeout has expired. This is reasonable for
low number of rounds, where the vast majority of instances finalize
within a single round. However, there is an edge-case where when an
instance enters more than a few rounds the exponential increase of phase
timeout results in extended periods of total radio silence.
As a result, the state propagation is hindered greatly, which in turn
increases the chances of the instance taking even longer to finalize.
The changes here introduce a threshold at which rebroadcast is scheduled
without waiting for phase timeout to expire first (defaulting to 3). In
this design, the rebroadcast and successive rebroadcasts work exactly
the same way as dictated in GPBFT design, except the trigger is adjsuted
to consider rounds larger than the threshold as "insufficient progress".
The implementation reverts back to the vanilla GPBFT phase timeout as
the phases progress and resets rebroadcast parameters accordingly
A test is added to assert that when an instance skips to future rounds,
rebroadcast is triggered without wait, and continues to do so after
phase change.
* Refine logging
// The rebroadcast timeout is set before the phase timeout; therefore, it should
962
+
// trigger before the phase timeout. Override the alarm with rebroadcast timeout
963
+
// and check for phase timeout in the next cycle of rebroadcast.
964
+
i.participant.host.SetAlarm(i.rebroadcastTimeout)
965
+
i.log("scheduled initial rebroadcast at %v before phase timeout at %v", i.rebroadcastTimeout, i.phaseTimeout)
966
+
} else {
967
+
// The phase timeout is set before the rebroadcast timeout. Therefore, there must
968
+
// have been an alarm set already for the phase. Do nothing, because the GPBFT
969
+
// process loop will trigger the phase alarm, which in turn tries the current
970
+
// phase and eventually will try rebroadcast.
971
+
//
972
+
// Therefore, reset the rebroadcast parameters to re-attempt setting the initial
973
+
// rebroadcast timeout once the phase expires.
974
+
i.log("Resetting rebroadcast as rebroadcast timeout at %v is after phase timeout at %v and the current phase has not timed out yet.", i.rebroadcastTimeout, i.phaseTimeout)
975
+
i.resetRebroadcastParams()
976
+
}
953
977
casei.rebroadcastTimeoutElapsed():
954
978
// Rebroadcast now that the corresponding timeout has elapsed, and schedule the
955
979
// successive rebroadcast.
@@ -958,13 +982,27 @@ func (i *instance) tryRebroadcast() {
958
982
959
983
// Use current host time as the offset for the next alarm to assure that rate of
960
984
// broadcasted messages grows relative to the actual time at which an alarm is
961
-
// triggered, not the absolute alarm time. This would avoid a "runaway
985
+
// triggered, not the absolute alarm time. This would avoid a "runaway
962
986
// rebroadcast" scenario where rebroadcast timeout consistently remains behind
963
987
// current time due to the discrepancy between set alarm time and the actual time
0 commit comments