Skip to content

Commit 403f2e6

Browse files
authored
[new-protocol] seed parent proposal from anchor leaf so leader can propose after restart (#4440)
* seed parent proposal from anchor leaf so leader can propose after restart * use proposal view number
1 parent 809b0a1 commit 403f2e6

5 files changed

Lines changed: 37 additions & 38 deletions

File tree

crates/hotshot/new-protocol/bench/src/node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ async fn build_coordinator(
175175
genesis_state,
176176
Leaf2::from(genesis_proposal.clone()),
177177
);
178-
consensus.seed_genesis(genesis_cert1, genesis_proposal);
178+
consensus.seed_parent(genesis_cert1, genesis_proposal);
179179

180180
let proposal_validator =
181181
ProposalValidator::new(membership.clone(), epoch_height, upgrade_lock.clone());

crates/hotshot/new-protocol/src/consensus.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -272,20 +272,16 @@ impl<T: NodeType> Consensus<T> {
272272
}
273273
}
274274

275-
/// Seed the genesis state so that the view-1 leader can propose without
276-
/// any external bootstrap injection.
277-
///
278-
/// Stores a genesis certificate and proposal at view 0, sets the locked
279-
/// certificate, and sets the current epoch. After calling this, a
280-
/// subsequent `apply` that triggers `maybe_propose(view=1)` will find the
275+
/// Seed a parent certificate and proposal so the leader of the *next* view
276+
/// can propose without any external bootstrap injection.
277+
/// Sets the locked certificate and current epoch. After calling this, a
278+
/// subsequent `apply` that triggers `maybe_propose` will find the
281279
/// parent cert and proposal it needs.
282-
pub fn seed_genesis(&mut self, genesis_cert1: Certificate1<T>, genesis_proposal: Proposal<T>) {
283-
self.current_epoch = Some(genesis_proposal.epoch);
284-
self.certs
285-
.insert(ViewNumber::genesis(), genesis_cert1.clone());
286-
self.locked_cert = Some(genesis_cert1);
287-
self.proposals
288-
.insert(ViewNumber::genesis(), genesis_proposal);
280+
pub fn seed_parent(&mut self, cert1: Certificate1<T>, proposal: Proposal<T>) {
281+
self.current_epoch = Some(proposal.epoch);
282+
self.certs.insert(cert1.view_number(), cert1.clone());
283+
self.locked_cert = Some(cert1);
284+
self.proposals.insert(proposal.view_number, proposal);
289285
}
290286

291287
/// Apply a [`PreCutoverSeed`] to bridge legacy state into the new

crates/hotshot/new-protocol/src/coordinator.rs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -134,38 +134,41 @@ where
134134
initializer.epoch_height,
135135
);
136136

137-
let genesis_cert1 = initializer.high_qc.clone();
138-
let genesis_proposal = message::Proposal {
139-
block_header: initializer.anchor_leaf.block_header().clone(),
140-
view_number: ViewNumber::genesis(),
141-
epoch: EpochNumber::genesis(),
142-
justify_qc: genesis_cert1.clone(),
137+
let anchor_leaf = &initializer.anchor_leaf;
138+
let anchor_view = anchor_leaf.view_number();
139+
let anchor_epoch = anchor_leaf
140+
.epoch(initializer.epoch_height)
141+
.unwrap_or(EpochNumber::genesis());
142+
let cert1 = initializer.high_qc.clone();
143+
let parent_proposal = message::Proposal {
144+
block_header: anchor_leaf.block_header().clone(),
145+
view_number: anchor_view,
146+
epoch: anchor_epoch,
147+
justify_qc: anchor_leaf.justify_qc(),
143148
next_epoch_justify_qc: None,
144-
upgrade_certificate: None,
145-
view_change_evidence: None,
146-
next_drb_result: None,
149+
upgrade_certificate: anchor_leaf.upgrade_certificate(),
150+
view_change_evidence: anchor_leaf
151+
.view_change_evidence
152+
.clone()
153+
.and_then(|e| match e {
154+
hotshot_types::data::ViewChangeEvidence2::Timeout(tc) => Some(tc),
155+
hotshot_types::data::ViewChangeEvidence2::ViewSync(_) => None,
156+
}),
157+
next_drb_result: anchor_leaf.next_drb_result,
147158
state_cert: None,
148159
};
160+
149161
let mut state_manager = StateManager::new(
150162
Arc::new(initializer.instance_state.clone()),
151163
upgrade_lock.clone(),
152164
);
153165
state_manager.seed_state(
154-
initializer.anchor_leaf.view_number(),
155-
initializer.anchor_state.clone(),
156-
initializer.anchor_leaf.clone(),
157-
);
158-
// The synthetic genesis proposal has a non-null justify_qc (the genesis
159-
// cert1) so the leaf derived from it has a different commitment than
160-
// the anchor leaf produced by `Leaf2::genesis`. `request_header` for
161-
// view 1 looks up the parent state by the *proposal's* leaf
162-
// commitment, so seed the same state under that commitment too.
163-
state_manager.seed_state(
164-
ViewNumber::genesis(),
166+
anchor_view,
165167
initializer.anchor_state.clone(),
166-
Leaf2::from(genesis_proposal.clone()),
168+
anchor_leaf.clone(),
167169
);
168-
consensus.seed_genesis(genesis_cert1, genesis_proposal);
170+
consensus.seed_parent(cert1, parent_proposal);
171+
consensus.set_view(anchor_view, anchor_epoch);
169172

170173
let lock = upgrade_lock.clone();
171174
Self::builder()

crates/hotshot/new-protocol/src/tests/common/coordinator_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub async fn build_test_coordinator<N: Network<TestTypes>>(
118118
genesis_state,
119119
Leaf2::from(genesis_proposal.clone()),
120120
);
121-
consensus.seed_genesis(genesis_cert1.clone(), genesis_proposal.clone());
121+
consensus.seed_parent(genesis_cert1.clone(), genesis_proposal.clone());
122122

123123
if let Some(seed) = pre_cutover_seed {
124124
consensus.apply_pre_cutover_seed(seed);

crates/hotshot/new-protocol/src/tests/legacy_cutover.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ async fn build_cutover_coordinator(
275275
genesis_state,
276276
Leaf2::from(genesis_proposal.clone()),
277277
);
278-
consensus.seed_genesis(genesis_cert1, genesis_proposal);
278+
consensus.seed_parent(genesis_cert1, genesis_proposal);
279279

280280
let block_builder = BlockBuilder::new(
281281
instance.clone(),

0 commit comments

Comments
 (0)