Merge pull request #131 from tnull/2024-02-align-rustfmt
[ldk-sample] / src / main.rs
index 50edb22ed54449d47d1f168c252ab05ff0ff7a6a..add6990056b03bedd823492f841e9b302164a47e 100644 (file)
@@ -20,12 +20,12 @@ use lightning::events::bump_transaction::{BumpTransactionEventHandler, Wallet};
 use lightning::events::{Event, PaymentFailureReason, PaymentPurpose};
 use lightning::ln::channelmanager::{self, RecentPaymentDetails};
 use lightning::ln::channelmanager::{
-       ChainParameters, ChannelManagerReadArgs, SimpleArcChannelManager,
+       ChainParameters, ChannelManagerReadArgs, PaymentId, SimpleArcChannelManager,
 };
 use lightning::ln::msgs::DecodeError;
 use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler, SimpleArcPeerManager};
 use lightning::ln::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret};
-use lightning::onion_message::{DefaultMessageRouter, SimpleArcOnionMessenger};
+use lightning::onion_message::messenger::{DefaultMessageRouter, SimpleArcOnionMessenger};
 use lightning::routing::gossip;
 use lightning::routing::gossip::{NodeId, P2PGossipSync};
 use lightning::routing::router::DefaultRouter;
@@ -51,6 +51,7 @@ use std::fs;
 use std::fs::File;
 use std::io;
 use std::io::Write;
+use std::net::ToSocketAddrs;
 use std::path::Path;
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, Mutex, RwLock};
@@ -109,11 +110,19 @@ impl_writeable_tlv_based!(PaymentInfo, {
        (6, amt_msat, required),
 });
 
