@@ -123,8 +123,12 @@ pub trait ManyChannelMonitor<ChanSigner: ChannelKeys>: Send + Sync {
123
123
fn add_update_monitor ( & self , funding_txo : OutPoint , monitor : ChannelMonitor < ChanSigner > ) -> Result < ( ) , ChannelMonitorUpdateErr > ;
124
124
125
125
/// Used by ChannelManager to get list of HTLC resolved onchain and which needed to be updated
126
- /// with success or failure backward
127
- fn fetch_pending_htlc_updated ( & self ) -> Vec < HTLCUpdate > ;
126
+ /// with success or failure.
127
+ ///
128
+ /// You should probably just call through to
129
+ /// ChannelMonitor::get_and_clear_pending_htlcs_updated() for each ChannelMonitor and return
130
+ /// the full list.
131
+ fn get_and_clear_pending_htlcs_updated ( & self ) -> Vec < HTLCUpdate > ;
128
132
}
129
133
130
134
/// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a
@@ -146,7 +150,6 @@ pub struct SimpleManyChannelMonitor<Key, ChanSigner: ChannelKeys> {
146
150
chain_monitor : Arc < ChainWatchInterface > ,
147
151
broadcaster : Arc < BroadcasterInterface > ,
148
152
pending_events : Mutex < Vec < events:: Event > > ,
149
- pending_htlc_updated : Mutex < HashMap < PaymentHash , Vec < ( HTLCSource , Option < PaymentPreimage > ) > > > ,
150
153
logger : Arc < Logger > ,
151
154
fee_estimator : Arc < FeeEstimator >
152
155
}
@@ -155,11 +158,10 @@ impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys> ChainListen
155
158
fn block_connected ( & self , header : & BlockHeader , height : u32 , txn_matched : & [ & Transaction ] , _indexes_of_txn_matched : & [ u32 ] ) {
156
159
let block_hash = header. bitcoin_hash ( ) ;
157
160
let mut new_events: Vec < events:: Event > = Vec :: with_capacity ( 0 ) ;
158
- let mut htlc_updated_infos = Vec :: new ( ) ;
159
161
{
160
162
let mut monitors = self . monitors . lock ( ) . unwrap ( ) ;
161
163
for monitor in monitors. values_mut ( ) {
162
- let ( txn_outputs, spendable_outputs, mut htlc_updated ) = monitor. block_connected ( txn_matched, height, & block_hash, & * self . broadcaster , & * self . fee_estimator ) ;
164
+ let ( txn_outputs, spendable_outputs) = monitor. block_connected ( txn_matched, height, & block_hash, & * self . broadcaster , & * self . fee_estimator ) ;
163
165
if spendable_outputs. len ( ) > 0 {
164
166
new_events. push ( events:: Event :: SpendableOutputs {
165
167
outputs : spendable_outputs,
@@ -171,35 +173,6 @@ impl<'a, Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys> ChainListen
171
173
self . chain_monitor . install_watch_outpoint ( ( txid. clone ( ) , idx as u32 ) , & output. script_pubkey ) ;
172
174
}
173
175
}
174
- htlc_updated_infos. append ( & mut htlc_updated) ;
175
- }
176
- }
177
- {
178
- // ChannelManager will just need to fetch pending_htlc_updated and pass state backward
179
- let mut pending_htlc_updated = self . pending_htlc_updated . lock ( ) . unwrap ( ) ;
180
- for htlc in htlc_updated_infos. drain ( ..) {
181
- match pending_htlc_updated. entry ( htlc. 2 ) {
182
- hash_map:: Entry :: Occupied ( mut e) => {
183
- // In case of reorg we may have htlc outputs solved in a different way so
184
- // we prefer to keep claims but don't store duplicate updates for a given
185
- // (payment_hash, HTLCSource) pair.
186
- let mut existing_claim = false ;
187
- e. get_mut ( ) . retain ( |htlc_data| {
188
- if htlc. 0 == htlc_data. 0 {
189
- if htlc_data. 1 . is_some ( ) {
190
- existing_claim = true ;
191
- true
192
- } else { false }
193
- } else { true }
194
- } ) ;
195
- if !existing_claim {
196
- e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
197
- }
198
- }
199
- hash_map:: Entry :: Vacant ( e) => {
200
- e. insert ( vec ! [ ( htlc. 0 , htlc. 1 ) ] ) ;
201
- }
202
- }
203
176
}
204
177
}
205
178
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
@@ -224,7 +197,6 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static, ChanSigner: ChannelKeys> Simpl
224
197
chain_monitor,
225
198
broadcaster,
226
199
pending_events : Mutex :: new ( Vec :: new ( ) ) ,
227
- pending_htlc_updated : Mutex :: new ( HashMap :: new ( ) ) ,
228
200
logger,
229
201
fee_estimator : feeest,
230
202
} ;
@@ -272,17 +244,10 @@ impl<ChanSigner: ChannelKeys> ManyChannelMonitor<ChanSigner> for SimpleManyChann
272
244
}
273
245
}
274
246
275
- fn fetch_pending_htlc_updated ( & self ) -> Vec < HTLCUpdate > {
276
- let mut updated = self . pending_htlc_updated . lock ( ) . unwrap ( ) ;
277
- let mut pending_htlcs_updated = Vec :: with_capacity ( updated. len ( ) ) ;
278
- for ( k, v) in updated. drain ( ) {
279
- for htlc_data in v {
280
- pending_htlcs_updated. push ( HTLCUpdate {
281
- payment_hash : k,
282
- payment_preimage : htlc_data. 1 ,
283
- source : htlc_data. 0 ,
284
- } ) ;
285
- }
247
+ fn get_and_clear_pending_htlcs_updated ( & self ) -> Vec < HTLCUpdate > {
248
+ let mut pending_htlcs_updated = Vec :: new ( ) ;
249
+ for chan in self . monitors . lock ( ) . unwrap ( ) . values_mut ( ) {
250
+ pending_htlcs_updated. append ( & mut chan. get_and_clear_pending_htlcs_updated ( ) ) ;
286
251
}
287
252
pending_htlcs_updated
288
253
}
@@ -628,6 +593,8 @@ pub struct ChannelMonitor<ChanSigner: ChannelKeys> {
628
593
629
594
payment_preimages : HashMap < PaymentHash , PaymentPreimage > ,
630
595
596
+ pending_htlcs_updated : HashMap < PaymentHash , Vec < ( HTLCSource , Option < PaymentPreimage > ) > > ,
597
+
631
598
destination_script : Script ,
632
599
// Thanks to data loss protection, we may be able to claim our non-htlc funds
633
600
// back, this is the script we have to spend from but we need to
@@ -732,6 +699,7 @@ impl<ChanSigner: ChannelKeys> PartialEq for ChannelMonitor<ChanSigner> {
732
699
self . current_remote_commitment_number != other. current_remote_commitment_number ||
733
700
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
734
701
self . payment_preimages != other. payment_preimages ||
702
+ self . pending_htlcs_updated != other. pending_htlcs_updated ||
735
703
self . destination_script != other. destination_script ||
736
704
self . to_remote_rescue != other. to_remote_rescue ||
737
705
self . pending_claim_requests != other. pending_claim_requests ||
@@ -919,6 +887,16 @@ impl<ChanSigner: ChannelKeys + Writeable> ChannelMonitor<ChanSigner> {
919
887
writer. write_all ( & payment_preimage. 0 [ ..] ) ?;
920
888
}
921
889
890
+ writer. write_all ( & byte_utils:: be64_to_array ( self . pending_htlcs_updated . len ( ) as u64 ) ) ?;
891
+ for ( payment_hash, data) in self . pending_htlcs_updated . iter ( ) {
892
+ writer. write_all ( & payment_hash. 0 [ ..] ) ?;
893
+ writer. write_all ( & byte_utils:: be64_to_array ( data. len ( ) as u64 ) ) ?;
894
+ for & ( ref source, ref payment_preimage) in data. iter ( ) {
895
+ source. write ( writer) ?;
896
+ write_option ! ( payment_preimage) ;
897
+ }
898
+ }
899
+
922
900
self . last_block_hash . write ( writer) ?;
923
901
self . destination_script . write ( writer) ?;
924
902
if let Some ( ( ref to_remote_script, ref local_key) ) = self . to_remote_rescue {
@@ -1028,6 +1006,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1028
1006
current_remote_commitment_number : 1 << 48 ,
1029
1007
1030
1008
payment_preimages : HashMap :: new ( ) ,
1009
+ pending_htlcs_updated : HashMap :: new ( ) ,
1010
+
1031
1011
destination_script : destination_script,
1032
1012
to_remote_rescue : None ,
1033
1013
@@ -1384,6 +1364,22 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1384
1364
res
1385
1365
}
1386
1366
1367
+ /// Get the list of HTLCs who's status has been updated on chain. This should be called by
1368
+ /// ChannelManager via ManyChannelMonitor::get_and_clear_pending_htlcs_updated().
1369
+ pub fn get_and_clear_pending_htlcs_updated ( & mut self ) -> Vec < HTLCUpdate > {
1370
+ let mut pending_htlcs_updated = Vec :: with_capacity ( self . pending_htlcs_updated . len ( ) ) ;
1371
+ for ( k, v) in self . pending_htlcs_updated . drain ( ) {
1372
+ for htlc_data in v {
1373
+ pending_htlcs_updated. push ( HTLCUpdate {
1374
+ payment_hash : k,
1375
+ payment_preimage : htlc_data. 1 ,
1376
+ source : htlc_data. 0 ,
1377
+ } ) ;
1378
+ }
1379
+ }
1380
+ pending_htlcs_updated
1381
+ }
1382
+
1387
1383
/// Can only fail if idx is < get_min_seen_secret
1388
1384
pub ( super ) fn get_secret ( & self , idx : u64 ) -> Option < [ u8 ; 32 ] > {
1389
1385
for i in 0 ..self . old_secrets . len ( ) {
@@ -2362,7 +2358,35 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2362
2358
}
2363
2359
}
2364
2360
2365
- 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 ) > ) {
2361
+ fn append_htlc_updated ( & mut self , mut htlc_updated_infos : Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > ) {
2362
+ // ChannelManager will just need to fetch pending_htlcs_updated and pass state backward
2363
+ for htlc in htlc_updated_infos. drain ( ..) {
2364
+ match self . pending_htlcs_updated . entry ( htlc. 2 ) {
2365
+ hash_map:: Entry :: Occupied ( mut e) => {
2366
+ // In case of reorg we may have htlc outputs solved in a different way so
2367
+ // we prefer to keep claims but don't store duplicate updates for a given
2368
+ // (payment_hash, HTLCSource) pair.
2369
+ let mut existing_claim = false ;
2370
+ e. get_mut ( ) . retain ( |htlc_data| {
2371
+ if htlc. 0 == htlc_data. 0 {
2372
+ if htlc_data. 1 . is_some ( ) {
2373
+ existing_claim = true ;
2374
+ true
2375
+ } else { false }
2376
+ } else { true }
2377
+ } ) ;
2378
+ if !existing_claim {
2379
+ e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
2380
+ }
2381
+ }
2382
+ hash_map:: Entry :: Vacant ( e) => {
2383
+ e. insert ( vec ! [ ( htlc. 0 , htlc. 1 ) ] ) ;
2384
+ }
2385
+ }
2386
+ }
2387
+ }
2388
+
2389
+ fn block_connected ( & mut self , txn_matched : & [ & Transaction ] , height : u32 , block_hash : & Sha256dHash , broadcaster : & BroadcasterInterface , fee_estimator : & FeeEstimator ) -> ( Vec < ( Sha256dHash , Vec < TxOut > ) > , Vec < SpendableOutputDescriptor > ) {
2366
2390
for tx in txn_matched {
2367
2391
let mut output_val = 0 ;
2368
2392
for out in tx. output . iter ( ) {
@@ -2375,7 +2399,6 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2375
2399
log_trace ! ( self , "Block {} at height {} connected with {} txn matched" , block_hash, height, txn_matched. len( ) ) ;
2376
2400
let mut watch_outputs = Vec :: new ( ) ;
2377
2401
let mut spendable_outputs = Vec :: new ( ) ;
2378
- let mut htlc_updated = Vec :: new ( ) ;
2379
2402
let mut bump_candidates = HashSet :: new ( ) ;
2380
2403
for tx in txn_matched {
2381
2404
if tx. input . len ( ) == 1 {
@@ -2434,10 +2457,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2434
2457
// While all commitment/HTLC-Success/HTLC-Timeout transactions have one input, HTLCs
2435
2458
// can also be resolved in a few other ways which can have more than one output. Thus,
2436
2459
// we call is_resolving_htlc_output here outside of the tx.input.len() == 1 check.
2437
- let mut updated = self . is_resolving_htlc_output ( & tx, height) ;
2438
- if updated. len ( ) > 0 {
2439
- htlc_updated. append ( & mut updated) ;
2440
- }
2460
+ let htlcs_updated = self . is_resolving_htlc_output ( & tx, height) ;
2461
+ self . append_htlc_updated ( htlcs_updated) ;
2441
2462
2442
2463
// Scan all input to verify is one of the outpoint spent is of interest for us
2443
2464
let mut claimed_outputs_material = Vec :: new ( ) ;
@@ -2560,7 +2581,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2560
2581
} ,
2561
2582
OnchainEvent :: HTLCUpdate { htlc_update } => {
2562
2583
log_trace ! ( self , "HTLC {} failure update has got enough confirmations to be passed upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
2563
- htlc_updated . push ( ( htlc_update. 0 , None , htlc_update. 1 ) ) ;
2584
+ self . append_htlc_updated ( vec ! [ ( htlc_update. 0 , None , htlc_update. 1 ) ] ) ;
2564
2585
} ,
2565
2586
OnchainEvent :: ContentiousOutpoint { outpoint, .. } => {
2566
2587
self . claimable_outpoints . remove ( & outpoint) ;
@@ -2589,7 +2610,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
2589
2610
}
2590
2611
}
2591
2612
self . last_block_hash = block_hash. clone ( ) ;
2592
- ( watch_outputs, spendable_outputs, htlc_updated )
2613
+ ( watch_outputs, spendable_outputs)
2593
2614
}
2594
2615
2595
2616
fn block_disconnected ( & mut self , height : u32 , block_hash : & Sha256dHash , broadcaster : & BroadcasterInterface , fee_estimator : & FeeEstimator ) {
@@ -3178,6 +3199,20 @@ impl<R: ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArgs<R,
3178
3199
}
3179
3200
}
3180
3201
3202
+ let pending_htlcs_updated_len: u64 = Readable :: read ( reader) ?;
3203
+ let mut pending_htlcs_updated = HashMap :: with_capacity ( cmp:: min ( pending_htlcs_updated_len as usize , MAX_ALLOC_SIZE / ( 32 + 8 * 3 ) ) ) ;
3204
+ for _ in 0 ..pending_htlcs_updated_len {
3205
+ let payment_hash: PaymentHash = Readable :: read ( reader) ?;
3206
+ let htlcs_len: u64 = Readable :: read ( reader) ?;
3207
+ let mut htlcs = Vec :: with_capacity ( cmp:: min ( htlcs_len as usize , MAX_ALLOC_SIZE / 64 ) ) ;
3208
+ for _ in 0 ..htlcs_len {
3209
+ htlcs. push ( ( Readable :: read ( reader) ?, Readable :: read ( reader) ?) ) ;
3210
+ }
3211
+ if let Some ( _) = pending_htlcs_updated. insert ( payment_hash, htlcs) {
3212
+ return Err ( DecodeError :: InvalidValue ) ;
3213
+ }
3214
+ }
3215
+
3181
3216
let last_block_hash: Sha256dHash = Readable :: read ( reader) ?;
3182
3217
let destination_script = Readable :: read ( reader) ?;
3183
3218
let to_remote_rescue = match <u8 as Readable < R > >:: read ( reader) ? {
@@ -3264,6 +3299,7 @@ impl<R: ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArgs<R,
3264
3299
current_remote_commitment_number,
3265
3300
3266
3301
payment_preimages,
3302
+ pending_htlcs_updated,
3267
3303
3268
3304
destination_script,
3269
3305
to_remote_rescue,
0 commit comments