-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
There is a subtle divergence from the consensus mechanism as outlined in the tendermint paper and the mechanism as implemented in this codebase that was discovered in discussion with @milosevic @josef-widder and @cmwaters .
In the paper, once a correct process has 'locked a block' that process will never clear the lockedBlock field during a run of consensus for a height. It may replace the lockedBlock when +2/3 prevotes are seen for a different block, but it will never end up with a nil lockedBlock. The only place that the lockedBlock is updated within run of consensus for a given height is on line 38 of the algorithm.
The go implementation modifies this lockedBlock value in an additional place. The go implementation nils out the lockedBlock if the process saw +2/3 prevotes for nil in state.go.
This logic of nil-ing out the locked block should be removed to bring the code in line with the spec. To do this, we should ensure there is a test for the current behavior of setting lockedBlock to nil when +2/3 are seen. We should then remove the logic, ensure that the test fails, and then invert the test to check that the block does not become unlocked.