@@ -544,23 +544,29 @@ struct ExpandedPmtKey {
544
544
metadata_key : [ u8 ; 32 ] ,
545
545
ldk_pmt_hash_key : [ u8 ; 32 ] ,
546
546
user_pmt_hash_key : [ u8 ; 32 ] ,
547
+ node_secret_key : Option < SecretKey > , // Only set for fake last hops
547
548
}
548
549
549
550
impl Writeable for ExpandedPmtKey {
550
551
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
551
- self . key_material . write ( w)
552
+ self . key_material . write ( w) ?;
553
+ if self . node_secret_key . is_some ( ) {
554
+ Ok ( true . write ( w) ?)
555
+ } else { Ok ( false . write ( w) ?) }
552
556
}
553
557
}
554
558
555
559
impl Readable for ExpandedPmtKey {
556
560
fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
557
561
let key_material: KeyMaterial = Readable :: read ( r) ?;
558
- let ( metadata_key, ldk_pmt_hash_key, user_pmt_hash_key) = hkdf_extract_expand ( & vec ! [ 0 ] , & key_material) ;
562
+ let fake_node_key: bool = Readable :: read ( r) ?; // TODO amend #1177 to write this value too
563
+ let ( metadata_key, ldk_pmt_hash_key, user_pmt_hash_key, node_key_bytes) = hkdf_extract_expand ( & vec ! [ 0 ] , & key_material) ;
559
564
Ok ( ExpandedPmtKey {
560
565
key_material,
561
566
metadata_key,
562
567
ldk_pmt_hash_key,
563
568
user_pmt_hash_key,
569
+ node_secret_key : if fake_node_key { Some ( SecretKey :: from_slice ( & node_key_bytes) . unwrap ( ) ) } else { None } ,
564
570
} )
565
571
}
566
572
}
@@ -644,6 +650,8 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
644
650
#[ cfg( not( any( test, feature = "_test_utils" ) ) ) ]
645
651
channel_state : Mutex < ChannelHolder < Signer > > ,
646
652
653
+ fake_last_hops : Mutex < HashMap < u64 , ExpandedPmtKey > > ,
654
+
647
655
/// Storage for PaymentSecrets and any requirements on future inbound payments before we will
648
656
/// expose them to users via a PaymentReceived event. HTLCs which do not meet the requirements
649
657
/// here are failed when we process them as pending-forwardable-HTLCs, and entries are removed
@@ -1347,12 +1355,13 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1347
1355
let mut secp_ctx = Secp256k1 :: new ( ) ;
1348
1356
secp_ctx. seeded_randomize ( & keys_manager. get_secure_random_bytes ( ) ) ;
1349
1357
let inbound_pmt_key_material = keys_manager. get_inbound_payment_key_material ( ) ;
1350
- let ( metadata_key, ldk_pmt_hash_key, user_pmt_hash_key) = hkdf_extract_expand ( & vec ! [ 0 ] , & inbound_pmt_key_material) ;
1358
+ let ( metadata_key, ldk_pmt_hash_key, user_pmt_hash_key, _ ) = hkdf_extract_expand ( & vec ! [ 0 ] , & inbound_pmt_key_material) ;
1351
1359
let expanded_inbound_key = ExpandedPmtKey {
1352
1360
key_material : inbound_pmt_key_material,
1353
1361
metadata_key,
1354
1362
ldk_pmt_hash_key,
1355
- user_pmt_hash_key
1363
+ user_pmt_hash_key,
1364
+ node_secret_key : None ,
1356
1365
} ;
1357
1366
1358
1367
ChannelManager {
@@ -1371,6 +1380,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1371
1380
claimable_htlcs : HashMap :: new ( ) ,
1372
1381
pending_msg_events : Vec :: new ( ) ,
1373
1382
} ) ,
1383
+ fake_last_hops : Mutex :: new ( HashMap :: new ( ) ) ,
1374
1384
pending_inbound_payments : Mutex :: new ( HashMap :: new ( ) ) ,
1375
1385
pending_outbound_payments : Mutex :: new ( HashMap :: new ( ) ) ,
1376
1386
@@ -1736,6 +1746,25 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1736
1746
}
1737
1747
}
1738
1748
1749
+ /// Insert a fake last hop. This allows you to generate invoices for payments that can
1750
+ /// actually be received by one of multiple nodes. `last_hop_key` should consist of 32 random
1751
+ /// bytes.
1752
+ // TODO we prob don't want to return the node secret, but how to sign invoices?
1753
+ pub fn create_fake_last_hop ( & self , last_hop_key : KeyMaterial , last_hop_scid : u64 ) -> SecretKey {
1754
+ let mut fake_hops = self . fake_last_hops . lock ( ) . unwrap ( ) ;
1755
+ let ( metadata_key, ldk_pmt_hash_key, user_pmt_hash_key, node_key) = hkdf_extract_expand ( & vec ! [ 0 ] , & last_hop_key) ;
1756
+ let node_secret = SecretKey :: from_slice ( & node_key) . unwrap ( ) ;
1757
+ fake_hops. insert ( last_hop_scid, ExpandedPmtKey {
1758
+ key_material : last_hop_key,
1759
+ metadata_key,
1760
+ ldk_pmt_hash_key,
1761
+ user_pmt_hash_key,
1762
+ node_secret_key : Some ( node_secret) ,
1763
+ } ) ;
1764
+
1765
+ node_secret
1766
+ }
1767
+
1739
1768
fn decode_update_add_htlc_onion ( & self , msg : & msgs:: UpdateAddHTLC ) -> ( PendingHTLCStatus , MutexGuard < ChannelHolder < Signer > > ) {
1740
1769
macro_rules! return_malformed_err {
1741
1770
( $msg: expr, $err_code: expr) => {
@@ -5882,9 +5911,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
5882
5911
_ => { } ,
5883
5912
}
5884
5913
}
5914
+ let fake_last_hops = self . fake_last_hops . lock ( ) . unwrap ( ) ;
5885
5915
write_tlv_fields ! ( writer, {
5886
5916
( 1 , pending_outbound_payments_no_retry, required) ,
5887
5917
( 3 , pending_outbound_payments, required) ,
5918
+ ( 5 , fake_last_hops, required) ,
5888
5919
} ) ;
5889
5920
5890
5921
Ok ( ( ) )
@@ -6179,9 +6210,11 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6179
6210
// pending_outbound_payments_no_retry is for compatibility with 0.0.101 clients.
6180
6211
let mut pending_outbound_payments_no_retry: Option < HashMap < PaymentId , HashSet < [ u8 ; 32 ] > > > = None ;
6181
6212
let mut pending_outbound_payments = None ;
6213
+ let mut fake_last_hops = Some ( HashMap :: new ( ) ) ;
6182
6214
read_tlv_fields ! ( reader, {
6183
6215
( 1 , pending_outbound_payments_no_retry, option) ,
6184
6216
( 3 , pending_outbound_payments, option) ,
6217
+ ( 5 , fake_last_hops, option) ,
6185
6218
} ) ;
6186
6219
if pending_outbound_payments. is_none ( ) && pending_outbound_payments_no_retry. is_none ( ) {
6187
6220
pending_outbound_payments = Some ( pending_outbound_payments_compat) ;
@@ -6246,12 +6279,13 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6246
6279
}
6247
6280
6248
6281
let inbound_pmt_key_material = args. keys_manager . get_inbound_payment_key_material ( ) ;
6249
- let ( metadata_key, ldk_pmt_hash_key, user_pmt_hash_key) = hkdf_extract_expand ( & vec ! [ 0 ] , & inbound_pmt_key_material) ;
6282
+ let ( metadata_key, ldk_pmt_hash_key, user_pmt_hash_key, _ ) = hkdf_extract_expand ( & vec ! [ 0 ] , & inbound_pmt_key_material) ;
6250
6283
let expanded_inbound_key = ExpandedPmtKey {
6251
6284
key_material : inbound_pmt_key_material,
6252
6285
metadata_key,
6253
6286
ldk_pmt_hash_key,
6254
- user_pmt_hash_key
6287
+ user_pmt_hash_key,
6288
+ node_secret_key : None ,
6255
6289
} ;
6256
6290
6257
6291
let channel_manager = ChannelManager {
@@ -6270,6 +6304,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6270
6304
pending_msg_events : Vec :: new ( ) ,
6271
6305
} ) ,
6272
6306
inbound_payment_key : expanded_inbound_key,
6307
+ fake_last_hops : Mutex :: new ( fake_last_hops. unwrap ( ) ) ,
6273
6308
pending_inbound_payments : Mutex :: new ( pending_inbound_payments) ,
6274
6309
pending_outbound_payments : Mutex :: new ( pending_outbound_payments. unwrap ( ) ) ,
6275
6310
@@ -6303,7 +6338,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
6303
6338
}
6304
6339
}
6305
6340
6306
- fn hkdf_extract_expand ( salt : & [ u8 ] , ikm : & KeyMaterial ) -> ( [ u8 ; 32 ] , [ u8 ; 32 ] , [ u8 ; 32 ] ) {
6341
+ fn hkdf_extract_expand ( salt : & [ u8 ] , ikm : & KeyMaterial ) -> ( [ u8 ; 32 ] , [ u8 ; 32 ] , [ u8 ; 32 ] , [ u8 ; 32 ] ) {
6307
6342
let mut hmac = HmacEngine :: < Sha256 > :: new ( salt) ;
6308
6343
hmac. input ( & ikm. 0 ) ;
6309
6344
let prk = Hmac :: from_engine ( hmac) . into_inner ( ) ;
@@ -6321,7 +6356,12 @@ fn hkdf_extract_expand(salt: &[u8], ikm: &KeyMaterial) -> ([u8; 32], [u8; 32], [
6321
6356
hmac. input ( & [ 3 ; 1 ] ) ;
6322
6357
let t3 = Hmac :: from_engine ( hmac) . into_inner ( ) ;
6323
6358
6324
- ( t1, t2, t3)
6359
+ let mut hmac = HmacEngine :: < Sha256 > :: new ( & prk[ ..] ) ;
6360
+ hmac. input ( & t3) ;
6361
+ hmac. input ( & [ 4 ; 1 ] ) ;
6362
+ let t4 = Hmac :: from_engine ( hmac) . into_inner ( ) ;
6363
+
6364
+ ( t1, t2, t3, t4)
6325
6365
}
6326
6366
6327
6367
#[ cfg( test) ]
0 commit comments