Update to LDK 0.0.121
[ldk-sample] / src / main.rs
index ffe0e69c4595c3d4067ef6336df2d8669da5e3a4..73a6ddf3356e7d2aabfa9c32ea9debfbef379250 100644 (file)
@@ -20,19 +20,19 @@ 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;
 use lightning::routing::scoring::ProbabilisticScoringFeeParameters;
 use lightning::sign::{EntropySource, InMemorySigner, KeysManager, SpendableOutputDescriptor};
 use lightning::util::config::UserConfig;
-use lightning::util::persist::{self, read_channel_monitors, KVStore};
+use lightning::util::persist::{self, KVStore, MonitorUpdatingPersister};
 use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
 use lightning::{chain, impl_writeable_tlv_based, impl_writeable_tlv_based_enum};
 use lightning_background_processor::{process_events_async, GossipSync};
@@ -109,11 +109,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),
 });
 
@@ -123,7 +131,20 @@ type ChainMonitor = chainmonitor::ChainMonitor<
        Arc<BitcoindClient>,
        Arc<BitcoindClient>,
        Arc<FilesystemLogger>,
-       Arc<FilesystemStore>,
+       Arc<
+               MonitorUpdatingPersister<
+                       Arc<FilesystemStore>,
+                       Arc<FilesystemLogger>,
+                       Arc<KeysManager>,
+                       Arc<KeysManager>,
+               >,
+       >,
+>;
+
+pub(crate) type GossipVerifier = lightning_block_sync::gossip::GossipVerifier<
+       lightning_block_sync::gossip::TokioSpawner,
+       Arc<lightning_block_sync::rpc::RpcClient>,
+       Arc<FilesystemLogger>,
 >;
 
 pub(crate) type PeerManager = SimpleArcPeerManager<
@@ -131,7 +152,7 @@ pub(crate) type PeerManager = SimpleArcPeerManager<
        ChainMonitor,
        BitcoindClient,
        BitcoindClient,
-       Arc<BitcoindClient>,
+       GossipVerifier,
        FilesystemLogger,
 >;
 
@@ -140,7 +161,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>,
@@ -152,8 +174,9 @@ pub(crate) type BumpTxEventHandler = BumpTransactionEventHandler<
 async fn handle_ldk_events(
        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>>, persister: &Arc<FilesystemStore>,
+       bump_tx_event_handler: &BumpTxEventHandler,
+       inbound_payments: Arc<Mutex<InboundPaymentInfoStorage>>,
+       outbound_payments: Arc<Mutex<OutboundPaymentInfoStorage>>, fs_store: &Arc<FilesystemStore>,
        network: Network, event: Event,
 ) {
        match event {
@@ -167,12 +190,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")
@@ -185,7 +208,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 =
@@ -265,12 +288,14 @@ async fn handle_ldk_events(
                                        });
                                }
                        }
-                       persister.write("", "", INBOUND_PAYMENTS_FNAME, &inbound.encode()).unwrap();
+                       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!(
@@ -289,7 +314,7 @@ async fn handle_ldk_events(
                                        io::stdout().flush().unwrap();
                                }
                        }
-                       persister.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
+                       fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
                }
                Event::OpenChannelRequest {
                        ref temporary_channel_id, ref counterparty_node_id, ..
@@ -324,7 +349,7 @@ async fn handle_ldk_events(
                Event::PaymentPathFailed { .. } => {}
                Event::ProbeSuccessful { .. } => {}
                Event::ProbeFailed { .. } => {}
-               Event::PaymentFailed { payment_hash, reason, .. } => {
+               Event::PaymentFailed { payment_hash, reason, payment_id, .. } => {
                        print!(
                                "\nEVENT: Failed to send payment to payment hash {}: {:?}",
                                payment_hash,
@@ -334,11 +359,23 @@ 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;
                        }
-                       persister.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
+                       fs_store.write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound.encode()).unwrap();
                }
                Event::PaymentForwarded {
                        prev_channel_id,
@@ -426,7 +463,7 @@ async fn handle_ldk_events(
                                let key = hex_utils::hex_str(&keys_manager.get_secure_random_bytes());
                                // Note that if the type here changes our read code needs to change as well.
                                let output: SpendableOutputDescriptor = output;
-                               persister.write(PENDING_SPENDABLE_OUTPUT_DIR, "", &key, &output.encode()).unwrap();
+                               fs_store.write(PENDING_SPENDABLE_OUTPUT_DIR, "", &key, &output.encode()).unwrap();
                        }
                }
                Event::ChannelPending { channel_id, counterparty_node_id, .. } => {
@@ -458,6 +495,7 @@ async fn handle_ldk_events(
                        user_channel_id: _,
                        counterparty_node_id,
                        channel_capacity_sats: _,
+                       channel_funding_txo: _,
                } => {
                        println!(
                                "\nEVENT: Channel {} with counterparty {} closed due to: {:?}",
@@ -474,6 +512,7 @@ async fn handle_ldk_events(
                }
                Event::HTLCIntercepted { .. } => {}
                Event::BumpTransaction(event) => bump_tx_event_handler.handle_event(&event),
+               Event::ConnectionNeeded { .. } => {}
        }
 }
 
@@ -497,6 +536,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),
        )
@@ -514,9 +554,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 ({})",
@@ -536,19 +576,7 @@ async fn start_ldk() {
        // broadcaster.
        let broadcaster = bitcoind_client.clone();
 
-       // Step 4: Initialize Persist
-       let persister = Arc::new(FilesystemStore::new(ldk_data_dir.clone().into()));
-
-       // Step 5: Initialize the ChainMonitor
-       let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new(
-               None,
-               broadcaster.clone(),
-               logger.clone(),
-               fee_estimator.clone(),
-               persister.clone(),
-       ));
-
-       // Step 6: Initialize the KeysManager
+       // Step 4: Initialize the KeysManager
 
        // The key seed that we use to derive the node privkey (that corresponds to the node pubkey) and
        // other secret key material.
@@ -583,10 +611,35 @@ async fn start_ldk() {
                Arc::clone(&logger),
        ));
 
