First, a part that is easier to fix: in this lineblock should be replaced with b.
Note that this line is incorrect with respect to our intention, but in reality it should not cause much trouble, since among the blocks that are committed with a single call to commit_block, only block can have associated validator set updates.
Secondly, even with the fix mentioned above we can face a possibly liveness-threatening situation. On committing a block b, the pending validator set updates associated with b are deleted from the BlockTree. When a child block of b is proposed, safe_qc returns true, since the justify is a commit QC and there are validator set updates associated with b in the BlockTree. Then b is committed and its pending validator set updates deleted. However, if another child block of b is proposed, the safe_qc (and hence safe_block) check will fail because the validator set updates associated with b have already been deleted.
In case the first child of b that was proposed cannot be committed, for instance because the proposal was only broadcasted to selected validators by a byzantine node, the validators that have inserted this block cannot insert any other conflicting block, hence this is a potential liveness threat.
The issue is twofold.
First, a part that is easier to fix: in this line
block
should be replaced withb
. Note that this line is incorrect with respect to our intention, but in reality it should not cause much trouble, since among the blocks that are committed with a single call tocommit_block
, onlyblock
can have associated validator set updates.Secondly, even with the fix mentioned above we can face a possibly liveness-threatening situation. On committing a block
b
, the pending validator set updates associated with b are deleted from theBlockTree
. When a child block ofb
is proposed,safe_qc
returns true, since the justify is a commit QC and there are validator set updates associated withb
in theBlockTree
. Thenb
is committed and its pending validator set updates deleted. However, if another child block ofb
is proposed, thesafe_qc
(and hencesafe_block
) check will fail because the validator set updates associated withb
have already been deleted.For reference:
In case the first child of
b
that was proposed cannot be committed, for instance because the proposal was only broadcasted to selected validators by a byzantine node, the validators that have inserted this block cannot insert any other conflicting block, hence this is a potential liveness threat.