Detect onchain timeout of a HTLC in ChannelManager block_connected
authorAntoine Riard <ariard@student.42.fr>
Mon, 10 Dec 2018 19:28:24 +0000 (14:28 -0500)
committerMatt Corallo <git@bluematt.me>
Thu, 13 Dec 2018 16:53:44 +0000 (11:53 -0500)
Pass failure backward

src/ln/channelmanager.rs
src/ln/channelmonitor.rs

index 52819526b727232907178c653d17b0c7ba542ea4..c2082f6ee1cb8be9a3d678b8f727c950b0012f65 100644 (file)
@@ -1558,7 +1558,7 @@ impl ChannelManager {
                                                rejected_by_dest: !payment_retryable,
                                        });
                                } else {
-                                       panic!("should have onion error packet here");
+                                       //TODO: Pass this back (see GH #243)
                                }
                        },
                        HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret }) => {
@@ -2715,6 +2715,8 @@ impl ChainListener for ChannelManager {
                        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);
+                               } else {
+                                       self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() });
                                }
                        }
                }
index 7c4dd7350bbda37e712c9b0192c1b5f2c94c0ead..59c50061ff290b16159b7ca884df756a4e97a196 100644 (file)
@@ -1295,6 +1295,31 @@ impl ChannelMonitor {
                                                                txn_to_broadcast.push(single_htlc_tx);
                                                        }
                                                }
+                                               if !htlc.offered {
+                                                       // TODO: If the HTLC has already expired, potentially merge it with the
+                                                       // rest of the claim transaction, as above.
+                                                       let input = TxIn {
+                                                               previous_output: BitcoinOutPoint {
+                                                                       txid: commitment_txid,
+                                                                       vout: htlc.transaction_output_index,
+                                                               },
+                                                               script_sig: Script::new(),
+                                                               sequence: idx as u32,
+                                                               witness: Vec::new(),
+                                                       };
+                                                       let mut timeout_tx = Transaction {
+                                                               version: 2,
+                                                               lock_time: htlc.cltv_expiry,
+                                                               input: vec![input],
+                                                               output: vec!(TxOut {
+                                                                       script_pubkey: self.destination_script.clone(),
+                                                                       value: htlc.amount_msat / 1000,
+                                                               }),
+                                                       };
+                                                       let sighash_parts = bip143::SighashComponents::new(&timeout_tx);
+                                                       sign_input!(sighash_parts, timeout_tx.input[0], htlc.amount_msat / 1000, vec![0]);
+                                                       txn_to_broadcast.push(timeout_tx);
+                                               }
                                        }
 
                                        if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs, htlc_updated); } // Nothing to be done...probably a false positive/local tx