@@ -49,7 +49,7 @@ use crate::routing::router::{BlindedTail, DefaultRouter, InFlightHtlcs, Path, Pa
4949use crate :: routing:: scoring:: ProbabilisticScorer ;
5050use crate :: ln:: msgs;
5151use crate :: ln:: onion_utils;
52- use crate :: ln:: onion_utils:: HTLCFailReason ;
52+ use crate :: ln:: onion_utils:: { HTLCFailReason , FailureStructure } ;
5353use crate :: ln:: msgs:: { ChannelMessageHandler , DecodeError , LightningError , MAX_VALUE_MSAT } ;
5454#[ cfg( test) ]
5555use crate :: ln:: outbound_payment;
@@ -128,6 +128,7 @@ pub(super) struct PendingHTLCInfo {
128128 /// may overshoot this in either case)
129129 pub ( super ) outgoing_amt_msat : u64 ,
130130 pub ( super ) outgoing_cltv_value : u32 ,
131+ pub ( super ) structure : Option < FailureStructure > ,
131132}
132133
133134#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
@@ -167,7 +168,7 @@ pub(super) enum HTLCForwardInfo {
167168}
168169
169170/// Tracks the inbound corresponding to an outbound HTLC
170- #[ derive( Clone , Hash , PartialEq , Eq ) ]
171+ #[ derive( Clone , Hash , PartialEq , Eq , Debug ) ]
171172pub ( crate ) struct HTLCPreviousHopData {
172173 // Note that this may be an outbound SCID alias for the associated channel.
173174 short_channel_id : u64 ,
@@ -178,6 +179,8 @@ pub(crate) struct HTLCPreviousHopData {
178179 // This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
179180 // channel with a preimage provided by the forward channel.
180181 outpoint : OutPoint ,
182+
183+ structure : Option < FailureStructure > ,
181184}
182185
183186enum OnionPayload {
@@ -278,7 +281,7 @@ impl_writeable_tlv_based_enum!(SentHTLCId,
278281
279282/// Tracks the inbound corresponding to an outbound HTLC
280283#[ allow( clippy:: derive_hash_xor_eq) ] // Our Hash is faithful to the data, we just don't have SecretKey::hash
281- #[ derive( Clone , PartialEq , Eq ) ]
284+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
282285pub ( crate ) enum HTLCSource {
283286 PreviousHopData ( HTLCPreviousHopData ) ,
284287 OutboundRoute {
@@ -2327,13 +2330,15 @@ where
23272330 }
23282331 } ,
23292332 } ;
2333+
23302334 Ok ( PendingHTLCInfo {
23312335 routing,
23322336 payment_hash,
23332337 incoming_shared_secret : shared_secret,
23342338 incoming_amt_msat : Some ( amt_msat) ,
23352339 outgoing_amt_msat : hop_data. amt_to_forward ,
23362340 outgoing_cltv_value : hop_data. outgoing_cltv_value ,
2341+ structure : hop_data. structure ,
23372342 } )
23382343 }
23392344
@@ -2373,11 +2378,15 @@ where
23732378 ( $msg: expr, $err_code: expr, $data: expr) => {
23742379 {
23752380 log_info!( self . logger, "Failed to accept/forward incoming HTLC: {}" , $msg) ;
2381+ let no_structure = FailureStructure { // TODO: Return legacy failure.
2382+ max_hops: 3 ,
2383+ payload_len: 8 ,
2384+ } ;
23762385 return PendingHTLCStatus :: Fail ( HTLCFailureMsg :: Relay ( msgs:: UpdateFailHTLC {
23772386 channel_id: msg. channel_id,
23782387 htlc_id: msg. htlc_id,
23792388 reason: HTLCFailReason :: reason( $err_code, $data. to_vec( ) )
2380- . get_encrypted_failure_packet( & shared_secret, & None ) ,
2389+ . get_encrypted_failure_packet( & shared_secret, & None , & no_structure ) ,
23812390 } ) ) ;
23822391 }
23832392 }
@@ -2433,6 +2442,7 @@ where
24332442 incoming_amt_msat : Some ( msg. amount_msat ) ,
24342443 outgoing_amt_msat : next_hop_data. amt_to_forward ,
24352444 outgoing_cltv_value : next_hop_data. outgoing_cltv_value ,
2445+ structure : next_hop_data. structure ,
24362446 } )
24372447 }
24382448 } ;
@@ -3219,6 +3229,7 @@ where
32193229 htlc_id : payment. prev_htlc_id ,
32203230 incoming_packet_shared_secret : payment. forward_info . incoming_shared_secret ,
32213231 phantom_shared_secret : None ,
3232+ structure : payment. forward_info . structure ,
32223233 } ) ;
32233234
32243235 let failure_reason = HTLCFailReason :: from_failure_code ( 0x4000 | 10 ) ;
@@ -3253,7 +3264,8 @@ where
32533264 prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
32543265 forward_info: PendingHTLCInfo {
32553266 routing, incoming_shared_secret, payment_hash, outgoing_amt_msat,
3256- outgoing_cltv_value, incoming_amt_msat: _
3267+ outgoing_cltv_value, incoming_amt_msat: _,
3268+ structure,
32573269 }
32583270 } ) => {
32593271 macro_rules! failure_handler {
@@ -3266,6 +3278,7 @@ where
32663278 htlc_id: prev_htlc_id,
32673279 incoming_packet_shared_secret: incoming_shared_secret,
32683280 phantom_shared_secret: $phantom_ss,
3281+ structure,
32693282 } ) ;
32703283
32713284 let reason = if $next_hop_unknown {
@@ -3367,6 +3380,7 @@ where
33673380 forward_info : PendingHTLCInfo {
33683381 incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value,
33693382 routing : PendingHTLCRouting :: Forward { onion_packet, .. } , incoming_amt_msat : _,
3383+ structure,
33703384 } ,
33713385 } ) => {
33723386 log_trace ! ( self . logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay" , prev_short_channel_id, log_bytes!( payment_hash. 0 ) , short_chan_id) ;
@@ -3377,6 +3391,7 @@ where
33773391 incoming_packet_shared_secret : incoming_shared_secret,
33783392 // Phantom payments are only PendingHTLCRouting::Receive.
33793393 phantom_shared_secret : None ,
3394+ structure,
33803395 } ) ;
33813396 if let Err ( e) = chan. get_mut ( ) . queue_add_htlc ( outgoing_amt_msat,
33823397 payment_hash, outgoing_cltv_value, htlc_source. clone ( ) ,
@@ -3424,7 +3439,8 @@ where
34243439 HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
34253440 prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
34263441 forward_info : PendingHTLCInfo {
3427- routing, incoming_shared_secret, payment_hash, incoming_amt_msat, outgoing_amt_msat, ..
3442+ routing, incoming_shared_secret, payment_hash, incoming_amt_msat, outgoing_amt_msat,
3443+ structure, ..
34283444 }
34293445 } ) => {
34303446 let ( cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing {
@@ -3451,6 +3467,7 @@ where
34513467 htlc_id : prev_htlc_id,
34523468 incoming_packet_shared_secret : incoming_shared_secret,
34533469 phantom_shared_secret,
3470+ structure : structure,
34543471 } ,
34553472 // We differentiate the received value from the sender intended value
34563473 // if possible so that we don't prematurely mark MPP payments complete
@@ -3479,6 +3496,7 @@ where
34793496 htlc_id: $htlc. prev_hop. htlc_id,
34803497 incoming_packet_shared_secret: $htlc. prev_hop. incoming_packet_shared_secret,
34813498 phantom_shared_secret,
3499+ structure: $htlc. prev_hop. structure,
34823500 } ) , payment_hash,
34833501 HTLCFailReason :: reason( 0x4000 | 15 , htlc_msat_height_data) ,
34843502 HTLCDestination :: FailedPayment { payment_hash: $payment_hash } ,
@@ -3676,6 +3694,7 @@ where
36763694 HTLCForwardInfo :: FailHTLC { .. } => {
36773695 panic ! ( "Got pending fail of our own HTLC" ) ;
36783696 }
3697+ _ => panic ! ( "Unsupported forward info" ) ,
36793698 }
36803699 }
36813700 }
@@ -4099,9 +4118,11 @@ where
40994118 & self . pending_events , & self . logger )
41004119 { self . push_pending_forwards_ev ( ) ; }
41014120 } ,
4102- HTLCSource :: PreviousHopData ( HTLCPreviousHopData { ref short_channel_id, ref htlc_id, ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint } ) => {
4121+ HTLCSource :: PreviousHopData ( HTLCPreviousHopData { ref short_channel_id, ref htlc_id, ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint, structure : Some ( structure ) } ) => {
41034122 log_trace ! ( self . logger, "Failing HTLC with payment_hash {} backwards from us with {:?}" , log_bytes!( payment_hash. 0 ) , onion_error) ;
4104- let err_packet = onion_error. get_encrypted_failure_packet ( incoming_packet_shared_secret, phantom_shared_secret) ;
4123+ let err_packet = onion_error. get_encrypted_failure_packet ( incoming_packet_shared_secret, phantom_shared_secret, structure) ;
4124+
4125+ log_trace ! ( self . logger, "Failure packet length: {}" , err_packet. data. len( ) ) ;
41054126
41064127 let mut push_forward_ev = false ;
41074128 let mut forward_htlcs = self . forward_htlcs . lock ( ) . unwrap ( ) ;
@@ -4124,6 +4145,7 @@ where
41244145 failed_next_destination : destination,
41254146 } ) ;
41264147 } ,
4148+ _ => panic ! ( "Unhandled htlc source type {:?}" , source) ,
41274149 }
41284150 }
41294151
@@ -5034,13 +5056,13 @@ where
50345056 // but if we've sent a shutdown and they haven't acknowledged it yet, we just
50355057 // want to reject the new HTLC and fail it backwards instead of forwarding.
50365058 match pending_forward_info {
5037- PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref incoming_shared_secret, .. } ) => {
5059+ PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref incoming_shared_secret, structure : Some ( structure ) , .. } ) => { // TODO: Implement legacy.
50385060 let reason = if ( error_code & 0x1000 ) != 0 {
50395061 let ( real_code, error_data) = self . get_htlc_inbound_temp_fail_err_and_data ( error_code, chan) ;
50405062 HTLCFailReason :: reason ( real_code, error_data)
50415063 } else {
50425064 HTLCFailReason :: from_failure_code ( error_code)
5043- } . get_encrypted_failure_packet ( incoming_shared_secret, & None ) ;
5065+ } . get_encrypted_failure_packet ( incoming_shared_secret, & None , & structure ) ;
50445066 let msg = msgs:: UpdateFailHTLC {
50455067 channel_id : msg. channel_id ,
50465068 htlc_id : msg. htlc_id ,
@@ -5190,6 +5212,7 @@ where
51905212 htlc_id : prev_htlc_id,
51915213 incoming_packet_shared_secret : forward_info. incoming_shared_secret ,
51925214 phantom_shared_secret : None ,
5215+ structure : forward_info. structure ,
51935216 } ) ;
51945217
51955218 failed_intercept_forwards. push ( ( htlc_source, forward_info. payment_hash ,
@@ -6273,6 +6296,7 @@ where
62736296 incoming_packet_shared_secret : htlc. forward_info . incoming_shared_secret ,
62746297 phantom_shared_secret : None ,
62756298 outpoint : htlc. prev_funding_outpoint ,
6299+ structure : htlc. forward_info . structure . clone ( ) ,
62766300 } ) ;
62776301
62786302 let requested_forward_scid /* intercept scid */ = match htlc. forward_info . routing {
@@ -6695,6 +6719,7 @@ pub fn provided_init_features(_config: &UserConfig) -> InitFeatures {
66956719 features. set_channel_type_optional ( ) ;
66966720 features. set_scid_privacy_optional ( ) ;
66976721 features. set_zero_conf_optional ( ) ;
6722+ features. set_attributable_errors_optional ( ) ;
66986723 #[ cfg( anchors) ]
66996724 { // Attributes are not allowed on if expressions on our current MSRV of 1.41.
67006725 if _config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx {
@@ -6855,13 +6880,34 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
68556880 } ,
68566881; ) ;
68576882
6883+ impl Writeable for FailureStructure {
6884+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
6885+ self . max_hops . write ( w) ?;
6886+ self . payload_len . write ( w) ?;
6887+
6888+ Ok ( ( ) )
6889+ }
6890+ }
6891+
6892+ impl Readable for FailureStructure {
6893+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
6894+ let max_hops: u8 = Readable :: read ( r) ?;
6895+ let payload_len: u8 = Readable :: read ( r) ?;
6896+ Ok ( FailureStructure {
6897+ max_hops,
6898+ payload_len,
6899+ } )
6900+ }
6901+ }
6902+
68586903impl_writeable_tlv_based ! ( PendingHTLCInfo , {
68596904 ( 0 , routing, required) ,
68606905 ( 2 , incoming_shared_secret, required) ,
68616906 ( 4 , payment_hash, required) ,
68626907 ( 6 , outgoing_amt_msat, required) ,
68636908 ( 8 , outgoing_cltv_value, required) ,
68646909 ( 9 , incoming_amt_msat, option) ,
6910+ ( 11 , structure, option) ,
68656911} ) ;
68666912
68676913
@@ -6942,7 +6988,8 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
69426988 ( 1 , phantom_shared_secret, option) ,
69436989 ( 2 , outpoint, required) ,
69446990 ( 4 , htlc_id, required) ,
6945- ( 6 , incoming_packet_shared_secret, required)
6991+ ( 6 , incoming_packet_shared_secret, required) ,
6992+ ( 7 , structure, option)
69466993} ) ;
69476994
69486995impl Writeable for ClaimableHTLC {
0 commit comments