It seems fairly simple to extend this algorithm to be live in partial synchrony - unless I’m missing something.
One simple approach is: if a newly added block does not finalize any previous blocks in its chain, increase the length of the timeout d
by some constant. As soon as any new block is finalized, set d
back to its base value.
Another possible approach (that is closer to the Exponential epoch backoff) would be doubling d
at the end of a period of N
blocks in which nothing new has been finalized, and setting d
back to its base value when something is finalized.
In the case of no finality, both strategies will continue to increase the timeout until it is greater than network latency, in which case blocks can again be finalized.