-pub(crate) struct PaymentInfoStorage {
+pub(crate) struct InboundPaymentInfoStorage {
        payments: HashMap<PaymentHash, PaymentInfo>,
 }
 
-impl_writeable_tlv_based!(PaymentInfoStorage, {
+impl_writeable_tlv_based!(InboundPaymentInfoStorage, {
+       (0, payments, required),
+});
+
+pub(crate) struct OutboundPaymentInfoStorage {
+       payments: HashMap<PaymentId, PaymentInfo>,
+}
+
+impl_writeable_tlv_based!(OutboundPaymentInfoStorage, {
        (0, payments, required),
 });
 
@@ -137,11 +146,6 @@ pub(crate) type GossipVerifier = lightning_block_sync::gossip::GossipVerifier<
        lightning_block_sync::gossip::TokioSpawner,
        Arc<lightning_block_sync::rpc::RpcClient>,
        Arc<FilesystemLogger>,
-       SocketDescriptor,
-       Arc<ChannelManager>,
-       Arc<SimpleArcOnionMessenger<FilesystemLogger>>,
-       IgnoringMessageHandler,
-       Arc<KeysManager>,
 >;
 
 pub(crate) type PeerManager = SimpleArcPeerManager<
@@ -158,7 +162,8 @@ pub(crate) type ChannelManager =
 
 pub(crate) type NetworkGraph = gossip::NetworkGraph<Arc<FilesystemLogger>>;
 
-type OnionMessenger = SimpleArcOnionMessenger<FilesystemLogger>;
+type OnionMessenger =
+       SimpleArcOnionMessenger<ChainMonitor, BitcoindClient, BitcoindClient, FilesystemLogger>;
 
 pub(crate) type BumpTxEventHandler = BumpTransactionEventHandler<
        Arc<BitcoindClient>,
@@ -168,10 +173,11 @@ pub(crate) type BumpTxEventHandler = BumpTransactionEventHandler<
 >;
 
 async fn handle_ldk_events(
-       channel_manager: &Arc<ChannelManager>, bitcoind_client: &BitcoindClient,
+       channel_manager: Arc<ChannelManager>, bitcoind_client: &BitcoindClient,
        network_graph: &NetworkGraph, keys_manager: &KeysManager,
-       bump_tx_event_handler: &BumpTxEventHandler, inbound_payments: Arc<Mutex<PaymentInfoStorage>>,
-       outbound_payments: Arc<Mutex<PaymentInfoStorage>>, fs_store: &Arc<FilesystemStore>,
+       bump_tx_event_handler: &BumpTxEventHandler, peer_manager: Arc<PeerManager>,
+       inbound_payments: Arc<Mutex<InboundPaymentInfoStorage>>,
+       outbound_payments: Arc<Mutex<OutboundPaymentInfoStorage>>, fs_store: Arc<FilesystemStore>,
        network: Network, event: Event,
 ) {
        match event {
@@ -185,12 +191,12 @@ async fn handle_ldk_events(
                        // Construct the raw transaction with one output, that is paid the amount of the
                        // channel.
                        let addr = WitnessProgram::from_scriptpubkey(
-                               &output_script[..],
+                               &output_script.as_bytes(),
                                match network {
                                        Network::Bitcoin => bitcoin_bech32::constants::Network::Bitcoin,
-                                       Network::Testnet => bitcoin_bech32::constants::Network::Testnet,
                                        Network::Regtest => bitcoin_bech32::constants::Network::Regtest,
                                        Network::Signet => bitcoin_bech32::constants::Network::Signet,
+                                       Network::Testnet | _ => bitcoin_bech32::constants::Network::Testnet,
                                },
                        )
                        .expect("Lightning funding tx should always be to a SegWit output")
@@ -203,7 +209,7 @@ async fn handle_ldk_events(
                        // satisfied.
                        let funded_tx = bitcoind_client.fund_raw_transaction(raw_tx).await;
 
-                       // Sign the final funding transaction and broadcast it.
+                       // Sign the final funding transaction and give it to LDK, who will eventually broadcast it.
                        let signed_tx = bitcoind_client.sign_raw_transaction_with_wallet(funded_tx.hex).await;
                        assert_eq!(signed_tx.complete, true);
                        let final_tx: Transaction =
@@ -222,7 +228,7 @@ async fn handle_ldk_events(
                                print!("> ");
                                io::stdout().flush().unwrap();
                        }
-               }
+               },
                Event::PaymentClaimable {
                        payment_hash,
                        purpose,
@@ -245,7 +251,7 @@ async fn handle_ldk_events(
                                PaymentPurpose::SpontaneousPayment(preimage) => Some(preimage),
                        };
                        channel_manager.claim_funds(payment_preimage.unwrap());
-               }
+               },
                Event::PaymentClaimed {
                        payment_hash,
                        purpose,
@@ -263,7 +269,7 @@ async fn handle_ldk_events(
                        let (payment_preimage, payment_secret) = match purpose {
                                PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => {
                                        (payment_preimage, Some(payment_secret))
-                               }
+                               },
                                PaymentPurpose::SpontaneousPayment(preimage) => (Some(preimage), None),
                        };
                        let mut inbound = inbound_payments.lock().unwrap();
@@ -273,7 +279,7 @@ async fn handle_ldk_events(
                                        payment.status = HTLCStatus::Succeeded;
                                        payment.preimage = payment_preimage;
                                        payment.secret = payment_secret;
-                               }
+                               },
                                Entry::Vacant(e) => {
                                        e.insert(PaymentInfo {
                                                preimage: payment_preimage,
@@ -281,14 +287,16 @@ async fn handle_ldk_events(
                                                status: HTLCStatus::Succeeded,
                                                amt_msat: MillisatAmount(Some(amount_msat)),
                                        });
-                               }
+                               },
                        }
                        fs_store.write("", "", INBOUND_PAYMENTS_FNAME, &inbound.encode()).unwrap();
-               }
-               Event::PaymentSent { payment_preimage, payment_hash, fee_paid_msat, .. } => {
+               },
+               Event::PaymentSent {
+                       payment_preimage, payment_hash, fee_paid_msat, payment_id, ..
+               } => {
                        let mut outbound = outbound_payments.lock().unwrap();
-                       for (hash, payment) in outbound.payments.iter_mut() {
-                               if *hash == payment_hash {
+                       for (id, payment) in outbound.payments.iter_mut() {
+                               if *id == payment_id.unwrap() {
                                        payment.preimage = Some(payment_preimage);
                                        payment.status = HTLCStatus::Succeeded;
                                        println!(
@@ -308,7 +316,7 @@ async fn handle_ldk_events(
                                }
                        }
                        fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
-               }
+               },
                Event::OpenChannelRequest {
                        ref temporary_channel_id, ref counterparty_node_id, ..
                } => {
@@ -337,12 +345,12 @@ async fn handle_ldk_events(
                        }
                        print!("> ");
                        io::stdout().flush().unwrap();
-               }
-               Event::PaymentPathSuccessful { .. } => {}
-               Event::PaymentPathFailed { .. } => {}
-               Event::ProbeSuccessful { .. } => {}
-               Event::ProbeFailed { .. } => {}
-               Event::PaymentFailed { payment_hash, reason, .. } => {
+               },
+               Event::PaymentPathSuccessful { .. } => {},
+               Event::PaymentPathFailed { .. } => {},
+               Event::ProbeSuccessful { .. } => {},
+               Event::ProbeFailed { .. } => {},
+               Event::PaymentFailed { payment_hash, reason, payment_id, .. } => {
                        print!(
                                "\nEVENT: Failed to send payment to payment hash {}: {:?}",
                                payment_hash,
@@ -352,12 +360,24 @@ async fn handle_ldk_events(
                        io::stdout().flush().unwrap();
 
                        let mut outbound = outbound_payments.lock().unwrap();
-                       if outbound.payments.contains_key(&payment_hash) {
-                               let payment = outbound.payments.get_mut(&payment_hash).unwrap();
+                       if outbound.payments.contains_key(&payment_id) {
+                               let payment = outbound.payments.get_mut(&payment_id).unwrap();
                                payment.status = HTLCStatus::Failed;
                        }
                        fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
-               }
+               },
+               Event::InvoiceRequestFailed { payment_id } => {
+                       print!("\nEVENT: Failed to request invoice to send payment with id {}", payment_id);
+                       print!("> ");
+                       io::stdout().flush().unwrap();
+
+                       let mut outbound = outbound_payments.lock().unwrap();
+                       if outbound.payments.contains_key(&payment_id) {
+                               let payment = outbound.payments.get_mut(&payment_id).unwrap();
+                               payment.status = HTLCStatus::Failed;
+                       }
+                       fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
+               },
                Event::PaymentForwarded {
                        prev_channel_id,
                        next_channel_id,
@@ -380,10 +400,10 @@ async fn handle_ldk_events(
                                                                None => "unnamed node".to_string(),
                                                                Some(announcement) => {
                                                                        format!("node {}", announcement.alias)
-                                                               }
+                                                               },
                                                        },
                                                }
-                                       }
+                                       },
                                },
                        };
                        let channel_str = |channel_id: &Option<ChannelId>| {
@@ -419,8 +439,8 @@ async fn handle_ldk_events(
                        }
                        print!("> ");
                        io::stdout().flush().unwrap();
-               }
-               Event::HTLCHandlingFailed { .. } => {}
+               },
+               Event::HTLCHandlingFailed { .. } => {},
                Event::PendingHTLCsForwardable { time_forwardable } => {
                        let forwarding_channel_manager = channel_manager.clone();
                        let min = time_forwardable.as_millis() as u64;
@@ -429,7 +449,7 @@ async fn handle_ldk_events(
                                tokio::time::sleep(Duration::from_millis(millis_to_sleep)).await;
                                forwarding_channel_manager.process_pending_htlc_forwards();
                        });
-               }
+               },
                Event::SpendableOutputs { outputs, channel_id: _ } => {
                        // SpendableOutputDescriptors, of which outputs is a vec of, are critical to keep track
                        // of! While a `StaticOutput` descriptor is just an output to a static, well-known key,
@@ -446,7 +466,7 @@ async fn handle_ldk_events(
                                let output: SpendableOutputDescriptor = output;
                                fs_store.write(PENDING_SPENDABLE_OUTPUT_DIR, "", &key, &output.encode()).unwrap();
                        }
-               }
+               },
                Event::ChannelPending { channel_id, counterparty_node_id, .. } => {
                        println!(
                                "\nEVENT: Channel {} with peer {} is pending awaiting funding lock-in!",
@@ -455,7 +475,7 @@ async fn handle_ldk_events(
                        );
                        print!("> ");
                        io::stdout().flush().unwrap();
-               }
+               },
                Event::ChannelReady {
                        ref channel_id,
                        user_channel_id: _,
@@ -469,13 +489,14 @@ async fn handle_ldk_events(
                        );
                        print!("> ");
                        io::stdout().flush().unwrap();
-               }
+               },
                Event::ChannelClosed {
                        channel_id,
                        reason,
                        user_channel_id: _,
                        counterparty_node_id,
                        channel_capacity_sats: _,
+                       channel_funding_txo: _,
                } => {
                        println!(
                                "\nEVENT: Channel {} with counterparty {} closed due to: {:?}",
@@ -485,13 +506,27 @@ async fn handle_ldk_events(
                        );
                        print!("> ");
                        io::stdout().flush().unwrap();
-               }
+               },
                Event::DiscardFunding { .. } => {
                        // A "real" node should probably "lock" the UTXOs spent in funding transactions until
                        // the funding transaction either confirms, or this event is generated.
-               }
-               Event::HTLCIntercepted { .. } => {}
+               },
+               Event::HTLCIntercepted { .. } => {},
                Event::BumpTransaction(event) => bump_tx_event_handler.handle_event(&event),
