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