55
66use bitcoin:: hashes:: Hash ;
77use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
8- use bitcoin:: secp256k1:: { self , PublicKey , Secp256k1 } ;
8+ use bitcoin:: secp256k1:: { self , PublicKey , Secp256k1 , ecdh :: SharedSecret } ;
99
1010use crate :: blinded_path;
1111use crate :: blinded_path:: payment:: { PaymentConstraints , PaymentRelay } ;
@@ -15,7 +15,7 @@ use crate::ln::channelmanager::{BlindedFailure, BlindedForward, CLTV_FAR_FAR_AWA
1515use crate :: types:: features:: BlindedHopFeatures ;
1616use crate :: ln:: msgs;
1717use crate :: ln:: onion_utils;
18- use crate :: ln:: onion_utils:: { HTLCFailReason , INVALID_ONION_BLINDING } ;
18+ use crate :: ln:: onion_utils:: { HTLCFailReason , INVALID_ONION_BLINDING , ONION_DATA_LEN } ;
1919use crate :: routing:: gossip:: NodeId ;
2020use crate :: sign:: { NodeSigner , Recipient } ;
2121use crate :: util:: logger:: Logger ;
@@ -61,20 +61,37 @@ fn check_blinded_forward(
6161 Ok ( ( amt_to_forward, outgoing_cltv_value) )
6262}
6363
64+ enum RoutingInfo {
65+ Direct {
66+ short_channel_id : u64 ,
67+ new_packet_bytes : [ u8 ; ONION_DATA_LEN ] ,
68+ next_hop_hmac : [ u8 ; 32 ]
69+ } ,
70+ #[ cfg( trampoline) ]
71+ Trampoline {
72+ outgoing_node_id : NodeId ,
73+ // Trampoline onions are currently variable length
74+ new_packet_bytes : Vec < u8 > ,
75+ next_hop_hmac : [ u8 ; 32 ] ,
76+ shared_secret : SharedSecret ,
77+ current_path_key : Option < PublicKey >
78+ }
79+ }
80+
6481pub ( super ) fn create_fwd_pending_htlc_info (
6582 msg : & msgs:: UpdateAddHTLC , hop_data : onion_utils:: Hop , shared_secret : [ u8 ; 32 ] ,
6683 next_packet_pubkey_opt : Option < Result < PublicKey , secp256k1:: Error > >
6784) -> Result < PendingHTLCInfo , InboundHTLCErr > {
6885 debug_assert ! ( next_packet_pubkey_opt. is_some( ) ) ;
6986
7087 let (
71- short_channel_id , amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
72- next_blinding_override, new_packet_bytes , next_hop_hmac
88+ routing_info , amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
89+ next_blinding_override
7390 ) = match hop_data {
7491 onion_utils:: Hop :: Forward { next_hop_data : msgs:: InboundOnionForwardPayload {
7592 short_channel_id, amt_to_forward, outgoing_cltv_value
7693 } , new_packet_bytes, next_hop_hmac, .. } =>
77- ( short_channel_id, amt_to_forward , outgoing_cltv_value , None , None , new_packet_bytes , next_hop_hmac ) ,
94+ ( RoutingInfo :: Direct { short_channel_id, new_packet_bytes , next_hop_hmac } , amt_to_forward , outgoing_cltv_value , None , None ) ,
7895 onion_utils:: Hop :: BlindedForward { next_hop_data : msgs:: InboundOnionBlindedForwardPayload {
7996 short_channel_id, payment_relay, payment_constraints, intro_node_blinding_point, features,
8097 next_blinding_override,
@@ -90,38 +107,124 @@ pub(super) fn create_fwd_pending_htlc_info(
90107 err_data : vec ! [ 0 ; 32 ] ,
91108 }
92109 } ) ?;
93- ( short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
94- next_blinding_override, new_packet_bytes , next_hop_hmac )
110+ ( RoutingInfo :: Direct { short_channel_id, new_packet_bytes , next_hop_hmac } , amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
111+ next_blinding_override)
95112 } ,
96113 onion_utils:: Hop :: Receive { .. } | onion_utils:: Hop :: BlindedReceive { .. } =>
97114 return Err ( InboundHTLCErr {
98115 msg : "Final Node OnionHopData provided for us as an intermediary node" ,
99116 err_code : 0x4000 | 22 ,
100117 err_data : Vec :: new ( ) ,
101118 } ) ,
119+ #[ cfg( trampoline) ]
120+ onion_utils:: Hop :: TrampolineReceive { .. } =>
121+ return Err ( InboundHTLCErr {
122+ msg : "Final Node OnionHopData provided for us as an intermediary node" ,
123+ err_code : 0x4000 | 22 ,
124+ err_data : Vec :: new ( ) ,
125+ } ) ,
126+ #[ cfg( trampoline) ]
127+ onion_utils:: Hop :: TrampolineForward { next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
128+ (
129+ RoutingInfo :: Trampoline {
130+ outgoing_node_id : next_trampoline_hop_data. outgoing_node_id ,
131+ new_packet_bytes : new_trampoline_packet_bytes,
132+ next_hop_hmac : next_trampoline_hop_hmac,
133+ shared_secret : trampoline_shared_secret,
134+ current_path_key : None
135+ } ,
136+ next_trampoline_hop_data. amt_to_forward ,
137+ next_trampoline_hop_data. outgoing_cltv_value ,
138+ None ,
139+ None
140+ )
141+ } ,
142+ #[ cfg( trampoline) ]
143+ onion_utils:: Hop :: TrampolineBlindedForward { outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
144+ let ( amt_to_forward, outgoing_cltv_value) = check_blinded_forward (
145+ msg. amount_msat , msg. cltv_expiry , & next_trampoline_hop_data. payment_relay , & next_trampoline_hop_data. payment_constraints , & next_trampoline_hop_data. features
146+ ) . map_err ( |( ) | {
147+ // We should be returning malformed here if `msg.blinding_point` is set, but this is
148+ // unreachable right now since we checked it in `decode_update_add_htlc_onion`.
149+ InboundHTLCErr {
150+ msg : "Underflow calculating outbound amount or cltv value for blinded forward" ,
151+ err_code : INVALID_ONION_BLINDING ,
152+ err_data : vec ! [ 0 ; 32 ] ,
153+ }
154+ } ) ?;
155+ (
156+ RoutingInfo :: Trampoline {
157+ outgoing_node_id : next_trampoline_hop_data. outgoing_node_id ,
158+ new_packet_bytes : new_trampoline_packet_bytes,
159+ next_hop_hmac : next_trampoline_hop_hmac,
160+ shared_secret : trampoline_shared_secret,
161+ current_path_key : outer_hop_data. current_path_key
162+ } ,
163+ amt_to_forward,
164+ outgoing_cltv_value,
165+ next_trampoline_hop_data. intro_node_blinding_point ,
166+ next_trampoline_hop_data. next_blinding_override
167+ )
168+ } ,
102169 } ;
103170
104- let outgoing_packet = msgs:: OnionPacket {
105- version : 0 ,
106- public_key : next_packet_pubkey_opt. unwrap_or ( Err ( secp256k1:: Error :: InvalidPublicKey ) ) ,
107- hop_data : new_packet_bytes,
108- hmac : next_hop_hmac,
171+ let routing = match routing_info {
172+ RoutingInfo :: Direct { short_channel_id, new_packet_bytes, next_hop_hmac } => {
173+ let outgoing_packet = msgs:: OnionPacket {
174+ version : 0 ,
175+ public_key : next_packet_pubkey_opt. unwrap_or ( Err ( secp256k1:: Error :: InvalidPublicKey ) ) ,
176+ hop_data : new_packet_bytes,
177+ hmac : next_hop_hmac,
178+ } ;
179+ PendingHTLCRouting :: Forward {
180+ onion_packet : outgoing_packet,
181+ short_channel_id,
182+ incoming_cltv_expiry : Some ( msg. cltv_expiry ) ,
183+ blinded : intro_node_blinding_point. or ( msg. blinding_point )
184+ . map ( |bp| BlindedForward {
185+ inbound_blinding_point : bp,
186+ next_blinding_override,
187+ failure : intro_node_blinding_point
188+ . map ( |_| BlindedFailure :: FromIntroductionNode )
189+ . unwrap_or ( BlindedFailure :: FromBlindedNode ) ,
190+ } ) ,
191+ }
192+ }
193+ #[ cfg( trampoline) ]
194+ RoutingInfo :: Trampoline { outgoing_node_id, new_packet_bytes, next_hop_hmac, shared_secret, current_path_key } => {
195+ let next_trampoline_packet_pubkey = match next_packet_pubkey_opt {
196+ Some ( Ok ( pubkey) ) => pubkey,
197+ _ => return Err ( InboundHTLCErr {
198+ msg : "Missing next Trampoline hop pubkey from intermediate Trampoline forwarding data" ,
199+ err_code : 0x4000 | 22 ,
200+ err_data : Vec :: new ( ) ,
201+ } ) ,
202+ } ;
203+ let outgoing_packet = msgs:: TrampolineOnionPacket {
204+ version : 0 ,
205+ public_key : next_trampoline_packet_pubkey,
206+ hop_data : new_packet_bytes,
207+ hmac : next_hop_hmac,
208+ } ;
209+ PendingHTLCRouting :: TrampolineForward {
210+ incoming_shared_secret : shared_secret. secret_bytes ( ) ,
211+ onion_packet : outgoing_packet,
212+ node_id : outgoing_node_id,
213+ incoming_cltv_expiry : msg. cltv_expiry ,
214+ blinded : intro_node_blinding_point. or ( current_path_key)
215+ . map ( |bp| BlindedForward {
216+ inbound_blinding_point : bp,
217+ next_blinding_override,
218+ failure : intro_node_blinding_point
219+ . map ( |_| BlindedFailure :: FromIntroductionNode )
220+ . unwrap_or ( BlindedFailure :: FromBlindedNode ) ,
221+ } )
222+ }
223+ }
109224 } ;
110225
111226 Ok ( PendingHTLCInfo {
112- routing : PendingHTLCRouting :: Forward {
113- onion_packet : outgoing_packet,
114- short_channel_id,
115- incoming_cltv_expiry : Some ( msg. cltv_expiry ) ,
116- blinded : intro_node_blinding_point. or ( msg. blinding_point )
117- . map ( |bp| BlindedForward {
118- inbound_blinding_point : bp,
119- next_blinding_override,
120- failure : intro_node_blinding_point
121- . map ( |_| BlindedFailure :: FromIntroductionNode )
122- . unwrap_or ( BlindedFailure :: FromBlindedNode ) ,
123- } ) ,
124- } ,
227+ routing,
125228 payment_hash : msg. payment_hash ,
126229 incoming_shared_secret : shared_secret,
127230 incoming_amt_msat : Some ( msg. amount_msat ) ,
@@ -167,6 +270,8 @@ pub(super) fn create_recv_pending_htlc_info(
167270 sender_intended_htlc_amt_msat, cltv_expiry_height, None , Some ( payment_context) ,
168271 intro_node_blinding_point. is_none ( ) , true , invoice_request)
169272 }
273+ #[ cfg( trampoline) ]
274+ onion_utils:: Hop :: TrampolineReceive { .. } => todo ! ( ) ,
170275 onion_utils:: Hop :: Forward { .. } => {
171276 return Err ( InboundHTLCErr {
172277 err_code : 0x4000 |22 ,
@@ -181,6 +286,14 @@ pub(super) fn create_recv_pending_htlc_info(
181286 msg : "Got blinded non final data with an HMAC of 0" ,
182287 } )
183288 } ,
289+ #[ cfg( trampoline) ]
290+ onion_utils:: Hop :: TrampolineForward { .. } | onion_utils:: Hop :: TrampolineBlindedForward { .. } => {
291+ return Err ( InboundHTLCErr {
292+ err_code : 0x4000 |22 ,
293+ err_data : Vec :: new ( ) ,
294+ msg : "Got Trampoline non final data with an HMAC of 0" ,
295+ } )
296+ } ,
184297 } ;
185298 // final_incorrect_cltv_expiry
186299 if onion_cltv_expiry > cltv_expiry {
@@ -391,7 +504,7 @@ where
391504 return_malformed_err ! ( "Unknown onion packet version" , 0x8000 | 0x4000 | 4 ) ;
392505 }
393506
394- let encode_relay_error = |message : & str , err_code : u16 , shared_secret : [ u8 ; 32 ] , data : & [ u8 ] | {
507+ let encode_relay_error = |message : & str , err_code : u16 , shared_secret : [ u8 ; 32 ] , trampoline_shared_secret : Option < [ u8 ; 32 ] > , data : & [ u8 ] | {
395508 if msg. blinding_point . is_some ( ) {
396509 return_malformed_err ! ( message, INVALID_ONION_BLINDING )
397510 }
@@ -401,7 +514,7 @@ where
401514 channel_id : msg. channel_id ,
402515 htlc_id : msg. htlc_id ,
403516 reason : HTLCFailReason :: reason ( err_code, data. to_vec ( ) )
404- . get_encrypted_failure_packet ( & shared_secret, & None ) ,
517+ . get_encrypted_failure_packet ( & shared_secret, & trampoline_shared_secret ) ,
405518 } ) ) ;
406519 } ;
407520
@@ -413,8 +526,8 @@ where
413526 Err ( onion_utils:: OnionDecodeErr :: Malformed { err_msg, err_code } ) => {
414527 return_malformed_err ! ( err_msg, err_code) ;
415528 } ,
416- Err ( onion_utils:: OnionDecodeErr :: Relay { err_msg, err_code, shared_secret } ) => {
417- return encode_relay_error ( err_msg, err_code, shared_secret. secret_bytes ( ) , & [ 0 ; 0 ] ) ;
529+ Err ( onion_utils:: OnionDecodeErr :: Relay { err_msg, err_code, shared_secret, trampoline_shared_secret } ) => {
530+ return encode_relay_error ( err_msg, err_code, shared_secret. secret_bytes ( ) , trampoline_shared_secret . map ( |tss| tss . secret_bytes ( ) ) , & [ 0 ; 0 ] ) ;
418531 } ,
419532 } ;
420533
@@ -434,7 +547,7 @@ where
434547 Ok ( ( amt, cltv) ) => ( amt, cltv) ,
435548 Err ( ( ) ) => {
436549 return encode_relay_error ( "Underflow calculating outbound amount or cltv value for blinded forward" ,
437- INVALID_ONION_BLINDING , shared_secret. secret_bytes ( ) , & [ 0 ; 32 ] ) ;
550+ INVALID_ONION_BLINDING , shared_secret. secret_bytes ( ) , None , & [ 0 ; 32 ] ) ;
438551 }
439552 } ;
440553 let next_packet_pubkey = onion_utils:: next_hop_pubkey ( & secp_ctx,
@@ -444,6 +557,17 @@ where
444557 outgoing_cltv_value
445558 } )
446559 }
560+ #[ cfg( trampoline) ]
561+ onion_utils:: Hop :: TrampolineForward { next_trampoline_hop_data : msgs:: InboundTrampolineForwardPayload { amt_to_forward, outgoing_cltv_value, outgoing_node_id } , trampoline_shared_secret, incoming_trampoline_public_key, .. } => {
562+ let next_trampoline_packet_pubkey = onion_utils:: next_hop_pubkey ( secp_ctx,
563+ incoming_trampoline_public_key, & trampoline_shared_secret. secret_bytes ( ) ) ;
564+ Some ( NextPacketDetails {
565+ next_packet_pubkey : next_trampoline_packet_pubkey,
566+ outgoing_connector : HopConnector :: Trampoline ( outgoing_node_id) ,
567+ outgoing_amt_msat : amt_to_forward,
568+ outgoing_cltv_value,
569+ } )
570+ }
447571 _ => None
448572 } ;
449573
0 commit comments