@@ -309,14 +309,14 @@ async def connect_to_fastest(self) -> Optional[ClientSession]:
309309 return
310310
311311 async def network_loop (self ):
312- sleep_delay = 15
312+ def reset_sleep ():
313+ return 10 + random .uniform (0 , 5 )
314+ sleep_delay = reset_sleep ()
313315 while self .running :
314316 await asyncio .wait (
315317 [asyncio .sleep (sleep_delay ), self ._urgent_need_reconnect .wait ()],
316318 return_when = asyncio .FIRST_COMPLETED
317319 )
318- if self ._urgent_need_reconnect .is_set ():
319- sleep_delay = 10 + random .uniform (0 , 5 )
320320 self ._urgent_need_reconnect .clear ()
321321 if not self .is_connected :
322322 client = await self .connect_to_fastest ()
@@ -325,17 +325,24 @@ async def network_loop(self):
325325 sleep_delay = min (sleep_delay , 120 )
326326 log .warning ("failed to connect to any spv servers, retrying after %.2fs" , sleep_delay )
327327 continue
328+ sleep_delay = reset_sleep ()
329+ server_str = "%s:%i" % client .server
328330 try :
331+ # Perform initial sequence of RPCs.
329332 log .debug ("get spv server features %s:%i" , * client .server )
330333 features = await client .send_request ('server.features' , [])
331- self .client , self .server_features = client , features
332334 log .debug ("discover other hubs %s:%i" , * client .server )
333335 await self ._update_hubs (await client .send_request ('server.peers.subscribe' , []))
334336 log .info ("subscribe to headers %s:%i" , * client .server )
335- self ._update_remote_height ((await self .subscribe_headers (),))
337+ self ._update_remote_height ((await client .send_request ('blockchain.headers.subscribe' , [True ]),))
338+
339+ # All initial RPCs were successful. We're now connected.
340+ self .client , self .server_features = client , features
341+ self ._urgent_need_reconnect .clear ()
342+ sleep_delay = reset_sleep ()
343+ # Release any waiters.
336344 self ._on_connected_controller .add (True )
337- sleep_delay = 15
338- server_str = "%s:%i" % client .server
345+
339346 log .info ("maintaining connection to spv server %s" , server_str )
340347 self ._keepalive_task = asyncio .create_task (self .client .keepalive_loop ())
341348 await asyncio .wait (
@@ -345,7 +352,9 @@ async def network_loop(self):
345352 if self ._urgent_need_reconnect .is_set ():
346353 log .warning ("urgent reconnect needed" )
347354 except (asyncio .TimeoutError , ConnectionResetError , ConnectionError , RPCError , ProtocolError ):
348- pass
355+ sleep_delay *= 2
356+ sleep_delay = min (sleep_delay , 120 )
357+ log .warning ("failed to connect to spv server %s, retrying after %.2fs" , server_str , sleep_delay )
349358 finally :
350359 if self ._keepalive_task and not self ._keepalive_task .done ():
351360 self ._keepalive_task .cancel ()
@@ -436,9 +445,6 @@ def get_history(self, address):
436445 def broadcast (self , raw_transaction ):
437446 return self .rpc ('blockchain.transaction.broadcast' , [raw_transaction ], True )
438447
439- def subscribe_headers (self ):
440- return self .rpc ('blockchain.headers.subscribe' , [True ], True )
441-
442448 async def subscribe_address (self , address , * addresses ):
443449 addresses = list ((address , ) + addresses )
444450 server_addr_and_port = self .client .server_address_and_port # on disconnect client will be None
0 commit comments