@@ -32,6 +32,8 @@ use bitcoin::script::ScriptBuf;
32
32
use bitcoin:: hash_types:: Txid ;
33
33
34
34
use crate :: blinded_path:: payment:: { BlindedPaymentTlvs , ForwardTlvs , ReceiveTlvs , UnauthenticatedReceiveTlvs } ;
35
+ #[ cfg( trampoline) ]
36
+ use crate :: blinded_path:: payment:: { BlindedTrampolineTlvs , TrampolineForwardTlvs } ;
35
37
use crate :: ln:: channelmanager:: Verification ;
36
38
use crate :: ln:: types:: ChannelId ;
37
39
use crate :: types:: payment:: { PaymentPreimage , PaymentHash , PaymentSecret } ;
@@ -1812,10 +1814,11 @@ mod fuzzy_internal_msgs {
1812
1814
}
1813
1815
1814
1816
#[ cfg( trampoline) ]
1817
+ #[ cfg_attr( trampoline, allow( unused) ) ]
1815
1818
pub struct InboundTrampolineEntrypointPayload {
1816
1819
pub amt_to_forward : u64 ,
1817
1820
pub outgoing_cltv_value : u32 ,
1818
- pub multipath_trampoline_data : Option < FinalOnionHopData > ,
1821
+ pub multipath_trampoline_data : FinalOnionHopData ,
1819
1822
pub trampoline_packet : TrampolineOnionPacket ,
1820
1823
/// The blinding point this hop needs to decrypt its Trampoline onion.
1821
1824
/// This is used for Trampoline hops that are not the blinded path intro hop.
@@ -1854,12 +1857,42 @@ mod fuzzy_internal_msgs {
1854
1857
pub enum InboundOnionPayload {
1855
1858
Forward ( InboundOnionForwardPayload ) ,
1856
1859
#[ cfg( trampoline) ]
1860
+ #[ cfg_attr( trampoline, allow( unused) ) ]
1857
1861
TrampolineEntrypoint ( InboundTrampolineEntrypointPayload ) ,
1858
1862
Receive ( InboundOnionReceivePayload ) ,
1859
1863
BlindedForward ( InboundOnionBlindedForwardPayload ) ,
1860
1864
BlindedReceive ( InboundOnionBlindedReceivePayload ) ,
1861
1865
}
1862
1866
1867
+ #[ cfg( trampoline) ]
1868
+ #[ cfg_attr( trampoline, allow( unused) ) ]
1869
+ pub struct InboundTrampolineForwardPayload {
1870
+ pub next_trampoline : PublicKey ,
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 : PublicKey ,
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
+
1863
1896
pub ( crate ) enum OutboundOnionPayload < ' a > {
1864
1897
Forward {
1865
1898
short_channel_id : u64 ,
@@ -3008,7 +3041,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
3008
3041
return Ok ( Self :: TrampolineEntrypoint ( InboundTrampolineEntrypointPayload {
3009
3042
amt_to_forward : amt. ok_or ( DecodeError :: InvalidValue ) ?,
3010
3043
outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
3011
- multipath_trampoline_data : payment_data,
3044
+ multipath_trampoline_data : payment_data. ok_or ( DecodeError :: InvalidValue ) ? ,
3012
3045
trampoline_packet : trampoline_onion_packet,
3013
3046
current_path_key : intro_node_blinding_point,
3014
3047
} ) )
@@ -3097,6 +3130,134 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, NS)> for InboundOnionPayload wh
3097
3130
}
3098
3131
}
3099
3132
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 < PublicKey > = 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
+
3100
3261
impl Writeable for Ping {
3101
3262
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
3102
3263
self . ponglen . write ( w) ?;
0 commit comments