+               Event::ConnectionNeeded { node_id, addresses } => {
+                       tokio::spawn(async move {
+                               for address in addresses {
+                                       if let Ok(sockaddrs) = address.to_socket_addrs() {
+                                               for addr in sockaddrs {
+                                                       let pm = Arc::clone(&peer_manager);
+                                                       if cli::connect_peer_if_necessary(node_id, addr, pm).await.is_ok() {
+                                                               return;
+                                                       }
+                                               }
+                                       }
+                               }
+                       });
+               },
        }
 }
 
@@ -515,6 +550,7 @@ async fn start_ldk() {
                args.bitcoind_rpc_port,
                args.bitcoind_rpc_username.clone(),
                args.bitcoind_rpc_password.clone(),
+               args.network,
                tokio::runtime::Handle::current(),
                Arc::clone(&logger),
        )
@@ -524,7 +560,7 @@ async fn start_ldk() {
                Err(e) => {
                        println!("Failed to connect to bitcoind client: {}", e);
                        return;
-               }
+               },
        };
 
        // Check that the bitcoind we've connected to is running the network we expect
@@ -532,9 +568,9 @@ async fn start_ldk() {
        if bitcoind_chain
                != match args.network {
                        bitcoin::Network::Bitcoin => "main",
-                       bitcoin::Network::Testnet => "test",
                        bitcoin::Network::Regtest => "regtest",
                        bitcoin::Network::Signet => "signet",
+                       bitcoin::Network::Testnet | _ => "test",
                } {
                println!(
                        "Chain argument ({}) didn't match bitcoind chain ({})",
@@ -571,11 +607,11 @@ async fn start_ldk() {
                        Ok(mut f) => {
                                Write::write_all(&mut f, &key).expect("Failed to write node keys seed to disk");
                                f.sync_all().expect("Failed to sync node keys seed to disk");
-                       }
+                       },
                        Err(e) => {
                                println!("ERROR: Unable to create keys seed file {}: {}", keys_seed_path, e);
                                return;
-                       }
+                       },
                }
                key
        };
