Skip to content

Commit 5062e37

Browse files
committed
Split last_confirmed_view variable
Tendermint worker's last_confirmed_view is used for two purposes. One is the previous height's finalized view, and the other one is the current height's finalized view. This commit is part of splitting the last_confirmed_view variable.
1 parent e96dc62 commit 5062e37

File tree

1 file changed

+59
-31
lines changed

1 file changed

+59
-31
lines changed

core/src/consensus/tendermint/worker.rs

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,11 @@ struct Worker {
8585
last_two_thirds_majority: TwoThirdsMajority,
8686
/// hash of the proposed block, used for seal submission.
8787
proposal: Proposal,
88-
/// The last confirmed view from the commit step.
89-
last_confirmed_view: View,
88+
/// The finalized view of the previous height's block.
89+
/// The signatures for the previous block is signed for the view below.
90+
finalized_view_of_previous_block: View,
91+
/// The finalized view of the current height's block.
92+
finalized_view_of_current_block: Option<View>,
9093
/// Set used to determine the current validators.
9194
validators: Arc<DynamicValidator>,
9295
/// Channel to the network extension, must be set later.
@@ -187,7 +190,8 @@ impl Worker {
187190
signer: Default::default(),
188191
last_two_thirds_majority: TwoThirdsMajority::Empty,
189192
proposal: Proposal::None,
190-
last_confirmed_view: 0,
193+
finalized_view_of_previous_block: 0,
194+
finalized_view_of_current_block: None,
191195
validators,
192196
extension,
193197
votes_received: MutTrigger::new(BitSet::new()),
@@ -418,7 +422,11 @@ impl Worker {
418422
return false
419423
}
420424

421-
let vote_step = VoteStep::new(self.height, self.last_confirmed_view, Step::Precommit);
425+
let vote_step = VoteStep::new(
426+
self.height,
427+
self.finalized_view_of_current_block.expect("finalized_view_of_current_height is not None in Commit state"),
428+
Step::Precommit,
429+
);
422430
if self.step.is_commit_timedout() && self.check_current_block_exists() {
423431
cinfo!(ENGINE, "Transition to Propose because best block is changed after commit timeout");
424432
return true
@@ -597,8 +605,10 @@ impl Worker {
597605
self.client().update_sealing(BlockId::Hash(parent_block_hash), true);
598606
}
599607

600-
fn save_last_confirmed_view(&mut self, view: View) {
601-
self.last_confirmed_view = view;
608+
/// Do we need this function?
609+
fn set_finalized_view_in_current_height(&mut self, view: View) {
610+
assert_eq!(self.finalized_view_of_current_block, None);
611+
self.finalized_view_of_current_block = Some(view);
602612
}
603613

604614
fn increment_view(&mut self, n: View) {
@@ -608,14 +618,37 @@ impl Worker {
608618
self.votes_received = MutTrigger::new(BitSet::new());
609619
}
610620

611-
fn move_to_height(&mut self, height: Height) {
621+
/// Move to the next height.
622+
fn move_to_the_next_height(&mut self) {
623+
assert!(
624+
self.step.is_commit(),
625+
"move_to_the_next_height should be called in Commit state, but the current step is {:?}",
626+
self.step
627+
);
628+
cinfo!(ENGINE, "Transitioning to height {}.", self.height + 1);
629+
self.last_two_thirds_majority = TwoThirdsMajority::Empty;
630+
self.height += 1;
631+
self.view = 0;
632+
self.proposal = Proposal::None;
633+
self.votes_received = MutTrigger::new(BitSet::new());
634+
self.finalized_view_of_previous_block =
635+
self.finalized_view_of_current_block.expect("self.step == Step::Commit");
636+
self.finalized_view_of_current_block = None;
637+
}
638+
639+
/// Jump to the height.
640+
/// This function is called when new blocks are received from block sync.
641+
/// This function could be called at any state.
642+
fn jump_to_height(&mut self, height: Height, finalized_view_of_previous_height: View) {
612643
assert!(height > self.height, "{} < {}", height, self.height);
613644
cinfo!(ENGINE, "Transitioning to height {}.", height);
614645
self.last_two_thirds_majority = TwoThirdsMajority::Empty;
615646
self.height = height;
616647
self.view = 0;
617648
self.proposal = Proposal::None;
618649
self.votes_received = MutTrigger::new(BitSet::new());
650+
self.finalized_view_of_previous_block = finalized_view_of_previous_height;
651+
self.finalized_view_of_current_block = None;
619652
}
620653

621654
#[allow(clippy::cognitive_complexity)]
@@ -736,7 +769,7 @@ impl Worker {
736769
Step::Commit => {
737770
cinfo!(ENGINE, "move_to_step: Commit.");
738771
let (view, block_hash) = state.committed().expect("commit always has committed_view");
739-
self.save_last_confirmed_view(view);
772+
self.set_finalized_view_in_current_height(view);
740773

741774
let proposal_received = self.is_proposal_received(self.height, view, block_hash);
742775
let proposal_imported = self.client().block(&block_hash.into()).is_some();
@@ -850,8 +883,7 @@ impl Worker {
850883
&& has_enough_aligned_votes
851884
{
852885
if self.can_move_from_commit_to_propose() {
853-
let height = self.height;
854-
self.move_to_height(height + 1);
886+
self.move_to_the_next_height();
855887
self.move_to_step(TendermintState::Propose, is_restoring);
856888
return
857889
}
@@ -957,9 +989,11 @@ impl Worker {
957989
_ => {}
958990
};
959991
} else if current_height < height {
960-
self.move_to_height(height);
961-
let prev_block_view = TendermintSealView::new(proposal.seal()).previous_block_view().unwrap();
962-
self.save_last_confirmed_view(prev_block_view);
992+
let finalized_view_of_previous_height =
993+
TendermintSealView::new(proposal.seal()).previous_block_view().unwrap();
994+
995+
self.jump_to_height(height, finalized_view_of_previous_height);
996+
963997
let proposal_is_for_view0 = self.votes.has_votes_for(
964998
&VoteStep {
965999
height,
@@ -981,8 +1015,8 @@ impl Worker {
9811015
view: &self.view,
9821016
step: &self.step.to_step(),
9831017
votes: &self.votes.get_all(),
984-
finalized_view_of_previous_block: &self.last_confirmed_view,
985-
finalized_view_of_current_block: &Some(self.last_confirmed_view),
1018+
finalized_view_of_previous_block: &self.finalized_view_of_previous_block,
1019+
finalized_view_of_current_block: &self.finalized_view_of_current_block,
9861020
});
9871021
}
9881022

@@ -1002,12 +1036,9 @@ impl Worker {
10021036
self.step = backup_step;
10031037
self.height = backup.height;
10041038
self.view = backup.view;
1005-
if backup.step == Step::Commit {
1006-
self.last_confirmed_view =
1007-
backup.finalized_view_of_current_block.expect("In commit step the finalized view exist")
1008-
} else {
1009-
self.last_confirmed_view = backup.finalized_view_of_previous_block;
1010-
}
1039+
self.finalized_view_of_previous_block = backup.finalized_view_of_previous_block;
1040+
self.finalized_view_of_current_block = backup.finalized_view_of_current_block;
1041+
10111042
if let Some(proposal) = backup.proposal {
10121043
if client.block(&BlockId::Hash(proposal)).is_some() {
10131044
self.proposal = Proposal::ProposalImported(proposal);
@@ -1045,7 +1076,7 @@ impl Worker {
10451076

10461077
let view = self.view;
10471078

1048-
let last_block_view = &self.last_confirmed_view;
1079+
let last_block_view = &self.finalized_view_of_previous_block;
10491080
assert_eq!(self.prev_block_hash(), parent_hash);
10501081

10511082
let (precommits, precommit_indices) = self
@@ -1305,8 +1336,7 @@ impl Worker {
13051336
return
13061337
}
13071338

1308-
let height = self.height;
1309-
self.move_to_height(height + 1);
1339+
self.move_to_the_next_height();
13101340
TendermintState::Propose
13111341
}
13121342
TendermintState::CommitTimedout {
@@ -1374,7 +1404,7 @@ impl Worker {
13741404
// the previous step. So, act as the last precommit step.
13751405
VoteStep {
13761406
height: self.height,
1377-
view: self.last_confirmed_view,
1407+
view: self.finalized_view_of_current_block.expect("self.step == Step::Commit"),
13781408
step: Step::Precommit,
13791409
}
13801410
} else {
@@ -1585,8 +1615,7 @@ impl Worker {
15851615
if enacted.first() == Some(&committed_block_hash) {
15861616
cdebug!(ENGINE, "Committed block {} is now the best block", committed_block_hash);
15871617
if self.can_move_from_commit_to_propose() {
1588-
let new_height = self.height + 1;
1589-
self.move_to_height(new_height);
1618+
self.move_to_the_next_height();
15901619
self.move_to_step(TendermintState::Propose, false);
15911620
return
15921621
}
@@ -1612,11 +1641,10 @@ impl Worker {
16121641
let full_header = header.decode();
16131642
if self.height < header.number() {
16141643
cinfo!(ENGINE, "Received a commit: {:?}.", header.number());
1615-
let prev_block_view = TendermintSealView::new(full_header.seal())
1644+
let finalized_view_of_previous_height = TendermintSealView::new(full_header.seal())
16161645
.previous_block_view()
16171646
.expect("Imported block already checked");
1618-
self.move_to_height(header.number());
1619-
self.save_last_confirmed_view(prev_block_view);
1647+
self.jump_to_height(header.number(), finalized_view_of_previous_height);
16201648
}
16211649
}
16221650
if height_at_begin != self.height {
@@ -1809,7 +1837,7 @@ impl Worker {
18091837
// the previous step. So, act as the last precommit step.
18101838
VoteStep {
18111839
height: self.height,
1812-
view: self.last_confirmed_view,
1840+
view: self.finalized_view_of_current_block.expect("self.step == Step::Commit"),
18131841
step: Step::Precommit,
18141842
}
18151843
} else {

0 commit comments

Comments
 (0)