1#![crate_name = "ldk_node"]
9
10#![cfg_attr(not(feature = "uniffi"), deny(missing_docs))]
74#![deny(rustdoc::broken_intra_doc_links)]
75#![deny(rustdoc::private_intra_doc_links)]
76#![allow(bare_trait_objects)]
77#![allow(ellipsis_inclusive_range_patterns)]
78#![cfg_attr(docsrs, feature(doc_cfg))]
79
80mod balance;
81mod builder;
82mod chain;
83pub mod config;
84mod connection;
85mod data_store;
86mod error;
87mod event;
88mod fee_estimator;
89mod ffi;
90mod gossip;
91pub mod graph;
92mod hex_utils;
93pub mod io;
94pub mod liquidity;
95pub mod logger;
96mod message_handler;
97pub mod payment;
98mod peer_store;
99mod runtime;
100mod scoring;
101mod tx_broadcaster;
102mod types;
103mod wallet;
104
105use std::default::Default;
106use std::net::ToSocketAddrs;
107use std::sync::{Arc, Mutex, RwLock};
108use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
109
110pub use balance::{BalanceDetails, LightningBalance, PendingSweepBalance};
111use bitcoin::secp256k1::PublicKey;
112use bitcoin::{Address, Amount};
113#[cfg(feature = "uniffi")]
114pub use builder::ArcedNodeBuilder as Builder;
115pub use builder::BuildError;
116#[cfg(not(feature = "uniffi"))]
117pub use builder::NodeBuilder as Builder;
118use chain::ChainSource;
119use config::{
120 default_user_config, may_announce_channel, AsyncPaymentsRole, ChannelConfig, Config,
121 NODE_ANN_BCAST_INTERVAL, PEER_RECONNECTION_INTERVAL, RGS_SYNC_INTERVAL,
122};
123use connection::ConnectionManager;
124pub use error::Error as NodeError;
125use error::Error;
126pub use event::Event;
127use event::{EventHandler, EventQueue};
128use fee_estimator::{ConfirmationTarget, FeeEstimator, OnchainFeeEstimator};
129#[cfg(feature = "uniffi")]
130use ffi::*;
131use gossip::GossipSource;
132use graph::NetworkGraph;
133pub use io::utils::generate_entropy_mnemonic;
134use io::utils::write_node_metrics;
135use lightning::chain::BestBlock;
136use lightning::events::bump_transaction::{Input, Wallet as LdkWallet};
137use lightning::impl_writeable_tlv_based;
138use lightning::ln::chan_utils::{make_funding_redeemscript, FUNDING_TRANSACTION_WITNESS_WEIGHT};
139use lightning::ln::channel_state::{ChannelDetails as LdkChannelDetails, ChannelShutdownState};
140use lightning::ln::channelmanager::PaymentId;
141use lightning::ln::funding::SpliceContribution;
142use lightning::ln::msgs::SocketAddress;
143use lightning::routing::gossip::NodeAlias;
144use lightning::util::persist::KVStoreSync;
145use lightning_background_processor::process_events_async;
146use liquidity::{LSPS1Liquidity, LiquiditySource};
147use logger::{log_debug, log_error, log_info, log_trace, LdkLogger, Logger};
148use payment::asynchronous::om_mailbox::OnionMessageMailbox;
149use payment::asynchronous::static_invoice_store::StaticInvoiceStore;
150use payment::{
151 Bolt11Payment, Bolt12Payment, OnchainPayment, PaymentDetails, SpontaneousPayment,
152 UnifiedQrPayment,
153};
154use peer_store::{PeerInfo, PeerStore};
155use rand::Rng;
156use runtime::Runtime;
157use types::{
158 Broadcaster, BumpTransactionEventHandler, ChainMonitor, ChannelManager, Graph, KeysManager,
159 OnionMessenger, PaymentStore, PeerManager, Router, Scorer, Sweeper, Wallet,
160};
161pub use types::{
162 ChannelDetails, CustomTlvRecord, DynStore, PeerDetails, SyncAndAsyncKVStore, UserChannelId,
163 WordCount,
164};
165pub use {
166 bip39, bitcoin, lightning, lightning_invoice, lightning_liquidity, lightning_types, tokio,
167 vss_client,
168};
169
170use crate::scoring::setup_background_pathfinding_scores_sync;
171
172#[cfg(feature = "uniffi")]
173uniffi::include_scaffolding!("ldk_node");
174
175pub struct Node {
179 runtime: Arc<Runtime>,
180 stop_sender: tokio::sync::watch::Sender<()>,
181 background_processor_stop_sender: tokio::sync::watch::Sender<()>,
182 config: Arc<Config>,
183 wallet: Arc<Wallet>,
184 chain_source: Arc<ChainSource>,
185 tx_broadcaster: Arc<Broadcaster>,
186 fee_estimator: Arc<OnchainFeeEstimator>,
187 event_queue: Arc<EventQueue<Arc<Logger>>>,
188 channel_manager: Arc<ChannelManager>,
189 chain_monitor: Arc<ChainMonitor>,
190 output_sweeper: Arc<Sweeper>,
191 peer_manager: Arc<PeerManager>,
192 onion_messenger: Arc<OnionMessenger>,
193 connection_manager: Arc<ConnectionManager<Arc<Logger>>>,
194 keys_manager: Arc<KeysManager>,
195 network_graph: Arc<Graph>,
196 gossip_source: Arc<GossipSource>,
197 pathfinding_scores_sync_url: Option<String>,
198 liquidity_source: Option<Arc<LiquiditySource<Arc<Logger>>>>,
199 kv_store: Arc<DynStore>,
200 logger: Arc<Logger>,
201 _router: Arc<Router>,
202 scorer: Arc<Mutex<Scorer>>,
203 peer_store: Arc<PeerStore<Arc<Logger>>>,
204 payment_store: Arc<PaymentStore>,
205 is_running: Arc<RwLock<bool>>,
206 node_metrics: Arc<RwLock<NodeMetrics>>,
207 om_mailbox: Option<Arc<OnionMessageMailbox>>,
208 async_payments_role: Option<AsyncPaymentsRole>,
209}
210
211impl Node {
212 pub fn start(&self) -> Result<(), Error> {
221 let mut is_running_lock = self.is_running.write().unwrap();
223 if *is_running_lock {
224 return Err(Error::AlreadyRunning);
225 }
226
227 log_info!(
228 self.logger,
229 "Starting up LDK Node with node ID {} on network: {}",
230 self.node_id(),
231 self.config.network
232 );
233
234 self.chain_source.start(Arc::clone(&self.runtime)).map_err(|e| {
236 log_error!(self.logger, "Failed to start chain syncing: {}", e);
237 e
238 })?;
239
240 let chain_source = Arc::clone(&self.chain_source);
242 self.runtime.block_on(async move { chain_source.update_fee_rate_estimates().await })?;
243
244 let stop_sync_receiver = self.stop_sender.subscribe();
246 let chain_source = Arc::clone(&self.chain_source);
247 let sync_wallet = Arc::clone(&self.wallet);
248 let sync_cman = Arc::clone(&self.channel_manager);
249 let sync_cmon = Arc::clone(&self.chain_monitor);
250 let sync_sweeper = Arc::clone(&self.output_sweeper);
251 self.runtime.spawn_background_task(async move {
252 chain_source
253 .continuously_sync_wallets(
254 stop_sync_receiver,
255 sync_wallet,
256 sync_cman,
257 sync_cmon,
258 sync_sweeper,
259 )
260 .await;
261 });
262
263 if self.gossip_source.is_rgs() {
264 let gossip_source = Arc::clone(&self.gossip_source);
265 let gossip_sync_store = Arc::clone(&self.kv_store);
266 let gossip_sync_logger = Arc::clone(&self.logger);
267 let gossip_node_metrics = Arc::clone(&self.node_metrics);
268 let mut stop_gossip_sync = self.stop_sender.subscribe();
269 self.runtime.spawn_cancellable_background_task(async move {
270 let mut interval = tokio::time::interval(RGS_SYNC_INTERVAL);
271 loop {
272 tokio::select! {
273 _ = stop_gossip_sync.changed() => {
274 log_debug!(
275 gossip_sync_logger,
276 "Stopping background syncing RGS gossip data.",
277 );
278 return;
279 }
280 _ = interval.tick() => {
281 let now = Instant::now();
282 match gossip_source.update_rgs_snapshot().await {
283 Ok(updated_timestamp) => {
284 log_info!(
285 gossip_sync_logger,
286 "Background sync of RGS gossip data finished in {}ms.",
287 now.elapsed().as_millis()
288 );
289 {
290 let mut locked_node_metrics = gossip_node_metrics.write().unwrap();
291 locked_node_metrics.latest_rgs_snapshot_timestamp = Some(updated_timestamp);
292 write_node_metrics(&*locked_node_metrics, Arc::clone(&gossip_sync_store), Arc::clone(&gossip_sync_logger))
293 .unwrap_or_else(|e| {
294 log_error!(gossip_sync_logger, "Persistence failed: {}", e);
295 });
296 }
297 }
298 Err(e) => {
299 log_error!(
300 gossip_sync_logger,
301 "Background sync of RGS gossip data failed: {}",
302 e
303 )
304 }
305 }
306 }
307 }
308 }
309 });
310 }
311
312 if let Some(pathfinding_scores_sync_url) = self.pathfinding_scores_sync_url.as_ref() {
313 setup_background_pathfinding_scores_sync(
314 pathfinding_scores_sync_url.clone(),
315 Arc::clone(&self.scorer),
316 Arc::clone(&self.node_metrics),
317 Arc::clone(&self.kv_store),
318 Arc::clone(&self.logger),
319 Arc::clone(&self.runtime),
320 self.stop_sender.subscribe(),
321 );
322 }
323
324 if let Some(listening_addresses) = &self.config.listening_addresses {
325 let peer_manager_connection_handler = Arc::clone(&self.peer_manager);
327 let listening_logger = Arc::clone(&self.logger);
328
329 let mut bind_addrs = Vec::with_capacity(listening_addresses.len());
330
331 for listening_addr in listening_addresses {
332 let resolved_address = listening_addr.to_socket_addrs().map_err(|e| {
333 log_error!(
334 self.logger,
335 "Unable to resolve listening address: {:?}. Error details: {}",
336 listening_addr,
337 e,
338 );
339 Error::InvalidSocketAddress
340 })?;
341
342 bind_addrs.extend(resolved_address);
343 }
344
345 let logger = Arc::clone(&listening_logger);
346 let listeners = self.runtime.block_on(async move {
347 let mut listeners = Vec::new();
348
349 for addr in &*bind_addrs {
351 match tokio::net::TcpListener::bind(addr).await {
352 Ok(listener) => {
353 log_trace!(logger, "Listener bound to {}", addr);
354 listeners.push(listener);
355 },
356 Err(e) => {
357 log_error!(
358 logger,
359 "Failed to bind to {}: {} - is something else already listening?",
360 addr,
361 e
362 );
363 return Err(Error::InvalidSocketAddress);
364 },
365 }
366 }
367
368 Ok(listeners)
369 })?;
370
371 for listener in listeners {
372 let logger = Arc::clone(&listening_logger);
373 let peer_mgr = Arc::clone(&peer_manager_connection_handler);
374 let mut stop_listen = self.stop_sender.subscribe();
375 let runtime = Arc::clone(&self.runtime);
376 self.runtime.spawn_cancellable_background_task(async move {
377 loop {
378 tokio::select! {
379 _ = stop_listen.changed() => {
380 log_debug!(
381 logger,
382 "Stopping listening to inbound connections."
383 );
384 break;
385 }
386 res = listener.accept() => {
387 let tcp_stream = res.unwrap().0;
388 let peer_mgr = Arc::clone(&peer_mgr);
389 runtime.spawn_cancellable_background_task(async move {
390 lightning_net_tokio::setup_inbound(
391 Arc::clone(&peer_mgr),
392 tcp_stream.into_std().unwrap(),
393 )
394 .await;
395 });
396 }
397 }
398 }
399 });
400 }
401 }
402
403 let connect_cm = Arc::clone(&self.connection_manager);
405 let connect_pm = Arc::clone(&self.peer_manager);
406 let connect_logger = Arc::clone(&self.logger);
407 let connect_peer_store = Arc::clone(&self.peer_store);
408 let mut stop_connect = self.stop_sender.subscribe();
409 self.runtime.spawn_cancellable_background_task(async move {
410 let mut interval = tokio::time::interval(PEER_RECONNECTION_INTERVAL);
411 interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
412 loop {
413 tokio::select! {
414 _ = stop_connect.changed() => {
415 log_debug!(
416 connect_logger,
417 "Stopping reconnecting known peers."
418 );
419 return;
420 }
421 _ = interval.tick() => {
422 let pm_peers = connect_pm
423 .list_peers()
424 .iter()
425 .map(|peer| peer.counterparty_node_id)
426 .collect::<Vec<_>>();
427
428 for peer_info in connect_peer_store.list_peers().iter().filter(|info| !pm_peers.contains(&info.node_id)) {
429 let _ = connect_cm.do_connect_peer(
430 peer_info.node_id,
431 peer_info.address.clone(),
432 ).await;
433 }
434 }
435 }
436 }
437 });
438
439 let bcast_cm = Arc::clone(&self.channel_manager);
441 let bcast_pm = Arc::clone(&self.peer_manager);
442 let bcast_config = Arc::clone(&self.config);
443 let bcast_store = Arc::clone(&self.kv_store);
444 let bcast_logger = Arc::clone(&self.logger);
445 let bcast_node_metrics = Arc::clone(&self.node_metrics);
446 let mut stop_bcast = self.stop_sender.subscribe();
447 let node_alias = self.config.node_alias.clone();
448 if may_announce_channel(&self.config).is_ok() {
449 self.runtime.spawn_cancellable_background_task(async move {
450 #[cfg(not(test))]
452 let mut interval = tokio::time::interval(Duration::from_secs(30));
453 #[cfg(test)]
454 let mut interval = tokio::time::interval(Duration::from_secs(5));
455 loop {
456 tokio::select! {
457 _ = stop_bcast.changed() => {
458 log_debug!(
459 bcast_logger,
460 "Stopping broadcasting node announcements.",
461 );
462 return;
463 }
464 _ = interval.tick() => {
465 let skip_broadcast = match bcast_node_metrics.read().unwrap().latest_node_announcement_broadcast_timestamp {
466 Some(latest_bcast_time_secs) => {
467 let next_bcast_unix_time = SystemTime::UNIX_EPOCH + Duration::from_secs(latest_bcast_time_secs) + NODE_ANN_BCAST_INTERVAL;
469 next_bcast_unix_time.elapsed().is_err()
470 }
471 None => {
472 false
474 }
475 };
476
477 if skip_broadcast {
478 continue;
479 }
480
481 if !bcast_cm.list_channels().iter().any(|chan| chan.is_announced && chan.is_channel_ready) {
482 continue;
484 }
485
486 if bcast_pm.list_peers().is_empty() {
487 continue;
489 }
490
491 let addresses = if let Some(announcement_addresses) = bcast_config.announcement_addresses.clone() {
492 announcement_addresses
493 } else if let Some(listening_addresses) = bcast_config.listening_addresses.clone() {
494 listening_addresses
495 } else {
496 debug_assert!(false, "We checked whether the node may announce, so listening addresses should always be set");
497 continue;
498 };
499
500 if let Some(node_alias) = node_alias.as_ref() {
501 bcast_pm.broadcast_node_announcement([0; 3], node_alias.0, addresses);
502
503 let unix_time_secs_opt =
504 SystemTime::now().duration_since(UNIX_EPOCH).ok().map(|d| d.as_secs());
505 {
506 let mut locked_node_metrics = bcast_node_metrics.write().unwrap();
507 locked_node_metrics.latest_node_announcement_broadcast_timestamp = unix_time_secs_opt;
508 write_node_metrics(&*locked_node_metrics, Arc::clone(&bcast_store), Arc::clone(&bcast_logger))
509 .unwrap_or_else(|e| {
510 log_error!(bcast_logger, "Persistence failed: {}", e);
511 });
512 }
513 } else {
514 debug_assert!(false, "We checked whether the node may announce, so node alias should always be set");
515 continue
516 }
517 }
518 }
519 }
520 });
521 }
522
523 let stop_tx_bcast = self.stop_sender.subscribe();
524 let chain_source = Arc::clone(&self.chain_source);
525 self.runtime.spawn_cancellable_background_task(async move {
526 chain_source.continuously_process_broadcast_queue(stop_tx_bcast).await
527 });
528
529 let bump_tx_event_handler = Arc::new(BumpTransactionEventHandler::new(
530 Arc::clone(&self.tx_broadcaster),
531 Arc::new(LdkWallet::new(Arc::clone(&self.wallet), Arc::clone(&self.logger))),
532 Arc::clone(&self.keys_manager),
533 Arc::clone(&self.logger),
534 ));
535
536 let static_invoice_store = if let Some(AsyncPaymentsRole::Server) = self.async_payments_role
537 {
538 Some(StaticInvoiceStore::new(Arc::clone(&self.kv_store)))
539 } else {
540 None
541 };
542
543 let event_handler = Arc::new(EventHandler::new(
544 Arc::clone(&self.event_queue),
545 Arc::clone(&self.wallet),
546 bump_tx_event_handler,
547 Arc::clone(&self.channel_manager),
548 Arc::clone(&self.connection_manager),
549 Arc::clone(&self.output_sweeper),
550 Arc::clone(&self.network_graph),
551 self.liquidity_source.clone(),
552 Arc::clone(&self.payment_store),
553 Arc::clone(&self.peer_store),
554 static_invoice_store,
555 Arc::clone(&self.onion_messenger),
556 self.om_mailbox.clone(),
557 Arc::clone(&self.runtime),
558 Arc::clone(&self.logger),
559 Arc::clone(&self.config),
560 ));
561
562 let background_persister = Arc::clone(&self.kv_store);
564 let background_event_handler = Arc::clone(&event_handler);
565 let background_chain_mon = Arc::clone(&self.chain_monitor);
566 let background_chan_man = Arc::clone(&self.channel_manager);
567 let background_gossip_sync = self.gossip_source.as_gossip_sync();
568 let background_peer_man = Arc::clone(&self.peer_manager);
569 let background_liquidity_man_opt =
570 self.liquidity_source.as_ref().map(|ls| ls.liquidity_manager());
571 let background_sweeper = Arc::clone(&self.output_sweeper);
572 let background_onion_messenger = Arc::clone(&self.onion_messenger);
573 let background_logger = Arc::clone(&self.logger);
574 let background_error_logger = Arc::clone(&self.logger);
575 let background_scorer = Arc::clone(&self.scorer);
576 let stop_bp = self.background_processor_stop_sender.subscribe();
577 let sleeper_logger = Arc::clone(&self.logger);
578 let sleeper = move |d| {
579 let mut stop = stop_bp.clone();
580 let sleeper_logger = Arc::clone(&sleeper_logger);
581 Box::pin(async move {
582 tokio::select! {
583 _ = stop.changed() => {
584 log_debug!(
585 sleeper_logger,
586 "Stopping processing events.",
587 );
588 true
589 }
590 _ = tokio::time::sleep(d) => {
591 false
592 }
593 }
594 })
595 };
596
597 self.runtime.spawn_background_processor_task(async move {
598 process_events_async(
599 background_persister,
600 |e| background_event_handler.handle_event(e),
601 background_chain_mon,
602 background_chan_man,
603 Some(background_onion_messenger),
604 background_gossip_sync,
605 background_peer_man,
606 background_liquidity_man_opt,
607 Some(background_sweeper),
608 background_logger,
609 Some(background_scorer),
610 sleeper,
611 true,
612 || Some(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()),
613 )
614 .await
615 .unwrap_or_else(|e| {
616 log_error!(background_error_logger, "Failed to process events: {}", e);
617 panic!("Failed to process events");
618 });
619 });
620
621 if let Some(liquidity_source) = self.liquidity_source.as_ref() {
622 let mut stop_liquidity_handler = self.stop_sender.subscribe();
623 let liquidity_handler = Arc::clone(&liquidity_source);
624 let liquidity_logger = Arc::clone(&self.logger);
625 self.runtime.spawn_background_task(async move {
626 loop {
627 tokio::select! {
628 _ = stop_liquidity_handler.changed() => {
629 log_debug!(
630 liquidity_logger,
631 "Stopping processing liquidity events.",
632 );
633 return;
634 }
635 _ = liquidity_handler.handle_next_event() => {}
636 }
637 }
638 });
639 }
640
641 log_info!(self.logger, "Startup complete.");
642 *is_running_lock = true;
643 Ok(())
644 }
645
646 pub fn stop(&self) -> Result<(), Error> {
650 let mut is_running_lock = self.is_running.write().unwrap();
651 if !*is_running_lock {
652 return Err(Error::NotRunning);
653 }
654
655 log_info!(self.logger, "Shutting down LDK Node with node ID {}...", self.node_id());
656
657 self.stop_sender
659 .send(())
660 .map(|_| {
661 log_trace!(self.logger, "Sent shutdown signal to background tasks.");
662 })
663 .unwrap_or_else(|e| {
664 log_error!(
665 self.logger,
666 "Failed to send shutdown signal. This should never happen: {}",
667 e
668 );
669 debug_assert!(false);
670 });
671
672 self.runtime.abort_cancellable_background_tasks();
674
675 self.peer_manager.disconnect_all_peers();
677 log_debug!(self.logger, "Disconnected all network peers.");
678
679 self.runtime.wait_on_background_tasks();
681
682 self.chain_source.stop();
684 log_debug!(self.logger, "Stopped chain sources.");
685
686 self.background_processor_stop_sender
688 .send(())
689 .map(|_| {
690 log_trace!(self.logger, "Sent shutdown signal to background processor.");
691 })
692 .unwrap_or_else(|e| {
693 log_error!(
694 self.logger,
695 "Failed to send shutdown signal. This should never happen: {}",
696 e
697 );
698 debug_assert!(false);
699 });
700
701 self.runtime.wait_on_background_processor_task();
703
704 #[cfg(tokio_unstable)]
705 self.runtime.log_metrics();
706
707 log_info!(self.logger, "Shutdown complete.");
708 *is_running_lock = false;
709 Ok(())
710 }
711
712 pub fn status(&self) -> NodeStatus {
714 let is_running = *self.is_running.read().unwrap();
715 let current_best_block = self.channel_manager.current_best_block().into();
716 let locked_node_metrics = self.node_metrics.read().unwrap();
717 let latest_lightning_wallet_sync_timestamp =
718 locked_node_metrics.latest_lightning_wallet_sync_timestamp;
719 let latest_onchain_wallet_sync_timestamp =
720 locked_node_metrics.latest_onchain_wallet_sync_timestamp;
721 let latest_fee_rate_cache_update_timestamp =
722 locked_node_metrics.latest_fee_rate_cache_update_timestamp;
723 let latest_rgs_snapshot_timestamp =
724 locked_node_metrics.latest_rgs_snapshot_timestamp.map(|val| val as u64);
725 let latest_pathfinding_scores_sync_timestamp =
726 locked_node_metrics.latest_pathfinding_scores_sync_timestamp;
727 let latest_node_announcement_broadcast_timestamp =
728 locked_node_metrics.latest_node_announcement_broadcast_timestamp;
729 let latest_channel_monitor_archival_height =
730 locked_node_metrics.latest_channel_monitor_archival_height;
731
732 NodeStatus {
733 is_running,
734 current_best_block,
735 latest_lightning_wallet_sync_timestamp,
736 latest_onchain_wallet_sync_timestamp,
737 latest_fee_rate_cache_update_timestamp,
738 latest_rgs_snapshot_timestamp,
739 latest_pathfinding_scores_sync_timestamp,
740 latest_node_announcement_broadcast_timestamp,
741 latest_channel_monitor_archival_height,
742 }
743 }
744
745 pub fn config(&self) -> Config {
747 self.config.as_ref().clone()
748 }
749
750 pub fn next_event(&self) -> Option<Event> {
759 self.event_queue.next_event()
760 }
761
762 pub async fn next_event_async(&self) -> Event {
771 self.event_queue.next_event_async().await
772 }
773
774 pub fn wait_next_event(&self) -> Event {
783 let fut = self.event_queue.next_event_async();
784 self.runtime.block_on(fut)
787 }
788
789 pub fn event_handled(&self) -> Result<(), Error> {
793 let fut = self.event_queue.event_handled();
796 self.runtime.block_on(fut).map_err(|e| {
797 log_error!(
798 self.logger,
799 "Couldn't mark event handled due to persistence failure: {}",
800 e
801 );
802 e
803 })
804 }
805
806 pub fn node_id(&self) -> PublicKey {
808 self.channel_manager.get_our_node_id()
809 }
810
811 pub fn listening_addresses(&self) -> Option<Vec<SocketAddress>> {
813 self.config.listening_addresses.clone()
814 }
815
816 pub fn announcement_addresses(&self) -> Option<Vec<SocketAddress>> {
818 self.config
819 .announcement_addresses
820 .clone()
821 .or_else(|| self.config.listening_addresses.clone())
822 }
823
824 pub fn node_alias(&self) -> Option<NodeAlias> {
826 self.config.node_alias
827 }
828
829 #[cfg(not(feature = "uniffi"))]
833 pub fn bolt11_payment(&self) -> Bolt11Payment {
834 Bolt11Payment::new(
835 Arc::clone(&self.runtime),
836 Arc::clone(&self.channel_manager),
837 Arc::clone(&self.connection_manager),
838 self.liquidity_source.clone(),
839 Arc::clone(&self.payment_store),
840 Arc::clone(&self.peer_store),
841 Arc::clone(&self.config),
842 Arc::clone(&self.is_running),
843 Arc::clone(&self.logger),
844 )
845 }
846
847 #[cfg(feature = "uniffi")]
851 pub fn bolt11_payment(&self) -> Arc<Bolt11Payment> {
852 Arc::new(Bolt11Payment::new(
853 Arc::clone(&self.runtime),
854 Arc::clone(&self.channel_manager),
855 Arc::clone(&self.connection_manager),
856 self.liquidity_source.clone(),
857 Arc::clone(&self.payment_store),
858 Arc::clone(&self.peer_store),
859 Arc::clone(&self.config),
860 Arc::clone(&self.is_running),
861 Arc::clone(&self.logger),
862 ))
863 }
864
865 #[cfg(not(feature = "uniffi"))]
869 pub fn bolt12_payment(&self) -> Bolt12Payment {
870 Bolt12Payment::new(
871 Arc::clone(&self.channel_manager),
872 Arc::clone(&self.payment_store),
873 Arc::clone(&self.config),
874 Arc::clone(&self.is_running),
875 Arc::clone(&self.logger),
876 self.async_payments_role,
877 )
878 }
879
880 #[cfg(feature = "uniffi")]
884 pub fn bolt12_payment(&self) -> Arc<Bolt12Payment> {
885 Arc::new(Bolt12Payment::new(
886 Arc::clone(&self.channel_manager),
887 Arc::clone(&self.payment_store),
888 Arc::clone(&self.config),
889 Arc::clone(&self.is_running),
890 Arc::clone(&self.logger),
891 self.async_payments_role,
892 ))
893 }
894
895 #[cfg(not(feature = "uniffi"))]
897 pub fn spontaneous_payment(&self) -> SpontaneousPayment {
898 SpontaneousPayment::new(
899 Arc::clone(&self.channel_manager),
900 Arc::clone(&self.keys_manager),
901 Arc::clone(&self.payment_store),
902 Arc::clone(&self.config),
903 Arc::clone(&self.is_running),
904 Arc::clone(&self.logger),
905 )
906 }
907
908 #[cfg(feature = "uniffi")]
910 pub fn spontaneous_payment(&self) -> Arc<SpontaneousPayment> {
911 Arc::new(SpontaneousPayment::new(
912 Arc::clone(&self.channel_manager),
913 Arc::clone(&self.keys_manager),
914 Arc::clone(&self.payment_store),
915 Arc::clone(&self.config),
916 Arc::clone(&self.is_running),
917 Arc::clone(&self.logger),
918 ))
919 }
920
921 #[cfg(not(feature = "uniffi"))]
923 pub fn onchain_payment(&self) -> OnchainPayment {
924 OnchainPayment::new(
925 Arc::clone(&self.wallet),
926 Arc::clone(&self.channel_manager),
927 Arc::clone(&self.config),
928 Arc::clone(&self.is_running),
929 Arc::clone(&self.logger),
930 )
931 }
932
933 #[cfg(feature = "uniffi")]
935 pub fn onchain_payment(&self) -> Arc<OnchainPayment> {
936 Arc::new(OnchainPayment::new(
937 Arc::clone(&self.wallet),
938 Arc::clone(&self.channel_manager),
939 Arc::clone(&self.config),
940 Arc::clone(&self.is_running),
941 Arc::clone(&self.logger),
942 ))
943 }
944
945 #[cfg(not(feature = "uniffi"))]
952 pub fn unified_qr_payment(&self) -> UnifiedQrPayment {
953 UnifiedQrPayment::new(
954 self.onchain_payment().into(),
955 self.bolt11_payment().into(),
956 self.bolt12_payment().into(),
957 Arc::clone(&self.config),
958 Arc::clone(&self.logger),
959 )
960 }
961
962 #[cfg(feature = "uniffi")]
969 pub fn unified_qr_payment(&self) -> Arc<UnifiedQrPayment> {
970 Arc::new(UnifiedQrPayment::new(
971 self.onchain_payment(),
972 self.bolt11_payment(),
973 self.bolt12_payment(),
974 Arc::clone(&self.config),
975 Arc::clone(&self.logger),
976 ))
977 }
978
979 #[cfg(not(feature = "uniffi"))]
983 pub fn lsps1_liquidity(&self) -> LSPS1Liquidity {
984 LSPS1Liquidity::new(
985 Arc::clone(&self.runtime),
986 Arc::clone(&self.wallet),
987 Arc::clone(&self.connection_manager),
988 self.liquidity_source.clone(),
989 Arc::clone(&self.logger),
990 )
991 }
992
993 #[cfg(feature = "uniffi")]
997 pub fn lsps1_liquidity(&self) -> Arc<LSPS1Liquidity> {
998 Arc::new(LSPS1Liquidity::new(
999 Arc::clone(&self.runtime),
1000 Arc::clone(&self.wallet),
1001 Arc::clone(&self.connection_manager),
1002 self.liquidity_source.clone(),
1003 Arc::clone(&self.logger),
1004 ))
1005 }
1006
1007 pub fn list_channels(&self) -> Vec<ChannelDetails> {
1009 self.channel_manager.list_channels().into_iter().map(|c| c.into()).collect()
1010 }
1011
1012 pub fn connect(
1016 &self, node_id: PublicKey, address: SocketAddress, persist: bool,
1017 ) -> Result<(), Error> {
1018 if !*self.is_running.read().unwrap() {
1019 return Err(Error::NotRunning);
1020 }
1021
1022 let peer_info = PeerInfo { node_id, address };
1023
1024 let con_node_id = peer_info.node_id;
1025 let con_addr = peer_info.address.clone();
1026 let con_cm = Arc::clone(&self.connection_manager);
1027
1028 self.runtime.block_on(async move {
1031 con_cm.connect_peer_if_necessary(con_node_id, con_addr).await
1032 })?;
1033
1034 log_info!(self.logger, "Connected to peer {}@{}. ", peer_info.node_id, peer_info.address);
1035
1036 if persist {
1037 self.peer_store.add_peer(peer_info)?;
1038 }
1039
1040 Ok(())
1041 }
1042
1043 pub fn disconnect(&self, counterparty_node_id: PublicKey) -> Result<(), Error> {
1048 if !*self.is_running.read().unwrap() {
1049 return Err(Error::NotRunning);
1050 }
1051
1052 log_info!(self.logger, "Disconnecting peer {}..", counterparty_node_id);
1053
1054 match self.peer_store.remove_peer(&counterparty_node_id) {
1055 Ok(()) => {},
1056 Err(e) => {
1057 log_error!(self.logger, "Failed to remove peer {}: {}", counterparty_node_id, e)
1058 },
1059 }
1060
1061 self.peer_manager.disconnect_by_node_id(counterparty_node_id);
1062 Ok(())
1063 }
1064
1065 fn open_channel_inner(
1066 &self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64,
1067 push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
1068 announce_for_forwarding: bool,
1069 ) -> Result<UserChannelId, Error> {
1070 if !*self.is_running.read().unwrap() {
1071 return Err(Error::NotRunning);
1072 }
1073
1074 let peer_info = PeerInfo { node_id, address };
1075
1076 let con_node_id = peer_info.node_id;
1077 let con_addr = peer_info.address.clone();
1078 let con_cm = Arc::clone(&self.connection_manager);
1079
1080 self.runtime.block_on(async move {
1083 con_cm.connect_peer_if_necessary(con_node_id, con_addr).await
1084 })?;
1085
1086 self.check_sufficient_funds_for_channel(channel_amount_sats, &node_id)?;
1088
1089 let mut user_config = default_user_config(&self.config);
1090 user_config.channel_handshake_config.announce_for_forwarding = announce_for_forwarding;
1091 user_config.channel_config = (channel_config.unwrap_or_default()).clone().into();
1092 if !announce_for_forwarding {
1096 user_config
1097 .channel_handshake_config
1098 .max_inbound_htlc_value_in_flight_percent_of_channel = 100;
1099 }
1100
1101 let push_msat = push_to_counterparty_msat.unwrap_or(0);
1102 let user_channel_id: u128 = rand::rng().random();
1103
1104 match self.channel_manager.create_channel(
1105 peer_info.node_id,
1106 channel_amount_sats,
1107 push_msat,
1108 user_channel_id,
1109 None,
1110 Some(user_config),
1111 ) {
1112 Ok(_) => {
1113 log_info!(
1114 self.logger,
1115 "Initiated channel creation with peer {}. ",
1116 peer_info.node_id
1117 );
1118 self.peer_store.add_peer(peer_info)?;
1119 Ok(UserChannelId(user_channel_id))
1120 },
1121 Err(e) => {
1122 log_error!(self.logger, "Failed to initiate channel creation: {:?}", e);
1123 Err(Error::ChannelCreationFailed)
1124 },
1125 }
1126 }
1127
1128 fn check_sufficient_funds_for_channel(
1129 &self, amount_sats: u64, peer_node_id: &PublicKey,
1130 ) -> Result<(), Error> {
1131 let cur_anchor_reserve_sats =
1132 total_anchor_channels_reserve_sats(&self.channel_manager, &self.config);
1133 let spendable_amount_sats =
1134 self.wallet.get_spendable_amount_sats(cur_anchor_reserve_sats).unwrap_or(0);
1135
1136 if spendable_amount_sats < amount_sats {
1138 log_error!(self.logger,
1139 "Unable to create channel due to insufficient funds. Available: {}sats, Required: {}sats",
1140 spendable_amount_sats, amount_sats
1141 );
1142 return Err(Error::InsufficientFunds);
1143 }
1144
1145 let init_features = self
1147 .peer_manager
1148 .peer_by_node_id(peer_node_id)
1149 .ok_or(Error::ConnectionFailed)?
1150 .init_features;
1151 let required_funds_sats = amount_sats
1152 + self.config.anchor_channels_config.as_ref().map_or(0, |c| {
1153 if init_features.requires_anchors_zero_fee_htlc_tx()
1154 && !c.trusted_peers_no_reserve.contains(peer_node_id)
1155 {
1156 c.per_channel_reserve_sats
1157 } else {
1158 0
1159 }
1160 });
1161
1162 if spendable_amount_sats < required_funds_sats {
1163 log_error!(self.logger,
1164 "Unable to create channel due to insufficient funds. Available: {}sats, Required: {}sats",
1165 spendable_amount_sats, required_funds_sats
1166 );
1167 return Err(Error::InsufficientFunds);
1168 }
1169
1170 Ok(())
1171 }
1172
1173 pub fn open_channel(
1191 &self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64,
1192 push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
1193 ) -> Result<UserChannelId, Error> {
1194 self.open_channel_inner(
1195 node_id,
1196 address,
1197 channel_amount_sats,
1198 push_to_counterparty_msat,
1199 channel_config,
1200 false,
1201 )
1202 }
1203
1204 pub fn open_announced_channel(
1226 &self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64,
1227 push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
1228 ) -> Result<UserChannelId, Error> {
1229 if let Err(err) = may_announce_channel(&self.config) {
1230 log_error!(self.logger, "Failed to open announced channel as the node hasn't been sufficiently configured to act as a forwarding node: {}", err);
1231 return Err(Error::ChannelCreationFailed);
1232 }
1233
1234 self.open_channel_inner(
1235 node_id,
1236 address,
1237 channel_amount_sats,
1238 push_to_counterparty_msat,
1239 channel_config,
1240 true,
1241 )
1242 }
1243
1244 pub fn splice_in(
1255 &self, user_channel_id: &UserChannelId, counterparty_node_id: PublicKey,
1256 splice_amount_sats: u64,
1257 ) -> Result<(), Error> {
1258 let open_channels =
1259 self.channel_manager.list_channels_with_counterparty(&counterparty_node_id);
1260 if let Some(channel_details) =
1261 open_channels.iter().find(|c| c.user_channel_id == user_channel_id.0)
1262 {
1263 self.check_sufficient_funds_for_channel(splice_amount_sats, &counterparty_node_id)?;
1264
1265 const EMPTY_SCRIPT_SIG_WEIGHT: u64 =
1266 1 * bitcoin::constants::WITNESS_SCALE_FACTOR as u64;
1267
1268 let dummy_pubkey = PublicKey::from_slice(&[2; 33]).unwrap();
1272
1273 let funding_txo = channel_details.funding_txo.ok_or_else(|| {
1274 log_error!(self.logger, "Failed to splice channel: channel not yet ready",);
1275 Error::ChannelSplicingFailed
1276 })?;
1277
1278 let shared_input = Input {
1279 outpoint: funding_txo.into_bitcoin_outpoint(),
1280 previous_utxo: bitcoin::TxOut {
1281 value: Amount::from_sat(channel_details.channel_value_satoshis),
1282 script_pubkey: make_funding_redeemscript(&dummy_pubkey, &dummy_pubkey)
1283 .to_p2wsh(),
1284 },
1285 satisfaction_weight: EMPTY_SCRIPT_SIG_WEIGHT + FUNDING_TRANSACTION_WITNESS_WEIGHT,
1286 };
1287
1288 let shared_output = bitcoin::TxOut {
1289 value: shared_input.previous_utxo.value + Amount::from_sat(splice_amount_sats),
1290 script_pubkey: make_funding_redeemscript(&dummy_pubkey, &dummy_pubkey).to_p2wsh(),
1291 };
1292
1293 let fee_rate = self.fee_estimator.estimate_fee_rate(ConfirmationTarget::ChannelFunding);
1294
1295 let inputs = self
1296 .wallet
1297 .select_confirmed_utxos(vec![shared_input], &[shared_output], fee_rate)
1298 .map_err(|()| {
1299 log_error!(
1300 self.logger,
1301 "Failed to splice channel: insufficient confirmed UTXOs",
1302 );
1303 Error::ChannelSplicingFailed
1304 })?;
1305
1306 let change_address = self.wallet.get_new_internal_address()?;
1307
1308 let contribution = SpliceContribution::SpliceIn {
1309 value: Amount::from_sat(splice_amount_sats),
1310 inputs,
1311 change_script: Some(change_address.script_pubkey()),
1312 };
1313
1314 let funding_feerate_per_kw: u32 = match fee_rate.to_sat_per_kwu().try_into() {
1315 Ok(fee_rate) => fee_rate,
1316 Err(_) => {
1317 debug_assert!(false);
1318 fee_estimator::get_fallback_rate_for_target(ConfirmationTarget::ChannelFunding)
1319 },
1320 };
1321
1322 self.channel_manager
1323 .splice_channel(
1324 &channel_details.channel_id,
1325 &counterparty_node_id,
1326 contribution,
1327 funding_feerate_per_kw,
1328 None,
1329 )
1330 .map_err(|e| {
1331 log_error!(self.logger, "Failed to splice channel: {:?}", e);
1332 let tx = bitcoin::Transaction {
1333 version: bitcoin::transaction::Version::TWO,
1334 lock_time: bitcoin::absolute::LockTime::ZERO,
1335 input: vec![],
1336 output: vec![bitcoin::TxOut {
1337 value: Amount::ZERO,
1338 script_pubkey: change_address.script_pubkey(),
1339 }],
1340 };
1341 match self.wallet.cancel_tx(&tx) {
1342 Ok(()) => Error::ChannelSplicingFailed,
1343 Err(e) => e,
1344 }
1345 })
1346 } else {
1347 log_error!(
1348 self.logger,
1349 "Channel not found for user_channel_id {} and counterparty {}",
1350 user_channel_id,
1351 counterparty_node_id
1352 );
1353
1354 Err(Error::ChannelSplicingFailed)
1355 }
1356 }
1357
1358 pub fn splice_out(
1370 &self, user_channel_id: &UserChannelId, counterparty_node_id: PublicKey, address: &Address,
1371 splice_amount_sats: u64,
1372 ) -> Result<(), Error> {
1373 let open_channels =
1374 self.channel_manager.list_channels_with_counterparty(&counterparty_node_id);
1375 if let Some(channel_details) =
1376 open_channels.iter().find(|c| c.user_channel_id == user_channel_id.0)
1377 {
1378 if splice_amount_sats > channel_details.outbound_capacity_msat {
1379 return Err(Error::ChannelSplicingFailed);
1380 }
1381
1382 self.wallet.parse_and_validate_address(address)?;
1383
1384 let contribution = SpliceContribution::SpliceOut {
1385 outputs: vec![bitcoin::TxOut {
1386 value: Amount::from_sat(splice_amount_sats),
1387 script_pubkey: address.script_pubkey(),
1388 }],
1389 };
1390
1391 let fee_rate = self.fee_estimator.estimate_fee_rate(ConfirmationTarget::ChannelFunding);
1392 let funding_feerate_per_kw: u32 = match fee_rate.to_sat_per_kwu().try_into() {
1393 Ok(fee_rate) => fee_rate,
1394 Err(_) => {
1395 debug_assert!(false, "FeeRate should always fit within u32");
1396 log_error!(self.logger, "FeeRate should always fit within u32");
1397 fee_estimator::get_fallback_rate_for_target(ConfirmationTarget::ChannelFunding)
1398 },
1399 };
1400
1401 self.channel_manager
1402 .splice_channel(
1403 &channel_details.channel_id,
1404 &counterparty_node_id,
1405 contribution,
1406 funding_feerate_per_kw,
1407 None,
1408 )
1409 .map_err(|e| {
1410 log_error!(self.logger, "Failed to splice channel: {:?}", e);
1411 Error::ChannelSplicingFailed
1412 })
1413 } else {
1414 log_error!(
1415 self.logger,
1416 "Channel not found for user_channel_id {} and counterparty {}",
1417 user_channel_id,
1418 counterparty_node_id
1419 );
1420 Err(Error::ChannelSplicingFailed)
1421 }
1422 }
1423
1424 pub fn sync_wallets(&self) -> Result<(), Error> {
1435 if !*self.is_running.read().unwrap() {
1436 return Err(Error::NotRunning);
1437 }
1438
1439 let chain_source = Arc::clone(&self.chain_source);
1440 let sync_wallet = Arc::clone(&self.wallet);
1441 let sync_cman = Arc::clone(&self.channel_manager);
1442 let sync_cmon = Arc::clone(&self.chain_monitor);
1443 let sync_sweeper = Arc::clone(&self.output_sweeper);
1444 self.runtime.block_on(async move {
1445 if chain_source.is_transaction_based() {
1446 chain_source.update_fee_rate_estimates().await?;
1447 chain_source
1448 .sync_lightning_wallet(sync_cman, sync_cmon, Arc::clone(&sync_sweeper))
1449 .await?;
1450 chain_source.sync_onchain_wallet(sync_wallet).await?;
1451 } else {
1452 chain_source.update_fee_rate_estimates().await?;
1453 chain_source
1454 .poll_and_update_listeners(
1455 sync_wallet,
1456 sync_cman,
1457 sync_cmon,
1458 Arc::clone(&sync_sweeper),
1459 )
1460 .await?;
1461 }
1462 let _ = sync_sweeper.regenerate_and_broadcast_spend_if_necessary().await;
1463 Ok(())
1464 })
1465 }
1466
1467 pub fn close_channel(
1472 &self, user_channel_id: &UserChannelId, counterparty_node_id: PublicKey,
1473 ) -> Result<(), Error> {
1474 self.close_channel_internal(user_channel_id, counterparty_node_id, false, None)
1475 }
1476
1477 pub fn force_close_channel(
1491 &self, user_channel_id: &UserChannelId, counterparty_node_id: PublicKey,
1492 reason: Option<String>,
1493 ) -> Result<(), Error> {
1494 self.close_channel_internal(user_channel_id, counterparty_node_id, true, reason)
1495 }
1496
1497 fn close_channel_internal(
1498 &self, user_channel_id: &UserChannelId, counterparty_node_id: PublicKey, force: bool,
1499 force_close_reason: Option<String>,
1500 ) -> Result<(), Error> {
1501 debug_assert!(
1502 force_close_reason.is_none() || force,
1503 "Reason can only be set for force closures"
1504 );
1505 let open_channels: Vec<LdkChannelDetails> =
1506 self.channel_manager.list_channels_with_counterparty(&counterparty_node_id);
1507 if let Some(channel_details) =
1508 open_channels.iter().find(|c| c.user_channel_id == user_channel_id.0)
1509 {
1510 if force {
1511 self.channel_manager
1512 .force_close_broadcasting_latest_txn(
1513 &channel_details.channel_id,
1514 &counterparty_node_id,
1515 force_close_reason.unwrap_or_default(),
1516 )
1517 .map_err(|e| {
1518 log_error!(self.logger, "Failed to force-close channel: {:?}", e);
1519 Error::ChannelClosingFailed
1520 })?;
1521 } else {
1522 self.channel_manager
1523 .close_channel(&channel_details.channel_id, &counterparty_node_id)
1524 .map_err(|e| {
1525 log_error!(self.logger, "Failed to close channel: {:?}", e);
1526 Error::ChannelClosingFailed
1527 })?;
1528 }
1529
1530 if open_channels.len() == 1 {
1532 self.peer_store.remove_peer(&counterparty_node_id)?;
1533 }
1534 }
1535
1536 Ok(())
1537 }
1538
1539 pub fn update_channel_config(
1541 &self, user_channel_id: &UserChannelId, counterparty_node_id: PublicKey,
1542 channel_config: ChannelConfig,
1543 ) -> Result<(), Error> {
1544 let open_channels: Vec<LdkChannelDetails> =
1545 self.channel_manager.list_channels_with_counterparty(&counterparty_node_id);
1546 if let Some(channel_details) =
1547 open_channels.iter().find(|c| c.user_channel_id == user_channel_id.0)
1548 {
1549 self.channel_manager
1550 .update_channel_config(
1551 &counterparty_node_id,
1552 &[channel_details.channel_id],
1553 &(channel_config).clone().into(),
1554 )
1555 .map_err(|_| Error::ChannelConfigUpdateFailed)
1556 } else {
1557 Err(Error::ChannelConfigUpdateFailed)
1558 }
1559 }
1560
1561 pub fn payment(&self, payment_id: &PaymentId) -> Option<PaymentDetails> {
1565 self.payment_store.get(payment_id)
1566 }
1567
1568 pub fn remove_payment(&self, payment_id: &PaymentId) -> Result<(), Error> {
1570 self.payment_store.remove(&payment_id)
1571 }
1572
1573 pub fn list_balances(&self) -> BalanceDetails {
1575 let cur_anchor_reserve_sats =
1576 total_anchor_channels_reserve_sats(&self.channel_manager, &self.config);
1577 let (total_onchain_balance_sats, spendable_onchain_balance_sats) =
1578 self.wallet.get_balances(cur_anchor_reserve_sats).unwrap_or((0, 0));
1579
1580 let total_anchor_channels_reserve_sats =
1581 std::cmp::min(cur_anchor_reserve_sats, total_onchain_balance_sats);
1582
1583 let mut total_lightning_balance_sats = 0;
1584 let mut lightning_balances = Vec::new();
1585 for channel_id in self.chain_monitor.list_monitors() {
1586 match self.chain_monitor.get_monitor(channel_id) {
1587 Ok(monitor) => {
1588 let counterparty_node_id = monitor.get_counterparty_node_id();
1589 for ldk_balance in monitor.get_claimable_balances() {
1590 total_lightning_balance_sats += ldk_balance.claimable_amount_satoshis();
1591 lightning_balances.push(LightningBalance::from_ldk_balance(
1592 channel_id,
1593 counterparty_node_id,
1594 ldk_balance,
1595 ));
1596 }
1597 },
1598 Err(()) => {
1599 continue;
1600 },
1601 }
1602 }
1603
1604 let pending_balances_from_channel_closures = self
1605 .output_sweeper
1606 .tracked_spendable_outputs()
1607 .into_iter()
1608 .map(PendingSweepBalance::from_tracked_spendable_output)
1609 .collect();
1610
1611 BalanceDetails {
1612 total_onchain_balance_sats,
1613 spendable_onchain_balance_sats,
1614 total_anchor_channels_reserve_sats,
1615 total_lightning_balance_sats,
1616 lightning_balances,
1617 pending_balances_from_channel_closures,
1618 }
1619 }
1620
1621 pub fn list_payments_with_filter<F: FnMut(&&PaymentDetails) -> bool>(
1637 &self, f: F,
1638 ) -> Vec<PaymentDetails> {
1639 self.payment_store.list_filter(f)
1640 }
1641
1642 pub fn list_payments(&self) -> Vec<PaymentDetails> {
1644 self.payment_store.list_filter(|_| true)
1645 }
1646
1647 pub fn list_peers(&self) -> Vec<PeerDetails> {
1649 let mut peers = Vec::new();
1650
1651 let connected_peers = self.peer_manager.list_peers();
1653 let connected_peers_len = connected_peers.len();
1654 for connected_peer in connected_peers {
1655 let node_id = connected_peer.counterparty_node_id;
1656 let stored_peer = self.peer_store.get_peer(&node_id);
1657 let stored_addr_opt = stored_peer.as_ref().map(|p| p.address.clone());
1658 let address = match (connected_peer.socket_address, stored_addr_opt) {
1659 (Some(con_addr), _) => con_addr,
1660 (None, Some(stored_addr)) => stored_addr,
1661 (None, None) => continue,
1662 };
1663
1664 let is_persisted = stored_peer.is_some();
1665 let is_connected = true;
1666 let details = PeerDetails { node_id, address, is_persisted, is_connected };
1667 peers.push(details);
1668 }
1669
1670 for p in self.peer_store.list_peers() {
1672 if peers.iter().take(connected_peers_len).any(|d| d.node_id == p.node_id) {
1673 continue;
1674 }
1675
1676 let details = PeerDetails {
1677 node_id: p.node_id,
1678 address: p.address,
1679 is_persisted: true,
1680 is_connected: false,
1681 };
1682
1683 peers.push(details);
1684 }
1685
1686 peers
1687 }
1688
1689 #[cfg(not(feature = "uniffi"))]
1691 pub fn network_graph(&self) -> NetworkGraph {
1692 NetworkGraph::new(Arc::clone(&self.network_graph))
1693 }
1694
1695 #[cfg(feature = "uniffi")]
1697 pub fn network_graph(&self) -> Arc<NetworkGraph> {
1698 Arc::new(NetworkGraph::new(Arc::clone(&self.network_graph)))
1699 }
1700
1701 pub fn sign_message(&self, msg: &[u8]) -> String {
1708 self.keys_manager.sign_message(msg)
1709 }
1710
1711 pub fn verify_signature(&self, msg: &[u8], sig: &str, pkey: &PublicKey) -> bool {
1714 self.keys_manager.verify_signature(msg, sig, pkey)
1715 }
1716
1717 pub fn export_pathfinding_scores(&self) -> Result<Vec<u8>, Error> {
1720 KVStoreSync::read(
1721 &*self.kv_store,
1722 lightning::util::persist::SCORER_PERSISTENCE_PRIMARY_NAMESPACE,
1723 lightning::util::persist::SCORER_PERSISTENCE_SECONDARY_NAMESPACE,
1724 lightning::util::persist::SCORER_PERSISTENCE_KEY,
1725 )
1726 .map_err(|e| {
1727 log_error!(
1728 self.logger,
1729 "Failed to access store while exporting pathfinding scores: {}",
1730 e
1731 );
1732 Error::PersistenceFailed
1733 })
1734 }
1735}
1736
1737impl Drop for Node {
1738 fn drop(&mut self) {
1739 let _ = self.stop();
1740 }
1741}
1742
1743#[derive(Clone, Debug, PartialEq, Eq)]
1745pub struct NodeStatus {
1746 pub is_running: bool,
1748 pub current_best_block: BestBlock,
1750 pub latest_lightning_wallet_sync_timestamp: Option<u64>,
1755 pub latest_onchain_wallet_sync_timestamp: Option<u64>,
1760 pub latest_fee_rate_cache_update_timestamp: Option<u64>,
1765 pub latest_rgs_snapshot_timestamp: Option<u64>,
1770 pub latest_pathfinding_scores_sync_timestamp: Option<u64>,
1772 pub latest_node_announcement_broadcast_timestamp: Option<u64>,
1777 pub latest_channel_monitor_archival_height: Option<u32>,
1781}
1782
1783#[derive(Clone, Debug, PartialEq, Eq)]
1785pub(crate) struct NodeMetrics {
1786 latest_lightning_wallet_sync_timestamp: Option<u64>,
1787 latest_onchain_wallet_sync_timestamp: Option<u64>,
1788 latest_fee_rate_cache_update_timestamp: Option<u64>,
1789 latest_rgs_snapshot_timestamp: Option<u32>,
1790 latest_pathfinding_scores_sync_timestamp: Option<u64>,
1791 latest_node_announcement_broadcast_timestamp: Option<u64>,
1792 latest_channel_monitor_archival_height: Option<u32>,
1793}
1794
1795impl Default for NodeMetrics {
1796 fn default() -> Self {
1797 Self {
1798 latest_lightning_wallet_sync_timestamp: None,
1799 latest_onchain_wallet_sync_timestamp: None,
1800 latest_fee_rate_cache_update_timestamp: None,
1801 latest_rgs_snapshot_timestamp: None,
1802 latest_pathfinding_scores_sync_timestamp: None,
1803 latest_node_announcement_broadcast_timestamp: None,
1804 latest_channel_monitor_archival_height: None,
1805 }
1806 }
1807}
1808
1809impl_writeable_tlv_based!(NodeMetrics, {
1810 (0, latest_lightning_wallet_sync_timestamp, option),
1811 (1, latest_pathfinding_scores_sync_timestamp, option),
1812 (2, latest_onchain_wallet_sync_timestamp, option),
1813 (4, latest_fee_rate_cache_update_timestamp, option),
1814 (6, latest_rgs_snapshot_timestamp, option),
1815 (8, latest_node_announcement_broadcast_timestamp, option),
1816 (10, latest_channel_monitor_archival_height, option),
1817});
1818
1819pub(crate) fn total_anchor_channels_reserve_sats(
1820 channel_manager: &ChannelManager, config: &Config,
1821) -> u64 {
1822 config.anchor_channels_config.as_ref().map_or(0, |anchor_channels_config| {
1823 channel_manager
1824 .list_channels()
1825 .into_iter()
1826 .filter(|c| {
1827 !anchor_channels_config.trusted_peers_no_reserve.contains(&c.counterparty.node_id)
1828 && c.channel_shutdown_state
1829 .map_or(true, |s| s != ChannelShutdownState::ShutdownComplete)
1830 && c.channel_type
1831 .as_ref()
1832 .map_or(false, |t| t.requires_anchors_zero_fee_htlc_tx())
1833 })
1834 .count() as u64
1835 * anchor_channels_config.per_channel_reserve_sats
1836 })
1837}