@@ -31,24 +31,26 @@ use bitcoin::{secp256k1, Witness};
31
31
use bitcoin:: blockdata:: script:: Script ;
32
32
use bitcoin:: hash_types:: { Txid , BlockHash } ;
33
33
34
+ use crate :: blinded_path:: payment:: ReceiveTlvs ;
34
35
use crate :: ln:: { ChannelId , PaymentPreimage , PaymentHash , PaymentSecret } ;
35
36
use crate :: ln:: features:: { ChannelFeatures , ChannelTypeFeatures , InitFeatures , NodeFeatures } ;
36
37
use crate :: ln:: onion_utils;
37
38
use crate :: onion_message;
38
- use crate :: sign:: NodeSigner ;
39
+ use crate :: sign:: { NodeSigner , Recipient } ;
39
40
40
41
use crate :: prelude:: * ;
41
42
use core:: convert:: TryFrom ;
42
43
use core:: fmt;
43
44
use core:: fmt:: Debug ;
44
45
use core:: ops:: Deref ;
45
46
use core:: str:: FromStr ;
46
- use crate :: io:: { self , Read } ;
47
+ use crate :: io:: { self , Cursor , Read } ;
47
48
use crate :: io_extras:: read_to_end;
48
49
49
50
use crate :: events:: { MessageSendEventsProvider , OnionMessageProvider } ;
51
+ use crate :: util:: chacha20poly1305rfc:: ChaChaPolyReadAdapter ;
50
52
use crate :: util:: logger;
51
- use crate :: util:: ser:: { LengthReadable , Readable , ReadableArgs , Writeable , Writer , WithoutLength , FixedLengthReader , HighZeroBytesDroppedBigSize , Hostname , TransactionU16LenLimited , BigSize } ;
53
+ use crate :: util:: ser:: { LengthReadable , LengthReadableArgs , Readable , ReadableArgs , Writeable , Writer , WithoutLength , FixedLengthReader , HighZeroBytesDroppedBigSize , Hostname , TransactionU16LenLimited , BigSize } ;
52
54
use crate :: util:: base32;
53
55
54
56
use crate :: routing:: gossip:: { NodeAlias , NodeId } ;
@@ -1520,6 +1522,7 @@ pub trait OnionMessageHandler : OnionMessageProvider {
1520
1522
1521
1523
mod fuzzy_internal_msgs {
1522
1524
use bitcoin:: secp256k1:: PublicKey ;
1525
+ use crate :: blinded_path:: payment:: PaymentConstraints ;
1523
1526
use crate :: prelude:: * ;
1524
1527
use crate :: ln:: { PaymentPreimage , PaymentSecret } ;
1525
1528
@@ -1548,6 +1551,14 @@ mod fuzzy_internal_msgs {
1548
1551
amt_msat : u64 ,
1549
1552
outgoing_cltv_value : u32 ,
1550
1553
} ,
1554
+ BlindedReceive {
1555
+ amt_msat : u64 ,
1556
+ total_msat : u64 ,
1557
+ outgoing_cltv_value : u32 ,
1558
+ payment_secret : PaymentSecret ,
1559
+ payment_constraints : PaymentConstraints ,
1560
+ intro_node_blinding_point : PublicKey ,
1561
+ }
1551
1562
}
1552
1563
1553
1564
pub ( crate ) enum OutboundOnionPayload {
@@ -2136,22 +2147,28 @@ impl Writeable for OutboundOnionPayload {
2136
2147
2137
2148
impl < NS : Deref > ReadableArgs < & NS > for InboundOnionPayload where NS :: Target : NodeSigner {
2138
2149
fn read < R : Read > ( r : & mut R , node_signer : & NS ) -> Result < Self , DecodeError > {
2139
- let mut amt = HighZeroBytesDroppedBigSize ( 0u64 ) ;
2140
- let mut cltv_value = HighZeroBytesDroppedBigSize ( 0u32 ) ;
2150
+ let mut amt = None ;
2151
+ let mut cltv_value = None ;
2141
2152
let mut short_id: Option < u64 > = None ;
2142
2153
let mut payment_data: Option < FinalOnionHopData > = None ;
2154
+ let mut encrypted_tlvs_opt: Option < WithoutLength < Vec < u8 > > > = None ;
2155
+ let mut intro_node_blinding_point = None ;
2143
2156
let mut payment_metadata: Option < WithoutLength < Vec < u8 > > > = None ;
2157
+ let mut total_msat = None ;
2144
2158
let mut keysend_preimage: Option < PaymentPreimage > = None ;
2145
2159
let mut custom_tlvs = Vec :: new ( ) ;
2146
2160
2147
2161
let tlv_len = BigSize :: read ( r) ?;
2148
2162
let rd = FixedLengthReader :: new ( r, tlv_len. 0 ) ;
2149
2163
decode_tlv_stream_with_custom_tlv_decode ! ( rd, {
2150
- ( 2 , amt, required ) ,
2151
- ( 4 , cltv_value, required ) ,
2164
+ ( 2 , amt, ( option , encoding : ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
2165
+ ( 4 , cltv_value, ( option , encoding : ( u32 , HighZeroBytesDroppedBigSize ) ) ) ,
2152
2166
( 6 , short_id, option) ,
2153
2167
( 8 , payment_data, option) ,
2168
+ ( 10 , encrypted_tlvs_opt, option) ,
2169
+ ( 12 , intro_node_blinding_point, option) ,
2154
2170
( 16 , payment_metadata, option) ,
2171
+ ( 18 , total_msat, ( option, encoding: ( u64 , HighZeroBytesDroppedBigSize ) ) ) ,
2155
2172
// See https://github.com/lightning/blips/blob/master/blip-0003.md
2156
2173
( 5482373484 , keysend_preimage, option)
2157
2174
} , |msg_type: u64 , msg_reader: & mut FixedLengthReader <_>| -> Result <bool , DecodeError > {
@@ -2162,16 +2179,44 @@ impl<NS: Deref> ReadableArgs<&NS> for InboundOnionPayload where NS::Target: Node
2162
2179
Ok ( true )
2163
2180
} ) ;
2164
2181
2165
- if amt. 0 > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
2166
- if let Some ( short_channel_id) = short_id {
2167
- if payment_data. is_some ( ) { return Err ( DecodeError :: InvalidValue ) }
2168
- if payment_metadata. is_some ( ) { return Err ( DecodeError :: InvalidValue ) ; }
2182
+ if amt. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
2183
+
2184
+ if let Some ( blinding_point) = intro_node_blinding_point {
2185
+ if short_id. is_some ( ) || payment_data. is_some ( ) || payment_metadata. is_some ( ) {
2186
+ return Err ( DecodeError :: InvalidValue )
2187
+ }
2188
+ let enc_tlvs = encrypted_tlvs_opt. ok_or ( DecodeError :: InvalidValue ) ?. 0 ;
2189
+ let enc_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & blinding_point, None )
2190
+ . map_err ( |_| DecodeError :: InvalidValue ) ?;
2191
+ let rho = onion_utils:: gen_rho_from_shared_secret ( & enc_tlvs_ss. secret_bytes ( ) ) ;
2192
+ let mut s = Cursor :: new ( & enc_tlvs) ;
2193
+ let mut reader = FixedLengthReader :: new ( & mut s, enc_tlvs. len ( ) as u64 ) ;
2194
+ match ChaChaPolyReadAdapter :: read ( & mut reader, rho) ? {
2195
+ ChaChaPolyReadAdapter { readable : ReceiveTlvs { payment_secret, payment_constraints } } => {
2196
+ if total_msat. unwrap_or ( 0 ) > MAX_VALUE_MSAT { return Err ( DecodeError :: InvalidValue ) }
2197
+ Ok ( Self :: BlindedReceive {
2198
+ amt_msat : amt. ok_or ( DecodeError :: InvalidValue ) ?,
2199
+ total_msat : total_msat. ok_or ( DecodeError :: InvalidValue ) ?,
2200
+ outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ?,
2201
+ payment_secret,
2202
+ payment_constraints,
2203
+ intro_node_blinding_point : blinding_point,
2204
+ } )
2205
+ } ,
2206
+ }
2207
+ } else if let Some ( short_channel_id) = short_id {
2208
+ if payment_data. is_some ( ) || payment_metadata. is_some ( ) || encrypted_tlvs_opt. is_some ( ) ||
2209
+ total_msat. is_some ( )
2210
+ { return Err ( DecodeError :: InvalidValue ) }
2169
2211
Ok ( Self :: Forward {
2170
2212
short_channel_id,
2171
- amt_to_forward : amt. 0 ,
2172
- outgoing_cltv_value : cltv_value. 0 ,
2213
+ amt_to_forward : amt. ok_or ( DecodeError :: InvalidValue ) ? ,
2214
+ outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ? ,
2173
2215
} )
2174
2216
} else {
2217
+ if encrypted_tlvs_opt. is_some ( ) || total_msat. is_some ( ) {
2218
+ return Err ( DecodeError :: InvalidValue )
2219
+ }
2175
2220
if let Some ( data) = & payment_data {
2176
2221
if data. total_msat > MAX_VALUE_MSAT {
2177
2222
return Err ( DecodeError :: InvalidValue ) ;
@@ -2181,8 +2226,8 @@ impl<NS: Deref> ReadableArgs<&NS> for InboundOnionPayload where NS::Target: Node
2181
2226
payment_data,
2182
2227
payment_metadata : payment_metadata. map ( |w| w. 0 ) ,
2183
2228
keysend_preimage,
2184
- amt_msat : amt. 0 ,
2185
- outgoing_cltv_value : cltv_value. 0 ,
2229
+ amt_msat : amt. ok_or ( DecodeError :: InvalidValue ) ? ,
2230
+ outgoing_cltv_value : cltv_value. ok_or ( DecodeError :: InvalidValue ) ? ,
2186
2231
custom_tlvs,
2187
2232
} )
2188
2233
}
0 commit comments