@@ -358,14 +358,15 @@ mod inbound_payment {
358
358
// our payment, which we can use to decode errors or inform the user that the payment was sent.
359
359
360
360
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
361
- enum PendingHTLCRouting {
361
+ pub ( super ) enum PendingHTLCRouting {
362
362
Forward {
363
363
onion_packet : msgs:: OnionPacket ,
364
364
short_channel_id : u64 , // This should be NonZero<u64> eventually when we bump MSRV
365
365
} ,
366
366
Receive {
367
367
payment_data : msgs:: FinalOnionHopData ,
368
368
incoming_cltv_expiry : u32 , // Used to track when we should expire pending HTLCs that go unclaimed
369
+ phantom_shared_secret : Option < [ u8 ; 32 ] > ,
369
370
} ,
370
371
ReceiveKeysend {
371
372
payment_preimage : PaymentPreimage ,
@@ -375,8 +376,8 @@ enum PendingHTLCRouting {
375
376
376
377
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
377
378
pub ( super ) struct PendingHTLCInfo {
378
- routing : PendingHTLCRouting ,
379
- incoming_shared_secret : [ u8 ; 32 ] ,
379
+ pub ( super ) routing : PendingHTLCRouting ,
380
+ pub ( super ) incoming_shared_secret : [ u8 ; 32 ] ,
380
381
payment_hash : PaymentHash ,
381
382
pub ( super ) amt_to_forward : u64 ,
382
383
pub ( super ) outgoing_cltv_value : u32 ,
@@ -419,6 +420,7 @@ pub(crate) struct HTLCPreviousHopData {
419
420
short_channel_id : u64 ,
420
421
htlc_id : u64 ,
421
422
incoming_packet_shared_secret : [ u8 ; 32 ] ,
423
+ phantom_shared_secret : Option < [ u8 ; 32 ] > ,
422
424
423
425
// This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
424
426
// channel with a preimage provided by the forward channel.
@@ -2072,7 +2074,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2072
2074
}
2073
2075
2074
2076
fn construct_recv_pending_htlc_info ( & self , hop_data : msgs:: OnionHopData , shared_secret : [ u8 ; 32 ] ,
2075
- payment_hash : PaymentHash , amt_msat : u64 , cltv_expiry : u32 ) -> Result < PendingHTLCInfo , ReceiveError >
2077
+ payment_hash : PaymentHash , amt_msat : u64 , cltv_expiry : u32 , phantom_shared_secret : Option < [ u8 ; 32 ] > ) -> Result < PendingHTLCInfo , ReceiveError >
2076
2078
{
2077
2079
// final_incorrect_cltv_expiry
2078
2080
if hop_data. outgoing_cltv_value != cltv_expiry {
@@ -2129,6 +2131,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2129
2131
PendingHTLCRouting :: Receive {
2130
2132
payment_data : data,
2131
2133
incoming_cltv_expiry : hop_data. outgoing_cltv_value ,
2134
+ phantom_shared_secret,
2132
2135
}
2133
2136
} else if let Some ( payment_preimage) = keysend_preimage {
2134
2137
// We need to check that the sender knows the keysend preimage before processing this
@@ -2232,7 +2235,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2232
2235
let pending_forward_info = match next_hop {
2233
2236
onion_utils:: Hop :: Receive ( next_hop_data) => {
2234
2237
// OUR PAYMENT!
2235
- match self . construct_recv_pending_htlc_info ( next_hop_data, shared_secret, msg. payment_hash , msg. amount_msat , msg. cltv_expiry ) {
2238
+ match self . construct_recv_pending_htlc_info ( next_hop_data, shared_secret, msg. payment_hash , msg. amount_msat , msg. cltv_expiry , None ) {
2236
2239
Ok ( info) => {
2237
2240
// Note that we could obviously respond immediately with an update_fulfill_htlc
2238
2241
// message, however that would leak that we are the recipient of this payment, so
@@ -3012,17 +3015,18 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3012
3015
routing, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value } ,
3013
3016
prev_funding_outpoint } => {
3014
3017
macro_rules! fail_forward {
3015
- ( $msg: expr, $err_code: expr, $err_data: expr) => {
3018
+ ( $msg: expr, $err_code: expr, $err_data: expr, $phantom_ss : expr ) => {
3016
3019
{
3017
3020
log_info!( self . logger, "Failed to accept/forward incoming HTLC: {}" , $msg) ;
3018
3021
let htlc_source = HTLCSource :: PreviousHopData ( HTLCPreviousHopData {
3019
- short_channel_id: short_chan_id ,
3022
+ short_channel_id: prev_short_channel_id ,
3020
3023
outpoint: prev_funding_outpoint,
3021
3024
htlc_id: prev_htlc_id,
3022
3025
incoming_packet_shared_secret: incoming_shared_secret,
3026
+ phantom_shared_secret: $phantom_ss,
3023
3027
} ) ;
3024
3028
failed_forwards. push( ( htlc_source, payment_hash,
3025
- HTLCFailReason :: Reason { failure_code: $err_code, data: $err_data }
3029
+ HTLCFailReason :: Reason { failure_code: $err_code, data: $err_data }
3026
3030
) ) ;
3027
3031
continue ;
3028
3032
}
@@ -3031,44 +3035,46 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3031
3035
if let PendingHTLCRouting :: Forward { onion_packet, .. } = routing {
3032
3036
let phantom_secret_res = self . keys_manager . get_node_secret ( Recipient :: PhantomNode ) ;
3033
3037
if phantom_secret_res. is_ok ( ) && fake_scid:: is_valid_phantom ( & self . fake_scid_rand_bytes , short_chan_id) {
3034
- let shared_secret = {
3038
+ let phantom_shared_secret = {
3035
3039
let mut arr = [ 0 ; 32 ] ;
3036
3040
arr. copy_from_slice ( & SharedSecret :: new ( & onion_packet. public_key . unwrap ( ) , & phantom_secret_res. unwrap ( ) ) [ ..] ) ;
3037
3041
arr
3038
3042
} ;
3039
- let next_hop = match onion_utils:: decode_next_hop ( shared_secret , & onion_packet. hop_data , onion_packet. hmac , payment_hash) {
3043
+ let next_hop = match onion_utils:: decode_next_hop ( phantom_shared_secret , & onion_packet. hop_data , onion_packet. hmac , payment_hash) {
3040
3044
Ok ( res) => res,
3041
3045
Err ( onion_utils:: OnionDecodeErr :: Malformed { err_msg, err_code } ) => {
3042
- fail_forward ! ( err_msg, err_code, Vec :: new( ) ) ;
3046
+ let sha256_of_onion = Sha256 :: hash ( & onion_packet. hop_data ) . into_inner ( ) ;
3047
+ // In this scenario, the phantom would have sent us an
3048
+ // `update_fail_malformed_htlc`, meaning here we encrypt the error as
3049
+ // if it came from us (the second-to-last hop) but contains the sha256
3050
+ // of the onion.
3051
+ fail_forward ! ( err_msg, err_code, sha256_of_onion. to_vec( ) , None ) ;
3043
3052
} ,
3044
3053
Err ( onion_utils:: OnionDecodeErr :: Relay { err_msg, err_code } ) => {
3045
- fail_forward ! ( err_msg, err_code, Vec :: new( ) ) ;
3054
+ fail_forward ! ( err_msg, err_code, Vec :: new( ) , Some ( phantom_shared_secret ) ) ;
3046
3055
} ,
3047
3056
} ;
3048
3057
match next_hop {
3049
3058
onion_utils:: Hop :: Receive ( hop_data) => {
3050
- match self . construct_recv_pending_htlc_info ( hop_data, shared_secret , payment_hash, amt_to_forward, outgoing_cltv_value) {
3059
+ match self . construct_recv_pending_htlc_info ( hop_data, incoming_shared_secret , payment_hash, amt_to_forward, outgoing_cltv_value, Some ( phantom_shared_secret ) ) {
3051
3060
Ok ( info) => phantom_receives. push ( ( prev_short_channel_id, prev_funding_outpoint, vec ! [ ( info, prev_htlc_id) ] ) ) ,
3052
- Err ( ReceiveError { err_code, err_data, msg } ) => fail_forward ! ( msg, err_code, err_data)
3061
+ Err ( ReceiveError { err_code, err_data, msg } ) => fail_forward ! ( msg, err_code, err_data, Some ( phantom_shared_secret ) )
3053
3062
}
3054
3063
} ,
3055
3064
_ => panic ! ( ) ,
3056
3065
}
3057
3066
} else {
3058
- fail_forward ! ( format!( "Unknown short channel id {} for forward HTLC" , short_chan_id) , 0x4000 | 10 , Vec :: new( ) ) ;
3067
+ fail_forward ! ( format!( "Unknown short channel id {} for forward HTLC" , short_chan_id) , 0x4000 | 10 , Vec :: new( ) , None ) ;
3059
3068
}
3060
3069
} else {
3061
- fail_forward ! ( format!( "Unknown short channel id {} for forward HTLC" , short_chan_id) , 0x4000 | 10 , Vec :: new( ) ) ;
3070
+ fail_forward ! ( format!( "Unknown short channel id {} for forward HTLC" , short_chan_id) , 0x4000 | 10 , Vec :: new( ) , None ) ;
3062
3071
}
3063
3072
} ,
3064
3073
HTLCForwardInfo :: FailHTLC { .. } => {
3065
3074
// Channel went away before we could fail it. This implies
3066
3075
// the channel is now on chain and our counterparty is
3067
3076
// trying to broadcast the HTLC-Timeout, but that's their
3068
3077
// problem, not ours.
3069
- //
3070
- // `fail_htlc_backwards_internal` is never called for
3071
- // phantom payments, so this is unreachable for them.
3072
3078
}
3073
3079
}
3074
3080
}
@@ -3091,6 +3097,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3091
3097
outpoint : prev_funding_outpoint,
3092
3098
htlc_id : prev_htlc_id,
3093
3099
incoming_packet_shared_secret : incoming_shared_secret,
3100
+ // Phantom payments are only PendingHTLCRouting::Receive.
3101
+ phantom_shared_secret : None ,
3094
3102
} ) ;
3095
3103
match chan. get_mut ( ) . send_htlc ( amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source. clone ( ) , onion_packet, & self . logger ) {
3096
3104
Err ( e) => {
@@ -3207,11 +3215,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3207
3215
HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info : PendingHTLCInfo {
3208
3216
routing, incoming_shared_secret, payment_hash, amt_to_forward, .. } ,
3209
3217
prev_funding_outpoint } => {
3210
- let ( cltv_expiry, onion_payload) = match routing {
3211
- PendingHTLCRouting :: Receive { payment_data, incoming_cltv_expiry } =>
3212
- ( incoming_cltv_expiry, OnionPayload :: Invoice ( payment_data) ) ,
3218
+ let ( cltv_expiry, onion_payload, phantom_shared_secret ) = match routing {
3219
+ PendingHTLCRouting :: Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } =>
3220
+ ( incoming_cltv_expiry, OnionPayload :: Invoice ( payment_data) , phantom_shared_secret ) ,
3213
3221
PendingHTLCRouting :: ReceiveKeysend { payment_preimage, incoming_cltv_expiry } =>
3214
- ( incoming_cltv_expiry, OnionPayload :: Spontaneous ( payment_preimage) ) ,
3222
+ ( incoming_cltv_expiry, OnionPayload :: Spontaneous ( payment_preimage) , None ) ,
3215
3223
_ => {
3216
3224
panic ! ( "short_channel_id == 0 should imply any pending_forward entries are of type Receive" ) ;
3217
3225
}
@@ -3222,6 +3230,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3222
3230
outpoint : prev_funding_outpoint,
3223
3231
htlc_id : prev_htlc_id,
3224
3232
incoming_packet_shared_secret : incoming_shared_secret,
3233
+ phantom_shared_secret,
3225
3234
} ,
3226
3235
value : amt_to_forward,
3227
3236
cltv_expiry,
@@ -3239,6 +3248,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3239
3248
outpoint: prev_funding_outpoint,
3240
3249
htlc_id: $htlc. prev_hop. htlc_id,
3241
3250
incoming_packet_shared_secret: $htlc. prev_hop. incoming_packet_shared_secret,
3251
+ phantom_shared_secret,
3242
3252
} ) , payment_hash,
3243
3253
HTLCFailReason :: Reason { failure_code: 0x4000 | 15 , data: htlc_msat_height_data }
3244
3254
) ) ;
@@ -3778,12 +3788,18 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3778
3788
pending_events. push ( path_failure) ;
3779
3789
if let Some ( ev) = full_failure_ev { pending_events. push ( ev) ; }
3780
3790
} ,
3781
- HTLCSource :: PreviousHopData ( HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret, .. } ) => {
3791
+ HTLCSource :: PreviousHopData ( HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret, phantom_shared_secret , .. } ) => {
3782
3792
let err_packet = match onion_error {
3783
3793
HTLCFailReason :: Reason { failure_code, data } => {
3784
3794
log_trace ! ( self . logger, "Failing HTLC with payment_hash {} backwards from us with code {}" , log_bytes!( payment_hash. 0 ) , failure_code) ;
3785
- let packet = onion_utils:: build_failure_packet ( & incoming_packet_shared_secret, failure_code, & data[ ..] ) . encode ( ) ;
3786
- onion_utils:: encrypt_failure_packet ( & incoming_packet_shared_secret, & packet)
3795
+ if let Some ( phantom_ss) = phantom_shared_secret {
3796
+ let phantom_packet = onion_utils:: build_failure_packet ( & phantom_ss, failure_code, & data[ ..] ) . encode ( ) ;
3797
+ let encrypted_phantom_packet = onion_utils:: encrypt_failure_packet ( & phantom_ss, & phantom_packet) ;
3798
+ onion_utils:: encrypt_failure_packet ( & incoming_packet_shared_secret, & encrypted_phantom_packet. data [ ..] )
3799
+ } else {
3800
+ let packet = onion_utils:: build_failure_packet ( & incoming_packet_shared_secret, failure_code, & data[ ..] ) . encode ( ) ;
3801
+ onion_utils:: encrypt_failure_packet ( & incoming_packet_shared_secret, & packet)
3802
+ }
3787
3803
} ,
3788
3804
HTLCFailReason :: LightningError { err } => {
3789
3805
log_trace ! ( self . logger, "Failing HTLC with payment_hash {} backwards with pre-built LightningError" , log_bytes!( payment_hash. 0 ) ) ;
@@ -4487,7 +4503,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
4487
4503
onion_utils:: build_first_hop_failure_packet ( incoming_shared_secret, error_code, & {
4488
4504
let mut res = Vec :: with_capacity ( 8 + 128 ) ;
4489
4505
// TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
4490
- res. extend_from_slice ( & byte_utils:: be16_to_array ( 0 ) ) ;
4506
+ if error_code == 0x1000 | 20 {
4507
+ res. extend_from_slice ( & byte_utils:: be16_to_array ( 0 ) ) ;
4508
+ }
4491
4509
res. extend_from_slice ( & upd. encode_with_len ( ) [ ..] ) ;
4492
4510
res
4493
4511
} [ ..] )
@@ -5978,6 +5996,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
5978
5996
} ,
5979
5997
( 1 , Receive ) => {
5980
5998
( 0 , payment_data, required) ,
5999
+ ( 1 , phantom_shared_secret, option) ,
5981
6000
( 2 , incoming_cltv_expiry, required) ,
5982
6001
} ,
5983
6002
( 2 , ReceiveKeysend ) => {
@@ -6069,6 +6088,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCStatus, ;
6069
6088
6070
6089
impl_writeable_tlv_based ! ( HTLCPreviousHopData , {
6071
6090
( 0 , short_channel_id, required) ,
6091
+ ( 1 , phantom_shared_secret, option) ,
6072
6092
( 2 , outpoint, required) ,
6073
6093
( 4 , htlc_id, required) ,
6074
6094
( 6 , incoming_packet_shared_secret, required)
0 commit comments