Prior to this patch bip8 allows for states to go STARTED -> FAILING -> ACTIVE in which case the last block of FAILING state signalling or not signalling would change the consensus rules applied to the very next block. This potentially gives very little warning of an upgrade.
Additionally, if it is desirable to reduce the timeoutheight for a bip8 deployment (for example from X to Y, Y < X), then activation via lockinontimeout at the shorter height would not result in consistent consensus rules. In particular, implementations would see:
- timeoutheight=Y, lockinontimeout=true: height Y-2016: STARTED, height Y: LOCKED_IN, height Y+2016: ACTIVE
- timeoutheight=Y, lockinontimeout=false: height Y-2016: STARTED, height Y: FAILING, height Y+2016: ACTIVE
- timeoutheight=X, lockinontimeout=*: height Y-2016: STARTED, height Y: STARTED, height Y+2016: LOCKED_IN, height Y+4032: ACTIVE
This patch also reduces the number of blocks that must signal during the new MUST_SIGNAL phase from the current 100% requirement to the same requirement as needed to trigger from STARTED to LOCKED_IN; this ensures that provided the same threshold is used, if the deployment transitions to LOCKED_IN at height X for any bip8 deployment, it will transition to LOCKED_IN at height X for every bip8 deployment, given the same startheight and timeoutheight > X.
It also uses the MUST_SIGNAL state to trigger validation rules checking blocks signal. It would be possible to use these rules for checking if reindexing is necessary -- if you added an "impossible" transition from MUST_SIGNAL to INVALID if the threshold isn't met, then reindexing necessary precisely when the current block is INVALID, or MUST_SIGNAL and fails validation, and you need to reindex back to the last STARTED/DEFINED block.