@@ -1802,6 +1802,36 @@ mod fuzzy_internal_msgs {
1802
1802
}
1803
1803
}
1804
1804
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
+
1805
1835
pub ( crate ) enum OutboundOnionPayload < ' a > {
1806
1836
Forward {
1807
1837
short_channel_id : u64 ,
@@ -2977,6 +3007,114 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
2977
3007
}
2978
3008
}
2979
3009
3010
+ impl < NS : Deref > ReadableArgs < ( Option < PublicKey > , NS ) > for InboundTrampolinePayload where NS :: Target : NodeSigner {
3011
+ fn read < R : Read > ( r : & mut R , args : ( Option < PublicKey > , NS ) ) -> Result < Self , DecodeError > {
3012
+ let ( update_add_blinding_point, node_signer) = args;
3013
+
3014
+ let mut amt = None ;
3015
+ let mut cltv_value = None ;
3016
+ let mut payment_data: Option < FinalOnionHopData > = None ;
3017
+ let mut encrypted_tlvs_opt: Option < WithoutLength < Vec < u8 > > > = None ;
3018
+ let mut intro_node_blinding_point = None ;
3019
+ let mut outgoing_node_id: Option < PublicKey > = None ;
3020
+ let mut total_msat = None ;
3021
+ let mut keysend_preimage: Option < PaymentPreimage > = None ;
3022
+ let mut custom_tlvs = Vec :: new ( ) ;
3023
+
3024
+ let tlv_len = <BigSize as Readable >:: read ( r) ?;
3025
+ let mut rd = FixedLengthReader :: new ( r, tlv_len. 0 ) ;
3026
+ decode_tlv_stream_with_custom_tlv_decode ! ( & mut rd, {
3027
+ ( 2 , amt, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
3028
+ ( 4 , cltv_value, ( option, encoding: ( u32 , HighZeroBytesDroppedBigSize ) ) ) ,
3029
+ ( 8 , payment_data, option) ,
3030
+ ( 10 , encrypted_tlvs_opt, option) ,
3031
+ ( 12 , intro_node_blinding_point, option) ,
3032
+ ( 14 , outgoing_node_id, option) ,
3033
+ ( 18 , total_msat, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
3034
+ // See https://github.com/lightning/blips/blob/master/blip-0003.md
3035
+ ( 5482373484 , keysend_preimage, option)
3036
+ } , |msg_type: u64 , msg_reader: & mut FixedLengthReader <_>| -> Result <bool , DecodeError > {
3037
+ if msg_type < 1 << 16 { return Ok ( false ) }
3038
+ let mut value = Vec :: new( ) ;
3039
+ msg_reader. read_to_limit( & mut value, u64 :: MAX ) ?;
3040
+ custom_tlvs. push( ( msg_type, value) ) ;
3041
+ Ok ( true )
3042
+ } ) ;
3043
+
3044
+ if amt. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
3045
+ if intro_node_blinding_point. is_some ( ) && update_add_blinding_point. is_some ( ) {
3046
+ return Err ( DecodeError :: InvalidValue )
3047
+ }
3048
+
3049
+ if let Some ( blinding_point) = intro_node_blinding_point. or ( update_add_blinding_point) {
3050
+ if payment_data. is_some ( ) {
3051
+ return Err ( DecodeError :: InvalidValue )
3052
+ }
3053
+ let enc_tlvs = encrypted_tlvs_opt. ok_or ( DecodeError :: InvalidValue ) ?. 0 ;
3054
+ let enc_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & blinding_point, None )
3055
+ . map_err ( |_| DecodeError :: InvalidValue ) ?;
3056
+ let rho = onion_utils:: gen_rho_from_shared_secret ( & enc_tlvs_ss. secret_bytes ( ) ) ;
3057
+ let mut s = Cursor :: new ( & enc_tlvs) ;
3058
+ let mut reader = FixedLengthReader :: new ( & mut s, enc_tlvs. len ( ) as u64 ) ;
3059
+ match ChaChaPolyReadAdapter :: read ( & mut reader, rho) ? {
3060
+ ChaChaPolyReadAdapter { readable : BlindedPaymentTlvs :: Forward ( ForwardTlvs {
3061
+ short_channel_id, payment_relay, payment_constraints, features, next_blinding_override
3062
+ } ) } => {
3063
+ if amt. is_some ( ) || cltv_value. is_some ( ) || total_msat. is_some ( ) ||
3064
+ keysend_preimage. is_some ( )
3065
+ {
3066
+ return Err ( DecodeError :: InvalidValue )
3067
+ }
3068
+ Ok ( Self :: BlindedForward {
3069
+ short_channel_id,
3070
+ payment_relay,
3071
+ payment_constraints,
3072
+ features,
3073
+ intro_node_blinding_point,
3074
+ next_blinding_override,
3075
+ } )
3076
+ } ,
3077
+ ChaChaPolyReadAdapter { readable : BlindedPaymentTlvs :: Receive ( receive_tlvs) } => {
3078
+ let ReceiveTlvs { tlvs, authentication : ( hmac, nonce) } = receive_tlvs;
3079
+ let expanded_key = node_signer. get_inbound_payment_key ( ) ;
3080
+ if tlvs. verify_for_offer_payment ( hmac, nonce, & expanded_key) . is_err ( ) {
3081
+ return Err ( DecodeError :: InvalidValue ) ;
3082
+ }
3083
+
3084
+ let UnauthenticatedReceiveTlvs {
3085
+ payment_secret, payment_constraints, payment_context,
3086
+ } = tlvs;
3087
+ if total_msat. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
3088
+ Ok ( Self :: BlindedReceive {
3089
+ sender_intended_htlc_amt_msat : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3090
+ total_msat : total_msat. ok_or ( DecodeError :: InvalidValue ) ?,
3091
+ cltv_expiry_height : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3092
+ payment_secret,
3093
+ payment_constraints,
3094
+ payment_context,
3095
+ intro_node_blinding_point,
3096
+ keysend_preimage,
3097
+ custom_tlvs,
3098
+ } )
3099
+ } ,
3100
+ }
3101
+ } else if let Some ( outgoing_node_id) = outgoing_node_id {
3102
+ if payment_data. is_some ( ) || encrypted_tlvs_opt. is_some ( ) ||
3103
+ total_msat. is_some ( )
3104
+ { return Err ( DecodeError :: InvalidValue ) }
3105
+ Ok ( Self :: Forward {
3106
+ outgoing_node_id,
3107
+ amt_to_forward : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3108
+ outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3109
+ } )
3110
+ } else {
3111
+ // unblinded Trampoline receives are not supported
3112
+ return Err ( DecodeError :: InvalidValue ) ;
3113
+ }
3114
+ }
3115
+ }
3116
+
3117
+
2980
3118
impl Writeable for Ping {
2981
3119
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
2982
3120
self . ponglen . write ( w) ?;
0 commit comments