@@ -1812,6 +1812,36 @@ mod fuzzy_internal_msgs {
18121812 }
18131813 }
18141814
1815+ #[ allow( unused) ]
1816+ pub enum InboundTrampolinePayload {
1817+ Forward {
1818+ /// The value, in msat, of the payment after this hop's fee is deducted.
1819+ amt_to_forward : u64 ,
1820+ outgoing_cltv_value : u32 ,
1821+ /// The node id to which the trampoline node must find a route.
1822+ outgoing_node_id : PublicKey ,
1823+ } ,
1824+ BlindedForward {
1825+ short_channel_id : u64 ,
1826+ payment_relay : PaymentRelay ,
1827+ payment_constraints : PaymentConstraints ,
1828+ features : BlindedHopFeatures ,
1829+ intro_node_blinding_point : Option < PublicKey > ,
1830+ next_blinding_override : Option < PublicKey > ,
1831+ } ,
1832+ BlindedReceive {
1833+ sender_intended_htlc_amt_msat : u64 ,
1834+ total_msat : u64 ,
1835+ cltv_expiry_height : u32 ,
1836+ payment_secret : PaymentSecret ,
1837+ payment_constraints : PaymentConstraints ,
1838+ payment_context : PaymentContext ,
1839+ intro_node_blinding_point : Option < PublicKey > ,
1840+ keysend_preimage : Option < PaymentPreimage > ,
1841+ custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
1842+ }
1843+ }
1844+
18151845 pub ( crate ) enum OutboundOnionPayload < ' a > {
18161846 Forward {
18171847 short_channel_id : u64 ,
@@ -2990,6 +3020,114 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
29903020 }
29913021}
29923022
3023+ impl < NS : Deref > ReadableArgs < ( Option < PublicKey > , NS ) > for InboundTrampolinePayload where NS :: Target : NodeSigner {
3024+ fn read < R : Read > ( r : & mut R , args : ( Option < PublicKey > , NS ) ) -> Result < Self , DecodeError > {
3025+ let ( update_add_blinding_point, node_signer) = args;
3026+
3027+ let mut amt = None ;
3028+ let mut cltv_value = None ;
3029+ let mut payment_data: Option < FinalOnionHopData > = None ;
3030+ let mut encrypted_tlvs_opt: Option < WithoutLength < Vec < u8 > > > = None ;
3031+ let mut intro_node_blinding_point = None ;
3032+ let mut outgoing_node_id: Option < PublicKey > = None ;
3033+ let mut total_msat = None ;
3034+ let mut keysend_preimage: Option < PaymentPreimage > = None ;
3035+ let mut custom_tlvs = Vec :: new ( ) ;
3036+
3037+ let tlv_len = <BigSize as Readable >:: read ( r) ?;
3038+ let mut rd = FixedLengthReader :: new ( r, tlv_len. 0 ) ;
3039+ decode_tlv_stream_with_custom_tlv_decode ! ( & mut rd, {
3040+ ( 2 , amt, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
3041+ ( 4 , cltv_value, ( option, encoding: ( u32 , HighZeroBytesDroppedBigSize ) ) ) ,
3042+ ( 8 , payment_data, option) ,
3043+ ( 10 , encrypted_tlvs_opt, option) ,
3044+ ( 12 , intro_node_blinding_point, option) ,
3045+ ( 14 , outgoing_node_id, option) ,
3046+ ( 18 , total_msat, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
3047+ // See https://github.com/lightning/blips/blob/master/blip-0003.md
3048+ ( 5482373484 , keysend_preimage, option)
3049+ } , |msg_type: u64 , msg_reader: & mut FixedLengthReader <_>| -> Result <bool , DecodeError > {
3050+ if msg_type < 1 << 16 { return Ok ( false ) }
3051+ let mut value = Vec :: new( ) ;
3052+ msg_reader. read_to_limit( & mut value, u64 :: MAX ) ?;
3053+ custom_tlvs. push( ( msg_type, value) ) ;
3054+ Ok ( true )
3055+ } ) ;
3056+
3057+ if amt. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
3058+ if intro_node_blinding_point. is_some ( ) && update_add_blinding_point. is_some ( ) {
3059+ return Err ( DecodeError :: InvalidValue )
3060+ }
3061+
3062+ if let Some ( blinding_point) = intro_node_blinding_point. or ( update_add_blinding_point) {
3063+ if payment_data. is_some ( ) {
3064+ return Err ( DecodeError :: InvalidValue )
3065+ }
3066+ let enc_tlvs = encrypted_tlvs_opt. ok_or ( DecodeError :: InvalidValue ) ?. 0 ;
3067+ let enc_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & blinding_point, None )
3068+ . map_err ( |_| DecodeError :: InvalidValue ) ?;
3069+ let rho = onion_utils:: gen_rho_from_shared_secret ( & enc_tlvs_ss. secret_bytes ( ) ) ;
3070+ let mut s = Cursor :: new ( & enc_tlvs) ;
3071+ let mut reader = FixedLengthReader :: new ( & mut s, enc_tlvs. len ( ) as u64 ) ;
3072+ match ChaChaPolyReadAdapter :: read ( & mut reader, rho) ? {
3073+ ChaChaPolyReadAdapter { readable : BlindedPaymentTlvs :: Forward ( ForwardTlvs {
3074+ short_channel_id, payment_relay, payment_constraints, features, next_blinding_override
3075+ } ) } => {
3076+ if amt. is_some ( ) || cltv_value. is_some ( ) || total_msat. is_some ( ) ||
3077+ keysend_preimage. is_some ( )
3078+ {
3079+ return Err ( DecodeError :: InvalidValue )
3080+ }
3081+ Ok ( Self :: BlindedForward {
3082+ short_channel_id,
3083+ payment_relay,
3084+ payment_constraints,
3085+ features,
3086+ intro_node_blinding_point,
3087+ next_blinding_override,
3088+ } )
3089+ } ,
3090+ ChaChaPolyReadAdapter { readable : BlindedPaymentTlvs :: Receive ( receive_tlvs) } => {
3091+ let ReceiveTlvs { tlvs, authentication : ( hmac, nonce) } = receive_tlvs;
3092+ let expanded_key = node_signer. get_inbound_payment_key ( ) ;
3093+ if tlvs. verify_for_offer_payment ( hmac, nonce, & expanded_key) . is_err ( ) {
3094+ return Err ( DecodeError :: InvalidValue ) ;
3095+ }
3096+
3097+ let UnauthenticatedReceiveTlvs {
3098+ payment_secret, payment_constraints, payment_context,
3099+ } = tlvs;
3100+ if total_msat. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
3101+ Ok ( Self :: BlindedReceive {
3102+ sender_intended_htlc_amt_msat : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3103+ total_msat : total_msat. ok_or ( DecodeError :: InvalidValue ) ?,
3104+ cltv_expiry_height : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3105+ payment_secret,
3106+ payment_constraints,
3107+ payment_context,
3108+ intro_node_blinding_point,
3109+ keysend_preimage,
3110+ custom_tlvs,
3111+ } )
3112+ } ,
3113+ }
3114+ } else if let Some ( outgoing_node_id) = outgoing_node_id {
3115+ if payment_data. is_some ( ) || encrypted_tlvs_opt. is_some ( ) ||
3116+ total_msat. is_some ( )
3117+ { return Err ( DecodeError :: InvalidValue ) }
3118+ Ok ( Self :: Forward {
3119+ outgoing_node_id,
3120+ amt_to_forward : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3121+ outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3122+ } )
3123+ } else {
3124+ // unblinded Trampoline receives are not supported
3125+ return Err ( DecodeError :: InvalidValue ) ;
3126+ }
3127+ }
3128+ }
3129+
3130+
29933131impl Writeable for Ping {
29943132 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
29953133 self . ponglen . write ( w) ?;
0 commit comments