pub async fn decide_from_proposal<TYPES: NodeType>(
    proposal: &QuorumProposal<TYPES>,
    consensus: OuterConsensus<TYPES>,
    existing_upgrade_cert: Arc<RwLock<Option<UpgradeCertificate<TYPES>>>>,
    public_key: &TYPES::SignatureKey
) -> LeafChainTraversalOutcome<TYPES>
Expand description

Ascends the leaf chain by traversing through the parent commitments of the proposal. We begin by obtaining the parent view, and if we are in a chain (i.e. the next view from the parent is one view newer), then we begin attempting to form the chain. This is a direct impl from HotStuff section 5:

When a node b* carries a QC that refers to a direct parent, i.e., b*.justify.node = b*.parent, we say that it forms a One-Chain. Denote by b’’ = b*.justify.node. Node b* forms a Two-Chain, if in addition to forming a One-Chain, b’‘.justify.node = b’‘.parent. It forms a Three-Chain, if b’’ forms a Two-Chain.

We follow this exact logic to determine if we are able to reach a commit and a decide. A commit is reached when we have a two chain, and a decide is reached when we have a three chain.

§Example

Suppose we have a decide for view 1, and we then move on to get undecided views 2, 3, and 4. Further, suppose that our next proposal is for view 5, but this leader did not see info for view 4, so the justify qc of the proposal points to view 3. This is fine, and the undecided chain now becomes 2-3-5.

Assuming we continue with honest leaders, we then eventually could get a chain like: 2-3-5-6-7-8. This will prompt a decide event to occur (this code), where the proposal is for view 8. Now, since the lowest value in the 3-chain here would be 5 (excluding 8 since we only walk the parents), we begin at the first link in the chain, and walk back through all undecided views, making our new anchor view 5, and out new locked view will be 6.

Upon receipt then of a proposal for view 9, assuming it is valid, this entire process will repeat, and the anchor view will be set to view 6, with the locked view as view 7.