@@ -341,7 +341,7 @@ impl HTLCSource {
341341 }
342342}
343343
344- struct ReceiveError {
344+ struct InboundOnionErr {
345345 err_code : u16 ,
346346 err_data : Vec < u8 > ,
347347 msg : & ' static str ,
@@ -2616,14 +2616,52 @@ where
26162616 }
26172617 }
26182618
2619+ fn construct_fwd_pending_htlc_info (
2620+ & self , msg : & msgs:: UpdateAddHTLC , hop_data : msgs:: OnionHopData , hop_hmac : [ u8 ; 32 ] ,
2621+ new_packet_bytes : [ u8 ; onion_utils:: ONION_DATA_LEN ] , shared_secret : [ u8 ; 32 ] ,
2622+ next_packet_pubkey_opt : Option < Result < PublicKey , secp256k1:: Error > >
2623+ ) -> Result < PendingHTLCInfo , InboundOnionErr > {
2624+ debug_assert ! ( next_packet_pubkey_opt. is_some( ) ) ;
2625+ let outgoing_packet = msgs:: OnionPacket {
2626+ version : 0 ,
2627+ public_key : next_packet_pubkey_opt. unwrap_or ( Err ( secp256k1:: Error :: InvalidPublicKey ) ) ,
2628+ hop_data : new_packet_bytes,
2629+ hmac : hop_hmac. clone ( ) ,
2630+ } ;
2631+
2632+ let short_channel_id = match hop_data. format {
2633+ msgs:: OnionHopDataFormat :: NonFinalNode { short_channel_id } => short_channel_id,
2634+ msgs:: OnionHopDataFormat :: FinalNode { .. } => {
2635+ return Err ( InboundOnionErr {
2636+ msg : "Final Node OnionHopData provided for us as an intermediary node" ,
2637+ err_code : 0x4000 | 22 ,
2638+ err_data : Vec :: new ( ) ,
2639+ } )
2640+ } ,
2641+ } ;
2642+
2643+ Ok ( PendingHTLCInfo {
2644+ routing : PendingHTLCRouting :: Forward {
2645+ onion_packet : outgoing_packet,
2646+ short_channel_id,
2647+ } ,
2648+ payment_hash : msg. payment_hash . clone ( ) ,
2649+ incoming_shared_secret : shared_secret,
2650+ incoming_amt_msat : Some ( msg. amount_msat ) ,
2651+ outgoing_amt_msat : hop_data. amt_to_forward ,
2652+ outgoing_cltv_value : hop_data. outgoing_cltv_value ,
2653+ skimmed_fee_msat : None ,
2654+ } )
2655+ }
2656+
26192657 fn construct_recv_pending_htlc_info (
26202658 & self , hop_data : msgs:: OnionHopData , shared_secret : [ u8 ; 32 ] , payment_hash : PaymentHash ,
26212659 amt_msat : u64 , cltv_expiry : u32 , phantom_shared_secret : Option < [ u8 ; 32 ] > , allow_underpay : bool ,
26222660 counterparty_skimmed_fee_msat : Option < u64 > ,
2623- ) -> Result < PendingHTLCInfo , ReceiveError > {
2661+ ) -> Result < PendingHTLCInfo , InboundOnionErr > {
26242662 // final_incorrect_cltv_expiry
26252663 if hop_data. outgoing_cltv_value > cltv_expiry {
2626- return Err ( ReceiveError {
2664+ return Err ( InboundOnionErr {
26272665 msg : "Upstream node set CLTV to less than the CLTV set by the sender" ,
26282666 err_code : 18 ,
26292667 err_data : cltv_expiry. to_be_bytes ( ) . to_vec ( )
@@ -2641,7 +2679,7 @@ where
26412679 let mut err_data = Vec :: with_capacity ( 12 ) ;
26422680 err_data. extend_from_slice ( & amt_msat. to_be_bytes ( ) ) ;
26432681 err_data. extend_from_slice ( & current_height. to_be_bytes ( ) ) ;
2644- return Err ( ReceiveError {
2682+ return Err ( InboundOnionErr {
26452683 err_code : 0x4000 | 15 , err_data,
26462684 msg : "The final CLTV expiry is too soon to handle" ,
26472685 } ) ;
@@ -2650,7 +2688,7 @@ where
26502688 ( allow_underpay && hop_data. amt_to_forward >
26512689 amt_msat. saturating_add ( counterparty_skimmed_fee_msat. unwrap_or ( 0 ) ) )
26522690 {
2653- return Err ( ReceiveError {
2691+ return Err ( InboundOnionErr {
26542692 err_code : 19 ,
26552693 err_data : amt_msat. to_be_bytes ( ) . to_vec ( ) ,
26562694 msg : "Upstream node sent less than we were supposed to receive in payment" ,
@@ -2659,7 +2697,7 @@ where
26592697
26602698 let routing = match hop_data. format {
26612699 msgs:: OnionHopDataFormat :: NonFinalNode { .. } => {
2662- return Err ( ReceiveError {
2700+ return Err ( InboundOnionErr {
26632701 err_code : 0x4000 |22 ,
26642702 err_data : Vec :: new ( ) ,
26652703 msg : "Got non final data with an HMAC of 0" ,
@@ -2674,14 +2712,14 @@ where
26742712 // time discrepancies due to a hash collision with X.
26752713 let hashed_preimage = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
26762714 if hashed_preimage != payment_hash {
2677- return Err ( ReceiveError {
2715+ return Err ( InboundOnionErr {
26782716 err_code : 0x4000 |22 ,
26792717 err_data : Vec :: new ( ) ,
26802718 msg : "Payment preimage didn't match payment hash" ,
26812719 } ) ;
26822720 }
26832721 if !self . default_configuration . accept_mpp_keysend && payment_data. is_some ( ) {
2684- return Err ( ReceiveError {
2722+ return Err ( InboundOnionErr {
26852723 err_code : 0x4000 |22 ,
26862724 err_data : Vec :: new ( ) ,
26872725 msg : "We don't support MPP keysend payments" ,
@@ -2701,7 +2739,7 @@ where
27012739 phantom_shared_secret,
27022740 }
27032741 } else {
2704- return Err ( ReceiveError {
2742+ return Err ( InboundOnionErr {
27052743 err_code : 0x4000 |0x2000 |3 ,
27062744 err_data : Vec :: new ( ) ,
27072745 msg : "We require payment_secrets" ,
@@ -2964,37 +3002,15 @@ where
29643002 // delay) once they've send us a commitment_signed!
29653003 PendingHTLCStatus :: Forward ( info)
29663004 } ,
2967- Err ( ReceiveError { err_code, err_data, msg } ) => return_err ! ( msg, err_code, & err_data)
3005+ Err ( InboundOnionErr { err_code, err_data, msg } ) => return_err ! ( msg, err_code, & err_data)
29683006 }
29693007 } ,
29703008 onion_utils:: Hop :: Forward { next_hop_data, next_hop_hmac, new_packet_bytes } => {
2971- debug_assert ! ( next_packet_pubkey_opt. is_some( ) ) ;
2972- let outgoing_packet = msgs:: OnionPacket {
2973- version : 0 ,
2974- public_key : next_packet_pubkey_opt. unwrap_or ( Err ( secp256k1:: Error :: InvalidPublicKey ) ) ,
2975- hop_data : new_packet_bytes,
2976- hmac : next_hop_hmac. clone ( ) ,
2977- } ;
2978-
2979- let short_channel_id = match next_hop_data. format {
2980- msgs:: OnionHopDataFormat :: NonFinalNode { short_channel_id } => short_channel_id,
2981- msgs:: OnionHopDataFormat :: FinalNode { .. } => {
2982- return_err ! ( "Final Node OnionHopData provided for us as an intermediary node" , 0x4000 | 22 , & [ 0 ; 0 ] ) ;
2983- } ,
2984- } ;
2985-
2986- PendingHTLCStatus :: Forward ( PendingHTLCInfo {
2987- routing : PendingHTLCRouting :: Forward {
2988- onion_packet : outgoing_packet,
2989- short_channel_id,
2990- } ,
2991- payment_hash : msg. payment_hash . clone ( ) ,
2992- incoming_shared_secret : shared_secret,
2993- incoming_amt_msat : Some ( msg. amount_msat ) ,
2994- outgoing_amt_msat : next_hop_data. amt_to_forward ,
2995- outgoing_cltv_value : next_hop_data. outgoing_cltv_value ,
2996- skimmed_fee_msat : None ,
2997- } )
3009+ match self . construct_fwd_pending_htlc_info ( msg, next_hop_data, next_hop_hmac,
3010+ new_packet_bytes, shared_secret, next_packet_pubkey_opt) {
3011+ Ok ( info) => PendingHTLCStatus :: Forward ( info) ,
3012+ Err ( InboundOnionErr { err_code, err_data, msg } ) => return_err ! ( msg, err_code, & err_data)
3013+ }
29983014 }
29993015 }
30003016 }
@@ -3777,7 +3793,7 @@ where
37773793 outgoing_cltv_value, Some ( phantom_shared_secret) , false , None )
37783794 {
37793795 Ok ( info) => phantom_receives. push( ( prev_short_channel_id, prev_funding_outpoint, prev_user_channel_id, vec![ ( info, prev_htlc_id) ] ) ) ,
3780- Err ( ReceiveError { err_code, err_data, msg } ) => failed_payment!( msg, err_code, err_data, Some ( phantom_shared_secret) )
3796+ Err ( InboundOnionErr { err_code, err_data, msg } ) => failed_payment!( msg, err_code, err_data, Some ( phantom_shared_secret) )
37813797 }
37823798 } ,
37833799 _ => panic!( ) ,
@@ -10018,7 +10034,7 @@ mod tests {
1001810034 } ;
1001910035 // Check that if the amount we received + the penultimate hop extra fee is less than the sender
1002010036 // intended amount, we fail the payment.
10021- if let Err ( crate :: ln:: channelmanager:: ReceiveError { err_code, .. } ) =
10037+ if let Err ( crate :: ln:: channelmanager:: InboundOnionErr { err_code, .. } ) =
1002210038 node[ 0 ] . node . construct_recv_pending_htlc_info ( hop_data, [ 0 ; 32 ] , PaymentHash ( [ 0 ; 32 ] ) ,
1002310039 sender_intended_amt_msat - extra_fee_msat - 1 , 42 , None , true , Some ( extra_fee_msat) )
1002410040 {
0 commit comments