@@ -93,11 +93,13 @@ pub struct MonitorUpdateError(pub &'static str);
93
93
94
94
/// Simple structure send back by ManyChannelMonitor in case of HTLC detected onchain from a
95
95
/// forward channel and from which info are needed to update HTLC in a backward channel.
96
+ #[ derive( Clone , PartialEq ) ]
96
97
pub struct HTLCUpdate {
97
98
pub ( super ) payment_hash : PaymentHash ,
98
99
pub ( super ) payment_preimage : Option < PaymentPreimage > ,
99
100
pub ( super ) source : HTLCSource
100
101
}
102
+ impl_writeable ! ( HTLCUpdate , 0 , { payment_hash, payment_preimage, source } ) ;
101
103
102
104
/// Simple trait indicating ability to track a set of ChannelMonitors and multiplex events between
103
105
/// them. Generally should be implemented by keeping a local SimpleManyChannelMonitor and passing
@@ -130,8 +132,12 @@ pub trait ManyChannelMonitor<ChanSigner: ChannelKeys>: Send + Sync {
130
132
fn add_update_monitor ( & self , funding_txo : OutPoint , monitor : ChannelMonitor < ChanSigner > ) -> Result < ( ) , ChannelMonitorUpdateErr > ;
131
133
132
134
/// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
133
- /// with success or failure backward
134
- fn fetch_pending_htlc_updated ( & self ) -> Vec < HTLCUpdate > ;
135
+ /// with success or failure.
136
+ ///
137
+ /// You should probably just call through to
138
+ /// ChannelMonitor::get_and_clear_pending_htlcs_updated() for each ChannelMonitor and return
139
+ /// the full list.
140
+ fn get_and_clear_pending_htlcs_updated ( & self ) -> Vec < HTLCUpdate > ;
135
141
}
136
142
137
143
/// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a
@@ -153,7 +159,6 @@ pub struct SimpleManyChannelMonitor<Key, ChanSigner: ChannelKeys> {
153
159
chain_monitor : Arc < ChainWatchInterface > ,
154
160
broadcaster : Arc < BroadcasterInterface > ,
155
161
pending_events : Mutex < Vec < events:: Event > > ,
156
- pending_htlc_updated : Mutex < HashMap < PaymentHash , Vec < ( HTLCSource , Option < PaymentPreimage > ) > > > ,
157
162
logger : Arc < Logger > ,
158
163
fee_estimator : Arc < FeeEstimator >
159
164
}
@@ -162,11 +167,10 @@ impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys> ChainListen
162
167
fn block_connected ( & self , header : & BlockHeader , height : u32 , txn_matched : & [ & Transaction ] , _indexes_of_txn_matched : & [ u32 ] ) {
163
168
let block_hash = header. bitcoin_hash ( ) ;
164
169
let mut new_events: Vec < events:: Event > = Vec :: with_capacity ( 0 ) ;
165
- let mut htlc_updated_infos = Vec :: new ( ) ;
166
170
{
167
171
let mut monitors = self . monitors . lock ( ) . unwrap ( ) ;
168
172
for monitor in monitors. values_mut ( ) {
169
- let ( txn_outputs, spendable_outputs, mut htlc_updated ) = monitor. block_connected ( txn_matched, height, & block_hash, & * self . broadcaster , & * self . fee_estimator ) ;
173
+ let ( txn_outputs, spendable_outputs) = monitor. block_connected ( txn_matched, height, & block_hash, & * self . broadcaster , & * self . fee_estimator ) ;
170
174
if spendable_outputs. len ( ) > 0 {
171
175
new_events. push ( events:: Event :: SpendableOutputs {
172
176
outputs : spendable_outputs,
@@ -178,35 +182,6 @@ impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys> ChainListen
178
182
self . chain_monitor . install_watch_outpoint ( ( txid. clone ( ) , idx as u32 ) , & output. script_pubkey ) ;
179
183
}
180
184
}
181
- htlc_updated_infos. append ( & mut htlc_updated) ;
182
- }
183
- }
184
- {
185
- // ChannelManager will just need to fetch pending_htlc_updated and pass state backward
186
- let mut pending_htlc_updated = self . pending_htlc_updated . lock ( ) . unwrap ( ) ;
187
- for htlc in htlc_updated_infos. drain ( ..) {
188
- match pending_htlc_updated. entry ( htlc. 2 ) {
189
- hash_map:: Entry :: Occupied ( mut e) => {
190
- // In case of reorg we may have htlc outputs solved in a different way so
191
- // we prefer to keep claims but don't store duplicate updates for a given
192
- // (payment_hash, HTLCSource) pair.
193
- let mut existing_claim = false ;
194
- e. get_mut ( ) . retain ( |htlc_data| {
195
- if htlc. 0 == htlc_data. 0 {
196
- if htlc_data. 1 . is_some ( ) {
197
- existing_claim = true ;
198
- true
199
- } else { false }
200
- } else { true }
201
- } ) ;
202
- if !existing_claim {
203
- e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
204
- }
205
- }
206
- hash_map:: Entry :: Vacant ( e) => {
207
- e. insert ( vec ! [ ( htlc. 0 , htlc. 1 ) ] ) ;
208
- }
209
- }
210
185
}
211
186
}
212
187
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
@@ -231,7 +206,6 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static, ChanSigner: ChannelKeys> Simpl
231
206
chain_monitor,
232
207
broadcaster,
233
208
pending_events : Mutex :: new ( Vec :: new ( ) ) ,
234
- pending_htlc_updated : Mutex :: new ( HashMap :: new ( ) ) ,
235
209
logger,
236
210
fee_estimator : feeest,
237
211
} ;
@@ -284,17 +258,10 @@ impl<ChanSigner: ChannelKeys> ManyChannelMonitor<ChanSigner> for SimpleManyChann
284
258
}
285
259
}
286
260
287
- fn fetch_pending_htlc_updated ( & self ) -> Vec < HTLCUpdate > {
288
- let mut updated = self . pending_htlc_updated . lock ( ) . unwrap ( ) ;
289
- let mut pending_htlcs_updated = Vec :: with_capacity ( updated. len ( ) ) ;
290
- for ( k, v) in updated. drain ( ) {
291
- for htlc_data in v {
292
- pending_htlcs_updated. push ( HTLCUpdate {
293
- payment_hash : k,
294
- payment_preimage : htlc_data. 1 ,
295
- source : htlc_data. 0 ,
296
- } ) ;
297
- }
261
+ fn get_and_clear_pending_htlcs_updated ( & self ) -> Vec < HTLCUpdate > {
262
+ let mut pending_htlcs_updated = Vec :: new ( ) ;
263
+ for chan in self . monitors . lock ( ) . unwrap ( ) . values_mut ( ) {
264
+ pending_htlcs_updated. append ( & mut chan. get_and_clear_pending_htlcs_updated ( ) ) ;
298
265
}
299
266
pending_htlcs_updated
300
267
}
@@ -640,6 +607,8 @@ pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
640
607
641
608
payment_preimages : HashMap < PaymentHash , PaymentPreimage > ,
642
609
610
+ pending_htlcs_updated : Vec < HTLCUpdate > ,
611
+
643
612
destination_script : Script ,
644
613
// Thanks to data loss protection, we may be able to claim our non-htlc funds
645
614
// back, this is the script we have to spend from but we need to
@@ -750,6 +719,7 @@ impl<ChanSigner: ChannelKeys> PartialEq for ChannelMonitor<ChanSigner> {
750
719
self . current_remote_commitment_number != other. current_remote_commitment_number ||
751
720
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
752
721
self . payment_preimages != other. payment_preimages ||
722
+ self . pending_htlcs_updated != other. pending_htlcs_updated ||
753
723
self . destination_script != other. destination_script ||
754
724
self . to_remote_rescue != other. to_remote_rescue ||
755
725
self . pending_claim_requests != other. pending_claim_requests ||
@@ -938,6 +908,11 @@ impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
938
908
writer. write_all ( & payment_preimage. 0 [ ..] ) ?;
939
909
}
940
910
911
+ writer. write_all ( & byte_utils:: be64_to_array ( self . pending_htlcs_updated . len ( ) as u64 ) ) ?;
912
+ for data in self . pending_htlcs_updated . iter ( ) {
913
+ data. write ( writer) ?;
914
+ }
915
+
941
916
self . last_block_hash . write ( writer) ?;
942
917
self . destination_script . write ( writer) ?;
943
918
if let Some ( ( ref to_remote_script, ref local_key) ) = self . to_remote_rescue {
@@ -1056,6 +1031,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1056
1031
current_remote_commitment_number : 1 << 48 ,
1057
1032
1058
1033
payment_preimages : HashMap :: new ( ) ,
1034
+ pending_htlcs_updated : Vec :: new ( ) ,
1035
+
1059
1036
destination_script : destination_script,
1060
1037
to_remote_rescue : None ,
1061
1038
@@ -1419,6 +1396,14 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1419
1396
res
1420
1397
}
1421
1398
1399
+ /// Get the list of HTLCs who's status has been updated on chain. This should be called by
1400
+ /// ChannelManager via ManyChannelMonitor::get_and_clear_pending_htlcs_updated().
1401
+ pub fn get_and_clear_pending_htlcs_updated ( & mut self ) -> Vec < HTLCUpdate > {
1402
+ let mut ret = Vec :: new ( ) ;
1403
+ mem:: swap ( & mut ret, & mut self . pending_htlcs_updated ) ;
1404
+ ret
1405
+ }
1406
+
1422
1407
/// Can only fail if idx is < get_min_seen_secret
1423
1408
pub ( super ) fn get_secret ( & self , idx : u64 ) -> Option < [ u8 ; 32 ] > {
1424
1409
for i in 0 ..self . old_secrets . len ( ) {
@@ -2402,7 +2387,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2402
2387
/// Eventually this should be pub and, roughly, implement ChainListener, however this requires
2403
2388
/// &mut self, as well as returns new spendable outputs and outpoints to watch for spending of
2404
2389
/// on-chain.
2405
- fn block_connected ( & mut self , txn_matched : & [ & Transaction ] , height : u32 , block_hash : & Sha256dHash , broadcaster : & BroadcasterInterface , fee_estimator : & FeeEstimator ) -> ( Vec < ( Sha256dHash , Vec < TxOut > ) > , Vec < SpendableOutputDescriptor > , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > ) {
2390
+ fn block_connected ( & mut self , txn_matched : & [ & Transaction ] , height : u32 , block_hash : & Sha256dHash , broadcaster : & BroadcasterInterface , fee_estimator : & FeeEstimator ) -> ( Vec < ( Sha256dHash , Vec < TxOut > ) > , Vec < SpendableOutputDescriptor > ) {
2406
2391
for tx in txn_matched {
2407
2392
let mut output_val = 0 ;
2408
2393
for out in tx. output . iter ( ) {
@@ -2415,7 +2400,6 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2415
2400
log_trace ! ( self , "Block {} at height {} connected with {} txn matched" , block_hash, height, txn_matched. len( ) ) ;
2416
2401
let mut watch_outputs = Vec :: new ( ) ;
2417
2402
let mut spendable_outputs = Vec :: new ( ) ;
2418
- let mut htlc_updated = Vec :: new ( ) ;
2419
2403
let mut bump_candidates = HashSet :: new ( ) ;
2420
2404
for tx in txn_matched {
2421
2405
if tx. input . len ( ) == 1 {
@@ -2474,10 +2458,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2474
2458
// While all commitment/HTLC-Success/HTLC-Timeout transactions have one input, HTLCs
2475
2459
// can also be resolved in a few other ways which can have more than one output. Thus,
2476
2460
// we call is_resolving_htlc_output here outside of the tx.input.len() == 1 check.
2477
- let mut updated = self . is_resolving_htlc_output ( & tx, height) ;
2478
- if updated. len ( ) > 0 {
2479
- htlc_updated. append ( & mut updated) ;
2480
- }
2461
+ self . is_resolving_htlc_output ( & tx, height) ;
2481
2462
2482
2463
// Scan all input to verify is one of the outpoint spent is of interest for us
2483
2464
let mut claimed_outputs_material = Vec :: new ( ) ;
@@ -2600,7 +2581,11 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2600
2581
} ,
2601
2582
OnchainEvent :: HTLCUpdate { htlc_update } => {
2602
2583
log_trace ! ( self , "HTLC {} failure update has got enough confirmations to be passed upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
2603
- htlc_updated. push ( ( htlc_update. 0 , None , htlc_update. 1 ) ) ;
2584
+ self . pending_htlcs_updated . push ( HTLCUpdate {
2585
+ payment_hash : htlc_update. 1 ,
2586
+ payment_preimage : None ,
2587
+ source : htlc_update. 0 ,
2588
+ } ) ;
2604
2589
} ,
2605
2590
OnchainEvent :: ContentiousOutpoint { outpoint, .. } => {
2606
2591
self . claimable_outpoints . remove ( & outpoint) ;
@@ -2632,7 +2617,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2632
2617
for & ( ref txid, ref output_scripts) in watch_outputs. iter ( ) {
2633
2618
self . outputs_to_watch . insert ( txid. clone ( ) , output_scripts. iter ( ) . map ( |o| o. script_pubkey . clone ( ) ) . collect ( ) ) ;
2634
2619
}
2635
- ( watch_outputs, spendable_outputs, htlc_updated )
2620
+ ( watch_outputs, spendable_outputs)
2636
2621
}
2637
2622
2638
2623
fn block_disconnected ( & mut self , height : u32 , block_hash : & Sha256dHash , broadcaster : & BroadcasterInterface , fee_estimator : & FeeEstimator ) {
@@ -2752,9 +2737,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2752
2737
2753
2738
/// Check if any transaction broadcasted is resolving HTLC output by a success or timeout on a local
2754
2739
/// or remote commitment tx, if so send back the source, preimage if found and payment_hash of resolved HTLC
2755
- fn is_resolving_htlc_output ( & mut self , tx : & Transaction , height : u32 ) -> Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > {
2756
- let mut htlc_updated = Vec :: new ( ) ;
2757
-
2740
+ fn is_resolving_htlc_output ( & mut self , tx : & Transaction , height : u32 ) {
2758
2741
' outer_loop: for input in & tx. input {
2759
2742
let mut payment_data = None ;
2760
2743
let revocation_sig_claim = ( input. witness . len ( ) == 3 && HTLCType :: scriptlen_to_htlctype ( input. witness [ 2 ] . len ( ) ) == Some ( HTLCType :: OfferedHTLC ) && input. witness [ 1 ] . len ( ) == 33 )
@@ -2854,10 +2837,18 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2854
2837
let mut payment_preimage = PaymentPreimage ( [ 0 ; 32 ] ) ;
2855
2838
if accepted_preimage_claim {
2856
2839
payment_preimage. 0 . copy_from_slice ( & input. witness [ 3 ] ) ;
2857
- htlc_updated. push ( ( source, Some ( payment_preimage) , payment_hash) ) ;
2840
+ self . pending_htlcs_updated . push ( HTLCUpdate {
2841
+ source,
2842
+ payment_preimage : Some ( payment_preimage) ,
2843
+ payment_hash
2844
+ } ) ;
2858
2845
} else if offered_preimage_claim {
2859
2846
payment_preimage. 0 . copy_from_slice ( & input. witness [ 1 ] ) ;
2860
- htlc_updated. push ( ( source, Some ( payment_preimage) , payment_hash) ) ;
2847
+ self . pending_htlcs_updated . push ( HTLCUpdate {
2848
+ source,
2849
+ payment_preimage : Some ( payment_preimage) ,
2850
+ payment_hash
2851
+ } ) ;
2861
2852
} else {
2862
2853
log_info ! ( self , "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height{})" , log_bytes!( payment_hash. 0 ) , height + ANTI_REORG_DELAY - 1 ) ;
2863
2854
match self . onchain_events_waiting_threshold_conf . entry ( height + ANTI_REORG_DELAY - 1 ) {
@@ -2880,7 +2871,6 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2880
2871
}
2881
2872
}
2882
2873
}
2883
- htlc_updated
2884
2874
}
2885
2875
2886
2876
/// Lightning security model (i.e being able to redeem/timeout HTLC or penalize coutnerparty onchain) lays on the assumption of claim transactions getting confirmed before timelock expiration
@@ -3221,6 +3211,12 @@ impl<R: ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArgs<R,
3221
3211
}
3222
3212
}
3223
3213
3214
+ let pending_htlcs_updated_len: u64 = Readable :: read ( reader) ?;
3215
+ let mut pending_htlcs_updated = Vec :: with_capacity ( cmp:: min ( pending_htlcs_updated_len as usize , MAX_ALLOC_SIZE / ( 32 + 8 * 3 ) ) ) ;
3216
+ for _ in 0 ..pending_htlcs_updated_len {
3217
+ pending_htlcs_updated. push ( Readable :: read ( reader) ?) ;
3218
+ }
3219
+
3224
3220
let last_block_hash: Sha256dHash = Readable :: read ( reader) ?;
3225
3221
let destination_script = Readable :: read ( reader) ?;
3226
3222
let to_remote_rescue = match <u8 as Readable < R > >:: read ( reader) ? {
@@ -3321,6 +3317,7 @@ impl<R: ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArgs<R,
3321
3317
current_remote_commitment_number,
3322
3318
3323
3319
payment_preimages,
3320
+ pending_htlcs_updated,
3324
3321
3325
3322
destination_script,
3326
3323
to_remote_rescue,
0 commit comments