@@ -89,6 +89,7 @@ pub mod logger;
8989mod message_handler;
9090pub mod payment;
9191mod peer_store;
92+ mod scoring;
9293mod sweep;
9394mod tx_broadcaster;
9495mod types;
@@ -122,7 +123,8 @@ pub use builder::NodeBuilder as Builder;
122123
123124use chain:: ChainSource ;
124125use config:: {
125- default_user_config, may_announce_channel, ChannelConfig , Config , NODE_ANN_BCAST_INTERVAL ,
126+ default_user_config, may_announce_channel, ChannelConfig , Config ,
127+ EXTERNAL_SCORES_SYNC_INTERVAL , EXTERNAL_SCORES_SYNC_TIMEOUT_SECS , NODE_ANN_BCAST_INTERVAL ,
126128 PEER_RECONNECTION_INTERVAL , RGS_SYNC_INTERVAL ,
127129} ;
128130use connection:: ConnectionManager ;
@@ -137,6 +139,7 @@ use payment::{
137139 UnifiedQrPayment ,
138140} ;
139141use peer_store:: { PeerInfo , PeerStore } ;
142+ use scoring:: ScoringSource ;
140143use types:: {
141144 Broadcaster , BumpTransactionEventHandler , ChainMonitor , ChannelManager , DynStore , Graph ,
142145 KeysManager , OnionMessenger , PeerManager , Router , Scorer , Sweeper , Wallet ,
@@ -190,6 +193,7 @@ pub struct Node {
190193 keys_manager : Arc < KeysManager > ,
191194 network_graph : Arc < Graph > ,
192195 gossip_source : Arc < GossipSource > ,
196+ scoring_source : Option < Arc < ScoringSource > > ,
193197 liquidity_source : Option < Arc < LiquiditySource < Arc < Logger > > > > ,
194198 kv_store : Arc < DynStore > ,
195199 logger : Arc < Logger > ,
@@ -304,6 +308,11 @@ impl Node {
304308 } ) ;
305309 }
306310
311+ // If scoring source is set
312+ if self . scoring_source . is_some ( ) {
313+ self . setup_external_scores_syncing ( & runtime) ;
314+ }
315+
307316 if let Some ( listening_addresses) = & self . config . listening_addresses {
308317 // Setup networking
309318 let peer_manager_connection_handler = Arc :: clone ( & self . peer_manager ) ;
@@ -634,6 +643,42 @@ impl Node {
634643 Ok ( ( ) )
635644 }
636645
646+ /// Spawn a background task to sync external scores from the given `url`.
647+ fn setup_external_scores_syncing ( & self , runtime : & tokio:: runtime:: Runtime ) {
648+ let scoring_source = Arc :: clone ( & self . scoring_source . as_ref ( ) . unwrap ( ) ) ;
649+ log_info ! (
650+ self . logger,
651+ "External scores background syncing from {} enabled" ,
652+ scoring_source. get_url( )
653+ ) ;
654+
655+ let external_scores_sync_logger = Arc :: clone ( & self . logger ) ;
656+ let mut stop_sync = self . stop_sender . subscribe ( ) ;
657+
658+ runtime. spawn ( async move {
659+ let mut interval = tokio:: time:: interval ( EXTERNAL_SCORES_SYNC_INTERVAL ) ;
660+ loop {
661+ tokio:: select! {
662+ _ = stop_sync. changed( ) => {
663+ log_trace!(
664+ external_scores_sync_logger,
665+ "Stopping background syncing external scores." ,
666+ ) ;
667+ return ;
668+ }
669+ _ = interval. tick( ) => {
670+ log_trace!(
671+ external_scores_sync_logger,
672+ "Background sync of external scores started." ,
673+ ) ;
674+
675+ scoring_source. sync_external_scores( ) . await ;
676+ }
677+ }
678+ }
679+ } ) ;
680+ }
681+
637682 /// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
638683 ///
639684 /// After this returns most API methods will return [`Error::NotRunning`].
@@ -725,6 +770,7 @@ impl Node {
725770 locked_node_metrics. latest_fee_rate_cache_update_timestamp ;
726771 let latest_rgs_snapshot_timestamp =
727772 locked_node_metrics. latest_rgs_snapshot_timestamp . map ( |val| val as u64 ) ;
773+ let latest_scores_sync_timestamp = locked_node_metrics. latest_scores_sync_timestamp ;
728774 let latest_node_announcement_broadcast_timestamp =
729775 locked_node_metrics. latest_node_announcement_broadcast_timestamp ;
730776 let latest_channel_monitor_archival_height =
@@ -738,6 +784,7 @@ impl Node {
738784 latest_onchain_wallet_sync_timestamp,
739785 latest_fee_rate_cache_update_timestamp,
740786 latest_rgs_snapshot_timestamp,
787+ latest_scores_sync_timestamp,
741788 latest_node_announcement_broadcast_timestamp,
742789 latest_channel_monitor_archival_height,
743790 }
@@ -1547,6 +1594,8 @@ pub struct NodeStatus {
15471594 ///
15481595 /// Will be `None` if RGS isn't configured or the snapshot hasn't been updated yet.
15491596 pub latest_rgs_snapshot_timestamp : Option < u64 > ,
1597+ /// The timestamp, in seconds since start of the UNIX epoch, when we last successfully merged external scores.
1598+ pub latest_scores_sync_timestamp : Option < u64 > ,
15501599 /// The timestamp, in seconds since start of the UNIX epoch, when we last broadcasted a node
15511600 /// announcement.
15521601 ///
@@ -1565,6 +1614,7 @@ pub(crate) struct NodeMetrics {
15651614 latest_onchain_wallet_sync_timestamp : Option < u64 > ,
15661615 latest_fee_rate_cache_update_timestamp : Option < u64 > ,
15671616 latest_rgs_snapshot_timestamp : Option < u32 > ,
1617+ latest_scores_sync_timestamp : Option < u64 > ,
15681618 latest_node_announcement_broadcast_timestamp : Option < u64 > ,
15691619 latest_channel_monitor_archival_height : Option < u32 > ,
15701620}
@@ -1576,6 +1626,7 @@ impl Default for NodeMetrics {
15761626 latest_onchain_wallet_sync_timestamp : None ,
15771627 latest_fee_rate_cache_update_timestamp : None ,
15781628 latest_rgs_snapshot_timestamp : None ,
1629+ latest_scores_sync_timestamp : None ,
15791630 latest_node_announcement_broadcast_timestamp : None ,
15801631 latest_channel_monitor_archival_height : None ,
15811632 }
@@ -1589,6 +1640,7 @@ impl_writeable_tlv_based!(NodeMetrics, {
15891640 ( 6 , latest_rgs_snapshot_timestamp, option) ,
15901641 ( 8 , latest_node_announcement_broadcast_timestamp, option) ,
15911642 ( 10 , latest_channel_monitor_archival_height, option) ,
1643+ ( 12 , latest_scores_sync_timestamp, option) ,
15921644} ) ;
15931645
15941646pub ( crate ) fn total_anchor_channels_reserve_sats (
0 commit comments