@@ -99,6 +99,8 @@ mod wallet;
9999pub use bip39;
100100pub use bitcoin;
101101pub use lightning;
102+ use lightning:: routing:: scoring:: { ChannelLiquidities , CombinedScorer } ;
103+ use lightning:: util:: ser:: Readable ;
102104pub use lightning_invoice;
103105pub use lightning_types;
104106pub use vss_client;
@@ -122,7 +124,8 @@ pub use builder::NodeBuilder as Builder;
122124
123125use chain:: ChainSource ;
124126use config:: {
125- default_user_config, may_announce_channel, ChannelConfig , Config , NODE_ANN_BCAST_INTERVAL ,
127+ default_user_config, may_announce_channel, ChannelConfig , Config ,
128+ EXTERNAL_SCORES_SYNC_INTERVAL , EXTERNAL_SCORES_SYNC_TIMEOUT_SECS , NODE_ANN_BCAST_INTERVAL ,
126129 PEER_RECONNECTION_INTERVAL , RGS_SYNC_INTERVAL ,
127130} ;
128131use connection:: ConnectionManager ;
@@ -162,6 +165,7 @@ use bitcoin::secp256k1::PublicKey;
162165use rand:: Rng ;
163166
164167use std:: default:: Default ;
168+ use std:: io:: Cursor ;
165169use std:: net:: ToSocketAddrs ;
166170use std:: sync:: atomic:: { AtomicBool , Ordering } ;
167171use std:: sync:: { Arc , Mutex , RwLock } ;
@@ -306,6 +310,36 @@ impl Node {
306310 } ) ;
307311 }
308312
313+ if let Some ( url) = & self . config . external_scores_url {
314+ let external_scores_sync_logger = Arc :: clone ( & self . logger ) ;
315+ let external_scores_scorer = Arc :: clone ( & self . scorer ) ;
316+ let mut stop_sync = self . stop_sender . subscribe ( ) ;
317+ let url = url. clone ( ) ;
318+
319+ runtime. spawn ( async move {
320+ let mut interval = tokio:: time:: interval ( EXTERNAL_SCORES_SYNC_INTERVAL ) ;
321+ loop {
322+ tokio:: select! {
323+ _ = stop_sync. changed( ) => {
324+ log_trace!(
325+ external_scores_sync_logger,
326+ "Stopping background syncing external scores." ,
327+ ) ;
328+ return ;
329+ }
330+ _ = interval. tick( ) => {
331+ log_trace!(
332+ external_scores_sync_logger,
333+ "Background sync of external scores started." ,
334+ ) ;
335+
336+ sync_external_scores( & external_scores_sync_logger, & external_scores_scorer, & url) . await ;
337+ }
338+ }
339+ }
340+ } ) ;
341+ }
342+
309343 if let Some ( listening_addresses) = & self . config . listening_addresses {
310344 // Setup networking
311345 let peer_manager_connection_handler = Arc :: clone ( & self . peer_manager ) ;
@@ -1612,3 +1646,51 @@ pub(crate) fn total_anchor_channels_reserve_sats(
16121646 * anchor_channels_config. per_channel_reserve_sats
16131647 } )
16141648}
1649+
1650+ async fn sync_external_scores (
1651+ logger : & FilesystemLogger , scorer : & Mutex < CombinedScorer < Arc < Graph > , Arc < FilesystemLogger > > > ,
1652+ url : & String ,
1653+ ) -> ( ) {
1654+ let response = tokio:: time:: timeout (
1655+ Duration :: from_secs ( EXTERNAL_SCORES_SYNC_TIMEOUT_SECS ) ,
1656+ reqwest:: get ( url) ,
1657+ )
1658+ . await ;
1659+
1660+ match response {
1661+ Ok ( Ok ( response) ) => {
1662+ let body = response. bytes ( ) . await ;
1663+ match body {
1664+ Err ( e) => {
1665+ log_trace ! (
1666+ logger,
1667+ "Failed to read external scores update from http source: {}" ,
1668+ e
1669+ ) ;
1670+ return ;
1671+ } ,
1672+ Ok ( body) => {
1673+ let mut reader = Cursor :: new ( body) ;
1674+ match ChannelLiquidities :: read ( & mut reader) {
1675+ Ok ( liquidities) => {
1676+ scorer. lock ( ) . unwrap ( ) . merge ( liquidities) ;
1677+ log_trace ! ( logger, "External scores merged successfully" , ) ;
1678+ } ,
1679+ Err ( e) => {
1680+ log_trace ! ( logger, "Failed to parse external scores update: {}" , e) ;
1681+ return ;
1682+ } ,
1683+ }
1684+ } ,
1685+ }
1686+ } ,
1687+ Err ( e) => {
1688+ log_trace ! ( logger, "Retrieving external scores timed out: {}" , e) ;
1689+ return ;
1690+ } ,
1691+ Ok ( Err ( e) ) => {
1692+ log_trace ! ( logger, "Failed to retrieve external scores update: {}" , e) ;
1693+ return ;
1694+ } ,
1695+ }
1696+ }
0 commit comments