Skip to content

Commit

Permalink
f - Fix htlc_fail_async_shutdown
Browse files Browse the repository at this point in the history
DO NOT MERGE - NEED TO BACKPORT FIXUP
  • Loading branch information
jkczyz committed Aug 25, 2021
1 parent ce12955 commit d5ea8e8
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 25 deletions.
2 changes: 1 addition & 1 deletion lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2164,7 +2164,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);
Expand Down
43 changes: 22 additions & 21 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3461,33 +3461,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
// (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, &[])
}
} 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,
Expand Down
3 changes: 1 addition & 2 deletions lightning/src/ln/functional_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1036,8 +1036,7 @@ macro_rules! expect_payment_failed_with_update {
match network_update {
&Some(NetworkUpdate::ChannelUpdateMessage { ref msg }) if !$chan_closed => {
assert_eq!(msg.contents.short_channel_id, $scid);
// TODO: Fails for htlc_fail_async_shutdown
//assert_eq!(msg.contents.flags & 2, 0);
assert_eq!(msg.contents.flags & 2, 0);
},
&Some(NetworkUpdate::ChannelClosed { short_channel_id, is_permanent }) if $chan_closed => {
assert_eq!(short_channel_id, $scid);
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/ln/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ fn htlc_fail_async_shutdown() {
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates_2.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], updates_2.commitment_signed, false, true);

expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, chan_1.0.contents.short_channel_id, false);
expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, chan_2.0.contents.short_channel_id, true);

let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(msg_events.len(), 1);
Expand Down

0 comments on commit d5ea8e8

Please sign in to comment.