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,36 @@ 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+ }
78+ }
79+
6480pub ( super ) fn create_fwd_pending_htlc_info (
6581 msg : & msgs:: UpdateAddHTLC , hop_data : onion_utils:: Hop , shared_secret : [ u8 ; 32 ] ,
6682 next_packet_pubkey_opt : Option < Result < PublicKey , secp256k1:: Error > >
6783) -> Result < PendingHTLCInfo , InboundHTLCErr > {
6884 debug_assert ! ( next_packet_pubkey_opt. is_some( ) ) ;
6985
7086 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
87+ routing_info , amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
88+ next_blinding_override
7389 ) = match hop_data {
7490 onion_utils:: Hop :: Forward { next_hop_data : msgs:: InboundOnionForwardPayload {
7591 short_channel_id, amt_to_forward, outgoing_cltv_value
7692 } , new_packet_bytes, next_hop_hmac, .. } =>
77- ( short_channel_id, amt_to_forward , outgoing_cltv_value , None , None , new_packet_bytes , next_hop_hmac ) ,
93+ ( RoutingInfo :: Direct { short_channel_id, new_packet_bytes , next_hop_hmac } , amt_to_forward , outgoing_cltv_value , None , None ) ,
7894 onion_utils:: Hop :: BlindedForward { next_hop_data : msgs:: InboundOnionBlindedForwardPayload {
7995 short_channel_id, payment_relay, payment_constraints, intro_node_blinding_point, features,
8096 next_blinding_override,
@@ -90,38 +106,115 @@ pub(super) fn create_fwd_pending_htlc_info(
90106 err_data : vec ! [ 0 ; 32 ] ,
91107 }
92108 } ) ?;
93- ( short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
94- next_blinding_override, new_packet_bytes , next_hop_hmac )
109+ ( RoutingInfo :: Direct { short_channel_id, new_packet_bytes , next_hop_hmac } , amt_to_forward, outgoing_cltv_value, intro_node_blinding_point,
110+ next_blinding_override)
95111 } ,
96112 onion_utils:: Hop :: Receive { .. } | onion_utils:: Hop :: BlindedReceive { .. } =>
97113 return Err ( InboundHTLCErr {
98114 msg : "Final Node OnionHopData provided for us as an intermediary node" ,
99115 err_code : 0x4000 | 22 ,
100116 err_data : Vec :: new ( ) ,
101117 } ) ,
118+ #[ cfg( trampoline) ]
119+ onion_utils:: Hop :: TrampolineReceive { .. } =>
120+ return Err ( InboundHTLCErr {
121+ msg : "Final Node OnionHopData provided for us as an intermediary node" ,
122+ err_code : 0x4000 | 22 ,
123+ err_data : Vec :: new ( ) ,
124+ } ) ,
125+ #[ cfg( trampoline) ]
126+ onion_utils:: Hop :: TrampolineForward { next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
127+ (
128+ RoutingInfo :: Trampoline {
129+ outgoing_node_id : next_trampoline_hop_data. outgoing_node_id ,
130+ new_packet_bytes : new_trampoline_packet_bytes,
131+ next_hop_hmac : next_trampoline_hop_hmac,
132+ shared_secret : trampoline_shared_secret
133+ } ,
134+ next_trampoline_hop_data. amt_to_forward ,
135+ next_trampoline_hop_data. outgoing_cltv_value ,
136+ None ,
137+ None
138+ )
139+ } ,
140+ #[ cfg( trampoline) ]
141+ onion_utils:: Hop :: TrampolineBlindedForward { next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
142+ let ( amt_to_forward, outgoing_cltv_value) = check_blinded_forward (
143+ msg. amount_msat , msg. cltv_expiry , & next_trampoline_hop_data. payment_relay , & next_trampoline_hop_data. payment_constraints , & next_trampoline_hop_data. features
144+ ) . map_err ( |( ) | {
145+ // We should be returning malformed here if `msg.blinding_point` is set, but this is
146+ // unreachable right now since we checked it in `decode_update_add_htlc_onion`.
147+ InboundHTLCErr {
148+ msg : "Underflow calculating outbound amount or cltv value for blinded forward" ,
149+ err_code : INVALID_ONION_BLINDING ,
150+ err_data : vec ! [ 0 ; 32 ] ,
151+ }
152+ } ) ?;
153+ (
154+ RoutingInfo :: Trampoline {
155+ outgoing_node_id : next_trampoline_hop_data. outgoing_node_id ,
156+ new_packet_bytes : new_trampoline_packet_bytes,
157+ next_hop_hmac : next_trampoline_hop_hmac,
158+ shared_secret : trampoline_shared_secret
159+ } ,
160+ amt_to_forward,
161+ outgoing_cltv_value,
162+ next_trampoline_hop_data. intro_node_blinding_point ,
163+ next_trampoline_hop_data. next_blinding_override
164+ )
165+ } ,
102166 } ;
103167
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,
168+ let routing = match routing_info {
169+ RoutingInfo :: Direct { short_channel_id, new_packet_bytes, next_hop_hmac } => {
170+ let outgoing_packet = msgs:: OnionPacket {
171+ version : 0 ,
172+ public_key : next_packet_pubkey_opt. unwrap_or ( Err ( secp256k1:: Error :: InvalidPublicKey ) ) ,
173+ hop_data : new_packet_bytes,
174+ hmac : next_hop_hmac,
175+ } ;
176+ PendingHTLCRouting :: Forward {
177+ onion_packet : outgoing_packet,
178+ short_channel_id,
179+ incoming_cltv_expiry : Some ( msg. cltv_expiry ) ,
180+ blinded : intro_node_blinding_point. or ( msg. blinding_point )
181+ . map ( |bp| BlindedForward {
182+ inbound_blinding_point : bp,
183+ next_blinding_override,
184+ failure : intro_node_blinding_point
185+ . map ( |_| BlindedFailure :: FromIntroductionNode )
186+ . unwrap_or ( BlindedFailure :: FromBlindedNode ) ,
187+ } ) ,
188+ }
189+ }
190+ #[ cfg( trampoline) ]
191+ RoutingInfo :: Trampoline { outgoing_node_id, new_packet_bytes, next_hop_hmac, shared_secret } => {
192+ let next_trampoline_packet_pubkey = match next_packet_pubkey_opt {
193+ Some ( Ok ( pubkey) ) => pubkey,
194+ _ => return Err ( InboundHTLCErr {
195+ msg : "Missing next Trampoline hop pubkey from intermediate Trampoline forwarding data" ,
196+ err_code : 0x4000 | 22 ,
197+ err_data : Vec :: new ( ) ,
198+ } ) ,
199+ } ;
200+ let outgoing_packet = msgs:: TrampolineOnionPacket {
201+ version : 0 ,
202+ public_key : next_trampoline_packet_pubkey,
203+ hop_data : new_packet_bytes,
204+ hmac : next_hop_hmac,
205+ } ;
206+ PendingHTLCRouting :: TrampolineForward {
207+ incoming_shared_secret : shared_secret. secret_bytes ( ) ,
208+ onion_packet : outgoing_packet,
209+ node_id : outgoing_node_id,
210+ incoming_cltv_expiry : msg. cltv_expiry ,
211+ blinded : None
212+ }
213+ }
109214 } ;
110215
111216 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- } ,
217+ routing,
125218 payment_hash : msg. payment_hash ,
126219 incoming_shared_secret : shared_secret,
127220 incoming_amt_msat : Some ( msg. amount_msat ) ,
@@ -167,6 +260,8 @@ pub(super) fn create_recv_pending_htlc_info(
167260 sender_intended_htlc_amt_msat, cltv_expiry_height, None , Some ( payment_context) ,
168261 intro_node_blinding_point. is_none ( ) , true , invoice_request)
169262 }
263+ #[ cfg( trampoline) ]
264+ onion_utils:: Hop :: TrampolineReceive { .. } => todo ! ( ) ,
170265 onion_utils:: Hop :: Forward { .. } => {
171266 return Err ( InboundHTLCErr {
172267 err_code : 0x4000 |22 ,
@@ -181,6 +276,14 @@ pub(super) fn create_recv_pending_htlc_info(
181276 msg : "Got blinded non final data with an HMAC of 0" ,
182277 } )
183278 } ,
279+ #[ cfg( trampoline) ]
280+ onion_utils:: Hop :: TrampolineForward { .. } | onion_utils:: Hop :: TrampolineBlindedForward { .. } => {
281+ return Err ( InboundHTLCErr {
282+ err_code : 0x4000 |22 ,
283+ err_data : Vec :: new ( ) ,
284+ msg : "Got Trampoline non final data with an HMAC of 0" ,
285+ } )
286+ } ,
184287 } ;
185288 // final_incorrect_cltv_expiry
186289 if onion_cltv_expiry > cltv_expiry {
@@ -391,7 +494,7 @@ where
391494 return_malformed_err ! ( "Unknown onion packet version" , 0x8000 | 0x4000 | 4 ) ;
392495 }
393496
394- let encode_relay_error = |message : & str , err_code : u16 , shared_secret : [ u8 ; 32 ] , data : & [ u8 ] | {
497+ let encode_relay_error = |message : & str , err_code : u16 , shared_secret : [ u8 ; 32 ] , trampoline_shared_secret : Option < [ u8 ; 32 ] > , data : & [ u8 ] | {
395498 if msg. blinding_point . is_some ( ) {
396499 return_malformed_err ! ( message, INVALID_ONION_BLINDING )
397500 }
@@ -401,7 +504,7 @@ where
401504 channel_id : msg. channel_id ,
402505 htlc_id : msg. htlc_id ,
403506 reason : HTLCFailReason :: reason ( err_code, data. to_vec ( ) )
404- . get_encrypted_failure_packet ( & shared_secret, & None ) ,
507+ . get_encrypted_failure_packet ( & shared_secret, & trampoline_shared_secret ) ,
405508 } ) ) ;
406509 } ;
407510
@@ -413,8 +516,8 @@ where
413516 Err ( onion_utils:: OnionDecodeErr :: Malformed { err_msg, err_code } ) => {
414517 return_malformed_err ! ( err_msg, err_code) ;
415518 } ,
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 ] ) ;
519+ Err ( onion_utils:: OnionDecodeErr :: Relay { err_msg, err_code, shared_secret, trampoline_shared_secret } ) => {
520+ return encode_relay_error ( err_msg, err_code, shared_secret. secret_bytes ( ) , trampoline_shared_secret . map ( |tss| tss . secret_bytes ( ) ) , & [ 0 ; 0 ] ) ;
418521 } ,
419522 } ;
420523
@@ -434,7 +537,7 @@ where
434537 Ok ( ( amt, cltv) ) => ( amt, cltv) ,
435538 Err ( ( ) ) => {
436539 return encode_relay_error ( "Underflow calculating outbound amount or cltv value for blinded forward" ,
437- INVALID_ONION_BLINDING , shared_secret. secret_bytes ( ) , & [ 0 ; 32 ] ) ;
540+ INVALID_ONION_BLINDING , shared_secret. secret_bytes ( ) , None , & [ 0 ; 32 ] ) ;
438541 }
439542 } ;
440543 let next_packet_pubkey = onion_utils:: next_hop_pubkey ( & secp_ctx,
@@ -444,6 +547,17 @@ where
444547 outgoing_cltv_value
445548 } )
446549 }
550+ #[ cfg( trampoline) ]
551+ 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, .. } => {
552+ let next_trampoline_packet_pubkey = onion_utils:: next_hop_pubkey ( secp_ctx,
553+ incoming_trampoline_public_key, & trampoline_shared_secret. secret_bytes ( ) ) ;
554+ Some ( NextPacketDetails {
555+ next_packet_pubkey : next_trampoline_packet_pubkey,
556+ outgoing_connector : HopConnector :: Trampoline ( outgoing_node_id) ,
557+ outgoing_amt_msat : amt_to_forward,
558+ outgoing_cltv_value,
559+ } )
560+ }
447561 _ => None
448562 } ;
449563
0 commit comments