This document describes how operations which change the identity table are applied to the protocol state, and provides proofs demonstrating that these rules result in only valid and correct identity table snapshots being stored by honest actors.
There are two broad kinds of identity-changing operation:
It is important to note the causal dependency between the block payload and Protocol State:
<aside> 📌 The field $\texttt{ProtocolStateID}$ is the root hash of the resulting protocol state after applying the identity-changing operations from the block payload.
This reasoning extends to the Identity Table, as it is part of the protocol state.
</aside>
We denote the protocol state that is referenced by some block $B$ as $B.\texttt{ProtocolState}$. The following two safety-critical rules need to be carefully considered.
All ProtocolState-changing operations that are contained in block $B$ only take effect at $B$’s child block(s). In other words, the processing of $B$’s payload is governed by the output Protocol State from its parent block (block $A$ in our example).
On a semantical level, $\texttt{QC}_B$ (certifying block $B$) belongs to block $B$. $\texttt{QC}_B$ is verified wrt. the same Protocol State that also governed the processing of $B$’s payload, i.e. $A.\texttt{ProtocolState}$ (the output protocol state from processing block $A$’s payload).
It is merely an optimization that QCs are distributed as part of the child blocks in Jolteon and later HotStuff versions.
To allow trustless light clients that do not download all blocks, the following is a universal safety requirement:
A proposed identity table (here, a new protocol state) must be certified by the appointed consensus committee (via a QC) before the proposed committee gains signing authority.
The alternative would be a design, where $\texttt{QC}_B$ considered valid, it it complies with $B.\texttt{ProtocolState}$. In other words, the block itself can declare which nodes (and keys) are valid to approve it — an devastating vulnerability in the presence of byzantine block proposers.
We emphasize that the argument of causality is strictly limited to the payload. Sealing is essentially augmenting execution results incorporated in ancestor blocks. For causality, the sealing process (determining the seals to be included in block $B$) cannot be contingent on the output protocol state $B.\texttt{ProtocolState}$.
Whether or not we require the inclusion of execution receipts and collections to be contingent on $B.\texttt{ProtocolState}$ is an open degree of freedom. Conceptually, both conventions are possible but might significantly differ in engineering complexity.