@@ -74,7 +74,9 @@ enum PendingHTLCRouting {
74
74
onion_packet : msgs:: OnionPacket ,
75
75
short_channel_id : u64 , // This should be NonZero<u64> eventually when we bump MSRV
76
76
} ,
77
- Receive { } ,
77
+ Receive {
78
+ payment_data : Option < msgs:: FinalOnionHopData > ,
79
+ } ,
78
80
}
79
81
80
82
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
@@ -119,6 +121,16 @@ pub(super) struct HTLCPreviousHopData {
119
121
incoming_packet_shared_secret : [ u8 ; 32 ] ,
120
122
}
121
123
124
+ struct ClaimableHTLC {
125
+ prev_hop : HTLCPreviousHopData ,
126
+ value : u64 ,
127
+ /// Filled in when the HTLC was received with a payment_secret packet, which contains a
128
+ /// total_msat (which may differ from value if this is a Multi-Path Payment) and a
129
+ /// payment_secret which prevents path-probing attacks and can associate different HTLCs which
130
+ /// are part of the same payment.
131
+ payment_data : Option < msgs:: FinalOnionHopData > ,
132
+ }
133
+
122
134
/// Tracks the inbound corresponding to an outbound HTLC
123
135
#[ derive( Clone , PartialEq ) ]
124
136
pub ( super ) enum HTLCSource {
@@ -276,12 +288,11 @@ pub(super) struct ChannelHolder<ChanSigner: ChannelKeys> {
276
288
/// guarantees are made about the existence of a channel with the short id here, nor the short
277
289
/// ids in the PendingHTLCInfo!
278
290
pub ( super ) forward_htlcs : HashMap < u64 , Vec < HTLCForwardInfo > > ,
279
- /// payment_hash -> Vec<(amount_received, htlc_source)> for tracking things that were to us and
280
- /// can be failed/claimed by the user
291
+ /// Tracks HTLCs that were to us and can be failed/claimed by the user
281
292
/// Note that while this is held in the same mutex as the channels themselves, no consistency
282
293
/// guarantees are made about the channels given here actually existing anymore by the time you
283
294
/// go to read them!
284
- pub ( super ) claimable_htlcs : HashMap < PaymentHash , Vec < ( u64 , HTLCPreviousHopData ) > > ,
295
+ claimable_htlcs : HashMap < PaymentHash , Vec < ClaimableHTLC > > ,
285
296
/// Messages to send to peers - pushed to in the same lock that they are generated in (except
286
297
/// for broadcast messages, where ordering isn't as strict).
287
298
pub ( super ) pending_msg_events : Vec < events:: MessageSendEvent > ,
@@ -1007,13 +1018,19 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1007
1018
return_err ! ( "Upstream node set CLTV to the wrong value" , 18 , & byte_utils:: be32_to_array( msg. cltv_expiry) ) ;
1008
1019
}
1009
1020
1021
+ let payment_data = match next_hop_data. format {
1022
+ msgs:: OnionHopDataFormat :: Legacy { .. } => None ,
1023
+ msgs:: OnionHopDataFormat :: NonFinalNode { .. } => return_err ! ( "Got non final data with an HMAC of 0" , 0x4000 | 22 , & [ 0 ; 0 ] ) ,
1024
+ msgs:: OnionHopDataFormat :: FinalNode { payment_data } => payment_data,
1025
+ } ;
1026
+
1010
1027
// Note that we could obviously respond immediately with an update_fulfill_htlc
1011
1028
// message, however that would leak that we are the recipient of this payment, so
1012
1029
// instead we stay symmetric with the forwarding case, only responding (after a
1013
1030
// delay) once they've send us a commitment_signed!
1014
1031
1015
1032
PendingHTLCStatus :: Forward ( PendingHTLCInfo {
1016
- routing : PendingHTLCRouting :: Receive { } ,
1033
+ routing : PendingHTLCRouting :: Receive { payment_data } ,
1017
1034
payment_hash : msg. payment_hash . clone ( ) ,
1018
1035
incoming_shared_secret : shared_secret,
1019
1036
amt_to_forward : next_hop_data. amt_to_forward ,
@@ -1580,17 +1597,18 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1580
1597
for forward_info in pending_forwards. drain ( ..) {
1581
1598
match forward_info {
1582
1599
HTLCForwardInfo :: AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info : PendingHTLCInfo {
1583
- routing : PendingHTLCRouting :: Receive { } ,
1600
+ routing : PendingHTLCRouting :: Receive { payment_data } ,
1584
1601
incoming_shared_secret, payment_hash, amt_to_forward, .. } , } => {
1585
- let prev_hop_data = HTLCPreviousHopData {
1602
+ let prev_hop = HTLCPreviousHopData {
1586
1603
short_channel_id : prev_short_channel_id,
1587
1604
htlc_id : prev_htlc_id,
1588
1605
incoming_packet_shared_secret : incoming_shared_secret,
1589
1606
} ;
1590
- match channel_state. claimable_htlcs . entry ( payment_hash) {
1591
- hash_map:: Entry :: Occupied ( mut entry) => entry. get_mut ( ) . push ( ( amt_to_forward, prev_hop_data) ) ,
1592
- hash_map:: Entry :: Vacant ( entry) => { entry. insert ( vec ! [ ( amt_to_forward, prev_hop_data) ] ) ; } ,
1593
- } ;
1607
+ channel_state. claimable_htlcs . entry ( payment_hash) . or_insert ( Vec :: new ( ) ) . push ( ClaimableHTLC {
1608
+ prev_hop,
1609
+ value : amt_to_forward,
1610
+ payment_data,
1611
+ } ) ;
1594
1612
new_events. push ( events:: Event :: PaymentReceived {
1595
1613
payment_hash : payment_hash,
1596
1614
amt : amt_to_forward,
@@ -1660,11 +1678,11 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1660
1678
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1661
1679
let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( payment_hash) ;
1662
1680
if let Some ( mut sources) = removed_source {
1663
- for ( recvd_value , htlc_with_hash ) in sources. drain ( ..) {
1681
+ for htlc in sources. drain ( ..) {
1664
1682
if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
1665
1683
self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) ,
1666
- HTLCSource :: PreviousHopData ( htlc_with_hash ) , payment_hash,
1667
- HTLCFailReason :: Reason { failure_code : 0x4000 | 15 , data : byte_utils:: be64_to_array ( recvd_value ) . to_vec ( ) } ) ;
1684
+ HTLCSource :: PreviousHopData ( htlc . prev_hop ) , payment_hash,
1685
+ HTLCFailReason :: Reason { failure_code : 0x4000 | 15 , data : byte_utils:: be64_to_array ( htlc . value ) . to_vec ( ) } ) ;
1668
1686
}
1669
1687
true
1670
1688
} else { false }
@@ -1788,17 +1806,17 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1788
1806
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1789
1807
let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) ;
1790
1808
if let Some ( mut sources) = removed_source {
1791
- for ( received_amount , htlc_with_hash ) in sources. drain ( ..) {
1809
+ for htlc in sources. drain ( ..) {
1792
1810
if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
1793
- if received_amount < expected_amount || received_amount > expected_amount * 2 {
1794
- let mut htlc_msat_data = byte_utils:: be64_to_array ( received_amount ) . to_vec ( ) ;
1811
+ if htlc . value < expected_amount || htlc . value > expected_amount * 2 {
1812
+ let mut htlc_msat_data = byte_utils:: be64_to_array ( htlc . value ) . to_vec ( ) ;
1795
1813
let mut height_data = byte_utils:: be32_to_array ( self . latest_block_height . load ( Ordering :: Acquire ) as u32 ) . to_vec ( ) ;
1796
1814
htlc_msat_data. append ( & mut height_data) ;
1797
1815
self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) ,
1798
- HTLCSource :: PreviousHopData ( htlc_with_hash ) , & payment_hash,
1816
+ HTLCSource :: PreviousHopData ( htlc . prev_hop ) , & payment_hash,
1799
1817
HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_data } ) ;
1800
1818
} else {
1801
- self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc_with_hash ) , payment_preimage) ;
1819
+ self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc . prev_hop ) , payment_preimage) ;
1802
1820
}
1803
1821
}
1804
1822
true
@@ -3098,8 +3116,9 @@ impl Writeable for PendingHTLCInfo {
3098
3116
onion_packet. write ( writer) ?;
3099
3117
short_channel_id. write ( writer) ?;
3100
3118
} ,
3101
- & PendingHTLCRouting :: Receive { } => {
3119
+ & PendingHTLCRouting :: Receive { ref payment_data } => {
3102
3120
1u8 . write ( writer) ?;
3121
+ payment_data. write ( writer) ?;
3103
3122
} ,
3104
3123
}
3105
3124
self . incoming_shared_secret . write ( writer) ?;
@@ -3118,7 +3137,9 @@ impl Readable for PendingHTLCInfo {
3118
3137
onion_packet : Readable :: read ( reader) ?,
3119
3138
short_channel_id : Readable :: read ( reader) ?,
3120
3139
} ,
3121
- 1u8 => PendingHTLCRouting :: Receive { } ,
3140
+ 1u8 => PendingHTLCRouting :: Receive {
3141
+ payment_data : Readable :: read ( reader) ?,
3142
+ } ,
3122
3143
_ => return Err ( DecodeError :: InvalidValue ) ,
3123
3144
} ,
3124
3145
incoming_shared_secret : Readable :: read ( reader) ?,
@@ -3187,6 +3208,12 @@ impl_writeable!(HTLCPreviousHopData, 0, {
3187
3208
incoming_packet_shared_secret
3188
3209
} ) ;
3189
3210
3211
+ impl_writeable ! ( ClaimableHTLC , 0 , {
3212
+ prev_hop,
3213
+ value,
3214
+ payment_data
3215
+ } ) ;
3216
+
3190
3217
impl Writeable for HTLCSource {
3191
3218
fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
3192
3219
match self {
@@ -3328,9 +3355,8 @@ impl<ChanSigner: ChannelKeys + Writeable, M: Deref, T: Deref, K: Deref, F: Deref
3328
3355
for ( payment_hash, previous_hops) in channel_state. claimable_htlcs . iter ( ) {
3329
3356
payment_hash. write ( writer) ?;
3330
3357
( previous_hops. len ( ) as u64 ) . write ( writer) ?;
3331
- for & ( recvd_amt, ref previous_hop) in previous_hops. iter ( ) {
3332
- recvd_amt. write ( writer) ?;
3333
- previous_hop. write ( writer) ?;
3358
+ for htlc in previous_hops. iter ( ) {
3359
+ htlc. write ( writer) ?;
3334
3360
}
3335
3361
}
3336
3362
@@ -3507,7 +3533,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De
3507
3533
let previous_hops_len: u64 = Readable :: read ( reader) ?;
3508
3534
let mut previous_hops = Vec :: with_capacity ( cmp:: min ( previous_hops_len as usize , 2 ) ) ;
3509
3535
for _ in 0 ..previous_hops_len {
3510
- previous_hops. push ( ( Readable :: read ( reader) ?, Readable :: read ( reader ) ? ) ) ;
3536
+ previous_hops. push ( Readable :: read ( reader) ?) ;
3511
3537
}
3512
3538
claimable_htlcs. insert ( payment_hash, previous_hops) ;
3513
3539
}
0 commit comments