@@ -36,7 +36,7 @@ use sp_consensus::{
3636 block_validation:: BlockAnnounceValidator ,
3737 import_queue:: { BlockImportResult , BlockImportError , IncomingBlock , Origin }
3838} ;
39- use codec:: { Decode , Encode } ;
39+ use codec:: { Decode , DecodeAll , Encode } ;
4040use sp_runtime:: { generic:: BlockId , ConsensusEngineId , Justification } ;
4141use sp_runtime:: traits:: {
4242 Block as BlockT , Header as HeaderT , NumberFor , Zero , CheckedSub
@@ -53,7 +53,7 @@ use std::borrow::Cow;
5353use std:: collections:: { HashMap , HashSet , VecDeque , hash_map:: Entry } ;
5454use std:: sync:: Arc ;
5555use std:: fmt:: Write ;
56- use std:: { io, num:: NonZeroUsize , pin:: Pin , task:: Poll , time} ;
56+ use std:: { io, iter , num:: NonZeroUsize , pin:: Pin , task:: Poll , time} ;
5757use log:: { log, Level , trace, debug, warn, error} ;
5858use wasm_timer:: Instant ;
5959
@@ -275,8 +275,6 @@ struct Peer<B: BlockT, H: ExHashT> {
275275pub struct PeerInfo < B : BlockT > {
276276 /// Roles
277277 pub roles : Roles ,
278- /// Protocol version
279- pub protocol_version : u32 ,
280278 /// Peer best block hash
281279 pub best_hash : B :: Hash ,
282280 /// Peer best block number
@@ -395,14 +393,6 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
395393 } ;
396394
397395 let ( peerset, peerset_handle) = sc_peerset:: Peerset :: from_config ( peerset_config) ;
398- let versions = & ( ( MIN_VERSION as u8 ) ..=( CURRENT_VERSION as u8 ) ) . collect :: < Vec < u8 > > ( ) ;
399- let mut behaviour = GenericProto :: new (
400- local_peer_id,
401- protocol_id. clone ( ) ,
402- versions,
403- build_status_message ( & config, & chain) ,
404- peerset,
405- ) ;
406396
407397 let mut legacy_equiv_by_name = HashMap :: new ( ) ;
408398
@@ -413,7 +403,6 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
413403 proto. push_str ( "/transactions/1" ) ;
414404 proto
415405 } ) ;
416- behaviour. register_notif_protocol ( transactions_protocol. clone ( ) , Vec :: new ( ) ) ;
417406 legacy_equiv_by_name. insert ( transactions_protocol. clone ( ) , Fallback :: Transactions ) ;
418407
419408 let block_announces_protocol: Cow < ' static , str > = Cow :: from ( {
@@ -423,12 +412,24 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
423412 proto. push_str ( "/block-announces/1" ) ;
424413 proto
425414 } ) ;
426- behaviour. register_notif_protocol (
427- block_announces_protocol. clone ( ) ,
428- BlockAnnouncesHandshake :: build ( & config, & chain) . encode ( )
429- ) ;
430415 legacy_equiv_by_name. insert ( block_announces_protocol. clone ( ) , Fallback :: BlockAnnounce ) ;
431416
417+ let behaviour = {
418+ let versions = & ( ( MIN_VERSION as u8 ) ..=( CURRENT_VERSION as u8 ) ) . collect :: < Vec < u8 > > ( ) ;
419+ let block_announces_handshake = BlockAnnouncesHandshake :: build ( & config, & chain) . encode ( ) ;
420+ GenericProto :: new (
421+ local_peer_id,
422+ protocol_id. clone ( ) ,
423+ versions,
424+ build_status_message ( & config, & chain) ,
425+ peerset,
426+ // As documented in `GenericProto`, the first protocol in the list is always the
427+ // one carrying the handshake reported in the `CustomProtocolOpen` event.
428+ iter:: once ( ( block_announces_protocol. clone ( ) , block_announces_handshake) )
429+ . chain ( iter:: once ( ( transactions_protocol. clone ( ) , vec ! [ ] ) ) ) ,
430+ )
431+ } ;
432+
432433 let protocol = Protocol {
433434 tick_timeout : Box :: pin ( interval ( TICK_TIMEOUT ) ) ,
434435 propagate_timeout : Box :: pin ( interval ( PROPAGATE_TIMEOUT ) ) ,
@@ -839,99 +840,86 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
839840 }
840841 }
841842
842- /// Called on receipt of a status message via the legacy protocol on the first connection between two peers.
843- pub fn on_peer_connected (
843+ /// Called on the first connection between two peers, after their exchange of handshake .
844+ fn on_peer_connected (
844845 & mut self ,
845846 who : PeerId ,
846- status : message :: Status < B > ,
847+ status : BlockAnnouncesHandshake < B > ,
847848 notifications_sink : NotificationsSink ,
848849 ) -> CustomMessageOutcome < B > {
849850 trace ! ( target: "sync" , "New peer {} {:?}" , who, status) ;
850- let _protocol_version = {
851- if self . context_data . peers . contains_key ( & who) {
852- debug ! ( target: "sync" , "Ignoring duplicate status packet from {}" , who) ;
853- return CustomMessageOutcome :: None ;
854- }
855- if status. genesis_hash != self . genesis_hash {
856- log ! (
857- target: "sync" ,
858- if self . important_peers. contains( & who) { Level :: Warn } else { Level :: Trace } ,
859- "Peer is on different chain (our genesis: {} theirs: {})" ,
860- self . genesis_hash, status. genesis_hash
861- ) ;
862- self . peerset_handle . report_peer ( who. clone ( ) , rep:: GENESIS_MISMATCH ) ;
863- self . behaviour . disconnect_peer ( & who) ;
864851
865- if self . boot_node_ids . contains ( & who) {
866- error ! (
867- target: "sync" ,
868- "Bootnode with peer id `{}` is on a different chain (our genesis: {} theirs: {})" ,
869- who,
870- self . genesis_hash,
871- status. genesis_hash,
872- ) ;
873- }
852+ if self . context_data . peers . contains_key ( & who) {
853+ debug ! ( target: "sync" , "Ignoring duplicate status packet from {}" , who) ;
854+ return CustomMessageOutcome :: None ;
855+ }
856+ if status. genesis_hash != self . genesis_hash {
857+ log ! (
858+ target: "sync" ,
859+ if self . important_peers. contains( & who) { Level :: Warn } else { Level :: Trace } ,
860+ "Peer is on different chain (our genesis: {} theirs: {})" ,
861+ self . genesis_hash, status. genesis_hash
862+ ) ;
863+ self . peerset_handle . report_peer ( who. clone ( ) , rep:: GENESIS_MISMATCH ) ;
864+ self . behaviour . disconnect_peer ( & who) ;
874865
875- return CustomMessageOutcome :: None ;
876- }
877- if status. version < MIN_VERSION && CURRENT_VERSION < status. min_supported_version {
878- log ! (
866+ if self . boot_node_ids . contains ( & who) {
867+ error ! (
879868 target: "sync" ,
880- if self . important_peers. contains( & who) { Level :: Warn } else { Level :: Trace } ,
881- "Peer {:?} using unsupported protocol version {}" , who, status. version
869+ "Bootnode with peer id `{}` is on a different chain (our genesis: {} theirs: {})" ,
870+ who,
871+ self . genesis_hash,
872+ status. genesis_hash,
882873 ) ;
883- self . peerset_handle . report_peer ( who. clone ( ) , rep:: BAD_PROTOCOL ) ;
884- self . behaviour . disconnect_peer ( & who) ;
885- return CustomMessageOutcome :: None ;
886874 }
887875
888- if self . config . roles . is_light ( ) {
889- // we're not interested in light peers
890- if status. roles . is_light ( ) {
891- debug ! ( target: "sync" , "Peer {} is unable to serve light requests" , who) ;
892- self . peerset_handle . report_peer ( who. clone ( ) , rep:: BAD_ROLE ) ;
893- self . behaviour . disconnect_peer ( & who) ;
894- return CustomMessageOutcome :: None ;
895- }
876+ return CustomMessageOutcome :: None ;
877+ }
896878
897- // we don't interested in peers that are far behind us
898- let self_best_block = self
899- . context_data
900- . chain
901- . info ( )
902- . best_number ;
903- let blocks_difference = self_best_block
904- . checked_sub ( & status. best_number )
905- . unwrap_or_else ( Zero :: zero)
906- . saturated_into :: < u64 > ( ) ;
907- if blocks_difference > LIGHT_MAXIMAL_BLOCKS_DIFFERENCE {
908- debug ! ( target: "sync" , "Peer {} is far behind us and will unable to serve light requests" , who) ;
909- self . peerset_handle . report_peer ( who. clone ( ) , rep:: PEER_BEHIND_US_LIGHT ) ;
910- self . behaviour . disconnect_peer ( & who) ;
911- return CustomMessageOutcome :: None ;
912- }
879+ if self . config . roles . is_light ( ) {
880+ // we're not interested in light peers
881+ if status. roles . is_light ( ) {
882+ debug ! ( target: "sync" , "Peer {} is unable to serve light requests" , who) ;
883+ self . peerset_handle . report_peer ( who. clone ( ) , rep:: BAD_ROLE ) ;
884+ self . behaviour . disconnect_peer ( & who) ;
885+ return CustomMessageOutcome :: None ;
913886 }
914887
915- let peer = Peer {
916- info : PeerInfo {
917- protocol_version : status. version ,
918- roles : status. roles ,
919- best_hash : status. best_hash ,
920- best_number : status. best_number
921- } ,
922- block_request : None ,
923- known_transactions : LruHashSet :: new ( NonZeroUsize :: new ( MAX_KNOWN_TRANSACTIONS )
924- . expect ( "Constant is nonzero" ) ) ,
925- known_blocks : LruHashSet :: new ( NonZeroUsize :: new ( MAX_KNOWN_BLOCKS )
926- . expect ( "Constant is nonzero" ) ) ,
927- next_request_id : 0 ,
928- obsolete_requests : HashMap :: new ( ) ,
929- } ;
930- self . context_data . peers . insert ( who. clone ( ) , peer) ;
888+ // we don't interested in peers that are far behind us
889+ let self_best_block = self
890+ . context_data
891+ . chain
892+ . info ( )
893+ . best_number ;
894+ let blocks_difference = self_best_block
895+ . checked_sub ( & status. best_number )
896+ . unwrap_or_else ( Zero :: zero)
897+ . saturated_into :: < u64 > ( ) ;
898+ if blocks_difference > LIGHT_MAXIMAL_BLOCKS_DIFFERENCE {
899+ debug ! ( target: "sync" , "Peer {} is far behind us and will unable to serve light requests" , who) ;
900+ self . peerset_handle . report_peer ( who. clone ( ) , rep:: PEER_BEHIND_US_LIGHT ) ;
901+ self . behaviour . disconnect_peer ( & who) ;
902+ return CustomMessageOutcome :: None ;
903+ }
904+ }
931905
932- debug ! ( target: "sync" , "Connected {}" , who) ;
933- status. version
906+ let peer = Peer {
907+ info : PeerInfo {
908+ roles : status. roles ,
909+ best_hash : status. best_hash ,
910+ best_number : status. best_number
911+ } ,
912+ block_request : None ,
913+ known_transactions : LruHashSet :: new ( NonZeroUsize :: new ( MAX_KNOWN_TRANSACTIONS )
914+ . expect ( "Constant is nonzero" ) ) ,
915+ known_blocks : LruHashSet :: new ( NonZeroUsize :: new ( MAX_KNOWN_BLOCKS )
916+ . expect ( "Constant is nonzero" ) ) ,
917+ next_request_id : 0 ,
918+ obsolete_requests : HashMap :: new ( ) ,
934919 } ;
920+ self . context_data . peers . insert ( who. clone ( ) , peer) ;
921+
922+ debug ! ( target: "sync" , "Connected {}" , who) ;
935923
936924 let info = self . context_data . peers . get ( & who) . expect ( "We just inserted above; QED" ) . info . clone ( ) ;
937925 self . pending_messages . push_back ( CustomMessageOutcome :: PeerNewBest ( who. clone ( ) , status. best_number ) ) ;
@@ -1161,20 +1149,12 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
11611149 if inserted || force {
11621150 let message = message:: BlockAnnounce {
11631151 header : header. clone ( ) ,
1164- state : if peer. info . protocol_version >= 4 {
1165- if is_best {
1166- Some ( message:: BlockState :: Best )
1167- } else {
1168- Some ( message:: BlockState :: Normal )
1169- }
1170- } else {
1171- None
1172- } ,
1173- data : if peer. info . protocol_version >= 4 {
1174- Some ( data. clone ( ) )
1152+ state : if is_best {
1153+ Some ( message:: BlockState :: Best )
11751154 } else {
1176- None
1155+ Some ( message :: BlockState :: Normal )
11771156 } ,
1157+ data : Some ( data. clone ( ) ) ,
11781158 } ;
11791159
11801160 self . behaviour . write_notification (
@@ -1620,9 +1600,20 @@ impl<B: BlockT, H: ExHashT> NetworkBehaviour for Protocol<B, H> {
16201600
16211601 let outcome = match event {
16221602 GenericProtoOut :: CustomProtocolOpen { peer_id, received_handshake, notifications_sink, .. } => {
1623- match <Message < B > as Decode >:: decode ( & mut & received_handshake[ ..] ) {
1624- Ok ( GenericMessage :: Status ( handshake) ) =>
1625- self . on_peer_connected ( peer_id, handshake, notifications_sink) ,
1603+ // `received_handshake` can be either a `Status` message if received from the
1604+ // legacy substream ,or a `BlockAnnouncesHandshake` if received from the block
1605+ // announces substream.
1606+ match <Message < B > as DecodeAll >:: decode_all ( & mut & received_handshake[ ..] ) {
1607+ Ok ( GenericMessage :: Status ( handshake) ) => {
1608+ let handshake = BlockAnnouncesHandshake {
1609+ roles : handshake. roles ,
1610+ best_number : handshake. best_number ,
1611+ best_hash : handshake. best_hash ,
1612+ genesis_hash : handshake. genesis_hash ,
1613+ } ;
1614+
1615+ self . on_peer_connected ( peer_id, handshake, notifications_sink)
1616+ } ,
16261617 Ok ( msg) => {
16271618 debug ! (
16281619 target: "sync" ,
@@ -1634,15 +1625,23 @@ impl<B: BlockT, H: ExHashT> NetworkBehaviour for Protocol<B, H> {
16341625 CustomMessageOutcome :: None
16351626 }
16361627 Err ( err) => {
1637- debug ! (
1638- target: "sync" ,
1639- "Couldn't decode handshake sent by {}: {:?}: {}" ,
1640- peer_id,
1641- received_handshake,
1642- err. what( )
1643- ) ;
1644- self . peerset_handle . report_peer ( peer_id, rep:: BAD_MESSAGE ) ;
1645- CustomMessageOutcome :: None
1628+ match <BlockAnnouncesHandshake < B > as DecodeAll >:: decode_all ( & mut & received_handshake[ ..] ) {
1629+ Ok ( handshake) => {
1630+ self . on_peer_connected ( peer_id, handshake, notifications_sink)
1631+ }
1632+ Err ( err2) => {
1633+ debug ! (
1634+ target: "sync" ,
1635+ "Couldn't decode handshake sent by {}: {:?}: {} & {}" ,
1636+ peer_id,
1637+ received_handshake,
1638+ err. what( ) ,
1639+ err2,
1640+ ) ;
1641+ self . peerset_handle . report_peer ( peer_id, rep:: BAD_MESSAGE ) ;
1642+ CustomMessageOutcome :: None
1643+ }
1644+ }
16461645 }
16471646 }
16481647 }
0 commit comments