+       // Step 5: Initialize Persistence
+       let fs_store = Arc::new(FilesystemStore::new(ldk_data_dir.clone().into()));
+       let persister = Arc::new(MonitorUpdatingPersister::new(
+               Arc::clone(&fs_store),
+               Arc::clone(&logger),
+               1000,
+               Arc::clone(&keys_manager),
+               Arc::clone(&keys_manager),
+       ));
+       // Alternatively, you can use the `FilesystemStore` as a `Persist` directly, at the cost of
+       // larger `ChannelMonitor` update writes (but no deletion or cleanup):
+       //let persister = Arc::clone(&fs_store);
+
+       // Step 6: Initialize the ChainMonitor
+       let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new(
+               None,
+               Arc::clone(&broadcaster),
+               Arc::clone(&logger),
+               Arc::clone(&fee_estimator),
+               Arc::clone(&persister),
+       ));
+
        // Step 7: Read ChannelMonitor state from disk
-       let mut channelmonitors =
-               read_channel_monitors(Arc::clone(&persister), keys_manager.clone(), keys_manager.clone())
-                       .unwrap();
+       let mut channelmonitors = persister
+               .read_all_channel_monitors_with_updates(&bitcoind_client, &bitcoind_client)
+               .unwrap();
+       // If you are using the `FilesystemStore` as a `Persist` directly, use
+       // `lightning::util::persist::read_channel_monitors` like this:
+       //read_channel_monitors(Arc::clone(&persister), Arc::clone(&keys_manager), Arc::clone(&keys_manager)).unwrap();
 
        // Step 8: Poll for the best chain tip, which may be used by the channel manager & spv client
        let polled_chain_tip = init::validate_best_block_header(bitcoind_client.as_ref())
@@ -713,11 +766,8 @@ async fn start_ldk() {
        }
 
        // Step 14: Optional: Initialize the P2PGossipSync
-       let gossip_sync = Arc::new(P2PGossipSync::new(
-               Arc::clone(&network_graph),
-               None::<Arc<BitcoindClient>>,
-               logger.clone(),
-       ));
+       let gossip_sync =
+               Arc::new(P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)));
 
        // Step 15: Initialize the PeerManager
        let channel_manager: Arc<ChannelManager> = Arc::new(channel_manager);
@@ -725,8 +775,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];
@@ -746,6 +796,15 @@ async fn start_ldk() {
                Arc::clone(&keys_manager),
        ));
 
+       // Install a GossipVerifier in in the P2PGossipSync
+       let utxo_lookup = GossipVerifier::new(
+               Arc::clone(&bitcoind_client.bitcoind_rpc_client),
+               lightning_block_sync::gossip::TokioSpawner,
+               Arc::clone(&gossip_sync),
+               Arc::clone(&peer_manager),
+       );
+       gossip_sync.add_utxo_lookup(Some(utxo_lookup));
+
        // ## Running LDK
        // Step 16: Initialize networking
 
@@ -788,36 +847,34 @@ 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;
                }
        }
-       persister
+       fs_store
                .write("", "", OUTBOUND_PAYMENTS_FNAME, &outbound_payments.lock().unwrap().encode())
                .unwrap();
 
@@ -828,7 +885,7 @@ async fn start_ldk() {
        let keys_manager_event_listener = Arc::clone(&keys_manager);
        let inbound_payments_event_listener = Arc::clone(&inbound_payments);
        let outbound_payments_event_listener = Arc::clone(&outbound_payments);
-       let persister_event_listener = Arc::clone(&persister);
+       let fs_store_event_listener = Arc::clone(&fs_store);
        let network = args.network;
        let event_handler = move |event: Event| {
                let channel_manager_event_listener = Arc::clone(&channel_manager_event_listener);
@@ -838,7 +895,7 @@ async fn start_ldk() {
                let bump_tx_event_handler = Arc::clone(&bump_tx_event_handler);
                let inbound_payments_event_listener = Arc::clone(&inbound_payments_event_listener);
                let outbound_payments_event_listener = Arc::clone(&outbound_payments_event_listener);
-               let persister_event_listener = Arc::clone(&persister_event_listener);
+               let fs_store_event_listener = Arc::clone(&fs_store_event_listener);
                async move {
                        handle_ldk_events(
                                &channel_manager_event_listener,
@@ -848,7 +905,7 @@ async fn start_ldk() {
                                &bump_tx_event_handler,
                                inbound_payments_event_listener,
                                outbound_payments_event_listener,
-                               &persister_event_listener,
+                               &fs_store_event_listener,
                                network,
                                event,
                        )
@@ -880,6 +937,7 @@ async fn start_ldk() {
                        })
                },
                false,
+               || Some(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()),
        ));
 
        // Regularly reconnect to channel peers.