Print next and previous nodes for PaymentForwarded
authorJeffrey Czyz <jkczyz@gmail.com>
Thu, 19 May 2022 02:36:56 +0000 (21:36 -0500)
committerJeffrey Czyz <jkczyz@gmail.com>
Thu, 9 Jun 2022 22:01:53 +0000 (17:01 -0500)
src/cli.rs
src/main.rs

index b392f0f355019a9b42cae0230afdc7b92c76af33..bf2f7929434de90f1fe9d9fd5f9f7fe9fb59a8df 100644 (file)
@@ -1,7 +1,7 @@
 use crate::disk;
 use crate::hex_utils;
 use crate::{
-       ChannelManager, HTLCStatus, InvoicePayer, MillisatAmount, NetworkGraph, PaymentInfo,
+       ChannelManager, HTLCStatus, InvoicePayer, MillisatAmount, NetworkGraph, NodeAlias, PaymentInfo,
        PaymentInfoStorage, PeerManager,
 };
 use bitcoin::hashes::sha256::Hash as Sha256;
@@ -457,19 +457,6 @@ fn list_peers(peer_manager: Arc<PeerManager>) {
        println!("\t}},");
 }
 
-/// Takes some untrusted bytes and returns a sanitized string that is safe to print
-fn sanitize_string(bytes: &[u8]) -> String {
-       let mut ret = String::with_capacity(bytes.len());
-       // We should really support some sane subset of UTF-8 here, but limiting to printable ASCII
-       // instead makes this trivial.
-       for b in bytes {
-               if *b >= 0x20 && *b <= 0x7e {
-                       ret.push(*b as char);
-               }
-       }
-       ret
-}
-
 fn list_channels(channel_manager: &Arc<ChannelManager>, network_graph: &Arc<NetworkGraph>) {
        print!("[");
        for chan_info in channel_manager.list_channels() {
@@ -490,7 +477,7 @@ fn list_channels(channel_manager: &Arc<ChannelManager>, network_graph: &Arc<Netw
                        .get(&NodeId::from_pubkey(&chan_info.counterparty.node_id))
                {
                        if let Some(announcement) = &node_info.announcement_info {
-                               println!("\t\tpeer_alias: {}", sanitize_string(&announcement.alias));
+                               println!("\t\tpeer_alias: {}", NodeAlias(&announcement.alias));
                        }
                }
 
index 1c1d7941011ae0602d174d9481e079a638d26110..edcec9b4ade5d6dcf01666e18a90146dc8b7b492 100644 (file)
@@ -24,9 +24,8 @@ use lightning::ln::channelmanager::{
 };
 use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler, SimpleArcPeerManager};
 use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-use lightning::log_bytes;
 use lightning::routing::gossip;
-use lightning::routing::gossip::P2PGossipSync;
+use lightning::routing::gossip::{NodeId, P2PGossipSync};
 use lightning::routing::scoring::ProbabilisticScorer;
 use lightning::util::config::UserConfig;
 use lightning::util::events::{Event, PaymentPurpose};
@@ -117,10 +116,26 @@ type GossipSync<P, G, A, L> =
 
 pub(crate) type NetworkGraph = gossip::NetworkGraph<Arc<FilesystemLogger>>;
 
+struct NodeAlias<'a>(&'a [u8; 32]);
+
+impl fmt::Display for NodeAlias<'_> {
+       fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+               let alias = self
+                       .0
+                       .iter()
+                       .map(|b| *b as char)
+                       .take_while(|c| *c != '\0')
+                       .filter(|c| c.is_ascii_graphic() || *c == ' ')
+                       .collect::<String>();
+               write!(f, "{}", alias)
+       }
+}
+
 async fn handle_ldk_events(
        channel_manager: Arc<ChannelManager>, bitcoind_client: Arc<BitcoindClient>,
-       keys_manager: Arc<KeysManager>, inbound_payments: PaymentInfoStorage,
-       outbound_payments: PaymentInfoStorage, network: Network, event: &Event,
+       network_graph: Arc<NetworkGraph>, keys_manager: Arc<KeysManager>,
+       inbound_payments: PaymentInfoStorage, outbound_payments: PaymentInfoStorage, network: Network,
+       event: &Event,
 ) {
        match event {
                Event::FundingGenerationReady {
@@ -265,12 +280,37 @@ async fn handle_ldk_events(
                        fee_earned_msat,
                        claim_from_onchain_tx,
                } => {
-                       let from_channel_str = prev_channel_id
-                               .map(|channel_id| format!(" from channel {}", log_bytes!(channel_id)))
-                               .unwrap_or_default();
-                       let to_channel_str = next_channel_id
-                               .map(|channel_id| format!(" to channel {}", log_bytes!(channel_id)))
-                               .unwrap_or_default();
+                       let read_only_network_graph = network_graph.read_only();
+                       let nodes = read_only_network_graph.nodes();
+                       let channels = channel_manager.list_channels();
+
+                       let node_str = |channel_id: &Option<[u8; 32]>| match channel_id {
+                               None => String::new(),
+                               Some(channel_id) => match channels.iter().find(|c| c.channel_id == *channel_id) {
+                                       None => String::new(),
+                                       Some(channel) => {
+                                               match nodes.get(&NodeId::from_pubkey(&channel.counterparty.node_id)) {
+                                                       None => " from private node".to_string(),
+                                                       Some(node) => match &node.announcement_info {
+                                                               None => " from unnamed node".to_string(),
+                                                               Some(announcement) => {
+                                                                       format!(" from node {}", NodeAlias(&announcement.alias))
+                                                               }
+                                                       },
+                                               }
+                                       }
+                               },
+                       };
+                       let channel_str = |channel_id: &Option<[u8; 32]>| {
+                               channel_id
+                                       .map(|channel_id| format!(" with channel {}", hex_utils::hex_str(&channel_id)))
+                                       .unwrap_or_default()
+                       };
+                       let from_prev_str =
+                               format!("{}{}", node_str(prev_channel_id), channel_str(prev_channel_id));
+                       let to_next_str =
+                               format!("{}{}", node_str(next_channel_id), channel_str(next_channel_id));
+
                        let from_onchain_str = if *claim_from_onchain_tx {
                                "from onchain downstream claim"
                        } else {
@@ -279,12 +319,12 @@ async fn handle_ldk_events(
                        if let Some(fee_earned) = fee_earned_msat {
                                println!(
                                        "\nEVENT: Forwarded payment{}{}, earning {} msat {}",
-                                       from_channel_str, to_channel_str, fee_earned, from_onchain_str
+                                       from_prev_str, to_next_str, fee_earned, from_onchain_str
                                );
                        } else {
                                println!(
                                        "\nEVENT: Forwarded payment{}{}, claiming onchain {}",
-                                       from_channel_str, to_channel_str, from_onchain_str
+                                       from_prev_str, to_next_str, from_onchain_str
                                );
                        }
                        print!("> ");
@@ -602,11 +642,13 @@ async fn start_ldk() {
        let outbound_pmts_for_events = outbound_payments.clone();
        let network = args.network;
        let bitcoind_rpc = bitcoind_client.clone();
+       let network_graph_events = network_graph.clone();
        let handle = tokio::runtime::Handle::current();
        let event_handler = move |event: &Event| {
                handle.block_on(handle_ldk_events(
                        channel_manager_event_listener.clone(),
                        bitcoind_rpc.clone(),
+                       network_graph_events.clone(),
                        keys_manager_listener.clone(),
                        inbound_pmts_for_events.clone(),
                        outbound_pmts_for_events.clone(),