@@ -137,8 +137,6 @@ pub(crate) struct SingleHeightConsensus {
137137 state_machine : StateMachine ,
138138 // Tracks rounds for which we started validating a proposal to avoid duplicate validations.
139139 pending_validation_rounds : HashSet < Round > ,
140- last_prevote : Option < Vote > ,
141- last_precommit : Option < Vote > ,
142140}
143141
144142impl SingleHeightConsensus {
@@ -154,14 +152,7 @@ impl SingleHeightConsensus {
154152 let n_validators =
155153 u64:: try_from ( validators. len ( ) ) . expect ( "Should have way less than u64::MAX validators" ) ;
156154 let state_machine = StateMachine :: new ( height, id, n_validators, is_observer, quorum_type) ;
157- Self {
158- validators,
159- timeouts,
160- state_machine,
161- pending_validation_rounds : HashSet :: new ( ) ,
162- last_prevote : None ,
163- last_precommit : None ,
164- }
155+ Self { validators, timeouts, state_machine, pending_validation_rounds : HashSet :: new ( ) }
165156 }
166157
167158 pub ( crate ) fn current_round ( & self ) -> Round {
@@ -242,7 +233,7 @@ impl SingleHeightConsensus {
242233 self . handle_timeout ( context, event) . await
243234 }
244235 StateMachineEvent :: Prevote ( vote) => {
245- let Some ( last_vote) = & self . last_prevote else {
236+ let Some ( last_vote) = self . state_machine . last_self_prevote ( ) else {
246237 return Err ( ConsensusError :: InternalInconsistency (
247238 "No prevote to send" . to_string ( ) ,
248239 ) ) ;
@@ -252,14 +243,14 @@ impl SingleHeightConsensus {
252243 return Ok ( ShcReturn :: Tasks ( Vec :: new ( ) ) ) ;
253244 }
254245 trace_every_n_sec ! ( REBROADCAST_LOG_PERIOD_SECS , "Rebroadcasting {last_vote:?}" ) ;
255- context. broadcast ( last_vote. clone ( ) ) . await ?;
246+ context. broadcast ( last_vote) . await ?;
256247 Ok ( ShcReturn :: Tasks ( vec ! [ ShcTask :: Prevote (
257248 self . timeouts. prevote_timeout,
258249 StateMachineEvent :: Prevote ( vote) ,
259250 ) ] ) )
260251 }
261252 StateMachineEvent :: Precommit ( vote) => {
262- let Some ( last_vote) = & self . last_precommit else {
253+ let Some ( last_vote) = self . state_machine . last_self_precommit ( ) else {
263254 return Err ( ConsensusError :: InternalInconsistency (
264255 "No precommit to send" . to_string ( ) ,
265256 ) ) ;
@@ -269,7 +260,7 @@ impl SingleHeightConsensus {
269260 return Ok ( ShcReturn :: Tasks ( Vec :: new ( ) ) ) ;
270261 }
271262 trace_every_n_sec ! ( REBROADCAST_LOG_PERIOD_SECS , "Rebroadcasting {last_vote:?}" ) ;
272- context. broadcast ( last_vote. clone ( ) ) . await ?;
263+ context. broadcast ( last_vote) . await ?;
273264 Ok ( ShcReturn :: Tasks ( vec ! [ ShcTask :: Precommit (
274265 self . timeouts. precommit_timeout,
275266 StateMachineEvent :: Precommit ( vote) ,
@@ -488,37 +479,18 @@ impl SingleHeightConsensus {
488479 context : & mut ContextT ,
489480 vote : Vote ,
490481 ) -> Result < Vec < ShcTask > , ConsensusError > {
491- let ( last_vote, task) = match vote. vote_type {
492- VoteType :: Prevote => (
493- & mut self . last_prevote ,
494- ShcTask :: Prevote (
495- self . timeouts . prevote_timeout ,
496- StateMachineEvent :: Prevote ( vote. clone ( ) ) ,
497- ) ,
482+ let task = match vote. vote_type {
483+ VoteType :: Prevote => ShcTask :: Prevote (
484+ self . timeouts . prevote_timeout ,
485+ StateMachineEvent :: Prevote ( vote. clone ( ) ) ,
498486 ) ,
499- VoteType :: Precommit => (
500- & mut self . last_precommit ,
501- ShcTask :: Precommit (
502- self . timeouts . precommit_timeout ,
503- StateMachineEvent :: Precommit ( vote. clone ( ) ) ,
504- ) ,
487+ VoteType :: Precommit => ShcTask :: Precommit (
488+ self . timeouts . precommit_timeout ,
489+ StateMachineEvent :: Precommit ( vote. clone ( ) ) ,
505490 ) ,
506491 } ;
507492 // Ensure the voter matches this node.
508493 assert_eq ! ( vote. voter, self . state_machine. id( ) ) ;
509- * last_vote = match last_vote {
510- None => Some ( vote. clone ( ) ) ,
511- Some ( last_vote) if vote. round > last_vote. round => Some ( vote. clone ( ) ) ,
512- Some ( _) => {
513- // According to the Tendermint paper, the state machine should only vote for its
514- // current round. It should monotonically increase its round. It should only vote
515- // once per step.
516- return Err ( ConsensusError :: InternalInconsistency ( format ! (
517- "State machine must progress in time: last_vote: {last_vote:?} new_vote: \
518- {vote:?}",
519- ) ) ) ;
520- }
521- } ;
522494
523495 info ! ( "Broadcasting {vote:?}" ) ;
524496 context. broadcast ( vote) . await ?;
0 commit comments