@@ -2063,11 +2063,57 @@ where
2063
2063
}
2064
2064
}
2065
2065
2066
- fn construct_recv_pending_htlc_info ( & self , hop_data : msgs:: OnionHopData , shared_secret : [ u8 ; 32 ] ,
2066
+ fn construct_fwd_pending_htlc_info (
2067
+ & self , curr_packet_pubkey : PublicKey , hop_data : msgs:: InboundPayload , hop_hmac : [ u8 ; 32 ] ,
2068
+ new_packet_bytes : [ u8 ; onion_utils:: ONION_DATA_LEN ] , shared_secret : [ u8 ; 32 ] ,
2069
+ payment_hash : PaymentHash , amt_msat : u64 , cltv_expiry : u32
2070
+ ) -> Result < PendingHTLCInfo , ReceiveError > {
2071
+ let outgoing_packet = msgs:: OnionPacket {
2072
+ version : 0 ,
2073
+ public_key : onion_utils:: next_hop_packet_pubkey ( & self . secp_ctx , curr_packet_pubkey, & shared_secret) ,
2074
+ hop_data : new_packet_bytes,
2075
+ hmac : hop_hmac,
2076
+ } ;
2077
+
2078
+ let ( short_channel_id, amt_to_forward, outgoing_cltv_value) = match hop_data {
2079
+ msgs:: InboundPayload :: Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } =>
2080
+ ( short_channel_id, amt_to_forward, outgoing_cltv_value) ,
2081
+ msgs:: InboundPayload :: Receive { .. } =>
2082
+ return Err ( ReceiveError {
2083
+ msg : "Final Node OnionHopData provided for us as an intermediary node" ,
2084
+ err_code : 0x4000 | 22 ,
2085
+ err_data : vec ! [ ] ,
2086
+ } ) ,
2087
+ _ => todo ! ( )
2088
+ } ;
2089
+
2090
+ Ok ( PendingHTLCInfo {
2091
+ routing : PendingHTLCRouting :: Forward {
2092
+ onion_packet : outgoing_packet,
2093
+ short_channel_id,
2094
+ } ,
2095
+ payment_hash,
2096
+ incoming_shared_secret : shared_secret,
2097
+ incoming_amt_msat : Some ( amt_msat) ,
2098
+ outgoing_amt_msat : amt_to_forward,
2099
+ outgoing_cltv_value,
2100
+ } )
2101
+ }
2102
+
2103
+ fn construct_recv_pending_htlc_info ( & self , hop_data : msgs:: InboundPayload , shared_secret : [ u8 ; 32 ] ,
2067
2104
payment_hash : PaymentHash , amt_msat : u64 , cltv_expiry : u32 , phantom_shared_secret : Option < [ u8 ; 32 ] > ) -> Result < PendingHTLCInfo , ReceiveError >
2068
2105
{
2106
+ let ( amt_to_forward, outgoing_cltv_value) = match hop_data {
2107
+ msgs:: InboundPayload :: Receive { amt_to_forward, outgoing_cltv_value, .. } => ( amt_to_forward, outgoing_cltv_value) ,
2108
+ _ =>
2109
+ return Err ( ReceiveError {
2110
+ err_code : 0x4000 |22 ,
2111
+ err_data : Vec :: new ( ) ,
2112
+ msg : "Got non final data with an HMAC of 0" ,
2113
+ } ) ,
2114
+ } ;
2069
2115
// final_incorrect_cltv_expiry
2070
- if hop_data . outgoing_cltv_value != cltv_expiry {
2116
+ if outgoing_cltv_value != cltv_expiry {
2071
2117
return Err ( ReceiveError {
2072
2118
msg : "Upstream node set CLTV to the wrong value" ,
2073
2119
err_code : 18 ,
@@ -2082,7 +2128,7 @@ where
2082
2128
// payment logic has enough time to fail the HTLC backward before our onchain logic triggers a
2083
2129
// channel closure (see HTLC_FAIL_BACK_BUFFER rationale).
2084
2130
let current_height: u32 = self . best_block . read ( ) . unwrap ( ) . height ( ) ;
2085
- if ( hop_data . outgoing_cltv_value as u64 ) <= current_height as u64 + HTLC_FAIL_BACK_BUFFER as u64 + 1 {
2131
+ if ( outgoing_cltv_value as u64 ) <= current_height as u64 + HTLC_FAIL_BACK_BUFFER as u64 + 1 {
2086
2132
let mut err_data = Vec :: with_capacity ( 12 ) ;
2087
2133
err_data. extend_from_slice ( & amt_msat. to_be_bytes ( ) ) ;
2088
2134
err_data. extend_from_slice ( & current_height. to_be_bytes ( ) ) ;
@@ -2091,23 +2137,16 @@ where
2091
2137
msg : "The final CLTV expiry is too soon to handle" ,
2092
2138
} ) ;
2093
2139
}
2094
- if hop_data . amt_to_forward > amt_msat {
2140
+ if amt_to_forward > amt_msat {
2095
2141
return Err ( ReceiveError {
2096
2142
err_code : 19 ,
2097
2143
err_data : amt_msat. to_be_bytes ( ) . to_vec ( ) ,
2098
2144
msg : "Upstream node sent less than we were supposed to receive in payment" ,
2099
2145
} ) ;
2100
2146
}
2101
2147
2102
- let routing = match hop_data. format {
2103
- msgs:: OnionHopDataFormat :: NonFinalNode { .. } => {
2104
- return Err ( ReceiveError {
2105
- err_code : 0x4000 |22 ,
2106
- err_data : Vec :: new ( ) ,
2107
- msg : "Got non final data with an HMAC of 0" ,
2108
- } ) ;
2109
- } ,
2110
- msgs:: OnionHopDataFormat :: FinalNode { payment_data, keysend_preimage } => {
2148
+ let routing = match hop_data {
2149
+ msgs:: InboundPayload :: Receive { payment_data, keysend_preimage, .. } => {
2111
2150
if payment_data. is_some ( ) && keysend_preimage. is_some ( ) {
2112
2151
return Err ( ReceiveError {
2113
2152
err_code : 0x4000 |22 ,
@@ -2117,7 +2156,7 @@ where
2117
2156
} else if let Some ( data) = payment_data {
2118
2157
PendingHTLCRouting :: Receive {
2119
2158
payment_data : data,
2120
- incoming_cltv_expiry : hop_data . outgoing_cltv_value ,
2159
+ incoming_cltv_expiry : outgoing_cltv_value,
2121
2160
phantom_shared_secret,
2122
2161
}
2123
2162
} else if let Some ( payment_preimage) = keysend_preimage {
@@ -2137,7 +2176,7 @@ where
2137
2176
2138
2177
PendingHTLCRouting :: ReceiveKeysend {
2139
2178
payment_preimage,
2140
- incoming_cltv_expiry : hop_data . outgoing_cltv_value ,
2179
+ incoming_cltv_expiry : outgoing_cltv_value,
2141
2180
}
2142
2181
} else {
2143
2182
return Err ( ReceiveError {
@@ -2147,14 +2186,15 @@ where
2147
2186
} ) ;
2148
2187
}
2149
2188
} ,
2189
+ _ => todo ! ( )
2150
2190
} ;
2151
2191
Ok ( PendingHTLCInfo {
2152
2192
routing,
2153
2193
payment_hash,
2154
2194
incoming_shared_secret : shared_secret,
2155
2195
incoming_amt_msat : Some ( amt_msat) ,
2156
2196
outgoing_amt_msat : amt_msat,
2157
- outgoing_cltv_value : hop_data . outgoing_cltv_value ,
2197
+ outgoing_cltv_value,
2158
2198
} )
2159
2199
}
2160
2200
@@ -2229,32 +2269,10 @@ where
2229
2269
}
2230
2270
} ,
2231
2271
onion_utils:: Hop :: Forward { next_hop_data, next_hop_hmac, new_packet_bytes } => {
2232
- let new_pubkey = msg. onion_routing_packet . public_key . unwrap ( ) ;
2233
- let outgoing_packet = msgs:: OnionPacket {
2234
- version : 0 ,
2235
- public_key : onion_utils:: next_hop_packet_pubkey ( & self . secp_ctx , new_pubkey, & shared_secret) ,
2236
- hop_data : new_packet_bytes,
2237
- hmac : next_hop_hmac. clone ( ) ,
2238
- } ;
2239
-
2240
- let short_channel_id = match next_hop_data. format {
2241
- msgs:: OnionHopDataFormat :: NonFinalNode { short_channel_id } => short_channel_id,
2242
- msgs:: OnionHopDataFormat :: FinalNode { .. } => {
2243
- return_err ! ( "Final Node OnionHopData provided for us as an intermediary node" , 0x4000 | 22 , & [ 0 ; 0 ] ) ;
2244
- } ,
2245
- } ;
2246
-
2247
- PendingHTLCStatus :: Forward ( PendingHTLCInfo {
2248
- routing : PendingHTLCRouting :: Forward {
2249
- onion_packet : outgoing_packet,
2250
- short_channel_id,
2251
- } ,
2252
- payment_hash : msg. payment_hash . clone ( ) ,
2253
- incoming_shared_secret : shared_secret,
2254
- incoming_amt_msat : Some ( msg. amount_msat ) ,
2255
- outgoing_amt_msat : next_hop_data. amt_to_forward ,
2256
- outgoing_cltv_value : next_hop_data. outgoing_cltv_value ,
2257
- } )
2272
+ match self . construct_fwd_pending_htlc_info ( msg. onion_routing_packet . public_key . unwrap ( ) , next_hop_data, next_hop_hmac, new_packet_bytes, shared_secret, msg. payment_hash , msg. amount_msat , msg. cltv_expiry ) {
2273
+ Ok ( info) => PendingHTLCStatus :: Forward ( info) ,
2274
+ Err ( ReceiveError { err_code, err_data, msg } ) => return_err ! ( msg, err_code, & err_data)
2275
+ }
2258
2276
}
2259
2277
} ;
2260
2278
@@ -2465,15 +2483,15 @@ where
2465
2483
self . send_payment_along_path ( path, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv_bytes)
2466
2484
}
2467
2485
2468
- fn send_payment_along_path ( & self , path : & Vec < RouteHop > , payment_hash : & PaymentHash , payment_secret : & Option < PaymentSecret > , total_value : u64 , cur_height : u32 , payment_id : PaymentId , keysend_preimage : & Option < PaymentPreimage > , session_priv_bytes : [ u8 ; 32 ] ) -> Result < ( ) , APIError > {
2486
+ fn send_payment_along_path ( & self , path : & Path , payment_hash : & PaymentHash , payment_secret : & Option < PaymentSecret > , total_value : u64 , cur_height : u32 , payment_id : PaymentId , keysend_preimage : & Option < PaymentPreimage > , session_priv_bytes : [ u8 ; 32 ] ) -> Result < ( ) , APIError > {
2469
2487
// The top-level caller should hold the total_consistency_lock read lock.
2470
2488
debug_assert ! ( self . total_consistency_lock. try_write( ) . is_err( ) ) ;
2471
2489
2472
- log_trace ! ( self . logger, "Attempting to send payment for path with next hop {}" , path. first( ) . unwrap( ) . short_channel_id) ;
2490
+ log_trace ! ( self . logger, "Attempting to send payment for path with next hop {}" , path. hops . first( ) . unwrap( ) . short_channel_id) ;
2473
2491
let prng_seed = self . entropy_source . get_secure_random_bytes ( ) ;
2474
2492
let session_priv = SecretKey :: from_slice ( & session_priv_bytes[ ..] ) . expect ( "RNG is busted" ) ;
2475
2493
2476
- let onion_keys = onion_utils:: construct_onion_keys ( & self . secp_ctx , & path, & session_priv)
2494
+ let onion_keys = onion_utils:: construct_onion_keys ( & self . secp_ctx , & path. hops , & session_priv)
2477
2495
. map_err ( |_| APIError :: InvalidRoute { err : "Pubkey along hop was maliciously selected" . to_owned ( ) } ) ?;
2478
2496
let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( path, total_value, payment_secret, cur_height, keysend_preimage) ?;
2479
2497
if onion_utils:: route_size_insane ( & onion_payloads) {
@@ -2482,7 +2500,7 @@ where
2482
2500
let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, prng_seed, payment_hash) ;
2483
2501
2484
2502
let err: Result < ( ) , _ > = loop {
2485
- let ( counterparty_node_id, id) = match self . short_to_chan_info . read ( ) . unwrap ( ) . get ( & path. first ( ) . unwrap ( ) . short_channel_id ) {
2503
+ let ( counterparty_node_id, id) = match self . short_to_chan_info . read ( ) . unwrap ( ) . get ( & path. hops . first ( ) . unwrap ( ) . short_channel_id ) {
2486
2504
None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" . to_owned ( ) } ) ,
2487
2505
Some ( ( cp_id, chan_id) ) => ( cp_id. clone ( ) , chan_id. clone ( ) ) ,
2488
2506
} ;
@@ -2499,7 +2517,7 @@ where
2499
2517
let funding_txo = chan. get ( ) . get_funding_txo ( ) . unwrap ( ) ;
2500
2518
let send_res = chan. get_mut ( ) . send_htlc_and_commit ( htlc_msat, payment_hash. clone ( ) ,
2501
2519
htlc_cltv, HTLCSource :: OutboundRoute {
2502
- path : path. clone ( ) ,
2520
+ path : path. hops . clone ( ) , // TODO do we need to pass in the whole Path?
2503
2521
session_priv : session_priv. clone ( ) ,
2504
2522
first_hop_htlc_msat : htlc_msat,
2505
2523
payment_id,
0 commit comments