@@ -53,6 +53,7 @@ use crate::error::{BlockError, Error};
5353use crate :: transaction:: { SignedTransaction , UnverifiedTransaction } ;
5454use crate :: views:: BlockView ;
5555use crate :: BlockId ;
56+ use std:: cell:: Cell ;
5657
5758type SpawnResult = (
5859 JoinHandle < ( ) > ,
@@ -75,9 +76,7 @@ struct Worker {
7576 /// Consensus step.
7677 step : TendermintState ,
7778 /// Record current round's received votes as bit set
78- votes_received : BitSet ,
79- /// The votes_received field is changed after last state broadcast.
80- votes_received_changed : bool ,
79+ votes_received : MutTrigger < BitSet > ,
8180 /// Vote accumulator.
8281 votes : VoteCollector ,
8382 /// Used to sign messages and proposals.
@@ -193,8 +192,7 @@ impl Worker {
193192 last_confirmed_view : 0 ,
194193 validators,
195194 extension,
196- votes_received : BitSet :: new ( ) ,
197- votes_received_changed : false ,
195+ votes_received : MutTrigger :: new ( BitSet :: new ( ) ) ,
198196 time_gap_params,
199197 timeout_token_nonce : ENGINE_TIMEOUT_TOKEN_NONCE_BASE ,
200198 }
@@ -577,13 +575,13 @@ impl Worker {
577575 . unwrap ( ) ;
578576 }
579577
580- fn broadcast_state ( & self , vote_step : VoteStep , proposal : Option < H256 > , lock_view : Option < View > , votes : BitSet ) {
578+ fn broadcast_state ( & self , vote_step : VoteStep , proposal : Option < H256 > , lock_view : Option < View > , votes : & BitSet ) {
581579 self . extension
582580 . send ( network:: Event :: BroadcastState {
583581 vote_step,
584582 proposal,
585583 lock_view,
586- votes,
584+ votes : * votes ,
587585 } )
588586 . unwrap ( ) ;
589587 }
@@ -618,7 +616,7 @@ impl Worker {
618616 cinfo ! ( ENGINE , "increment_view: New view." ) ;
619617 self . view += n;
620618 self . proposal = Proposal :: None ;
621- self . votes_received = BitSet :: new ( ) ;
619+ self . votes_received = MutTrigger :: new ( BitSet :: new ( ) ) ;
622620 }
623621
624622 fn move_to_height ( & mut self , height : Height ) {
@@ -628,7 +626,7 @@ impl Worker {
628626 self . height = height;
629627 self . view = 0 ;
630628 self . proposal = Proposal :: None ;
631- self . votes_received = BitSet :: new ( ) ;
629+ self . votes_received = MutTrigger :: new ( BitSet :: new ( ) ) ;
632630 }
633631
634632 #[ allow( clippy:: cognitive_complexity) ]
@@ -655,15 +653,15 @@ impl Worker {
655653 // Also, when moving to the commit step,
656654 // keep `votes_received` for gossiping.
657655 if prev_step. to_step ( ) != state. to_step ( ) && !state. is_commit ( ) {
658- self . votes_received = BitSet :: new ( ) ;
656+ self . votes_received = MutTrigger :: new ( BitSet :: new ( ) ) ;
659657 }
660658
661659 // need to reset vote
662660 self . broadcast_state (
663661 vote_step,
664662 self . proposal . block_hash ( ) ,
665663 self . last_two_thirds_majority . view ( ) ,
666- self . votes_received ,
664+ self . votes_received . borrow_anyway ( ) ,
667665 ) ;
668666 match state. to_step ( ) {
669667 Step :: Propose => {
@@ -931,10 +929,6 @@ impl Worker {
931929 return
932930 }
933931 }
934-
935- // self.move_to_step() calls self.broadcast_state()
936- // If self.move_to_step() is not called, call self.broadcast_state() in here.
937- self . votes_received_changed = true ;
938932 }
939933
940934 pub fn on_imported_proposal ( & mut self , proposal : & Header ) {
@@ -1248,13 +1242,12 @@ impl Worker {
12481242 }
12491243
12501244 if token == ENGINE_TIMEOUT_BROADCAST_STEP_STATE {
1251- if self . votes_received_changed {
1252- self . votes_received_changed = false ;
1245+ if let Some ( votes_received) = self . votes_received . borrow_if_mutated ( ) {
12531246 self . broadcast_state (
12541247 self . vote_step ( ) ,
12551248 self . proposal . block_hash ( ) ,
12561249 self . last_two_thirds_majority . view ( ) ,
1257- self . votes_received ,
1250+ votes_received,
12581251 ) ;
12591252 }
12601253 return
@@ -1749,7 +1742,7 @@ impl Worker {
17491742 VoteStep :: new ( self . height , self . view , self . step . to_step ( ) ) ,
17501743 self . proposal . block_hash ( ) ,
17511744 self . last_two_thirds_majority . view ( ) ,
1752- self . votes_received ,
1745+ self . votes_received . borrow_anyway ( ) ,
17531746 ) ;
17541747 }
17551748
@@ -1824,8 +1817,7 @@ impl Worker {
18241817 BitSet :: new ( )
18251818 } ;
18261819
1827- let current_votes = self . votes_received ;
1828- let difference = & peer_known_votes - & current_votes;
1820+ let difference = & peer_known_votes - & self . votes_received ;
18291821 if !difference. is_empty ( ) {
18301822 self . send_request_messages ( token, current_vote_step, difference, & result) ;
18311823 }
@@ -2095,7 +2087,7 @@ impl Worker {
20952087 // Since we don't have proposal vote, set proposal = None
20962088 self . proposal = Proposal :: None ;
20972089 self . view = commit_view;
2098- self . votes_received = vote_bitset;
2090+ self . votes_received = MutTrigger :: new ( vote_bitset) ;
20992091 self . last_two_thirds_majority = TwoThirdsMajority :: Empty ;
21002092
21012093 self . move_to_step (
@@ -2121,3 +2113,46 @@ fn calculate_score(height: Height, view: View) -> U256 {
21212113 let height = U256 :: from ( height) ;
21222114 u256_from_u128 ( std:: u128:: MAX ) * height - view
21232115}
2116+
2117+ struct MutTrigger < T > {
2118+ target : T ,
2119+ deref_mut_triggered : Cell < bool > ,
2120+ }
2121+
2122+ impl < T > MutTrigger < T > {
2123+ fn new ( target : T ) -> Self {
2124+ Self {
2125+ target,
2126+ deref_mut_triggered : Cell :: new ( true ) ,
2127+ }
2128+ }
2129+
2130+ fn borrow_if_mutated ( & self ) -> Option < & T > {
2131+ if self . deref_mut_triggered . get ( ) {
2132+ self . deref_mut_triggered . set ( false ) ;
2133+ Some ( & self . target )
2134+ } else {
2135+ None
2136+ }
2137+ }
2138+
2139+ fn borrow_anyway ( & self ) -> & T {
2140+ self . deref_mut_triggered . set ( false ) ;
2141+ & self . target
2142+ }
2143+ }
2144+
2145+ impl < T > std:: ops:: Deref for MutTrigger < T > {
2146+ type Target = T ;
2147+
2148+ fn deref ( & self ) -> & Self :: Target {
2149+ & self . target
2150+ }
2151+ }
2152+
2153+ impl < T > std:: ops:: DerefMut for MutTrigger < T > {
2154+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
2155+ self . deref_mut_triggered . set ( true ) ;
2156+ & mut self . target
2157+ }
2158+ }
0 commit comments