11use std:: {
2- collections:: { HashMap , VecDeque } ,
2+ collections:: { BTreeMap , HashMap , VecDeque } ,
33 time:: Duration ,
44} ;
55
@@ -16,7 +16,7 @@ use tracing::{info, warn};
1616pub struct NetworkManager {
1717 network_magic : u64 ,
1818 next_id : u64 ,
19- peers : HashMap < PeerId , PeerConnection > ,
19+ peers : BTreeMap < PeerId , PeerConnection > ,
2020 preferred_upstream : Option < PeerId > ,
2121 blocks_to_fetch : VecDeque < Header > ,
2222 blocks : HashMap < BlockHash , BlockStatus > ,
@@ -38,7 +38,7 @@ impl NetworkManager {
3838 Self {
3939 network_magic,
4040 next_id : 0 ,
41- peers : HashMap :: new ( ) ,
41+ peers : BTreeMap :: new ( ) ,
4242 preferred_upstream : None ,
4343 blocks_to_fetch : VecDeque :: new ( ) ,
4444 blocks : HashMap :: new ( ) ,
@@ -54,18 +54,18 @@ impl NetworkManager {
5454 pub async fn run ( mut self ) -> Result < ( ) > {
5555 while let Some ( event) = self . events . recv ( ) . await {
5656 match event {
57- NetworkEvent :: NewConnection { address, delay } => {
58- self . handle_new_connection ( address, delay) . await
59- }
6057 NetworkEvent :: PeerUpdate { peer, event } => {
61- self . handle_peer_update ( peer, event) . await ?
58+ let maybe_publish_blocks = self . handle_peer_update ( peer, event) ?;
59+ if maybe_publish_blocks {
60+ self . publish_blocks ( ) . await ?;
61+ }
6262 }
6363 }
6464 }
6565 bail ! ( "event sink closed" )
6666 }
6767
68- pub async fn handle_new_connection ( & mut self , address : String , delay : Duration ) {
68+ pub fn handle_new_connection ( & mut self , address : String , delay : Duration ) {
6969 let id = PeerId ( self . next_id ) ;
7070 self . next_id += 1 ;
7171 let sender = PeerMessageSender {
@@ -75,10 +75,10 @@ impl NetworkManager {
7575 let conn = PeerConnection :: new ( address, self . network_magic , sender, delay) ;
7676 if self . preferred_upstream . is_none ( ) {
7777 self . peers . insert ( id, conn) ;
78- self . set_preferred_upstream ( id) . await ;
78+ self . set_preferred_upstream ( id) ;
7979 } else {
8080 if let Some ( head) = self . head . clone ( )
81- && let Err ( error) = conn. find_intersect ( vec ! [ head] ) . await
81+ && let Err ( error) = conn. find_intersect ( vec ! [ head] )
8282 {
8383 warn ! ( "could not sync {}: {error}" , conn. address) ;
8484 }
@@ -96,26 +96,26 @@ impl NetworkManager {
9696 } ;
9797 match conn. find_tip ( ) . await {
9898 Ok ( point) => {
99- self . sync_to_point ( point) . await ;
99+ self . sync_to_point ( point) ;
100100 return Ok ( ( ) ) ;
101101 }
102102 Err ( e) => {
103103 warn ! ( "could not fetch tip from {}: {e}" , conn. address) ;
104- self . handle_disconnect ( upstream) . await ? ;
104+ self . handle_disconnect ( upstream) ;
105105 }
106106 }
107107 }
108108 }
109109
110- pub async fn sync_to_point ( & mut self , point : Point ) {
110+ pub fn sync_to_point ( & mut self , point : Point ) {
111111 for conn in self . peers . values ( ) {
112- if let Err ( error) = conn. find_intersect ( vec ! [ point. clone( ) ] ) . await {
112+ if let Err ( error) = conn. find_intersect ( vec ! [ point. clone( ) ] ) {
113113 warn ! ( "could not sync {}: {error}" , conn. address) ;
114114 }
115115 }
116116 }
117117
118- async fn handle_peer_update ( & mut self , peer : PeerId , event : PeerEvent ) -> Result < ( ) > {
118+ fn handle_peer_update ( & mut self , peer : PeerId , event : PeerEvent ) -> Result < bool > {
119119 let is_preferred = self . preferred_upstream . is_some_and ( |id| id == peer) ;
120120 match event {
121121 PeerEvent :: ChainSync ( PeerChainSyncEvent :: RollForward ( header) ) => {
@@ -132,21 +132,20 @@ impl NetworkManager {
132132 let Some ( peer) = self . peers . get ( & announcer) else {
133133 continue ;
134134 } ;
135- if let Err ( e) = peer. request_block ( header. hash , header. slot ) . await
135+ if let Err ( e) = peer. request_block ( header. hash , header. slot )
136136 {
137137 warn ! ( "could not request block from {}: {e}" , peer. address) ;
138- self . handle_disconnect ( announcer) . await ?
138+ self . handle_disconnect ( announcer) ;
139139 }
140140 break ; // only fetch from one
141141 }
142142 }
143+ Ok ( false )
143144 }
144145 BlockStatus :: Fetched ( _) => {
145- if is_preferred {
146- // Chainsync has requested a block which we've already fetched,
147- // so we might be able to publish one or more.
148- self . publish_blocks ( ) . await ?;
149- }
146+ // If chainsync has requested a block which we've already fetched,
147+ // we might be able to publish one or more.
148+ Ok ( is_preferred)
150149 }
151150 }
152151 }
@@ -173,40 +172,48 @@ impl NetworkManager {
173172 }
174173 }
175174 }
175+ Ok ( false )
176176 }
177177 PeerEvent :: BlockFetched ( fetched) => {
178178 let Some ( block) = self . blocks . get_mut ( & fetched. hash ) else {
179- return Ok ( ( ) ) ;
179+ return Ok ( false ) ;
180180 } ;
181181 block. set_body ( & fetched. body ) ;
182- self . publish_blocks ( ) . await ?;
182+ Ok ( true )
183+ }
184+ PeerEvent :: Disconnected => {
185+ self . handle_disconnect ( peer) ;
186+ Ok ( false )
183187 }
184- PeerEvent :: Disconnected => self . handle_disconnect ( peer) . await ?,
185188 }
186- Ok ( ( ) )
187189 }
188190
189- async fn handle_disconnect ( & mut self , peer : PeerId ) -> Result < ( ) > {
191+ fn handle_disconnect ( & mut self , peer : PeerId ) {
190192 let Some ( conn) = self . peers . remove ( & peer) else {
191- return Ok ( ( ) ) ;
193+ return ;
192194 } ;
195+ warn ! ( "disconnected from {}" , conn. address) ;
193196 let is_preferred = self . preferred_upstream . is_some_and ( |id| id == peer) ;
194197 if is_preferred && let Some ( new_preferred) = self . peers . keys ( ) . next ( ) . copied ( ) {
195- self . set_preferred_upstream ( new_preferred) . await ;
198+ self . set_preferred_upstream ( new_preferred) ;
196199 }
197- self . events_sender
198- . send ( NetworkEvent :: NewConnection {
199- address : conn. address ,
200- delay : Duration :: from_secs ( 5 ) ,
201- } )
202- . await ?;
203- Ok ( ( ) )
200+ if self . peers . is_empty ( ) {
201+ warn ! ( "no upstream peers!" ) ;
202+ }
203+ let address = conn. address . clone ( ) ;
204+ drop ( conn) ;
205+ self . handle_new_connection ( address, Duration :: from_secs ( 5 ) ) ;
204206 }
205207
206- async fn set_preferred_upstream ( & mut self , peer : PeerId ) {
208+ fn set_preferred_upstream ( & mut self , peer : PeerId ) {
209+ if let Some ( conn) = self . peers . get ( & peer) {
210+ info ! ( "setting preferred upstream to {}" , conn. address) ;
211+ } else {
212+ warn ! ( "setting preferred upstream to unrecognized node {peer:?}" ) ;
213+ }
207214 self . preferred_upstream = Some ( peer) ;
208215 if let Some ( head) = self . head . clone ( ) {
209- self . sync_to_point ( head) . await ;
216+ self . sync_to_point ( head) ;
210217 }
211218 }
212219
@@ -229,11 +236,10 @@ impl NetworkManager {
229236}
230237
231238pub enum NetworkEvent {
232- NewConnection { address : String , delay : Duration } ,
233239 PeerUpdate { peer : PeerId , event : PeerEvent } ,
234240}
235241
236- #[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
242+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
237243pub struct PeerId ( u64 ) ;
238244
239245pub struct PeerMessageSender {
0 commit comments