-
Notifications
You must be signed in to change notification settings - Fork 173
[new-protocol] seed parent proposal from anchor leaf so leader can propose after restart #4440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -134,38 +134,41 @@ where | |
| initializer.epoch_height, | ||
| ); | ||
|
|
||
| let genesis_cert1 = initializer.high_qc.clone(); | ||
| let genesis_proposal = message::Proposal { | ||
| block_header: initializer.anchor_leaf.block_header().clone(), | ||
| view_number: ViewNumber::genesis(), | ||
| epoch: EpochNumber::genesis(), | ||
| justify_qc: genesis_cert1.clone(), | ||
| let anchor_leaf = &initializer.anchor_leaf; | ||
| let anchor_view = anchor_leaf.view_number(); | ||
| let anchor_epoch = anchor_leaf | ||
| .epoch(initializer.epoch_height) | ||
| .unwrap_or(EpochNumber::genesis()); | ||
| let cert1 = initializer.high_qc.clone(); | ||
| let parent_proposal = message::Proposal { | ||
| block_header: anchor_leaf.block_header().clone(), | ||
| view_number: anchor_view, | ||
| epoch: anchor_epoch, | ||
| justify_qc: anchor_leaf.justify_qc(), | ||
| next_epoch_justify_qc: None, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit (correctness at epoch boundaries): This likely doesn't matter if the anchor_leaf is never at an epoch boundary when this code path runs, but worth keeping in mind. |
||
| upgrade_certificate: None, | ||
| view_change_evidence: None, | ||
| next_drb_result: None, | ||
| upgrade_certificate: anchor_leaf.upgrade_certificate(), | ||
| view_change_evidence: anchor_leaf | ||
| .view_change_evidence | ||
| .clone() | ||
| .and_then(|e| match e { | ||
| hotshot_types::data::ViewChangeEvidence2::Timeout(tc) => Some(tc), | ||
| hotshot_types::data::ViewChangeEvidence2::ViewSync(_) => None, | ||
| }), | ||
| next_drb_result: anchor_leaf.next_drb_result, | ||
| state_cert: None, | ||
| }; | ||
|
|
||
| let mut state_manager = StateManager::new( | ||
| Arc::new(initializer.instance_state.clone()), | ||
| upgrade_lock.clone(), | ||
| ); | ||
| state_manager.seed_state( | ||
| initializer.anchor_leaf.view_number(), | ||
| initializer.anchor_state.clone(), | ||
| initializer.anchor_leaf.clone(), | ||
| ); | ||
| // The synthetic genesis proposal has a non-null justify_qc (the genesis | ||
| // cert1) so the leaf derived from it has a different commitment than | ||
| // the anchor leaf produced by `Leaf2::genesis`. `request_header` for | ||
| // view 1 looks up the parent state by the *proposal's* leaf | ||
| // commitment, so seed the same state under that commitment too. | ||
| state_manager.seed_state( | ||
| ViewNumber::genesis(), | ||
| anchor_view, | ||
| initializer.anchor_state.clone(), | ||
| Leaf2::from(genesis_proposal.clone()), | ||
| anchor_leaf.clone(), | ||
| ); | ||
| consensus.seed_genesis(genesis_cert1, genesis_proposal); | ||
| consensus.seed_parent(cert1, parent_proposal); | ||
|
Comment on lines
+142
to
+170
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question (correctness): } else if proposal_commitment(proposal) != parent_cert.data.leaf_commit {
warn!("stored proposal at parent_view does not match parent cert's leaf_commit; refusing to propose with mismatched parent");
return;
Is there an invariant guaranteeing |
||
| consensus.set_view(anchor_view, anchor_epoch); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good addition — previously |
||
|
|
||
| let lock = upgrade_lock.clone(); | ||
| Self::builder() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The generalization from
seed_genesistoseed_parentlooks clean. One thing the doc could mention: this method assumescert1.view_number()matchesproposal.view_number(i.e., the cert certifies the leaf derived from this proposal). If they can legitimately differ, the method will store the proposal under a view key that doesn't match its ownview_numberfield, which will trip the commitment check inmaybe_propose.