Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/hotshot/new-protocol/bench/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ async fn build_coordinator(
genesis_state,
Leaf2::from(genesis_proposal.clone()),
);
consensus.seed_genesis(genesis_cert1, genesis_proposal);
consensus.seed_parent(genesis_cert1, genesis_proposal);

let proposal_validator =
ProposalValidator::new(membership.clone(), epoch_height, upgrade_lock.clone());
Expand Down
22 changes: 9 additions & 13 deletions crates/hotshot/new-protocol/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,20 +272,16 @@ impl<T: NodeType> Consensus<T> {
}
}

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

/// Apply a [`PreCutoverSeed`] to bridge legacy state into the new
Expand Down
47 changes: 25 additions & 22 deletions crates/hotshot/new-protocol/src/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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);
consensus.set_view(anchor_view, anchor_epoch);

let lock = upgrade_lock.clone();
Self::builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub async fn build_test_coordinator<N: Network<TestTypes>>(
genesis_state,
Leaf2::from(genesis_proposal.clone()),
);
consensus.seed_genesis(genesis_cert1.clone(), genesis_proposal.clone());
consensus.seed_parent(genesis_cert1.clone(), genesis_proposal.clone());

if let Some(seed) = pre_cutover_seed {
consensus.apply_pre_cutover_seed(seed);
Expand Down
2 changes: 1 addition & 1 deletion crates/hotshot/new-protocol/src/tests/legacy_cutover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ async fn build_cutover_coordinator(
genesis_state,
Leaf2::from(genesis_proposal.clone()),
);
consensus.seed_genesis(genesis_cert1, genesis_proposal);
consensus.seed_parent(genesis_cert1, genesis_proposal);

let block_builder = BlockBuilder::new(
instance.clone(),
Expand Down
Loading