@@ -106,11 +106,13 @@ pub(super) enum PendingHTLCRouting {
106
106
} ,
107
107
Receive {
108
108
payment_data : msgs:: FinalOnionHopData ,
109
+ payment_metadata : Option < Vec < u8 > > ,
109
110
incoming_cltv_expiry : u32 , // Used to track when we should expire pending HTLCs that go unclaimed
110
111
phantom_shared_secret : Option < [ u8 ; 32 ] > ,
111
112
} ,
112
113
ReceiveKeysend {
113
114
payment_preimage : PaymentPreimage ,
115
+ payment_metadata : Option < Vec < u8 > > ,
114
116
incoming_cltv_expiry : u32 , // Used to track when we should expire pending HTLCs that go unclaimed
115
117
} ,
116
118
}
@@ -472,6 +474,7 @@ impl_writeable_tlv_based!(ClaimingPayment, {
472
474
473
475
struct ClaimablePayment {
474
476
purpose : events:: PaymentPurpose ,
477
+ onion_fields : Option < RecipientOnionFields > ,
475
478
htlcs : Vec < ClaimableHTLC > ,
476
479
}
477
480
@@ -2168,7 +2171,7 @@ where
2168
2171
msg : "Got non final data with an HMAC of 0" ,
2169
2172
} ) ;
2170
2173
} ,
2171
- msgs:: OnionHopDataFormat :: FinalNode { payment_data, keysend_preimage, .. } => { // TODO: expose the payment_metadata to the user
2174
+ msgs:: OnionHopDataFormat :: FinalNode { payment_data, keysend_preimage, payment_metadata } => {
2172
2175
if payment_data. is_some ( ) && keysend_preimage. is_some ( ) {
2173
2176
return Err ( ReceiveError {
2174
2177
err_code : 0x4000 |22 ,
@@ -2178,6 +2181,7 @@ where
2178
2181
} else if let Some ( data) = payment_data {
2179
2182
PendingHTLCRouting :: Receive {
2180
2183
payment_data : data,
2184
+ payment_metadata,
2181
2185
incoming_cltv_expiry : hop_data. outgoing_cltv_value ,
2182
2186
phantom_shared_secret,
2183
2187
}
@@ -2198,6 +2202,7 @@ where
2198
2202
2199
2203
PendingHTLCRouting :: ReceiveKeysend {
2200
2204
payment_preimage,
2205
+ payment_metadata,
2201
2206
incoming_cltv_expiry : hop_data. outgoing_cltv_value ,
2202
2207
}
2203
2208
} else {
@@ -3284,13 +3289,19 @@ where
3284
3289
routing, incoming_shared_secret, payment_hash, incoming_amt_msat, outgoing_amt_msat, ..
3285
3290
}
3286
3291
} ) => {
3287
- let ( cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing {
3288
- PendingHTLCRouting :: Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } => {
3292
+ let ( cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields ) = match routing {
3293
+ PendingHTLCRouting :: Receive { payment_data, payment_metadata , incoming_cltv_expiry, phantom_shared_secret } => {
3289
3294
let _legacy_hop_data = Some ( payment_data. clone ( ) ) ;
3290
- ( incoming_cltv_expiry, OnionPayload :: Invoice { _legacy_hop_data } , Some ( payment_data) , phantom_shared_secret)
3295
+ let onion_fields =
3296
+ RecipientOnionFields { payment_secret : Some ( payment_data. payment_secret ) , payment_metadata } ;
3297
+ ( incoming_cltv_expiry, OnionPayload :: Invoice { _legacy_hop_data } ,
3298
+ Some ( payment_data) , phantom_shared_secret, onion_fields)
3299
+ } ,
3300
+ PendingHTLCRouting :: ReceiveKeysend { payment_preimage, payment_metadata, incoming_cltv_expiry } => {
3301
+ let onion_fields = RecipientOnionFields { payment_secret : None , payment_metadata } ;
3302
+ ( incoming_cltv_expiry, OnionPayload :: Spontaneous ( payment_preimage) ,
3303
+ None , None , onion_fields)
3291
3304
} ,
3292
- PendingHTLCRouting :: ReceiveKeysend { payment_preimage, incoming_cltv_expiry } =>
3293
- ( incoming_cltv_expiry, OnionPayload :: Spontaneous ( payment_preimage) , None , None ) ,
3294
3305
_ => {
3295
3306
panic ! ( "short_channel_id == 0 should imply any pending_forward entries are of type Receive" ) ;
3296
3307
}
@@ -3358,8 +3369,15 @@ where
3358
3369
. entry( payment_hash)
3359
3370
// Note that if we insert here we MUST NOT fail_htlc!()
3360
3371
. or_insert_with( || ClaimablePayment {
3361
- purpose: purpose( ) , htlcs: Vec :: new( )
3372
+ purpose: purpose( ) , htlcs: Vec :: new( ) , onion_fields : None ,
3362
3373
} ) ;
3374
+ if let Some ( earlier_fields) = & mut claimable_payment. onion_fields {
3375
+ if earlier_fields. check_merge( & mut onion_fields) . is_err( ) {
3376
+ fail_htlc!( claimable_htlc, payment_hash) ;
3377
+ }
3378
+ } else {
3379
+ claimable_payment. onion_fields = Some ( onion_fields) ;
3380
+ }
3363
3381
let ref mut htlcs = & mut claimable_payment. htlcs;
3364
3382
if htlcs. len( ) == 1 {
3365
3383
if let OnionPayload :: Spontaneous ( _) = htlcs[ 0 ] . onion_payload {
@@ -3459,6 +3477,7 @@ where
3459
3477
let purpose = events:: PaymentPurpose :: SpontaneousPayment ( preimage) ;
3460
3478
e. insert ( ClaimablePayment {
3461
3479
purpose : purpose. clone ( ) ,
3480
+ onion_fields : Some ( onion_fields. clone ( ) ) ,
3462
3481
htlcs : vec ! [ claimable_htlc] ,
3463
3482
} ) ;
3464
3483
let prev_channel_id = prev_funding_outpoint. to_channel_id ( ) ;
@@ -6703,10 +6722,12 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
6703
6722
( 0 , payment_data, required) ,
6704
6723
( 1 , phantom_shared_secret, option) ,
6705
6724
( 2 , incoming_cltv_expiry, required) ,
6725
+ ( 3 , payment_metadata, option) ,
6706
6726
} ,
6707
6727
( 2 , ReceiveKeysend ) => {
6708
6728
( 0 , payment_preimage, required) ,
6709
6729
( 2 , incoming_cltv_expiry, required) ,
6730
+ ( 3 , payment_metadata, option) ,
6710
6731
} ,
6711
6732
; ) ;
6712
6733
@@ -7039,6 +7060,7 @@ where
7039
7060
let pending_outbound_payments = self . pending_outbound_payments . pending_outbound_payments . lock ( ) . unwrap ( ) ;
7040
7061
7041
7062
let mut htlc_purposes: Vec < & events:: PaymentPurpose > = Vec :: new ( ) ;
7063
+ let mut htlc_onion_fields: Vec < & _ > = Vec :: new ( ) ;
7042
7064
( claimable_payments. claimable_htlcs . len ( ) as u64 ) . write ( writer) ?;
7043
7065
for ( payment_hash, payment) in claimable_payments. claimable_htlcs . iter ( ) {
7044
7066
payment_hash. write ( writer) ?;
@@ -7047,6 +7069,7 @@ where
7047
7069
htlc. write ( writer) ?;
7048
7070
}
7049
7071
htlc_purposes. push ( & payment. purpose ) ;
7072
+ htlc_onion_fields. push ( & payment. onion_fields ) ;
7050
7073
}
7051
7074
7052
7075
let mut monitor_update_blocked_actions_per_peer = None ;
@@ -7161,6 +7184,7 @@ where
7161
7184
( 7 , self . fake_scid_rand_bytes, required) ,
7162
7185
( 9 , htlc_purposes, vec_type) ,
7163
7186
( 11 , self . probing_cookie_secret, required) ,
7187
+ ( 13 , htlc_onion_fields, optional_vec) ,
7164
7188
} ) ;
7165
7189
7166
7190
Ok ( ( ) )
@@ -7539,6 +7563,7 @@ where
7539
7563
let mut fake_scid_rand_bytes: Option < [ u8 ; 32 ] > = None ;
7540
7564
let mut probing_cookie_secret: Option < [ u8 ; 32 ] > = None ;
7541
7565
let mut claimable_htlc_purposes = None ;
7566
+ let mut claimable_htlc_onion_fields = None ;
7542
7567
let mut pending_claiming_payments = Some ( HashMap :: new ( ) ) ;
7543
7568
let mut monitor_update_blocked_actions_per_peer = Some ( Vec :: new ( ) ) ;
7544
7569
read_tlv_fields ! ( reader, {
@@ -7551,6 +7576,7 @@ where
7551
7576
( 7 , fake_scid_rand_bytes, option) ,
7552
7577
( 9 , claimable_htlc_purposes, vec_type) ,
7553
7578
( 11 , probing_cookie_secret, option) ,
7579
+ ( 13 , claimable_htlc_onion_fields, optional_vec) ,
7554
7580
} ) ;
7555
7581
if fake_scid_rand_bytes. is_none ( ) {
7556
7582
fake_scid_rand_bytes = Some ( args. entropy_source . get_secure_random_bytes ( ) ) ;
@@ -7700,15 +7726,30 @@ where
7700
7726
let expanded_inbound_key = inbound_payment:: ExpandedKey :: new ( & inbound_pmt_key_material) ;
7701
7727
7702
7728
let mut claimable_htlcs = HashMap :: with_capacity ( claimable_htlcs_list. len ( ) ) ;
7703
- if let Some ( mut purposes) = claimable_htlc_purposes {
7729
+ if let Some ( purposes) = claimable_htlc_purposes {
7704
7730
if purposes. len ( ) != claimable_htlcs_list. len ( ) {
7705
7731
return Err ( DecodeError :: InvalidValue ) ;
7706
7732
}
7707
- for ( purpose, ( payment_hash, htlcs) ) in purposes. drain ( ..) . zip ( claimable_htlcs_list. drain ( ..) ) {
7708
- let existing_payment = claimable_htlcs. insert ( payment_hash, ClaimablePayment {
7709
- purpose, htlcs,
7710
- } ) ;
7711
- if existing_payment. is_some ( ) { return Err ( DecodeError :: InvalidValue ) ; }
7733
+ if let Some ( onion_fields) = claimable_htlc_onion_fields {
7734
+ if onion_fields. len ( ) != claimable_htlcs_list. len ( ) {
7735
+ return Err ( DecodeError :: InvalidValue ) ;
7736
+ }
7737
+ for ( purpose, ( onion, ( payment_hash, htlcs) ) ) in
7738
+ purposes. into_iter ( ) . zip ( onion_fields. into_iter ( ) . zip ( claimable_htlcs_list. into_iter ( ) ) )
7739
+ {
7740
+ let existing_payment = claimable_htlcs. insert ( payment_hash, ClaimablePayment {
7741
+ purpose, htlcs, onion_fields : onion,
7742
+ } ) ;
7743
+ if existing_payment. is_some ( ) { return Err ( DecodeError :: InvalidValue ) ; }
7744
+ }
7745
+
7746
+ } else {
7747
+ for ( purpose, ( payment_hash, htlcs) ) in purposes. into_iter ( ) . zip ( claimable_htlcs_list. into_iter ( ) ) {
7748
+ let existing_payment = claimable_htlcs. insert ( payment_hash, ClaimablePayment {
7749
+ purpose, htlcs, onion_fields : None ,
7750
+ } ) ;
7751
+ if existing_payment. is_some ( ) { return Err ( DecodeError :: InvalidValue ) ; }
7752
+ }
7712
7753
}
7713
7754
} else {
7714
7755
// LDK versions prior to 0.0.107 did not write a `pending_htlc_purposes`, but do
@@ -7717,10 +7758,10 @@ where
7717
7758
if htlcs. is_empty ( ) {
7718
7759
return Err ( DecodeError :: InvalidValue ) ;
7719
7760
}
7720
- let purpose = match & htlcs[ 0 ] . onion_payload {
7761
+ let ( purpose, onion_fields ) = match & htlcs[ 0 ] . onion_payload {
7721
7762
OnionPayload :: Invoice { _legacy_hop_data } => {
7722
7763
if let Some ( hop_data) = _legacy_hop_data {
7723
- events:: PaymentPurpose :: InvoicePayment {
7764
+ ( events:: PaymentPurpose :: InvoicePayment {
7724
7765
payment_preimage : match pending_inbound_payments. get ( & payment_hash) {
7725
7766
Some ( inbound_payment) => inbound_payment. payment_preimage ,
7726
7767
None => match inbound_payment:: verify ( payment_hash, & hop_data, 0 , & expanded_inbound_key, & args. logger ) {
@@ -7732,14 +7773,14 @@ where
7732
7773
}
7733
7774
} ,
7734
7775
payment_secret : hop_data. payment_secret ,
7735
- }
7776
+ } , None )
7736
7777
} else { return Err ( DecodeError :: InvalidValue ) ; }
7737
7778
} ,
7738
7779
OnionPayload :: Spontaneous ( payment_preimage) =>
7739
- events:: PaymentPurpose :: SpontaneousPayment ( * payment_preimage) ,
7780
+ ( events:: PaymentPurpose :: SpontaneousPayment ( * payment_preimage) , None ) ,
7740
7781
} ;
7741
7782
claimable_htlcs. insert ( payment_hash, ClaimablePayment {
7742
- purpose, htlcs,
7783
+ purpose, htlcs, onion_fields ,
7743
7784
} ) ;
7744
7785
}
7745
7786
}
0 commit comments