@@ -49,7 +49,7 @@ use crate::routing::router::{BlindedTail, DefaultRouter, InFlightHtlcs, Path, Pa
49
49
use crate :: routing:: scoring:: ProbabilisticScorer ;
50
50
use crate :: ln:: msgs;
51
51
use crate :: ln:: onion_utils;
52
- use crate :: ln:: onion_utils:: HTLCFailReason ;
52
+ use crate :: ln:: onion_utils:: { HTLCFailReason , FailureStructure } ;
53
53
use crate :: ln:: msgs:: { ChannelMessageHandler , DecodeError , LightningError , MAX_VALUE_MSAT } ;
54
54
#[ cfg( test) ]
55
55
use crate :: ln:: outbound_payment;
@@ -128,6 +128,7 @@ pub(super) struct PendingHTLCInfo {
128
128
/// may overshoot this in either case)
129
129
pub ( super ) outgoing_amt_msat : u64 ,
130
130
pub ( super ) outgoing_cltv_value : u32 ,
131
+ pub ( super ) structure : Option < FailureStructure > ,
131
132
}
132
133
133
134
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
@@ -167,7 +168,7 @@ pub(super) enum HTLCForwardInfo {
167
168
}
168
169
169
170
/// Tracks the inbound corresponding to an outbound HTLC
170
- #[ derive( Clone , Hash , PartialEq , Eq ) ]
171
+ #[ derive( Clone , Hash , PartialEq , Eq , Debug ) ]
171
172
pub ( crate ) struct HTLCPreviousHopData {
172
173
// Note that this may be an outbound SCID alias for the associated channel.
173
174
short_channel_id : u64 ,
@@ -178,6 +179,8 @@ pub(crate) struct HTLCPreviousHopData {
178
179
// This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
179
180
// channel with a preimage provided by the forward channel.
180
181
outpoint : OutPoint ,
182
+
183
+ structure : Option < FailureStructure > ,
181
184
}
182
185
183
186
enum OnionPayload {
@@ -278,7 +281,7 @@ impl_writeable_tlv_based_enum!(SentHTLCId,
278
281
279
282
/// Tracks the inbound corresponding to an outbound HTLC
280
283
#[ 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 ) ]
282
285
pub ( crate ) enum HTLCSource {
283
286
PreviousHopData ( HTLCPreviousHopData ) ,
284
287
OutboundRoute {
@@ -2327,13 +2330,15 @@ where
2327
2330
}
2328
2331
} ,
2329
2332
} ;
2333
+
2330
2334
Ok ( PendingHTLCInfo {
2331
2335
routing,
2332
2336
payment_hash,
2333
2337
incoming_shared_secret : shared_secret,
2334
2338
incoming_amt_msat : Some ( amt_msat) ,
2335
2339
outgoing_amt_msat : hop_data. amt_to_forward ,
2336
2340
outgoing_cltv_value : hop_data. outgoing_cltv_value ,
2341
+ structure : hop_data. structure ,
2337
2342
} )
2338
2343
}
2339
2344
@@ -2373,11 +2378,15 @@ where
2373
2378
( $msg: expr, $err_code: expr, $data: expr) => {
2374
2379
{
2375
2380
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
+ } ;
2376
2385
return PendingHTLCStatus :: Fail ( HTLCFailureMsg :: Relay ( msgs:: UpdateFailHTLC {
2377
2386
channel_id: msg. channel_id,
2378
2387
htlc_id: msg. htlc_id,
2379
2388
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 ) ,
2381
2390
} ) ) ;
2382
2391
}
2383
2392
}
@@ -2433,6 +2442,7 @@ where
2433
2442
incoming_amt_msat : Some ( msg. amount_msat ) ,
2434
2443
outgoing_amt_msat : next_hop_data. amt_to_forward ,
2435
2444
outgoing_cltv_value : next_hop_data. outgoing_cltv_value ,
2445
+ structure : next_hop_data. structure ,
2436
2446
} )
2437
2447
}
2438
2448
} ;
@@ -3219,6 +3229,7 @@ where
3219
3229
htlc_id : payment. prev_htlc_id ,
3220
3230
incoming_packet_shared_secret : payment. forward_info . incoming_shared_secret ,
3221
3231
phantom_shared_secret : None ,
3232
+ structure : payment. forward_info . structure ,
3222
3233
} ) ;
3223
3234
3224
3235
let failure_reason = HTLCFailReason :: from_failure_code ( 0x4000 | 10 ) ;
@@ -3253,7 +3264,8 @@ where
3253
3264
prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
3254
3265
forward_info: PendingHTLCInfo {
3255
3266
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,
3257
3269
}
3258
3270
} ) => {
3259
3271
macro_rules! failure_handler {
@@ -3266,6 +3278,7 @@ where
3266
3278
htlc_id: prev_htlc_id,
3267
3279
incoming_packet_shared_secret: incoming_shared_secret,
3268
3280
phantom_shared_secret: $phantom_ss,
3281
+ structure,
3269
3282
} ) ;
3270
3283
3271
3284
let reason = if $next_hop_unknown {
@@ -3367,6 +3380,7 @@ where
3367
3380
forward_info : PendingHTLCInfo {
3368
3381
incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value,
3369
3382
routing : PendingHTLCRouting :: Forward { onion_packet, .. } , incoming_amt_msat : _,
3383
+ structure,
3370
3384
} ,
3371
3385
} ) => {
3372
3386
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
3377
3391
incoming_packet_shared_secret : incoming_shared_secret,
3378
3392
// Phantom payments are only PendingHTLCRouting::Receive.
3379
3393
phantom_shared_secret : None ,
3394
+ structure,
3380
3395
} ) ;
3381
3396
if let Err ( e) = chan. get_mut ( ) . queue_add_htlc ( outgoing_amt_msat,
3382
3397
payment_hash, outgoing_cltv_value, htlc_source. clone ( ) ,
@@ -3424,7 +3439,8 @@ where
3424
3439
HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
3425
3440
prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
3426
3441
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, ..
3428
3444
}
3429
3445
} ) => {
3430
3446
let ( cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing {
@@ -3451,6 +3467,7 @@ where
3451
3467
htlc_id : prev_htlc_id,
3452
3468
incoming_packet_shared_secret : incoming_shared_secret,
3453
3469
phantom_shared_secret,
3470
+ structure : structure,
3454
3471
} ,
3455
3472
// We differentiate the received value from the sender intended value
3456
3473
// if possible so that we don't prematurely mark MPP payments complete
@@ -3479,6 +3496,7 @@ where
3479
3496
htlc_id: $htlc. prev_hop. htlc_id,
3480
3497
incoming_packet_shared_secret: $htlc. prev_hop. incoming_packet_shared_secret,
3481
3498
phantom_shared_secret,
3499
+ structure: $htlc. prev_hop. structure,
3482
3500
} ) , payment_hash,
3483
3501
HTLCFailReason :: reason( 0x4000 | 15 , htlc_msat_height_data) ,
3484
3502
HTLCDestination :: FailedPayment { payment_hash: $payment_hash } ,
@@ -3676,6 +3694,7 @@ where
3676
3694
HTLCForwardInfo :: FailHTLC { .. } => {
3677
3695
panic ! ( "Got pending fail of our own HTLC" ) ;
3678
3696
}
3697
+ _ => panic ! ( "Unsupported forward info" ) ,
3679
3698
}
3680
3699
}
3681
3700
}
@@ -4099,9 +4118,11 @@ where
4099
4118
& self . pending_events , & self . logger )
4100
4119
{ self . push_pending_forwards_ev ( ) ; }
4101
4120
} ,
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 ) } ) => {
4103
4122
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( ) ) ;
4105
4126
4106
4127
let mut push_forward_ev = false ;
4107
4128
let mut forward_htlcs = self . forward_htlcs . lock ( ) . unwrap ( ) ;
@@ -4124,6 +4145,7 @@ where
4124
4145
failed_next_destination : destination,
4125
4146
} ) ;
4126
4147
} ,
4148
+ _ => panic ! ( "Unhandled htlc source type {:?}" , source) ,
4127
4149
}
4128
4150
}
4129
4151
@@ -5034,13 +5056,13 @@ where
5034
5056
// but if we've sent a shutdown and they haven't acknowledged it yet, we just
5035
5057
// want to reject the new HTLC and fail it backwards instead of forwarding.
5036
5058
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.
5038
5060
let reason = if ( error_code & 0x1000 ) != 0 {
5039
5061
let ( real_code, error_data) = self . get_htlc_inbound_temp_fail_err_and_data ( error_code, chan) ;
5040
5062
HTLCFailReason :: reason ( real_code, error_data)
5041
5063
} else {
5042
5064
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 ) ;
5044
5066
let msg = msgs:: UpdateFailHTLC {
5045
5067
channel_id : msg. channel_id ,
5046
5068
htlc_id : msg. htlc_id ,
@@ -5190,6 +5212,7 @@ where
5190
5212
htlc_id : prev_htlc_id,
5191
5213
incoming_packet_shared_secret : forward_info. incoming_shared_secret ,
5192
5214
phantom_shared_secret : None ,
5215
+ structure : forward_info. structure ,
5193
5216
} ) ;
5194
5217
5195
5218
failed_intercept_forwards. push ( ( htlc_source, forward_info. payment_hash ,
@@ -6273,6 +6296,7 @@ where
6273
6296
incoming_packet_shared_secret : htlc. forward_info . incoming_shared_secret ,
6274
6297
phantom_shared_secret : None ,
6275
6298
outpoint : htlc. prev_funding_outpoint ,
6299
+ structure : htlc. forward_info . structure . clone ( ) ,
6276
6300
} ) ;
6277
6301
6278
6302
let requested_forward_scid /* intercept scid */ = match htlc. forward_info . routing {
@@ -6695,6 +6719,7 @@ pub fn provided_init_features(_config: &UserConfig) -> InitFeatures {
6695
6719
features. set_channel_type_optional ( ) ;
6696
6720
features. set_scid_privacy_optional ( ) ;
6697
6721
features. set_zero_conf_optional ( ) ;
6722
+ features. set_attributable_errors_optional ( ) ;
6698
6723
#[ cfg( anchors) ]
6699
6724
{ // Attributes are not allowed on if expressions on our current MSRV of 1.41.
6700
6725
if _config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx {
@@ -6855,13 +6880,34 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
6855
6880
} ,
6856
6881
; ) ;
6857
6882
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
+
6858
6903
impl_writeable_tlv_based ! ( PendingHTLCInfo , {
6859
6904
( 0 , routing, required) ,
6860
6905
( 2 , incoming_shared_secret, required) ,
6861
6906
( 4 , payment_hash, required) ,
6862
6907
( 6 , outgoing_amt_msat, required) ,
6863
6908
( 8 , outgoing_cltv_value, required) ,
6864
6909
( 9 , incoming_amt_msat, option) ,
6910
+ ( 11 , structure, option) ,
6865
6911
} ) ;
6866
6912
6867
6913
@@ -6942,7 +6988,8 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
6942
6988
( 1 , phantom_shared_secret, option) ,
6943
6989
( 2 , outpoint, required) ,
6944
6990
( 4 , htlc_id, required) ,
6945
- ( 6 , incoming_packet_shared_secret, required)
6991
+ ( 6 , incoming_packet_shared_secret, required) ,
6992
+ ( 7 , structure, option)
6946
6993
} ) ;
6947
6994
6948
6995
impl Writeable for ClaimableHTLC {
0 commit comments