@@ -1766,6 +1766,13 @@ mod fuzzy_internal_msgs {
17661766 amt_to_forward : u64 ,
17671767 outgoing_cltv_value : u32 ,
17681768 } ,
1769+ #[ allow( unused) ]
1770+ TrampolineEntrypoint {
1771+ amt_to_forward : u64 ,
1772+ outgoing_cltv_value : u32 ,
1773+ multipath_trampoline_data : Option < FinalOnionHopData > ,
1774+ trampoline_packet : TrampolineOnionPacket ,
1775+ } ,
17691776 Receive {
17701777 payment_data : Option < FinalOnionHopData > ,
17711778 payment_metadata : Option < Vec < u8 > > ,
@@ -1795,6 +1802,36 @@ mod fuzzy_internal_msgs {
17951802 }
17961803 }
17971804
1805+ #[ allow( unused) ]
1806+ pub enum InboundTrampolinePayload {
1807+ Forward {
1808+ /// The value, in msat, of the payment after this hop's fee is deducted.
1809+ amt_to_forward : u64 ,
1810+ outgoing_cltv_value : u32 ,
1811+ /// The node id to which the trampoline node must find a route.
1812+ outgoing_node_id : PublicKey ,
1813+ } ,
1814+ BlindedForward {
1815+ short_channel_id : u64 ,
1816+ payment_relay : PaymentRelay ,
1817+ payment_constraints : PaymentConstraints ,
1818+ features : BlindedHopFeatures ,
1819+ intro_node_blinding_point : Option < PublicKey > ,
1820+ next_blinding_override : Option < PublicKey > ,
1821+ } ,
1822+ BlindedReceive {
1823+ sender_intended_htlc_amt_msat : u64 ,
1824+ total_msat : u64 ,
1825+ cltv_expiry_height : u32 ,
1826+ payment_secret : PaymentSecret ,
1827+ payment_constraints : PaymentConstraints ,
1828+ payment_context : PaymentContext ,
1829+ intro_node_blinding_point : Option < PublicKey > ,
1830+ keysend_preimage : Option < PaymentPreimage > ,
1831+ custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
1832+ }
1833+ }
1834+
17981835 pub ( crate ) enum OutboundOnionPayload < ' a > {
17991836 Forward {
18001837 short_channel_id : u64 ,
@@ -2847,6 +2884,8 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
28472884 let mut intro_node_blinding_point = None ;
28482885 let mut payment_metadata: Option < WithoutLength < Vec < u8 > > > = None ;
28492886 let mut total_msat = None ;
2887+ let mut trampoline_onion_packet: Option < TrampolineOnionPacket > = None ;
2888+
28502889 let mut keysend_preimage: Option < PaymentPreimage > = None ;
28512890 let mut custom_tlvs = Vec :: new ( ) ;
28522891
@@ -2861,6 +2900,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
28612900 ( 12 , intro_node_blinding_point, option) ,
28622901 ( 16 , payment_metadata, option) ,
28632902 ( 18 , total_msat, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
2903+ ( 20 , trampoline_onion_packet, option) ,
28642904 // See https://github.com/lightning/blips/blob/master/blip-0003.md
28652905 ( 5482373484 , keysend_preimage, option)
28662906 } , |msg_type: u64 , msg_reader: & mut FixedLengthReader <_>| -> Result <bool , DecodeError > {
@@ -2937,6 +2977,16 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
29372977 amt_to_forward : amt. ok_or ( DecodeError :: InvalidValue ) ?,
29382978 outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
29392979 } )
2980+ } else if let Some ( trampoline_onion_packet) = trampoline_onion_packet {
2981+ if payment_metadata. is_some ( ) || encrypted_tlvs_opt. is_some ( ) ||
2982+ total_msat. is_some ( )
2983+ { return Err ( DecodeError :: InvalidValue ) }
2984+ Ok ( Self :: TrampolineEntrypoint {
2985+ amt_to_forward : amt. ok_or ( DecodeError :: InvalidValue ) ?,
2986+ outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
2987+ multipath_trampoline_data : payment_data,
2988+ trampoline_packet : trampoline_onion_packet,
2989+ } )
29402990 } else {
29412991 if encrypted_tlvs_opt. is_some ( ) || total_msat. is_some ( ) {
29422992 return Err ( DecodeError :: InvalidValue )
@@ -2958,6 +3008,114 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
29583008 }
29593009}
29603010
3011+ impl < NS : Deref > ReadableArgs < ( Option < PublicKey > , NS ) > for InboundTrampolinePayload where NS :: Target : NodeSigner {
3012+ fn read < R : Read > ( r : & mut R , args : ( Option < PublicKey > , NS ) ) -> Result < Self , DecodeError > {
3013+ let ( update_add_blinding_point, node_signer) = args;
3014+
3015+ let mut amt = None ;
3016+ let mut cltv_value = None ;
3017+ let mut payment_data: Option < FinalOnionHopData > = None ;
3018+ let mut encrypted_tlvs_opt: Option < WithoutLength < Vec < u8 > > > = None ;
3019+ let mut intro_node_blinding_point = None ;
3020+ let mut outgoing_node_id: Option < PublicKey > = None ;
3021+ let mut total_msat = None ;
3022+ let mut keysend_preimage: Option < PaymentPreimage > = None ;
3023+ let mut custom_tlvs = Vec :: new ( ) ;
3024+
3025+ let tlv_len = <BigSize as Readable >:: read ( r) ?;
3026+ let mut rd = FixedLengthReader :: new ( r, tlv_len. 0 ) ;
3027+ decode_tlv_stream_with_custom_tlv_decode ! ( & mut rd, {
3028+ ( 2 , amt, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
3029+ ( 4 , cltv_value, ( option, encoding: ( u32 , HighZeroBytesDroppedBigSize ) ) ) ,
3030+ ( 8 , payment_data, option) ,
3031+ ( 10 , encrypted_tlvs_opt, option) ,
3032+ ( 12 , intro_node_blinding_point, option) ,
3033+ ( 14 , outgoing_node_id, option) ,
3034+ ( 18 , total_msat, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
3035+ // See https://github.com/lightning/blips/blob/master/blip-0003.md
3036+ ( 5482373484 , keysend_preimage, option)
3037+ } , |msg_type: u64 , msg_reader: & mut FixedLengthReader <_>| -> Result <bool , DecodeError > {
3038+ if msg_type < 1 << 16 { return Ok ( false ) }
3039+ let mut value = Vec :: new( ) ;
3040+ msg_reader. read_to_limit( & mut value, u64 :: MAX ) ?;
3041+ custom_tlvs. push( ( msg_type, value) ) ;
3042+ Ok ( true )
3043+ } ) ;
3044+
3045+ if amt. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
3046+ if intro_node_blinding_point. is_some ( ) && update_add_blinding_point. is_some ( ) {
3047+ return Err ( DecodeError :: InvalidValue )
3048+ }
3049+
3050+ if let Some ( blinding_point) = intro_node_blinding_point. or ( update_add_blinding_point) {
3051+ if payment_data. is_some ( ) {
3052+ return Err ( DecodeError :: InvalidValue )
3053+ }
3054+ let enc_tlvs = encrypted_tlvs_opt. ok_or ( DecodeError :: InvalidValue ) ?. 0 ;
3055+ let enc_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & blinding_point, None )
3056+ . map_err ( |_| DecodeError :: InvalidValue ) ?;
3057+ let rho = onion_utils:: gen_rho_from_shared_secret ( & enc_tlvs_ss. secret_bytes ( ) ) ;
3058+ let mut s = Cursor :: new ( & enc_tlvs) ;
3059+ let mut reader = FixedLengthReader :: new ( & mut s, enc_tlvs. len ( ) as u64 ) ;
3060+ match ChaChaPolyReadAdapter :: read ( & mut reader, rho) ? {
3061+ ChaChaPolyReadAdapter { readable : BlindedPaymentTlvs :: Forward ( ForwardTlvs {
3062+ short_channel_id, payment_relay, payment_constraints, features, next_blinding_override
3063+ } ) } => {
3064+ if amt. is_some ( ) || cltv_value. is_some ( ) || total_msat. is_some ( ) ||
3065+ keysend_preimage. is_some ( )
3066+ {
3067+ return Err ( DecodeError :: InvalidValue )
3068+ }
3069+ Ok ( Self :: BlindedForward {
3070+ short_channel_id,
3071+ payment_relay,
3072+ payment_constraints,
3073+ features,
3074+ intro_node_blinding_point,
3075+ next_blinding_override,
3076+ } )
3077+ } ,
3078+ ChaChaPolyReadAdapter { readable : BlindedPaymentTlvs :: Receive ( receive_tlvs) } => {
3079+ let ReceiveTlvs { tlvs, authentication : ( hmac, nonce) } = receive_tlvs;
3080+ let expanded_key = node_signer. get_inbound_payment_key ( ) ;
3081+ if tlvs. verify_for_offer_payment ( hmac, nonce, & expanded_key) . is_err ( ) {
3082+ return Err ( DecodeError :: InvalidValue ) ;
3083+ }
3084+
3085+ let UnauthenticatedReceiveTlvs {
3086+ payment_secret, payment_constraints, payment_context,
3087+ } = tlvs;
3088+ if total_msat. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
3089+ Ok ( Self :: BlindedReceive {
3090+ sender_intended_htlc_amt_msat : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3091+ total_msat : total_msat. ok_or ( DecodeError :: InvalidValue ) ?,
3092+ cltv_expiry_height : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3093+ payment_secret,
3094+ payment_constraints,
3095+ payment_context,
3096+ intro_node_blinding_point,
3097+ keysend_preimage,
3098+ custom_tlvs,
3099+ } )
3100+ } ,
3101+ }
3102+ } else if let Some ( outgoing_node_id) = outgoing_node_id {
3103+ if payment_data. is_some ( ) || encrypted_tlvs_opt. is_some ( ) ||
3104+ total_msat. is_some ( )
3105+ { return Err ( DecodeError :: InvalidValue ) }
3106+ Ok ( Self :: Forward {
3107+ outgoing_node_id,
3108+ amt_to_forward : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3109+ outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3110+ } )
3111+ } else {
3112+ // unblinded Trampoline receives are not supported
3113+ return Err ( DecodeError :: InvalidValue ) ;
3114+ }
3115+ }
3116+ }
3117+
3118+
29613119impl Writeable for Ping {
29623120 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
29633121 self . ponglen . write ( w) ?;
0 commit comments