@@ -32,6 +32,8 @@ use bitcoin::script::ScriptBuf;
3232use bitcoin:: hash_types:: Txid ;
3333
3434use crate :: blinded_path:: payment:: { BlindedPaymentTlvs , ForwardTlvs , ReceiveTlvs , UnauthenticatedReceiveTlvs } ;
35+ #[ cfg( trampoline) ]
36+ use crate :: blinded_path:: payment:: { BlindedTrampolineTlvs , TrampolineForwardTlvs } ;
3537use crate :: ln:: channelmanager:: Verification ;
3638use crate :: ln:: types:: ChannelId ;
3739use crate :: types:: payment:: { PaymentPreimage , PaymentHash , PaymentSecret } ;
@@ -1794,6 +1796,8 @@ mod fuzzy_internal_msgs {
17941796 use bitcoin:: secp256k1:: PublicKey ;
17951797 use crate :: blinded_path:: payment:: { BlindedPaymentPath , PaymentConstraints , PaymentContext , PaymentRelay } ;
17961798 use crate :: offers:: invoice_request:: InvoiceRequest ;
1799+ #[ cfg( trampoline) ]
1800+ use crate :: routing:: gossip:: NodeId ;
17971801 use crate :: types:: payment:: { PaymentPreimage , PaymentSecret } ;
17981802 use crate :: types:: features:: { BlindedHopFeatures , Bolt12InvoiceFeatures } ;
17991803 use super :: { FinalOnionHopData , TrampolineOnionPacket } ;
@@ -1812,6 +1816,7 @@ mod fuzzy_internal_msgs {
18121816 }
18131817
18141818 #[ cfg( trampoline) ]
1819+ #[ cfg_attr( trampoline, allow( unused) ) ]
18151820 pub struct InboundTrampolineEntrypointPayload {
18161821 pub amt_to_forward : u64 ,
18171822 pub outgoing_cltv_value : u32 ,
@@ -1852,12 +1857,42 @@ mod fuzzy_internal_msgs {
18521857 pub enum InboundOnionPayload {
18531858 Forward ( InboundOnionForwardPayload ) ,
18541859 #[ cfg( trampoline) ]
1860+ #[ cfg_attr( trampoline, allow( unused) ) ]
18551861 TrampolineEntrypoint ( InboundTrampolineEntrypointPayload ) ,
18561862 Receive ( InboundOnionReceivePayload ) ,
18571863 BlindedForward ( InboundOnionBlindedForwardPayload ) ,
18581864 BlindedReceive ( InboundOnionBlindedReceivePayload ) ,
18591865 }
18601866
1867+ #[ cfg( trampoline) ]
1868+ #[ cfg_attr( trampoline, allow( unused) ) ]
1869+ pub struct InboundTrampolineForwardPayload {
1870+ pub next_trampoline : NodeId ,
1871+ /// The value, in msat, of the payment after this hop's fee is deducted.
1872+ pub amt_to_forward : u64 ,
1873+ pub outgoing_cltv_value : u32 ,
1874+ }
1875+
1876+ #[ cfg( trampoline) ]
1877+ #[ cfg_attr( trampoline, allow( unused) ) ]
1878+ pub struct InboundTrampolineBlindedForwardPayload {
1879+ pub next_trampoline : NodeId ,
1880+ pub payment_relay : PaymentRelay ,
1881+ pub payment_constraints : PaymentConstraints ,
1882+ pub features : BlindedHopFeatures ,
1883+ pub intro_node_blinding_point : Option < PublicKey > ,
1884+ pub next_blinding_override : Option < PublicKey > ,
1885+ }
1886+
1887+ #[ cfg( trampoline) ]
1888+ #[ cfg_attr( trampoline, allow( unused) ) ]
1889+ pub enum InboundTrampolinePayload {
1890+ Forward ( InboundTrampolineForwardPayload ) ,
1891+ BlindedForward ( InboundTrampolineBlindedForwardPayload ) ,
1892+ Receive ( InboundOnionReceivePayload ) ,
1893+ BlindedReceive ( InboundOnionBlindedReceivePayload ) ,
1894+ }
1895+
18611896 pub ( crate ) enum OutboundOnionPayload < ' a > {
18621897 Forward {
18631898 short_channel_id : u64 ,
@@ -3095,6 +3130,134 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
30953130 }
30963131}
30973132
3133+ #[ cfg( trampoline) ]
3134+ impl < NS : Deref > ReadableArgs < ( Option < PublicKey > , NS ) > for InboundTrampolinePayload where NS :: Target : NodeSigner {
3135+ fn read < R : Read > ( r : & mut R , args : ( Option < PublicKey > , NS ) ) -> Result < Self , DecodeError > {
3136+ let ( update_add_blinding_point, node_signer) = args;
3137+
3138+ let mut amt = None ;
3139+ let mut cltv_value = None ;
3140+ let mut payment_data: Option < FinalOnionHopData > = None ;
3141+ let mut encrypted_tlvs_opt: Option < WithoutLength < Vec < u8 > > > = None ;
3142+ let mut intro_node_blinding_point = None ;
3143+ let mut next_trampoline: Option < NodeId > = None ;
3144+ let mut payment_metadata: Option < WithoutLength < Vec < u8 > > > = None ;
3145+ let mut total_msat = None ;
3146+ let mut keysend_preimage: Option < PaymentPreimage > = None ;
3147+ let mut invoice_request: Option < InvoiceRequest > = None ;
3148+ let mut custom_tlvs = Vec :: new ( ) ;
3149+
3150+ let tlv_len = BigSize :: read ( r) ?;
3151+ let mut rd = FixedLengthReader :: new ( r, tlv_len. 0 ) ;
3152+ decode_tlv_stream_with_custom_tlv_decode ! ( & mut rd, {
3153+ ( 2 , amt, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
3154+ ( 4 , cltv_value, ( option, encoding: ( u32 , HighZeroBytesDroppedBigSize ) ) ) ,
3155+ ( 8 , payment_data, option) ,
3156+ ( 10 , encrypted_tlvs_opt, option) ,
3157+ ( 12 , intro_node_blinding_point, option) ,
3158+ ( 14 , next_trampoline, option) ,
3159+ ( 16 , payment_metadata, option) ,
3160+ ( 18 , total_msat, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
3161+ ( 77_777 , invoice_request, option) ,
3162+ // See https://github.com/lightning/blips/blob/master/blip-0003.md
3163+ ( 5482373484 , keysend_preimage, option)
3164+ } , |msg_type: u64 , msg_reader: & mut FixedLengthReader <_>| -> Result <bool , DecodeError > {
3165+ if msg_type < 1 << 16 { return Ok ( false ) }
3166+ let mut value = Vec :: new( ) ;
3167+ msg_reader. read_to_limit( & mut value, u64 :: MAX ) ?;
3168+ custom_tlvs. push( ( msg_type, value) ) ;
3169+ Ok ( true )
3170+ } ) ;
3171+
3172+ if amt. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
3173+ if intro_node_blinding_point. is_some ( ) && update_add_blinding_point. is_some ( ) {
3174+ return Err ( DecodeError :: InvalidValue )
3175+ }
3176+
3177+ if let Some ( blinding_point) = intro_node_blinding_point. or ( update_add_blinding_point) {
3178+ if next_trampoline. is_some ( ) || payment_data. is_some ( ) || payment_metadata. is_some ( ) {
3179+ return Err ( DecodeError :: InvalidValue )
3180+ }
3181+ let enc_tlvs = encrypted_tlvs_opt. ok_or ( DecodeError :: InvalidValue ) ?. 0 ;
3182+ let enc_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & blinding_point, None )
3183+ . map_err ( |_| DecodeError :: InvalidValue ) ?;
3184+ let rho = onion_utils:: gen_rho_from_shared_secret ( & enc_tlvs_ss. secret_bytes ( ) ) ;
3185+ let mut s = Cursor :: new ( & enc_tlvs) ;
3186+ let mut reader = FixedLengthReader :: new ( & mut s, enc_tlvs. len ( ) as u64 ) ;
3187+ match ChaChaPolyReadAdapter :: read ( & mut reader, rho) ? {
3188+ ChaChaPolyReadAdapter { readable : BlindedTrampolineTlvs :: Forward ( TrampolineForwardTlvs {
3189+ next_trampoline, payment_relay, payment_constraints, features, next_blinding_override
3190+ } ) } => {
3191+ if amt. is_some ( ) || cltv_value. is_some ( ) || total_msat. is_some ( ) ||
3192+ keysend_preimage. is_some ( ) || invoice_request. is_some ( )
3193+ {
3194+ return Err ( DecodeError :: InvalidValue )
3195+ }
3196+ Ok ( Self :: BlindedForward ( InboundTrampolineBlindedForwardPayload {
3197+ next_trampoline,
3198+ payment_relay,
3199+ payment_constraints,
3200+ features,
3201+ intro_node_blinding_point,
3202+ next_blinding_override,
3203+ } ) )
3204+ } ,
3205+ ChaChaPolyReadAdapter { readable : BlindedTrampolineTlvs :: Receive ( receive_tlvs) } => {
3206+ let ReceiveTlvs { tlvs, authentication : ( hmac, nonce) } = receive_tlvs;
3207+ let expanded_key = node_signer. get_inbound_payment_key ( ) ;
3208+ if tlvs. verify_for_offer_payment ( hmac, nonce, & expanded_key) . is_err ( ) {
3209+ return Err ( DecodeError :: InvalidValue ) ;
3210+ }
3211+
3212+ let UnauthenticatedReceiveTlvs {
3213+ payment_secret, payment_constraints, payment_context,
3214+ } = tlvs;
3215+ if total_msat. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
3216+ Ok ( Self :: BlindedReceive ( InboundOnionBlindedReceivePayload {
3217+ sender_intended_htlc_amt_msat : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3218+ total_msat : total_msat. ok_or ( DecodeError :: InvalidValue ) ?,
3219+ cltv_expiry_height : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3220+ payment_secret,
3221+ payment_constraints,
3222+ payment_context,
3223+ intro_node_blinding_point,
3224+ keysend_preimage,
3225+ invoice_request,
3226+ custom_tlvs,
3227+ } ) )
3228+ } ,
3229+ }
3230+ } else if let Some ( next_trampoline) = next_trampoline {
3231+ if payment_data. is_some ( ) || payment_metadata. is_some ( ) || encrypted_tlvs_opt. is_some ( ) ||
3232+ total_msat. is_some ( ) || invoice_request. is_some ( )
3233+ { return Err ( DecodeError :: InvalidValue ) }
3234+ Ok ( Self :: Forward ( InboundTrampolineForwardPayload {
3235+ next_trampoline,
3236+ amt_to_forward : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3237+ outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3238+ } ) )
3239+ } else {
3240+ if encrypted_tlvs_opt. is_some ( ) || total_msat. is_some ( ) || invoice_request. is_some ( ) {
3241+ return Err ( DecodeError :: InvalidValue )
3242+ }
3243+ if let Some ( data) = & payment_data {
3244+ if data. total_msat > MAX_VALUE_MSAT {
3245+ return Err ( DecodeError :: InvalidValue ) ;
3246+ }
3247+ }
3248+ Ok ( Self :: Receive ( InboundOnionReceivePayload {
3249+ payment_data,
3250+ payment_metadata : payment_metadata. map ( |w| w. 0 ) ,
3251+ keysend_preimage,
3252+ sender_intended_htlc_amt_msat : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3253+ cltv_expiry_height : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3254+ custom_tlvs,
3255+ } ) )
3256+ }
3257+ }
3258+ }
3259+
3260+
30983261impl Writeable for Ping {
30993262 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
31003263 self . ponglen . write ( w) ?;
0 commit comments