Add is_resolving_output in ChannelMonitor
[rust-lightning] / src / ln / channelmanager.rs
index e0d2b9aaaa37222a17f5b134a994bf1080ed4f2b..52819526b727232907178c653d17b0c7ba542ea4 100644 (file)
@@ -90,7 +90,7 @@ mod channel_held_info {
        }
 
        /// Tracks the inbound corresponding to an outbound HTLC
-       #[derive(Clone)]
+       #[derive(Clone, PartialEq)]
        pub struct HTLCPreviousHopData {
                pub(super) short_channel_id: u64,
                pub(super) htlc_id: u64,
@@ -98,7 +98,7 @@ mod channel_held_info {
        }
 
        /// Tracks the inbound corresponding to an outbound HTLC
-       #[derive(Clone)]
+       #[derive(Clone, PartialEq)]
        pub enum HTLCSource {
                PreviousHopData(HTLCPreviousHopData),
                OutboundRoute {
@@ -679,13 +679,6 @@ impl ChannelManager {
                for tx in local_txn {
                        self.tx_broadcaster.broadcast_transaction(&tx);
                }
-               //TODO: We need to have a way where outbound HTLC claims can result in us claiming the
-               //now-on-chain HTLC output for ourselves (and, thereafter, passing the HTLC backwards).
-               //TODO: We need to handle monitoring of pending offered HTLCs which just hit the chain and
-               //may be claimed, resulting in us claiming the inbound HTLCs (and back-failing after
-               //timeouts are hit and our claims confirm).
-               //TODO: In any case, we need to make sure we remove any pending htlc tracking (via
-               //fail_backwards or claim_funds) eventually for all HTLCs that were in the channel
        }
 
        /// Force closes a channel, immediately broadcasting the latest local commitment transaction to
@@ -2718,6 +2711,13 @@ impl ChainListener for ChannelManager {
                for failure in failed_channels.drain(..) {
                        self.finish_force_close_channel(failure);
                }
+               {
+                       for htlc_update in self.monitor.fetch_pending_htlc_updated() {
+                               if let Some(preimage) = htlc_update.payment_preimage {
+                                       self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage);
+                               }
+                       }
+               }
                self.latest_block_height.store(height as usize, Ordering::Release);
                *self.last_block_hash.try_lock().expect("block_(dis)connected must not be called in parallel") = header.bitcoin_hash();
        }
@@ -5344,7 +5344,10 @@ mod tests {
                                        false
                                } else { true }
                        });
-                       assert_eq!(res.len(), 2);
+                       assert!(res.len() == 2 || res.len() == 3);
+                       if res.len() == 3 {
+                               assert_eq!(res[1], res[2]);
+                       }
                }
 
                assert!(node_txn.is_empty());
@@ -8429,10 +8432,12 @@ mod tests {
                        _ => panic!("Unexpected event"),
                }
                let revoked_htlc_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
-               assert_eq!(revoked_htlc_txn.len(), 2);
+               assert_eq!(revoked_htlc_txn.len(), 3);
+               assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]);
                assert_eq!(revoked_htlc_txn[0].input.len(), 1);
                assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), 133);
                check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone());
+               check_spends!(revoked_htlc_txn[1], chan_1.3.clone());
 
                // B will generate justice tx from A's revoked commitment/HTLC tx
                nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1);
@@ -8479,7 +8484,8 @@ mod tests {
                }
                let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
 
-               assert_eq!(revoked_htlc_txn.len(), 2);
+               assert_eq!(revoked_htlc_txn.len(), 3);
+               assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]);
                assert_eq!(revoked_htlc_txn[0].input.len(), 1);
                assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), 138);
                check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone());
@@ -8540,8 +8546,9 @@ mod tests {
 
                // Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor
                let spend_txn = check_spendable_outputs!(nodes[1], 1);
-               assert_eq!(spend_txn.len(), 1);
+               assert_eq!(spend_txn.len(), 2);
                check_spends!(spend_txn[0], node_txn[0].clone());
+               check_spends!(spend_txn[1], node_txn[2].clone());
        }
 
        #[test]
@@ -8571,9 +8578,13 @@ mod tests {
 
                // Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor
                let spend_txn = check_spendable_outputs!(nodes[0], 1);
-               assert_eq!(spend_txn.len(), 4);
+               assert_eq!(spend_txn.len(), 8);
                assert_eq!(spend_txn[0], spend_txn[2]);
+               assert_eq!(spend_txn[0], spend_txn[4]);
+               assert_eq!(spend_txn[0], spend_txn[6]);
                assert_eq!(spend_txn[1], spend_txn[3]);
+               assert_eq!(spend_txn[1], spend_txn[5]);
+               assert_eq!(spend_txn[1], spend_txn[7]);
                check_spends!(spend_txn[0], local_txn[0].clone());
                check_spends!(spend_txn[1], node_txn[0].clone());
        }