@@ -21,8 +21,8 @@ use std::time::Duration;
2121
2222use ccore:: encoded:: Header as EncodedHeader ;
2323use ccore:: {
24- Block , BlockChainClient , BlockChainTrait , BlockId , BlockImportError , ChainNotify , Client , ImportBlock , ImportError ,
25- UnverifiedTransaction ,
24+ Block , BlockChainClient , BlockChainTrait , BlockId , BlockImportError , BlockStatus , ChainNotify , Client , ImportBlock ,
25+ ImportError , UnverifiedTransaction ,
2626} ;
2727use cmerkle:: TrieFactory ;
2828use cnetwork:: { Api , EventSender , NetworkExtension , NodeId } ;
@@ -76,6 +76,7 @@ pub struct Extension {
7676 client : Arc < Client > ,
7777 api : Box < dyn Api > ,
7878 last_request : u64 ,
79+ nonce : u64 ,
7980}
8081
8182impl Extension {
@@ -126,6 +127,7 @@ impl Extension {
126127 client,
127128 api,
128129 last_request : Default :: default ( ) ,
130+ nonce : Default :: default ( ) ,
129131 }
130132 }
131133
@@ -146,6 +148,14 @@ impl Extension {
146148 }
147149
148150 fn send_body_request ( & mut self , id : & NodeId ) {
151+ if let Some ( downloader) = self . header_downloaders . get ( & id) {
152+ if self . client . block_status ( & BlockId :: Hash ( downloader. best_hash ( ) ) ) == BlockStatus :: InChain {
153+ // Peer is lagging behind the local blockchain.
154+ // We don't need to request block bodies to this peer
155+ return
156+ }
157+ }
158+
149159 self . check_sync_variable ( ) ;
150160 if let Some ( requests) = self . requests . get_mut ( id) {
151161 let have_body_request = {
@@ -243,14 +253,15 @@ impl NetworkExtension<Event> for Extension {
243253 id,
244254 Arc :: new (
245255 Message :: Status {
246- total_score : chain_info . best_proposal_score ,
256+ nonce : U256 :: from ( self . nonce ) ,
247257 best_hash : chain_info. best_proposal_block_hash ,
248258 genesis_hash : chain_info. genesis_hash ,
249259 }
250260 . rlp_bytes ( )
251261 . into_vec ( ) ,
252262 ) ,
253263 ) ;
264+ self . nonce += 1 ;
254265 let t = self . connected_nodes . insert ( * id) ;
255266 debug_assert ! ( t, "{} is already added to peer list" , id) ;
256267
@@ -299,10 +310,10 @@ impl NetworkExtension<Event> for Extension {
299310 if let Ok ( received_message) = UntrustedRlp :: new ( data) . as_val ( ) {
300311 match received_message {
301312 Message :: Status {
302- total_score ,
313+ nonce ,
303314 best_hash,
304315 genesis_hash,
305- } => self . on_peer_status ( id, total_score , best_hash, genesis_hash) ,
316+ } => self . on_peer_status ( id, nonce , best_hash, genesis_hash) ,
306317 Message :: Request ( request_id, request) => self . on_peer_request ( id, request_id, request) ,
307318 Message :: Response ( request_id, response) => self . on_peer_response ( id, request_id, response) ,
308319 }
@@ -328,7 +339,6 @@ impl NetworkExtension<Event> for Extension {
328339 }
329340 State :: SnapshotChunk ( ..) => unimplemented ! ( ) ,
330341 State :: Full => {
331- let best_proposal_score = self . client . chain_info ( ) . best_proposal_score ;
332342 for id in & peer_ids {
333343 let request =
334344 self . header_downloaders . get_mut ( id) . and_then ( HeaderDownloader :: create_request) ;
@@ -339,15 +349,7 @@ impl NetworkExtension<Event> for Extension {
339349 }
340350
341351 for id in peer_ids {
342- let peer_score = if let Some ( peer) = self . header_downloaders . get ( & id) {
343- peer. total_score ( )
344- } else {
345- U256 :: zero ( )
346- } ;
347-
348- if peer_score > best_proposal_score {
349- self . send_body_request ( & id) ;
350- }
352+ self . send_body_request ( & id) ;
351353 }
352354 }
353355 }
@@ -501,20 +503,21 @@ impl Extension {
501503 id,
502504 Arc :: new (
503505 Message :: Status {
504- total_score : chain_info . best_proposal_score ,
506+ nonce : U256 :: from ( self . nonce ) ,
505507 best_hash : chain_info. best_proposal_block_hash ,
506508 genesis_hash : chain_info. genesis_hash ,
507509 }
508510 . rlp_bytes ( )
509511 . into_vec ( ) ,
510512 ) ,
511513 ) ;
514+ self . nonce += 1 ;
512515 }
513516 }
514517}
515518
516519impl Extension {
517- fn on_peer_status ( & mut self , from : & NodeId , total_score : U256 , best_hash : BlockHash , genesis_hash : BlockHash ) {
520+ fn on_peer_status ( & mut self , from : & NodeId , nonce : U256 , best_hash : BlockHash , genesis_hash : BlockHash ) {
518521 // Validity check
519522 if genesis_hash != self . client . chain_info ( ) . genesis_hash {
520523 cinfo ! ( SYNC , "Genesis hash mismatch with peer {}" , from) ;
@@ -523,17 +526,17 @@ impl Extension {
523526
524527 match self . header_downloaders . entry ( * from) {
525528 Entry :: Occupied ( mut peer) => {
526- if !peer. get_mut ( ) . update ( total_score , best_hash) {
529+ if !peer. get_mut ( ) . update ( nonce , best_hash) {
527530 // FIXME: It should be an error level if the consensus is PoW.
528531 cdebug ! ( SYNC , "Peer #{} status updated but score is less than before" , from) ;
529532 return
530533 }
531534 }
532535 Entry :: Vacant ( e) => {
533- e. insert ( HeaderDownloader :: new ( self . client . clone ( ) , total_score , best_hash) ) ;
536+ e. insert ( HeaderDownloader :: new ( self . client . clone ( ) , nonce , best_hash) ) ;
534537 }
535538 }
536- cinfo ! ( SYNC , "Peer #{} status update: total_score : {}, best_hash: {}" , from, total_score , best_hash) ;
539+ cinfo ! ( SYNC , "Peer #{} status update: nonce : {}, best_hash: {}" , from, nonce , best_hash) ;
537540 }
538541
539542 fn on_peer_request ( & self , from : & NodeId , id : u64 , request : RequestMessage ) {
@@ -759,14 +762,12 @@ impl Extension {
759762 }
760763 State :: SnapshotChunk ( ..) => { }
761764 State :: Full => {
762- let ( mut completed, pivot_score_changed) = if let Some ( peer) = self . header_downloaders . get_mut ( from) {
763- let before_pivot_score = peer. pivot_score ( ) ;
765+ let ( mut completed, peer_is_caught_up) = if let Some ( peer) = self . header_downloaders . get_mut ( from) {
764766 let encoded: Vec < _ > = headers. iter ( ) . map ( |h| EncodedHeader :: new ( h. rlp_bytes ( ) . to_vec ( ) ) ) . collect ( ) ;
765767 peer. import_headers ( & encoded) ;
766- let after_pivot_score = peer. pivot_score ( ) ;
767- ( peer. downloaded ( ) , before_pivot_score != after_pivot_score)
768+ ( peer. downloaded ( ) , peer. is_caught_up ( ) )
768769 } else {
769- ( Vec :: new ( ) , false )
770+ ( Vec :: new ( ) , true )
770771 } ;
771772 completed. sort_unstable_by_key ( EncodedHeader :: number) ;
772773
@@ -792,7 +793,7 @@ impl Extension {
792793 peer. mark_as_imported ( exists) ;
793794 peer. create_request ( )
794795 } ) ;
795- if pivot_score_changed {
796+ if !peer_is_caught_up {
796797 if let Some ( request) = request {
797798 self . send_header_request ( from, request) ;
798799 }
@@ -834,20 +835,11 @@ impl Extension {
834835 }
835836 }
836837
837- let total_score = self . client . chain_info ( ) . best_proposal_score ;
838838 let mut peer_ids: Vec < _ > = self . header_downloaders . keys ( ) . cloned ( ) . collect ( ) ;
839839 peer_ids. shuffle ( & mut thread_rng ( ) ) ;
840840
841841 for id in peer_ids {
842- let peer_score = if let Some ( peer) = self . header_downloaders . get ( & id) {
843- peer. total_score ( )
844- } else {
845- U256 :: zero ( )
846- } ;
847-
848- if peer_score > total_score {
849- self . send_body_request ( & id) ;
850- }
842+ self . send_body_request ( & id) ;
851843 }
852844 }
853845}
0 commit comments