@@ -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 } ;
@@ -74,6 +74,7 @@ pub struct Extension {
7474 client : Arc < Client > ,
7575 api : Box < dyn Api > ,
7676 last_request : u64 ,
77+ nonce : u64 ,
7778}
7879
7980impl Extension {
@@ -124,6 +125,7 @@ impl Extension {
124125 client,
125126 api,
126127 last_request : Default :: default ( ) ,
128+ nonce : Default :: default ( ) ,
127129 }
128130 }
129131
@@ -144,6 +146,14 @@ impl Extension {
144146 }
145147
146148 fn send_body_request ( & mut self , id : & NodeId ) {
149+ if let Some ( downloader) = self . header_downloaders . get ( & id) {
150+ if self . client . block_status ( & BlockId :: Hash ( downloader. best_hash ( ) ) ) == BlockStatus :: InChain {
151+ // Peer is lagging behind the local blockchain.
152+ // We don't need to request block bodies to this peer
153+ return
154+ }
155+ }
156+
147157 self . check_sync_variable ( ) ;
148158 if let Some ( requests) = self . requests . get_mut ( id) {
149159 let have_body_request = {
@@ -241,14 +251,15 @@ impl NetworkExtension<Event> for Extension {
241251 id,
242252 Arc :: new (
243253 Message :: Status {
244- total_score : chain_info . best_proposal_score ,
254+ nonce : U256 :: from ( self . nonce ) ,
245255 best_hash : chain_info. best_proposal_block_hash ,
246256 genesis_hash : chain_info. genesis_hash ,
247257 }
248258 . rlp_bytes ( )
249259 . into_vec ( ) ,
250260 ) ,
251261 ) ;
262+ self . nonce += 1 ;
252263 let t = self . connected_nodes . insert ( * id) ;
253264 debug_assert ! ( t, "{} is already added to peer list" , id) ;
254265
@@ -297,10 +308,10 @@ impl NetworkExtension<Event> for Extension {
297308 if let Ok ( received_message) = UntrustedRlp :: new ( data) . as_val ( ) {
298309 match received_message {
299310 Message :: Status {
300- total_score ,
311+ nonce ,
301312 best_hash,
302313 genesis_hash,
303- } => self . on_peer_status ( id, total_score , best_hash, genesis_hash) ,
314+ } => self . on_peer_status ( id, nonce , best_hash, genesis_hash) ,
304315 Message :: Request ( request_id, request) => self . on_peer_request ( id, request_id, request) ,
305316 Message :: Response ( request_id, response) => self . on_peer_response ( id, request_id, response) ,
306317 }
@@ -326,7 +337,6 @@ impl NetworkExtension<Event> for Extension {
326337 }
327338 State :: SnapshotChunk ( ..) => unimplemented ! ( ) ,
328339 State :: Full => {
329- let best_proposal_score = self . client . chain_info ( ) . best_proposal_score ;
330340 for id in & peer_ids {
331341 let request =
332342 self . header_downloaders . get_mut ( id) . and_then ( HeaderDownloader :: create_request) ;
@@ -337,15 +347,7 @@ impl NetworkExtension<Event> for Extension {
337347 }
338348
339349 for id in peer_ids {
340- let peer_score = if let Some ( peer) = self . header_downloaders . get ( & id) {
341- peer. total_score ( )
342- } else {
343- U256 :: zero ( )
344- } ;
345-
346- if peer_score > best_proposal_score {
347- self . send_body_request ( & id) ;
348- }
350+ self . send_body_request ( & id) ;
349351 }
350352 }
351353 }
@@ -499,20 +501,21 @@ impl Extension {
499501 id,
500502 Arc :: new (
501503 Message :: Status {
502- total_score : chain_info . best_proposal_score ,
504+ nonce : U256 :: from ( self . nonce ) ,
503505 best_hash : chain_info. best_proposal_block_hash ,
504506 genesis_hash : chain_info. genesis_hash ,
505507 }
506508 . rlp_bytes ( )
507509 . into_vec ( ) ,
508510 ) ,
509511 ) ;
512+ self . nonce += 1 ;
510513 }
511514 }
512515}
513516
514517impl Extension {
515- fn on_peer_status ( & mut self , from : & NodeId , total_score : U256 , best_hash : BlockHash , genesis_hash : BlockHash ) {
518+ fn on_peer_status ( & mut self , from : & NodeId , nonce : U256 , best_hash : BlockHash , genesis_hash : BlockHash ) {
516519 // Validity check
517520 if genesis_hash != self . client . chain_info ( ) . genesis_hash {
518521 cinfo ! ( SYNC , "Genesis hash mismatch with peer {}" , from) ;
@@ -521,17 +524,17 @@ impl Extension {
521524
522525 match self . header_downloaders . entry ( * from) {
523526 Entry :: Occupied ( mut peer) => {
524- if !peer. get_mut ( ) . update ( total_score , best_hash) {
527+ if !peer. get_mut ( ) . update ( nonce , best_hash) {
525528 // FIXME: It should be an error level if the consensus is PoW.
526529 cdebug ! ( SYNC , "Peer #{} status updated but score is less than before" , from) ;
527530 return
528531 }
529532 }
530533 Entry :: Vacant ( e) => {
531- e. insert ( HeaderDownloader :: new ( self . client . clone ( ) , total_score , best_hash) ) ;
534+ e. insert ( HeaderDownloader :: new ( self . client . clone ( ) , nonce , best_hash) ) ;
532535 }
533536 }
534- cinfo ! ( SYNC , "Peer #{} status update: total_score : {}, best_hash: {}" , from, total_score , best_hash) ;
537+ cinfo ! ( SYNC , "Peer #{} status update: nonce : {}, best_hash: {}" , from, nonce , best_hash) ;
535538 }
536539
537540 fn on_peer_request ( & self , from : & NodeId , id : u64 , request : RequestMessage ) {
@@ -746,14 +749,12 @@ impl Extension {
746749 } ,
747750 State :: SnapshotChunk ( ..) => { }
748751 State :: Full => {
749- let ( mut completed, pivot_score_changed) = if let Some ( peer) = self . header_downloaders . get_mut ( from) {
750- let before_pivot_score = peer. pivot_score ( ) ;
752+ let ( mut completed, peer_is_caught_up) = if let Some ( peer) = self . header_downloaders . get_mut ( from) {
751753 let encoded: Vec < _ > = headers. iter ( ) . map ( |h| EncodedHeader :: new ( h. rlp_bytes ( ) . to_vec ( ) ) ) . collect ( ) ;
752754 peer. import_headers ( & encoded) ;
753- let after_pivot_score = peer. pivot_score ( ) ;
754- ( peer. downloaded ( ) , before_pivot_score != after_pivot_score)
755+ ( peer. downloaded ( ) , peer. is_caught_up ( ) )
755756 } else {
756- ( Vec :: new ( ) , false )
757+ ( Vec :: new ( ) , true )
757758 } ;
758759 completed. sort_unstable_by_key ( EncodedHeader :: number) ;
759760
@@ -779,7 +780,7 @@ impl Extension {
779780 peer. mark_as_imported ( exists) ;
780781 peer. create_request ( )
781782 } ) ;
782- if pivot_score_changed {
783+ if !peer_is_caught_up {
783784 if let Some ( request) = request {
784785 self . send_header_request ( from, request) ;
785786 }
@@ -821,20 +822,11 @@ impl Extension {
821822 }
822823 }
823824
824- let total_score = self . client . chain_info ( ) . best_proposal_score ;
825825 let mut peer_ids: Vec < _ > = self . header_downloaders . keys ( ) . cloned ( ) . collect ( ) ;
826826 peer_ids. shuffle ( & mut thread_rng ( ) ) ;
827827
828828 for id in peer_ids {
829- let peer_score = if let Some ( peer) = self . header_downloaders . get ( & id) {
830- peer. total_score ( )
831- } else {
832- U256 :: zero ( )
833- } ;
834-
835- if peer_score > total_score {
836- self . send_body_request ( & id) ;
837- }
829+ self . send_body_request ( & id) ;
838830 }
839831 }
840832}
0 commit comments