@@ -2413,9 +2413,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2413
2413
} ;
2414
2414
let ( chan_update_opt, forwardee_cltv_expiry_delta) = if let Some ( forwarding_id) = forwarding_id_opt {
2415
2415
let chan = channel_state. as_mut ( ) . unwrap ( ) . by_id . get_mut ( & forwarding_id) . unwrap ( ) ;
2416
- // Leave channel updates as None for private channels.
2417
- let chan_update_opt = if chan. should_announce ( ) {
2418
- Some ( self . get_channel_update_for_unicast ( chan) . unwrap ( ) ) } else { None } ;
2416
+ let chan_update_opt = self . get_channel_update_for_broadcast ( chan) . ok ( ) ;
2419
2417
if !chan. should_announce ( ) && !self . default_configuration . accept_forwards_to_priv_channels {
2420
2418
// Note that the behavior here should be identical to the above block - we
2421
2419
// should NOT reveal the existence or non-existence of a private channel if
@@ -3215,9 +3213,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3215
3213
} else {
3216
3214
panic ! ( "Stated return value requirements in send_htlc() were not met" ) ;
3217
3215
}
3218
- let chan_update = self . get_channel_update_for_unicast ( chan. get ( ) ) . unwrap ( ) ;
3216
+ let ( failure_code , data ) = self . get_htlc_temp_fail_err_and_data ( 0x1000 | 7 , chan. get ( ) ) ;
3219
3217
failed_forwards. push ( ( htlc_source, payment_hash,
3220
- HTLCFailReason :: Reason { failure_code : 0x1000 | 7 , data : chan_update . encode_with_len ( ) }
3218
+ HTLCFailReason :: Reason { failure_code, data }
3221
3219
) ) ;
3222
3220
continue ;
3223
3221
} ,
@@ -3713,6 +3711,28 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3713
3711
} else { false }
3714
3712
}
3715
3713
3714
+ /// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
3715
+ /// that we want to return and a channel.
3716
+ fn get_htlc_temp_fail_err_and_data ( & self , desired_err_code : u16 , chan : & Channel < Signer > ) -> ( u16 , Vec < u8 > ) {
3717
+ debug_assert_eq ! ( desired_err_code & 0x1000 , 0x1000 ) ;
3718
+ if let Ok ( upd) = self . get_channel_update_for_unicast ( chan) {
3719
+ let enc = if desired_err_code == 0x1000 | 20 {
3720
+ let mut res = Vec :: new ( ) ;
3721
+ // TODO: underspecified, follow https://github.com/lightning/bolts/issues/791
3722
+ res. extend_from_slice ( & byte_utils:: be16_to_array ( 0 ) ) ;
3723
+ res. extend_from_slice ( & upd. encode_with_len ( ) ) ;
3724
+ res
3725
+ } else { upd. encode_with_len ( ) } ;
3726
+ ( desired_err_code, enc)
3727
+ } else {
3728
+ // If we fail to get a unicast channel_update, it implies we don't yet have an SCID,
3729
+ // which means we really shouldn't have gotten a payment to be forwarded over this
3730
+ // channel yet, or if we did its from a route hint. Either way, returning an error of
3731
+ // PERM|no_such_channel should be fine.
3732
+ ( 0x4000 |10 , Vec :: new ( ) )
3733
+ }
3734
+ }
3735
+
3716
3736
// Fail a list of HTLCs that were just freed from the holding cell. The HTLCs need to be
3717
3737
// failed backwards or, if they were one of our outgoing HTLCs, then their failure needs to
3718
3738
// be surfaced to the user.
@@ -3723,11 +3743,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3723
3743
let ( failure_code, onion_failure_data) =
3724
3744
match self . channel_state . lock ( ) . unwrap ( ) . by_id . entry ( channel_id) {
3725
3745
hash_map:: Entry :: Occupied ( chan_entry) => {
3726
- if let Ok ( upd) = self . get_channel_update_for_unicast ( & chan_entry. get ( ) ) {
3727
- ( 0x1000 |7 , upd. encode_with_len ( ) )
3728
- } else {
3729
- ( 0x4000 |10 , Vec :: new ( ) )
3730
- }
3746
+ self . get_htlc_temp_fail_err_and_data ( 0x1000 |7 , & chan_entry. get ( ) )
3731
3747
} ,
3732
3748
hash_map:: Entry :: Vacant ( _) => ( 0x4000 |10 , Vec :: new ( ) )
3733
3749
} ;
@@ -4240,10 +4256,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4240
4256
// channel_update later through the announcement_signatures process for public
4241
4257
// channels, but there's no reason not to just inform our counterparty of our fees
4242
4258
// now.
4243
- Some ( events:: MessageSendEvent :: SendChannelUpdate {
4244
- node_id : channel. get ( ) . get_counterparty_node_id ( ) ,
4245
- msg : self . get_channel_update_for_unicast ( channel. get ( ) ) . unwrap ( ) ,
4246
- } )
4259
+ if let Ok ( msg) = self . get_channel_update_for_unicast ( channel. get ( ) ) {
4260
+ Some ( events:: MessageSendEvent :: SendChannelUpdate {
4261
+ node_id : channel. get ( ) . get_counterparty_node_id ( ) ,
4262
+ msg,
4263
+ } )
4264
+ } else { None }
4247
4265
} else { None } ;
4248
4266
chan_restoration_res = handle_chan_restoration_locked ! ( self , channel_lock, channel_state, channel, updates. raa, updates. commitment_update, updates. order, None , updates. accepted_htlcs, updates. funding_broadcastable, updates. funding_locked, updates. announcement_sigs) ;
4249
4267
if let Some ( upd) = channel_update {
@@ -4479,10 +4497,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4479
4497
// channel_update here if the channel is not public, i.e. we're not sending an
4480
4498
// announcement_signatures.
4481
4499
log_trace ! ( self . logger, "Sending private initial channel_update for our counterparty on channel {}" , log_bytes!( chan. get( ) . channel_id( ) ) ) ;
4482
- channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendChannelUpdate {
4483
- node_id : counterparty_node_id. clone ( ) ,
4484
- msg : self . get_channel_update_for_unicast ( chan. get ( ) ) . unwrap ( ) ,
4485
- } ) ;
4500
+ if let Ok ( msg) = self . get_channel_update_for_unicast ( chan. get ( ) ) {
4501
+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendChannelUpdate {
4502
+ node_id : counterparty_node_id. clone ( ) ,
4503
+ msg,
4504
+ } ) ;
4505
+ }
4486
4506
}
4487
4507
Ok ( ( ) )
4488
4508
} ,
@@ -4613,28 +4633,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4613
4633
match pending_forward_info {
4614
4634
PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref incoming_shared_secret, .. } ) => {
4615
4635
let reason = if ( error_code & 0x1000 ) != 0 {
4616
- if let Ok ( upd) = self . get_channel_update_for_unicast ( chan) {
4617
- onion_utils:: build_first_hop_failure_packet ( incoming_shared_secret, error_code, & {
4618
- let mut res = Vec :: with_capacity ( 8 + 128 ) ;
4619
- // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
4620
- if error_code == 0x1000 | 20 {
4621
- res. extend_from_slice ( & byte_utils:: be16_to_array ( 0 ) ) ;
4622
- }
4623
- res. extend_from_slice ( & upd. encode_with_len ( ) [ ..] ) ;
4624
- res
4625
- } [ ..] )
4626
- } else {
4627
- // The only case where we'd be unable to
4628
- // successfully get a channel update is if the
4629
- // channel isn't in the fully-funded state yet,
4630
- // implying our counterparty is trying to route
4631
- // payments over the channel back to themselves
4632
- // (because no one else should know the short_id
4633
- // is a lightning channel yet). We should have
4634
- // no problem just calling this
4635
- // unknown_next_peer (0x4000|10).
4636
- onion_utils:: build_first_hop_failure_packet ( incoming_shared_secret, 0x4000 |10 , & [ ] )
4637
- }
4636
+ let ( real_code, error_data) = self . get_htlc_temp_fail_err_and_data ( error_code, chan) ;
4637
+ onion_utils:: build_first_hop_failure_packet ( incoming_shared_secret, real_code, & error_data)
4638
4638
} else {
4639
4639
onion_utils:: build_first_hop_failure_packet ( incoming_shared_secret, error_code, & [ ] )
4640
4640
} ;
@@ -4956,10 +4956,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4956
4956
// If the channel is in a usable state (ie the channel is not being shut
4957
4957
// down), send a unicast channel_update to our counterparty to make sure
4958
4958
// they have the latest channel parameters.
4959
- channel_update = Some ( events:: MessageSendEvent :: SendChannelUpdate {
4960
- node_id : chan. get ( ) . get_counterparty_node_id ( ) ,
4961
- msg : self . get_channel_update_for_unicast ( chan. get ( ) ) . unwrap ( ) ,
4962
- } ) ;
4959
+ if let Ok ( msg) = self . get_channel_update_for_unicast ( chan. get ( ) ) {
4960
+ channel_update = Some ( events:: MessageSendEvent :: SendChannelUpdate {
4961
+ node_id : chan. get ( ) . get_counterparty_node_id ( ) ,
4962
+ msg,
4963
+ } ) ;
4964
+ }
4963
4965
}
4964
4966
let need_lnd_workaround = chan. get_mut ( ) . workaround_lnd_bug_4006 . take ( ) ;
4965
4967
chan_restoration_res = handle_chan_restoration_locked ! (
@@ -5622,20 +5624,21 @@ where
5622
5624
let res = f ( channel) ;
5623
5625
if let Ok ( ( funding_locked_opt, mut timed_out_pending_htlcs, announcement_sigs) ) = res {
5624
5626
for ( source, payment_hash) in timed_out_pending_htlcs. drain ( ..) {
5625
- let chan_update = self . get_channel_update_for_unicast ( & channel ) . map ( |u| u . encode_with_len ( ) ) . unwrap ( ) ; // Cannot add/recv HTLCs before we have a short_id so unwrap is safe
5627
+ let ( failure_code , data ) = self . get_htlc_temp_fail_err_and_data ( 0x1000 | 14 /* expiry_too_soon */ , & channel ) ;
5626
5628
timed_out_htlcs. push ( ( source, payment_hash, HTLCFailReason :: Reason {
5627
- failure_code : 0x1000 | 14 , // expiry_too_soon, or at least it is now
5628
- data : chan_update,
5629
+ failure_code, data,
5629
5630
} ) ) ;
5630
5631
}
5631
5632
if let Some ( funding_locked) = funding_locked_opt {
5632
5633
send_funding_locked ! ( short_to_id, pending_msg_events, channel, funding_locked) ;
5633
5634
if channel. is_usable ( ) {
5634
5635
log_trace ! ( self . logger, "Sending funding_locked with private initial channel_update for our counterparty on channel {}" , log_bytes!( channel. channel_id( ) ) ) ;
5635
- pending_msg_events. push ( events:: MessageSendEvent :: SendChannelUpdate {
5636
- node_id : channel. get_counterparty_node_id ( ) ,
5637
- msg : self . get_channel_update_for_unicast ( channel) . unwrap ( ) ,
5638
- } ) ;
5636
+ if let Ok ( msg) = self . get_channel_update_for_unicast ( channel) {
5637
+ pending_msg_events. push ( events:: MessageSendEvent :: SendChannelUpdate {
5638
+ node_id : channel. get_counterparty_node_id ( ) ,
5639
+ msg,
5640
+ } ) ;
5641
+ }
5639
5642
} else {
5640
5643
log_trace ! ( self . logger, "Sending funding_locked WITHOUT channel_update for {}" , log_bytes!( channel. channel_id( ) ) ) ;
5641
5644
}
0 commit comments