@@ -753,8 +789,8 @@ async fn start_ldk() {
                Arc::clone(&keys_manager),
                Arc::clone(&keys_manager),
                Arc::clone(&logger),
-               Arc::new(DefaultMessageRouter {}),
-               IgnoringMessageHandler {},
+               Arc::new(DefaultMessageRouter::new(Arc::clone(&network_graph))),
+               Arc::clone(&channel_manager),
                IgnoringMessageHandler {},
        ));
        let mut ephemeral_bytes = [0; 32];
@@ -825,32 +861,30 @@ async fn start_ldk() {
                }
        });
 
-       let inbound_payments = Arc::new(Mutex::new(disk::read_payment_info(Path::new(&format!(
-               "{}/{}",
-               ldk_data_dir, INBOUND_PAYMENTS_FNAME
-       )))));
-       let outbound_payments = Arc::new(Mutex::new(disk::read_payment_info(Path::new(&format!(
-               "{}/{}",
-               ldk_data_dir, OUTBOUND_PAYMENTS_FNAME
-       )))));
-       let recent_payments_payment_hashes = channel_manager
+       let inbound_payments = Arc::new(Mutex::new(disk::read_inbound_payment_info(Path::new(
+               &format!("{}/{}", ldk_data_dir, INBOUND_PAYMENTS_FNAME),
+       ))));
+       let outbound_payments = Arc::new(Mutex::new(disk::read_outbound_payment_info(Path::new(
+               &format!("{}/{}", ldk_data_dir, OUTBOUND_PAYMENTS_FNAME),
+       ))));
+       let recent_payments_payment_ids = channel_manager
                .list_recent_payments()
                .into_iter()
                .filter_map(|p| match p {
-                       RecentPaymentDetails::Pending { payment_hash, .. } => Some(payment_hash),
-                       RecentPaymentDetails::Fulfilled { payment_hash, .. } => payment_hash,
-                       RecentPaymentDetails::Abandoned { payment_hash, .. } => Some(payment_hash),
-                       RecentPaymentDetails::AwaitingInvoice { payment_id: _ } => todo!(),
+                       RecentPaymentDetails::Pending { payment_id, .. } => Some(payment_id),
+                       RecentPaymentDetails::Fulfilled { payment_id, .. } => Some(payment_id),
+                       RecentPaymentDetails::Abandoned { payment_id, .. } => Some(payment_id),
+                       RecentPaymentDetails::AwaitingInvoice { payment_id } => Some(payment_id),
                })
