Support failing blinded non-intro HTLCs after RAA processing.
authorValentine Wallace <vwallace@protonmail.com>
Wed, 6 Dec 2023 20:19:23 +0000 (15:19 -0500)
committerValentine Wallace <vwallace@protonmail.com>
Tue, 12 Dec 2023 23:38:58 +0000 (18:38 -0500)
If an HTLC fails after its RAA is processed, it is failed back with
ChannelManager::fail_htlc_backwards_internal. This method will now correctly
inform the channel that this HTLC is blinded and to construct an
update_malformed message accordingly.

lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs

index a991c8eeda13fbe29a35cb9b8845dccea202ae09..bac45076891aefc9ab2df35187e2847002e20c27 100644 (file)
@@ -2881,6 +2881,17 @@ impl<SP: Deref> Channel<SP> where
                        .map(|msg_opt| assert!(msg_opt.is_none(), "We forced holding cell?"))
        }
 
+       /// Used for failing back with [`msgs::UpdateFailMalformedHTLC`]. For now, this is used when we
+       /// want to fail blinded HTLCs where we are not the intro node.
+       ///
+       /// See [`Self::queue_fail_htlc`] for more info.
+       pub fn queue_fail_malformed_htlc<L: Deref>(
+               &mut self, htlc_id_arg: u64, failure_code: u16, sha256_of_onion: [u8; 32], logger: &L
+       ) -> Result<(), ChannelError> where L::Target: Logger {
+               self.fail_htlc(htlc_id_arg, (failure_code, sha256_of_onion), true, logger)
+                       .map(|msg_opt| assert!(msg_opt.is_none(), "We forced holding cell?"))
+       }
+
        /// We can only have one resolution per HTLC. In some cases around reconnect, we may fulfill
        /// an HTLC more than once or fulfill once and then attempt to fail after reconnect. We cannot,
        /// however, fail more than once as we wait for an upstream failure to be irrevocably committed
index aed58f84db1c91284bb370d3f8a90d1f5edd8655..bf02015faf5f137f7db51364224c8a63e0602d6f 100644 (file)
@@ -4387,8 +4387,19 @@ where
                                                                                continue;
                                                                        }
                                                                },
-                                                               HTLCForwardInfo::FailMalformedHTLC { .. } => {
-                                                                       todo!()
+                                                               HTLCForwardInfo::FailMalformedHTLC { htlc_id, failure_code, sha256_of_onion } => {
+                                                                       log_trace!(self.logger, "Failing malformed HTLC back to channel with short id {} (backward HTLC ID {}) after delay", short_chan_id, htlc_id);
+                                                                       if let Err(e) = chan.queue_fail_malformed_htlc(htlc_id, failure_code, sha256_of_onion, &self.logger) {
+                                                                               if let ChannelError::Ignore(msg) = e {
+                                                                                       log_trace!(self.logger, "Failed to fail HTLC with ID {} backwards to short_id {}: {}", htlc_id, short_chan_id, msg);
+                                                                               } else {
+                                                                                       panic!("Stated return value requirements in queue_fail_malformed_htlc() were not met");
+                                                                               }
+                                                                               // fail-backs are best-effort, we probably already have one
+                                                                               // pending, and if not that's OK, if not, the channel is on
+                                                                               // the chain and sending the HTLC-Timeout is their problem.
+                                                                               continue;
+                                                                       }
                                                                },
                                                        }
                                                }
@@ -5257,7 +5268,13 @@ where
                                                );
                                                HTLCForwardInfo::FailHTLC { htlc_id: *htlc_id, err_packet }
                                        },
-                                       Some(BlindedFailure::FromBlindedNode) => todo!(),
+                                       Some(BlindedFailure::FromBlindedNode) => {
+                                               HTLCForwardInfo::FailMalformedHTLC {
+                                                       htlc_id: *htlc_id,
+                                                       failure_code: INVALID_ONION_BLINDING,
+                                                       sha256_of_onion: [0; 32]
+                                               }
+                                       },
                                        None => {
                                                let err_packet = onion_error.get_encrypted_failure_packet(
                                                        incoming_packet_shared_secret, phantom_shared_secret