Fail with PERM|8 (permanent_channel_failure)
authorJeffrey Czyz <jkczyz@gmail.com>
Wed, 25 Aug 2021 01:24:23 +0000 (20:24 -0500)
committerJeffrey Czyz <jkczyz@gmail.com>
Fri, 10 Sep 2021 04:11:12 +0000 (23:11 -0500)
This affects the htlc_fail_async_shutdown test.

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

index bd97326ac12b7102568ff0e31f124aad62959c0f..7f84ecf3e599e8919f9d765f2003edcaf29a3c57 100644 (file)
@@ -2178,7 +2178,7 @@ impl<Signer: Sign> Channel<Signer> {
                // We can't accept HTLCs sent after we've sent a shutdown.
                let local_sent_shutdown = (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::LocalShutdownSent as u32)) != (ChannelState::ChannelFunded as u32);
                if local_sent_shutdown {
-                       pending_forward_status = create_pending_htlc_status(self, pending_forward_status, 0x1000|20);
+                       pending_forward_status = create_pending_htlc_status(self, pending_forward_status, 0x4000|8);
                }
                // If the remote has sent a shutdown prior to adding this HTLC, then they are in violation of the spec.
                let remote_sent_shutdown = (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) != (ChannelState::ChannelFunded as u32);
index 346dddf9261c86b7aa9e43920ce8f42753685c8c..35535c058803c7c71a63ecc5f1928f2e59d89fe1 100644 (file)
@@ -3519,33 +3519,34 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                }
 
                                let create_pending_htlc_status = |chan: &Channel<Signer>, pending_forward_info: PendingHTLCStatus, error_code: u16| {
-                                       // Ensure error_code has the UPDATE flag set, since by default we send a
-                                       // channel update along as part of failing the HTLC.
-                                       assert!((error_code & 0x1000) != 0);
                                        // If the update_add is completely bogus, the call will Err and we will close,
                                        // but if we've sent a shutdown and they haven't acknowledged it yet, we just
                                        // want to reject the new HTLC and fail it backwards instead of forwarding.
                                        match pending_forward_info {
                                                PendingHTLCStatus::Forward(PendingHTLCInfo { ref incoming_shared_secret, .. }) => {
-                                                       let reason = if let Ok(upd) = self.get_channel_update_for_unicast(chan) {
-                                                               onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &{
-                                                                       let mut res = Vec::with_capacity(8 + 128);
-                                                                       // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
-                                                                       res.extend_from_slice(&byte_utils::be16_to_array(0));
-                                                                       res.extend_from_slice(&upd.encode_with_len()[..]);
-                                                                       res
-                                                               }[..])
+                                                       let reason = if (error_code & 0x1000) != 0 {
+                                                               if let Ok(upd) = self.get_channel_update_for_unicast(chan) {
+                                                                       onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &{
+                                                                               let mut res = Vec::with_capacity(8 + 128);
+                                                                               // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
+                                                                               res.extend_from_slice(&byte_utils::be16_to_array(0));
+                                                                               res.extend_from_slice(&upd.encode_with_len()[..]);
+                                                                               res
+                                                                       }[..])
+                                                               } else {
+                                                                       // The only case where we'd be unable to
+                                                                       // successfully get a channel update is if the
+                                                                       // channel isn't in the fully-funded state yet,
+                                                                       // implying our counterparty is trying to route
+                                                                       // payments over the channel back to themselves
+                                                                       // (because no one else should know the short_id
+                                                                       // is a lightning channel yet). We should have
+                                                                       // no problem just calling this
+                                                                       // unknown_next_peer (0x4000|10).
+                                                                       onion_utils::build_first_hop_failure_packet(incoming_shared_secret, 0x4000|10, &[])
+                                                               }
                                                        } else {
-                                                               // The only case where we'd be unable to
-                                                               // successfully get a channel update is if the
-                                                               // channel isn't in the fully-funded state yet,
-                                                               // implying our counterparty is trying to route
-                                                               // payments over the channel back to themselves
-                                                               // (cause no one else should know the short_id
-                                                               // is a lightning channel yet). We should have
-                                                               // no problem just calling this
-                                                               // unknown_next_peer (0x4000|10).
-                                                               onion_utils::build_first_hop_failure_packet(incoming_shared_secret, 0x4000|10, &[])
+                                                               onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &[])
                                                        };
                                                        let msg = msgs::UpdateFailHTLC {
                                                                channel_id: msg.channel_id,
index 9f5db40c883d6ce65296fb75a7b04550582c50eb..c1140ac43e9f420c1187cc818d1de4d2f210f86e 100644 (file)
@@ -197,8 +197,9 @@ fn htlc_fail_async_shutdown() {
        let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(msg_events.len(), 2);
        match msg_events[0] {
-               MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg }} => {
-                       assert_eq!(msg.contents.short_channel_id, chan_1.0.contents.short_channel_id);
+               MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent }} => {
+                       assert_eq!(short_channel_id, chan_2.0.contents.short_channel_id);
+                       assert!(is_permanent);
                },
                _ => panic!("Unexpected event"),
        }