Chain halt due to unbounded votes by proposer
Description
Due to a lack of validation, the number of votes that can be included in MsgAddVote
is limitless. As such, this poses problems as attestations that were registered are deleted after a certain block window. As there is no penalty to double voting and the maximum block size is 100 MB, these unbounded computations in halo's EndBlocker
could result in several issues.
func (k *Keeper) deleteBefore(ctx context.Context, height uint64) error {
...
for iter.Next() {
...
// Delete signatures
if err := k.sigTable.DeleteBy(ctx, SignatureAttIdIndexKey{}.WithAttId(att.GetId())); err != nil {
return errors.Wrap(err, "delete sigs")
}
// Delete attestation
err = k.attTable.Delete(ctx, att)
if err != nil {
return errors.Wrap(err, "delete att")
}
}
Impact
A malicious proposer could propose a block with up to ~100 MB of votes. This large computation could result in a liveness issue with the processing of votes, which would result in a consensus failure and an eventual chain halt.
Recommendations
Harden the vote verification to ensure that only votes that were in the voting rounds can be proposed. This includes ensuring that double voting cannot happen and that the vote limit cannot be bypassed.
Remediation
This was remediated in commit c4050e17668423f2447b3c223eac1d9a7b5d8728↗ by hardening the vote verification. This included preventing double signing, applying the vote extension limit on the votes and also fixed an issue that would allow proposers to submit votes for unsupported ConfLevels allowing proposers to insert invalid votes on chain without risking slashing.