@@ -127,8 +127,12 @@ pub trait ManyChannelMonitor<ChanSigner: ChannelKeys>: Send + Sync {
127
127
fn add_update_monitor ( & self , funding_txo : OutPoint , monitor : ChannelMonitor < ChanSigner > ) -> Result < ( ) , ChannelMonitorUpdateErr > ;
128
128
129
129
/// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
130
- /// with success or failure backward
131
- fn fetch_pending_htlc_updated ( & self ) -> Vec < HTLCUpdate > ;
130
+ /// with success or failure.
131
+ ///
132
+ /// You should probably just call through to
133
+ /// ChannelMonitor::get_and_clear_pending_htlcs_updated() for each ChannelMonitor and return
134
+ /// the full list.
135
+ fn get_and_clear_pending_htlcs_updated ( & self ) -> Vec < HTLCUpdate > ;
132
136
}
133
137
134
138
/// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a
@@ -150,7 +154,6 @@ pub struct SimpleManyChannelMonitor<Key, ChanSigner: ChannelKeys> {
150
154
chain_monitor : Arc < ChainWatchInterface > ,
151
155
broadcaster : Arc < BroadcasterInterface > ,
152
156
pending_events : Mutex < Vec < events:: Event > > ,
153
- pending_htlc_updated : Mutex < HashMap < PaymentHash , Vec < ( HTLCSource , Option < PaymentPreimage > ) > > > ,
154
157
logger : Arc < Logger > ,
155
158
fee_estimator : Arc < FeeEstimator >
156
159
}
@@ -159,11 +162,10 @@ impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys> ChainListen
159
162
fn block_connected ( & self , header : & BlockHeader , height : u32 , txn_matched : & [ & Transaction ] , _indexes_of_txn_matched : & [ u32 ] ) {
160
163
let block_hash = header. bitcoin_hash ( ) ;
161
164
let mut new_events: Vec < events:: Event > = Vec :: with_capacity ( 0 ) ;
162
- let mut htlc_updated_infos = Vec :: new ( ) ;
163
165
{
164
166
let mut monitors = self . monitors . lock ( ) . unwrap ( ) ;
165
167
for monitor in monitors. values_mut ( ) {
166
- let ( txn_outputs, spendable_outputs, mut htlc_updated ) = monitor. block_connected ( txn_matched, height, & block_hash, & * self . broadcaster , & * self . fee_estimator ) ;
168
+ let ( txn_outputs, spendable_outputs) = monitor. block_connected ( txn_matched, height, & block_hash, & * self . broadcaster , & * self . fee_estimator ) ;
167
169
if spendable_outputs. len ( ) > 0 {
168
170
new_events. push ( events:: Event :: SpendableOutputs {
169
171
outputs : spendable_outputs,
@@ -175,35 +177,6 @@ impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys> ChainListen
175
177
self . chain_monitor . install_watch_outpoint ( ( txid. clone ( ) , idx as u32 ) , & output. script_pubkey ) ;
176
178
}
177
179
}
178
- htlc_updated_infos. append ( & mut htlc_updated) ;
179
- }
180
- }
181
- {
182
- // ChannelManager will just need to fetch pending_htlc_updated and pass state backward
183
- let mut pending_htlc_updated = self . pending_htlc_updated . lock ( ) . unwrap ( ) ;
184
- for htlc in htlc_updated_infos. drain ( ..) {
185
- match pending_htlc_updated. entry ( htlc. 2 ) {
186
- hash_map:: Entry :: Occupied ( mut e) => {
187
- // In case of reorg we may have htlc outputs solved in a different way so
188
- // we prefer to keep claims but don't store duplicate updates for a given
189
- // (payment_hash, HTLCSource) pair.
190
- let mut existing_claim = false ;
191
- e. get_mut ( ) . retain ( |htlc_data| {
192
- if htlc. 0 == htlc_data. 0 {
193
- if htlc_data. 1 . is_some ( ) {
194
- existing_claim = true ;
195
- true
196
- } else { false }
197
- } else { true }
198
- } ) ;
199
- if !existing_claim {
200
- e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
201
- }
202
- }
203
- hash_map:: Entry :: Vacant ( e) => {
204
- e. insert ( vec ! [ ( htlc. 0 , htlc. 1 ) ] ) ;
205
- }
206
- }
207
180
}
208
181
}
209
182
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
@@ -228,7 +201,6 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static, ChanSigner: ChannelKeys> Simpl
228
201
chain_monitor,
229
202
broadcaster,
230
203
pending_events : Mutex :: new ( Vec :: new ( ) ) ,
231
- pending_htlc_updated : Mutex :: new ( HashMap :: new ( ) ) ,
232
204
logger,
233
205
fee_estimator : feeest,
234
206
} ;
@@ -281,17 +253,10 @@ impl<ChanSigner: ChannelKeys> ManyChannelMonitor<ChanSigner> for SimpleManyChann
281
253
}
282
254
}
283
255
284
- fn fetch_pending_htlc_updated ( & self ) -> Vec < HTLCUpdate > {
285
- let mut updated = self . pending_htlc_updated . lock ( ) . unwrap ( ) ;
286
- let mut pending_htlcs_updated = Vec :: with_capacity ( updated. len ( ) ) ;
287
- for ( k, v) in updated. drain ( ) {
288
- for htlc_data in v {
289
- pending_htlcs_updated. push ( HTLCUpdate {
290
- payment_hash : k,
291
- payment_preimage : htlc_data. 1 ,
292
- source : htlc_data. 0 ,
293
- } ) ;
294
- }
256
+ fn get_and_clear_pending_htlcs_updated ( & self ) -> Vec < HTLCUpdate > {
257
+ let mut pending_htlcs_updated = Vec :: new ( ) ;
258
+ for chan in self . monitors . lock ( ) . unwrap ( ) . values_mut ( ) {
259
+ pending_htlcs_updated. append ( & mut chan. get_and_clear_pending_htlcs_updated ( ) ) ;
295
260
}
296
261
pending_htlcs_updated
297
262
}
@@ -637,6 +602,8 @@ pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
637
602
638
603
payment_preimages : HashMap < PaymentHash , PaymentPreimage > ,
639
604
605
+ pending_htlcs_updated : HashMap < PaymentHash , Vec < ( HTLCSource , Option < PaymentPreimage > ) > > ,
606
+
640
607
destination_script : Script ,
641
608
// Thanks to data loss protection, we may be able to claim our non-htlc funds
642
609
// back, this is the script we have to spend from but we need to
@@ -747,6 +714,7 @@ impl<ChanSigner: ChannelKeys> PartialEq for ChannelMonitor<ChanSigner> {
747
714
self . current_remote_commitment_number != other. current_remote_commitment_number ||
748
715
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
749
716
self . payment_preimages != other. payment_preimages ||
717
+ self . pending_htlcs_updated != other. pending_htlcs_updated ||
750
718
self . destination_script != other. destination_script ||
751
719
self . to_remote_rescue != other. to_remote_rescue ||
752
720
self . pending_claim_requests != other. pending_claim_requests ||
@@ -935,6 +903,16 @@ impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
935
903
writer. write_all ( & payment_preimage. 0 [ ..] ) ?;
936
904
}
937
905
906
+ writer. write_all ( & byte_utils:: be64_to_array ( self . pending_htlcs_updated . len ( ) as u64 ) ) ?;
907
+ for ( payment_hash, data) in self . pending_htlcs_updated . iter ( ) {
908
+ writer. write_all ( & payment_hash. 0 [ ..] ) ?;
909
+ writer. write_all ( & byte_utils:: be64_to_array ( data. len ( ) as u64 ) ) ?;
910
+ for & ( ref source, ref payment_preimage) in data. iter ( ) {
911
+ source. write ( writer) ?;
912
+ write_option ! ( payment_preimage) ;
913
+ }
914
+ }
915
+
938
916
self . last_block_hash . write ( writer) ?;
939
917
self . destination_script . write ( writer) ?;
940
918
if let Some ( ( ref to_remote_script, ref local_key) ) = self . to_remote_rescue {
@@ -1053,6 +1031,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1053
1031
current_remote_commitment_number : 1 << 48 ,
1054
1032
1055
1033
payment_preimages : HashMap :: new ( ) ,
1034
+ pending_htlcs_updated : HashMap :: new ( ) ,
1035
+
1056
1036
destination_script : destination_script,
1057
1037
to_remote_rescue : None ,
1058
1038
@@ -1416,6 +1396,22 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1416
1396
res
1417
1397
}
1418
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 pending_htlcs_updated = Vec :: with_capacity ( self . pending_htlcs_updated . len ( ) ) ;
1403
+ for ( k, v) in self . pending_htlcs_updated . drain ( ) {
1404
+ for htlc_data in v {
1405
+ pending_htlcs_updated. push ( HTLCUpdate {
1406
+ payment_hash : k,
1407
+ payment_preimage : htlc_data. 1 ,
1408
+ source : htlc_data. 0 ,
1409
+ } ) ;
1410
+ }
1411
+ }
1412
+ pending_htlcs_updated
1413
+ }
1414
+
1419
1415
/// Can only fail if idx is < get_min_seen_secret
1420
1416
pub ( super ) fn get_secret ( & self , idx : u64 ) -> Option < [ u8 ; 32 ] > {
1421
1417
for i in 0 ..self . old_secrets . len ( ) {
@@ -2394,11 +2390,39 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2394
2390
}
2395
2391
}
2396
2392
2393
+ fn append_htlc_updated ( & mut self , mut htlc_updated_infos : Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > ) {
2394
+ // ChannelManager will just need to fetch pending_htlcs_updated and pass state backward
2395
+ for htlc in htlc_updated_infos. drain ( ..) {
2396
+ match self . pending_htlcs_updated . entry ( htlc. 2 ) {
2397
+ hash_map:: Entry :: Occupied ( mut e) => {
2398
+ // In case of reorg we may have htlc outputs solved in a different way so
2399
+ // we prefer to keep claims but don't store duplicate updates for a given
2400
+ // (payment_hash, HTLCSource) pair.
2401
+ let mut existing_claim = false ;
2402
+ e. get_mut ( ) . retain ( |htlc_data| {
2403
+ if htlc. 0 == htlc_data. 0 {
2404
+ if htlc_data. 1 . is_some ( ) {
2405
+ existing_claim = true ;
2406
+ true
2407
+ } else { false }
2408
+ } else { true }
2409
+ } ) ;
2410
+ if !existing_claim {
2411
+ e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
2412
+ }
2413
+ }
2414
+ hash_map:: Entry :: Vacant ( e) => {
2415
+ e. insert ( vec ! [ ( htlc. 0 , htlc. 1 ) ] ) ;
2416
+ }
2417
+ }
2418
+ }
2419
+ }
2420
+
2397
2421
/// Called by ChannelMonitor::block_connected, which implements ChainListener::block_connected.
2398
2422
/// Eventually this should be pub and, roughly, implement ChainListener, however this requires
2399
2423
/// &mut self, as well as returns new spendable outputs and outpoints to watch for spending of
2400
2424
/// on-chain.
2401
- 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 ) > ) {
2425
+ fn block_connected ( & mut self , txn_matched : & [ & Transaction ] , height : u32 , block_hash : & Sha256dHash , broadcaster : & BroadcasterInterface , fee_estimator : & FeeEstimator ) -> ( Vec < ( Sha256dHash , Vec < TxOut > ) > , Vec < SpendableOutputDescriptor > ) {
2402
2426
for tx in txn_matched {
2403
2427
let mut output_val = 0 ;
2404
2428
for out in tx. output . iter ( ) {
@@ -2411,7 +2435,6 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2411
2435
log_trace ! ( self , "Block {} at height {} connected with {} txn matched" , block_hash, height, txn_matched. len( ) ) ;
2412
2436
let mut watch_outputs = Vec :: new ( ) ;
2413
2437
let mut spendable_outputs = Vec :: new ( ) ;
2414
- let mut htlc_updated = Vec :: new ( ) ;
2415
2438
let mut bump_candidates = HashSet :: new ( ) ;
2416
2439
for tx in txn_matched {
2417
2440
if tx. input . len ( ) == 1 {
@@ -2470,10 +2493,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2470
2493
// While all commitment/HTLC-Success/HTLC-Timeout transactions have one input, HTLCs
2471
2494
// can also be resolved in a few other ways which can have more than one output. Thus,
2472
2495
// we call is_resolving_htlc_output here outside of the tx.input.len() == 1 check.
2473
- let mut updated = self . is_resolving_htlc_output ( & tx, height) ;
2474
- if updated. len ( ) > 0 {
2475
- htlc_updated. append ( & mut updated) ;
2476
- }
2496
+ let htlcs_updated = self . is_resolving_htlc_output ( & tx, height) ;
2497
+ self . append_htlc_updated ( htlcs_updated) ;
2477
2498
2478
2499
// Scan all input to verify is one of the outpoint spent is of interest for us
2479
2500
let mut claimed_outputs_material = Vec :: new ( ) ;
@@ -2596,7 +2617,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2596
2617
} ,
2597
2618
OnchainEvent :: HTLCUpdate { htlc_update } => {
2598
2619
log_trace ! ( self , "HTLC {} failure update has got enough confirmations to be passed upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
2599
- htlc_updated . push ( ( htlc_update. 0 , None , htlc_update. 1 ) ) ;
2620
+ self . append_htlc_updated ( vec ! [ ( htlc_update. 0 , None , htlc_update. 1 ) ] ) ;
2600
2621
} ,
2601
2622
OnchainEvent :: ContentiousOutpoint { outpoint, .. } => {
2602
2623
self . claimable_outpoints . remove ( & outpoint) ;
@@ -2628,7 +2649,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2628
2649
for & ( ref txid, ref output_scripts) in watch_outputs. iter ( ) {
2629
2650
self . outputs_to_watch . insert ( txid. clone ( ) , output_scripts. iter ( ) . map ( |o| o. script_pubkey . clone ( ) ) . collect ( ) ) ;
2630
2651
}
2631
- ( watch_outputs, spendable_outputs, htlc_updated )
2652
+ ( watch_outputs, spendable_outputs)
2632
2653
}
2633
2654
2634
2655
fn block_disconnected ( & mut self , height : u32 , block_hash : & Sha256dHash , broadcaster : & BroadcasterInterface , fee_estimator : & FeeEstimator ) {
@@ -3217,6 +3238,20 @@ impl<R: ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArgs<R,
3217
3238
}
3218
3239
}
3219
3240
3241
+ let pending_htlcs_updated_len: u64 = Readable :: read ( reader) ?;
3242
+ let mut pending_htlcs_updated = HashMap :: with_capacity ( cmp:: min ( pending_htlcs_updated_len as usize , MAX_ALLOC_SIZE / ( 32 + 8 * 3 ) ) ) ;
3243
+ for _ in 0 ..pending_htlcs_updated_len {
3244
+ let payment_hash: PaymentHash = Readable :: read ( reader) ?;
3245
+ let htlcs_len: u64 = Readable :: read ( reader) ?;
3246
+ let mut htlcs = Vec :: with_capacity ( cmp:: min ( htlcs_len as usize , MAX_ALLOC_SIZE / 64 ) ) ;
3247
+ for _ in 0 ..htlcs_len {
3248
+ htlcs. push ( ( Readable :: read ( reader) ?, Readable :: read ( reader) ?) ) ;
3249
+ }
3250
+ if let Some ( _) = pending_htlcs_updated. insert ( payment_hash, htlcs) {
3251
+ return Err ( DecodeError :: InvalidValue ) ;
3252
+ }
3253
+ }
3254
+
3220
3255
let last_block_hash: Sha256dHash = Readable :: read ( reader) ?;
3221
3256
let destination_script = Readable :: read ( reader) ?;
3222
3257
let to_remote_rescue = match <u8 as Readable < R > >:: read ( reader) ? {
@@ -3317,6 +3352,7 @@ impl<R: ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArgs<R,
3317
3352
current_remote_commitment_number,
3318
3353
3319
3354
payment_preimages,
3355
+ pending_htlcs_updated,
3320
3356
3321
3357
destination_script,
3322
3358
to_remote_rescue,
0 commit comments