X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fmain.rs;h=927284aaf7dadb8cf1046772bbbdf8a70808e84b;hb=85e890be4909361b7163fa09fa4bb271463af271;hp=5f213fca40b2dffac9a72c3ed0897c58b84e4bf3;hpb=0f8635873858a05cdffee21eb99dd2e100e6cebc;p=ldk-sample diff --git a/src/main.rs b/src/main.rs index 5f213fc..927284a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,8 @@ use lightning::chain::Filter; use lightning::chain::Watch; use lightning::ln::channelmanager; use lightning::ln::channelmanager::{ - ChainParameters, ChannelManagerReadArgs, PaymentHash, PaymentPreimage, SimpleArcChannelManager, + ChainParameters, ChannelManagerReadArgs, PaymentHash, PaymentPreimage, PaymentSecret, + SimpleArcChannelManager, }; use lightning::ln::peer_handler::{MessageHandler, SimpleArcPeerManager}; use lightning::routing::network_graph::NetGraphMsgHandler; @@ -50,21 +51,15 @@ use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime}; use tokio::sync::mpsc; -#[derive(PartialEq)] -pub(crate) enum HTLCDirection { - Inbound, - Outbound, -} - pub(crate) enum HTLCStatus { Pending, Succeeded, Failed, } -pub(crate) struct SatoshiAmount(Option); +pub(crate) struct MillisatAmount(Option); -impl fmt::Display for SatoshiAmount { +impl fmt::Display for MillisatAmount { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.0 { Some(amt) => write!(f, "{}", amt), @@ -73,11 +68,14 @@ impl fmt::Display for SatoshiAmount { } } -pub(crate) type PaymentInfoStorage = Arc< - Mutex< - HashMap, HTLCDirection, HTLCStatus, SatoshiAmount)>, - >, ->; +pub(crate) struct PaymentInfo { + preimage: Option, + secret: Option, + status: HTLCStatus, + amt_msat: MillisatAmount, +} + +pub(crate) type PaymentInfoStorage = Arc>>; type ChainMonitor = chainmonitor::ChainMonitor< InMemorySigner, @@ -103,7 +101,7 @@ pub(crate) type ChannelManager = async fn handle_ldk_events( channel_manager: Arc, chain_monitor: Arc, bitcoind_client: Arc, keys_manager: Arc, - payment_storage: PaymentInfoStorage, network: Network, + inbound_payments: PaymentInfoStorage, outbound_payments: PaymentInfoStorage, network: Network, ) { loop { let loop_channel_manager = channel_manager.clone(); @@ -151,47 +149,58 @@ async fn handle_ldk_events( .funding_transaction_generated(&temporary_channel_id, final_tx) .unwrap(); } - Event::FundingBroadcastSafe { funding_txo, .. } => { - Event::PaymentReceived { payment_hash, payment_secret, amt: amt_msat } => { - let mut payments = payment_storage.lock().unwrap(); - if let Some((Some(preimage), _, _, _)) = payments.get(&payment_hash) { - assert!(loop_channel_manager.claim_funds( - preimage.clone(), - &payment_secret, - amt_msat - )); - println!( - "\nEVENT: received payment from payment_hash {} of {} satoshis", - hex_utils::hex_str(&payment_hash.0), - amt_msat / 1000 - ); - print!("> "); - io::stdout().flush().unwrap(); - let (_, _, ref mut status, _) = payments.get_mut(&payment_hash).unwrap(); - *status = HTLCStatus::Succeeded; + Event::PaymentReceived { payment_hash, payment_secret, amt } => { + let mut payments = inbound_payments.lock().unwrap(); + if let Some(payment) = payments.get_mut(&payment_hash) { + if payment.secret == payment_secret { + assert!(loop_channel_manager.claim_funds( + payment.preimage.unwrap().clone(), + &payment.secret, + payment.amt_msat.0.unwrap(), + )); + println!( + "\nEVENT: received payment from payment hash {} of {} millisatoshis", + hex_utils::hex_str(&payment_hash.0), + payment.amt_msat + ); + print!("> "); + io::stdout().flush().unwrap(); + payment.status = HTLCStatus::Succeeded; + } else { + loop_channel_manager + .fail_htlc_backwards(&payment_hash, &payment.secret); + println!("\nERROR: we received a payment from payment hash {} but the payment secret didn't match", hex_utils::hex_str(&payment_hash.0)); + print!("> "); + io::stdout().flush().unwrap(); + payment.status = HTLCStatus::Failed; + } } else { - println!("\nERROR: we received a payment but didn't know the preimage"); + loop_channel_manager.fail_htlc_backwards(&payment_hash, &payment_secret); + println!("\nERROR: we received a payment for payment hash {} but didn't know the preimage", hex_utils::hex_str(&payment_hash.0)); print!("> "); io::stdout().flush().unwrap(); - loop_channel_manager.fail_htlc_backwards(&payment_hash, &payment_secret); payments.insert( payment_hash, - (None, HTLCDirection::Inbound, HTLCStatus::Failed, SatoshiAmount(None)), + PaymentInfo { + preimage: None, + secret: payment_secret, + status: HTLCStatus::Failed, + amt_msat: MillisatAmount(Some(amt)), + }, ); } } Event::PaymentSent { payment_preimage } => { let hashed = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner()); - let mut payments = payment_storage.lock().unwrap(); - for (payment_hash, (preimage_option, _, status, amt_sat)) in payments.iter_mut() - { + let mut payments = outbound_payments.lock().unwrap(); + for (payment_hash, payment) in payments.iter_mut() { if *payment_hash == hashed { - *preimage_option = Some(payment_preimage); - *status = HTLCStatus::Succeeded; + payment.preimage = Some(payment_preimage); + payment.status = HTLCStatus::Succeeded; println!( - "\nEVENT: successfully sent payment of {} satoshis from \ + "\nEVENT: successfully sent payment of {} millisatoshis from \ payment hash {:?} with preimage {:?}", - amt_sat, + payment.amt_msat, hex_utils::hex_str(&payment_hash.0), hex_utils::hex_str(&payment_preimage.0) ); @@ -213,10 +222,10 @@ async fn handle_ldk_events( print!("> "); io::stdout().flush().unwrap(); - let mut payments = payment_storage.lock().unwrap(); + let mut payments = outbound_payments.lock().unwrap(); if payments.contains_key(&payment_hash) { - let (_, _, ref mut status, _) = payments.get_mut(&payment_hash).unwrap(); - *status = HTLCStatus::Failed; + let payment = payments.get_mut(&payment_hash).unwrap(); + payment.status = HTLCStatus::Failed; } } Event::PendingHTLCsForwardable { time_forwardable } => { @@ -492,20 +501,15 @@ async fn start_ldk() { logger.clone(), ); - let peer_manager_processor = peer_manager.clone(); - tokio::spawn(async move { - loop { - peer_manager_processor.timer_tick_occurred(); - tokio::time::sleep(Duration::from_secs(60)).await; - } - }); - // Step 15: Initialize LDK Event Handling let channel_manager_event_listener = channel_manager.clone(); let chain_monitor_event_listener = chain_monitor.clone(); let keys_manager_listener = keys_manager.clone(); - let payment_info: PaymentInfoStorage = Arc::new(Mutex::new(HashMap::new())); - let payment_info_for_events = payment_info.clone(); + // TODO: persist payment info to disk + let inbound_payments: PaymentInfoStorage = Arc::new(Mutex::new(HashMap::new())); + let outbound_payments: PaymentInfoStorage = Arc::new(Mutex::new(HashMap::new())); + let inbound_pmts_for_events = inbound_payments.clone(); + let outbound_pmts_for_events = outbound_payments.clone(); let network = args.network; let bitcoind_rpc = bitcoind_client.clone(); tokio::spawn(async move { @@ -514,7 +518,8 @@ async fn start_ldk() { chain_monitor_event_listener, bitcoind_rpc, keys_manager_listener, - payment_info_for_events, + inbound_pmts_for_events, + outbound_pmts_for_events, network, ) .await; @@ -545,7 +550,8 @@ async fn start_ldk() { peer_manager.clone(), channel_manager.clone(), router.clone(), - payment_info, + inbound_payments, + outbound_payments, keys_manager.get_node_secret(), event_ntfn_sender, ldk_data_dir.clone(),