@@ -40,15 +40,16 @@ use ln::chan_utils;
40
40
use ln:: chan_utils:: { CounterpartyCommitmentSecrets , HTLCOutputInCommitment , HolderCommitmentTransaction , HTLCType } ;
41
41
use ln:: channelmanager:: { HTLCSource , PaymentPreimage , PaymentHash } ;
42
42
use ln:: onchaintx:: { OnchainTxHandler , InputDescriptors } ;
43
- use chain:: chaininterface:: { ChainListener , ChainWatchInterface , BroadcasterInterface , FeeEstimator } ;
43
+ use chain;
44
+ use chain:: chaininterface:: { ChainListener , ChainWatchInterface , ChainWatchedUtil , BroadcasterInterface , FeeEstimator } ;
44
45
use chain:: transaction:: OutPoint ;
45
46
use chain:: keysinterface:: { SpendableOutputDescriptor , ChannelKeys } ;
46
47
use util:: logger:: Logger ;
47
48
use util:: ser:: { Readable , MaybeReadable , Writer , Writeable , U48 } ;
48
49
use util:: { byte_utils, events} ;
49
50
use util:: events:: Event ;
50
51
51
- use std:: collections:: { HashMap , hash_map} ;
52
+ use std:: collections:: { HashMap , HashSet , hash_map} ;
52
53
use std:: sync:: Mutex ;
53
54
use std:: { hash, cmp, mem} ;
54
55
use std:: ops:: Deref ;
@@ -198,12 +199,74 @@ pub struct SimpleManyChannelMonitor<Key, ChanSigner: ChannelKeys, T: Deref, F: D
198
199
{
199
200
/// The monitors
200
201
pub monitors : Mutex < HashMap < Key , ChannelMonitor < ChanSigner > > > ,
202
+ watch_events : Mutex < WatchEventQueue > ,
201
203
chain_monitor : C ,
202
204
broadcaster : T ,
203
205
logger : L ,
204
206
fee_estimator : F
205
207
}
206
208
209
+ struct WatchEventQueue {
210
+ watched : ChainWatchedUtil ,
211
+ events : Vec < chain:: WatchEvent > ,
212
+ }
213
+
214
+ impl WatchEventQueue {
215
+ fn new ( ) -> Self {
216
+ Self {
217
+ watched : ChainWatchedUtil :: new ( ) ,
218
+ events : Vec :: new ( ) ,
219
+ }
220
+ }
221
+
222
+ fn watch_tx ( & mut self , txid : & Txid , script_pubkey : & Script ) {
223
+ if self . watched . register_tx ( txid, script_pubkey) {
224
+ self . events . push ( chain:: WatchEvent :: WatchTransaction {
225
+ txid : * txid,
226
+ script_pubkey : script_pubkey. clone ( )
227
+ } ) ;
228
+ }
229
+ }
230
+
231
+ fn watch_output ( & mut self , outpoint : ( & Txid , usize ) , script_pubkey : & Script ) {
232
+ let ( txid, index) = outpoint;
233
+ if self . watched . register_outpoint ( ( * txid, index as u32 ) , script_pubkey) {
234
+ self . events . push ( chain:: WatchEvent :: WatchOutput {
235
+ outpoint : OutPoint {
236
+ txid : * txid,
237
+ index : index as u16 ,
238
+ } ,
239
+ script_pubkey : script_pubkey. clone ( ) ,
240
+ } ) ;
241
+ }
242
+ }
243
+
244
+ fn dequeue_events ( & mut self ) -> Vec < chain:: WatchEvent > {
245
+ let mut pending_events = Vec :: with_capacity ( self . events . len ( ) ) ;
246
+ pending_events. append ( & mut self . events ) ;
247
+ pending_events
248
+ }
249
+
250
+ fn filter_block < ' a > ( & self , txdata : & [ ( usize , & ' a Transaction ) ] ) -> Vec < ( usize , & ' a Transaction ) > {
251
+ let mut matched_txids = HashSet :: new ( ) ;
252
+ txdata. iter ( ) . filter ( |& & ( _, tx) | {
253
+ // A tx matches the filter if it either matches the filter directly (via does_match_tx)
254
+ // or if it is a descendant of another matched transaction within the same block.
255
+ let mut matched = self . watched . does_match_tx ( tx) ;
256
+ for input in tx. input . iter ( ) {
257
+ if matched || matched_txids. contains ( & input. previous_output . txid ) {
258
+ matched = true ;
259
+ break ;
260
+ }
261
+ }
262
+ if matched {
263
+ matched_txids. insert ( tx. txid ( ) ) ;
264
+ }
265
+ matched
266
+ } ) . map ( |e| * e) . collect ( )
267
+ }
268
+ }
269
+
207
270
impl < Key : Send + cmp:: Eq + hash:: Hash , ChanSigner : ChannelKeys , T : Deref + Sync + Send , F : Deref + Sync + Send , L : Deref + Sync + Send , C : Deref + Sync + Send >
208
271
ChainListener for SimpleManyChannelMonitor < Key , ChanSigner , T , F , L , C >
209
272
where T :: Target : BroadcasterInterface ,
@@ -212,24 +275,19 @@ impl<Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys, T: Deref + Sync
212
275
C :: Target : ChainWatchInterface ,
213
276
{
214
277
fn block_connected ( & self , header : & BlockHeader , txdata : & [ ( usize , & Transaction ) ] , height : u32 ) {
215
- let mut reentered = true ;
216
- while reentered {
217
- let matched_indexes = self . chain_monitor . filter_block ( header, txdata) ;
218
- let matched_txn: Vec < _ > = matched_indexes. iter ( ) . map ( |index| txdata[ * index] ) . collect ( ) ;
219
- let last_seen = self . chain_monitor . reentered ( ) ;
220
- {
221
- let mut monitors = self . monitors . lock ( ) . unwrap ( ) ;
222
- for monitor in monitors. values_mut ( ) {
223
- let txn_outputs = monitor. block_connected ( header, & matched_txn, height, & * self . broadcaster , & * self . fee_estimator , & * self . logger ) ;
224
-
225
- for ( ref txid, ref outputs) in txn_outputs {
226
- for ( idx, output) in outputs. iter ( ) . enumerate ( ) {
227
- self . chain_monitor . install_watch_outpoint ( ( txid. clone ( ) , idx as u32 ) , & output. script_pubkey ) ;
228
- }
278
+ let mut watch_events = self . watch_events . lock ( ) . unwrap ( ) ;
279
+ let matched_txn = watch_events. filter_block ( txdata) ;
280
+ {
281
+ let mut monitors = self . monitors . lock ( ) . unwrap ( ) ;
282
+ for monitor in monitors. values_mut ( ) {
283
+ let txn_outputs = monitor. block_connected ( header, & matched_txn, height, & * self . broadcaster , & * self . fee_estimator , & * self . logger ) ;
284
+
285
+ for ( ref txid, ref outputs) in txn_outputs {
286
+ for ( idx, output) in outputs. iter ( ) . enumerate ( ) {
287
+ watch_events. watch_output ( ( txid, idx) , & output. script_pubkey ) ;
229
288
}
230
289
}
231
290
}
232
- reentered = last_seen != self . chain_monitor . reentered ( ) ;
233
291
}
234
292
}
235
293
@@ -252,6 +310,7 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static, ChanSigner: ChannelKeys, T: De
252
310
pub fn new ( chain_monitor : C , broadcaster : T , logger : L , feeest : F ) -> SimpleManyChannelMonitor < Key , ChanSigner , T , F , L , C > {
253
311
let res = SimpleManyChannelMonitor {
254
312
monitors : Mutex :: new ( HashMap :: new ( ) ) ,
313
+ watch_events : Mutex :: new ( WatchEventQueue :: new ( ) ) ,
255
314
chain_monitor,
256
315
broadcaster,
257
316
logger,
@@ -263,6 +322,7 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static, ChanSigner: ChannelKeys, T: De
263
322
264
323
/// Adds or updates the monitor which monitors the channel referred to by the given key.
265
324
pub fn add_monitor_by_key ( & self , key : Key , monitor : ChannelMonitor < ChanSigner > ) -> Result < ( ) , MonitorUpdateError > {
325
+ let mut watch_events = self . watch_events . lock ( ) . unwrap ( ) ;
266
326
let mut monitors = self . monitors . lock ( ) . unwrap ( ) ;
267
327
let entry = match monitors. entry ( key) {
268
328
hash_map:: Entry :: Occupied ( _) => return Err ( MonitorUpdateError ( "Channel monitor for given key is already present" ) ) ,
@@ -271,11 +331,11 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static, ChanSigner: ChannelKeys, T: De
271
331
{
272
332
let funding_txo = monitor. get_funding_txo ( ) ;
273
333
log_trace ! ( self . logger, "Got new Channel Monitor for channel {}" , log_bytes!( funding_txo. 0 . to_channel_id( ) [ ..] ) ) ;
274
- self . chain_monitor . install_watch_tx ( & funding_txo. 0 . txid , & funding_txo. 1 ) ;
275
- self . chain_monitor . install_watch_outpoint ( ( funding_txo. 0 . txid , funding_txo. 0 . index as u32 ) , & funding_txo. 1 ) ;
334
+ watch_events . watch_tx ( & funding_txo. 0 . txid , & funding_txo. 1 ) ;
335
+ watch_events . watch_output ( ( & funding_txo. 0 . txid , funding_txo. 0 . index as usize ) , & funding_txo. 1 ) ;
276
336
for ( txid, outputs) in monitor. get_outputs_to_watch ( ) . iter ( ) {
277
337
for ( idx, script) in outputs. iter ( ) . enumerate ( ) {
278
- self . chain_monitor . install_watch_outpoint ( ( * txid, idx as u32 ) , script) ;
338
+ watch_events . watch_output ( ( txid, idx) , script) ;
279
339
}
280
340
}
281
341
}
@@ -342,6 +402,17 @@ impl<Key : Send + cmp::Eq + hash::Hash, ChanSigner: ChannelKeys, T: Deref, F: De
342
402
}
343
403
}
344
404
405
+ impl < Key : Send + cmp:: Eq + hash:: Hash , ChanSigner : ChannelKeys , T : Deref , F : Deref , L : Deref , C : Deref > chain:: WatchEventProvider for SimpleManyChannelMonitor < Key , ChanSigner , T , F , L , C >
406
+ where T :: Target : BroadcasterInterface ,
407
+ F :: Target : FeeEstimator ,
408
+ L :: Target : Logger ,
409
+ C :: Target : ChainWatchInterface ,
410
+ {
411
+ fn release_pending_watch_events ( & self ) -> Vec < chain:: WatchEvent > {
412
+ self . watch_events . lock ( ) . unwrap ( ) . dequeue_events ( )
413
+ }
414
+ }
415
+
345
416
/// If an HTLC expires within this many blocks, don't try to claim it in a shared transaction,
346
417
/// instead claiming it in its own individual transaction.
347
418
pub ( crate ) const CLTV_SHARED_CLAIM_BUFFER : u32 = 12 ;
@@ -881,30 +952,14 @@ pub trait ManyChannelMonitor: Send + Sync {
881
952
882
953
/// Adds a monitor for the given `funding_txo`.
883
954
///
884
- /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
885
- /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
886
- /// callbacks with the funding transaction, or any spends of it.
887
- ///
888
- /// Further, the implementer must also ensure that each output returned in
889
- /// monitor.get_outputs_to_watch() is registered to ensure that the provided monitor learns about
890
- /// any spends of any of the outputs.
891
- ///
892
- /// Any spends of outputs which should have been registered which aren't passed to
893
- /// ChannelMonitors via block_connected may result in FUNDS LOSS.
955
+ /// Implementations must ensure that `monitor` receives block_connected calls for blocks with
956
+ /// the funding transaction or any spends of it, as well as any spends of outputs returned by
957
+ /// get_outputs_to_watch. Not doing so may result in LOST FUNDS.
894
958
fn add_monitor ( & self , funding_txo : OutPoint , monitor : ChannelMonitor < Self :: Keys > ) -> Result < ( ) , ChannelMonitorUpdateErr > ;
895
959
896
960
/// Updates a monitor for the given `funding_txo`.
897
961
///
898
- /// Implementer must also ensure that the funding_txo txid *and* outpoint are registered with
899
- /// any relevant ChainWatchInterfaces such that the provided monitor receives block_connected
900
- /// callbacks with the funding transaction, or any spends of it.
901
- ///
902
- /// Further, the implementer must also ensure that each output returned in
903
- /// monitor.get_watch_outputs() is registered to ensure that the provided monitor learns about
904
- /// any spends of any of the outputs.
905
- ///
906
- /// Any spends of outputs which should have been registered which aren't passed to
907
- /// ChannelMonitors via block_connected may result in FUNDS LOSS.
962
+ /// TODO(jkczyz): Determine where this should go from e73036c6845fd3cc16479a1b497db82a5ebb3897.
908
963
///
909
964
/// In case of distributed watchtowers deployment, even if an Err is return, the new version
910
965
/// must be written to disk, as state may have been stored but rejected due to a block forcing
0 commit comments