@@ -34,7 +34,7 @@ use super::message::*;
3434use super :: params:: TimeoutParams ;
3535use super :: types:: { PeerState , Step , View } ;
3636use super :: worker;
37- use crate :: consensus:: { EngineError , PriorityInfo } ;
37+ use crate :: consensus:: { EngineError , Priority , PriorityInfo } ;
3838
3939use super :: {
4040 ENGINE_TIMEOUT_BROADCAST_STEP_STATE , ENGINE_TIMEOUT_BROADCAT_STEP_STATE_INTERVAL , ENGINE_TIMEOUT_TOKEN_NONCE_BASE ,
@@ -154,21 +154,25 @@ impl TendermintExtension {
154154 }
155155 }
156156
157- fn request_proposal_to_any ( & self , round : SortitionRound ) {
158- for ( token, peer) in & self . peers {
159- let is_future_height_and_view = round < peer. vote_step . into ( ) ;
160-
161- if is_future_height_and_view {
162- self . request_proposal ( token, round) ;
163- continue
164- }
165-
166- let is_same_height_and_view = round == peer. vote_step . into ( ) ;
167-
168- if is_same_height_and_view && peer. proposal . is_some ( ) {
169- self . request_proposal ( token, round) ;
170- }
171- }
157+ fn request_proposal_to_superiors ( & self , round : SortitionRound , my_highest : Option < Priority > ) {
158+ // Request to future round peers
159+ self . peers
160+ . iter ( )
161+ . filter ( |( _, peer) | round < peer. vote_step . into ( ) )
162+ . for_each ( |( token, _) | self . request_proposal ( token, round) ) ;
163+
164+ let current_round_peers = self . peers . iter ( ) . filter ( |( _, peer) | round == peer. vote_step . into ( ) ) ;
165+ // Request to current round higher peers
166+ if let Some ( current_round_highest_priority) = current_round_peers
167+ . clone ( )
168+ . map ( |( _id, peer) | peer. priority ( ) )
169+ . max ( )
170+ . filter ( |highest_priority| * highest_priority > my_highest)
171+ {
172+ current_round_peers
173+ . filter ( |( _id, peer) | peer. priority ( ) == current_round_highest_priority)
174+ . for_each ( |( token, _) | self . request_proposal ( token, round) )
175+ } ;
172176 }
173177
174178 fn request_proposal ( & self , token : & NodeId , round : SortitionRound ) {
@@ -301,21 +305,44 @@ impl NetworkExtension<Event> for TendermintExtension {
301305 lock_view,
302306 known_votes,
303307 ) ;
304- self . update_peer_state ( token, vote_step, ( * proposal) . clone ( ) , known_votes) ;
305- let ( result, receiver) = crossbeam:: unbounded ( ) ;
306- self . inner
307- . send ( worker:: Event :: StepState {
308- token : * token,
309- vote_step,
310- proposal : * proposal,
311- lock_view,
312- known_votes : Box :: from ( known_votes) ,
313- result,
314- } )
315- . unwrap ( ) ;
316-
317- while let Ok ( message) = receiver. recv ( ) {
318- self . api . send ( token, Arc :: new ( message) ) ;
308+ let unchanged = match self . peers . get ( token) {
309+ Some ( peer_state) => * proposal == peer_state. proposal ,
310+ None => false ,
311+ } ;
312+ let verified = unchanged || {
313+ ( * proposal)
314+ . clone ( )
315+ . map ( |summary| {
316+ let ( result, receiver) = crossbeam:: bounded ( 1 ) ;
317+ self . inner
318+ . send ( worker:: Event :: VerifyPriorityInfo {
319+ height : vote_step. height ,
320+ view : vote_step. view ,
321+ priority_info : summary. priority_info ,
322+ result,
323+ } )
324+ . unwrap ( ) ;
325+ receiver. recv ( ) . unwrap ( ) . unwrap_or ( false )
326+ } )
327+ . unwrap_or ( true )
328+ } ;
329+ if verified {
330+ self . update_peer_state ( token, vote_step, ( * proposal) . clone ( ) , known_votes) ;
331+ let ( result, receiver) = crossbeam:: unbounded ( ) ;
332+ self . inner
333+ . send ( worker:: Event :: StepState {
334+ token : * token,
335+ vote_step,
336+ proposal : * proposal,
337+ lock_view,
338+ known_votes : Box :: from ( known_votes) ,
339+ result,
340+ } )
341+ . unwrap ( ) ;
342+
343+ while let Ok ( message) = receiver. recv ( ) {
344+ self . api . send ( token, Arc :: new ( message) ) ;
345+ }
319346 }
320347 }
321348 Ok ( TendermintMessage :: RequestProposal {
@@ -420,10 +447,11 @@ impl NetworkExtension<Event> for TendermintExtension {
420447 } => {
421448 self . request_messages_to_all ( vote_step, requested_votes) ;
422449 }
423- Event :: RequestProposalToAny {
450+ Event :: RequestProposalToSuperiors {
424451 round,
452+ current_highest,
425453 } => {
426- self . request_proposal_to_any ( round) ;
454+ self . request_proposal_to_superiors ( round, current_highest ) ;
427455 }
428456 Event :: SetTimerStep {
429457 step,
@@ -456,8 +484,9 @@ pub enum Event {
456484 vote_step : VoteStep ,
457485 requested_votes : BitSet ,
458486 } ,
459- RequestProposalToAny {
487+ RequestProposalToSuperiors {
460488 round : SortitionRound ,
489+ current_highest : Option < Priority > ,
461490 } ,
462491 SetTimerStep {
463492 step : Step ,
0 commit comments