-               .collect::<Vec<PaymentHash>>();
-       for (payment_hash, payment_info) in outbound_payments
+               .collect::<Vec<PaymentId>>();
+       for (payment_id, payment_info) in outbound_payments
                .lock()
                .unwrap()
                .payments
                .iter_mut()
                .filter(|(_, i)| matches!(i.status, HTLCStatus::Pending))
        {
-               if !recent_payments_payment_hashes.contains(payment_hash) {
+               if !recent_payments_payment_ids.contains(payment_id) {
                        payment_info.status = HTLCStatus::Failed;
                }
        }
@@ -866,6 +900,7 @@ async fn start_ldk() {
        let inbound_payments_event_listener = Arc::clone(&inbound_payments);
        let outbound_payments_event_listener = Arc::clone(&outbound_payments);
        let fs_store_event_listener = Arc::clone(&fs_store);
+       let peer_manager_event_listener = Arc::clone(&peer_manager);
        let network = args.network;
        let event_handler = move |event: Event| {
                let channel_manager_event_listener = Arc::clone(&channel_manager_event_listener);
@@ -876,16 +911,18 @@ async fn start_ldk() {
                let inbound_payments_event_listener = Arc::clone(&inbound_payments_event_listener);
                let outbound_payments_event_listener = Arc::clone(&outbound_payments_event_listener);
                let fs_store_event_listener = Arc::clone(&fs_store_event_listener);
+               let peer_manager_event_listener = Arc::clone(&peer_manager_event_listener);
                async move {
                        handle_ldk_events(
-                               &channel_manager_event_listener,
+                               channel_manager_event_listener,
                                &bitcoind_client_event_listener,
                                &network_graph_event_listener,
                                &keys_manager_event_listener,
                                &bump_tx_event_handler,
+                               peer_manager_event_listener,
                                inbound_payments_event_listener,
                                outbound_payments_event_listener,
-                               &fs_store_event_listener,
+                               fs_store_event_listener,
                                network,
                                event,
                        )
@@ -917,6 +954,7 @@ async fn start_ldk() {
                        })
                },
                false,
+               || Some(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()),
        ));
 
        // Regularly reconnect to channel peers.
@@ -952,7 +990,7 @@ async fn start_ldk() {
                                                        }
                                                }
                                        }
-                               }
+                               },
                                Err(e) => println!("ERROR: errored reading channel peer info from disk: {:?}", e),
                        }
                }