@@ -243,6 +243,7 @@ const MIN_SERIALIZATION_VERSION: u8 = 1;
243
243
///
244
244
/// You MUST ensure that no ChannelMonitors for a given channel anywhere contain out-of-date
245
245
/// information and are actively monitoring the chain.
246
+ #[ derive( Clone ) ]
246
247
pub struct ChannelMonitor {
247
248
funding_txo : Option < ( OutPoint , Script ) > ,
248
249
commitment_transaction_number_obscure_factor : u64 ,
@@ -263,7 +264,7 @@ pub struct ChannelMonitor {
263
264
/// spending. Thus, in order to claim them via revocation key, we track all the remote
264
265
/// commitment transactions which we find on-chain, mapping them to the commitment number which
265
266
/// can be used to derive the revocation key and claim the transactions.
266
- remote_commitment_txn_on_chain : Mutex < HashMap < Sha256dHash , u64 > > ,
267
+ remote_commitment_txn_on_chain : HashMap < Sha256dHash , ( u64 , Vec < Script > ) > ,
267
268
/// Cache used to make pruning of payment_preimages faster.
268
269
/// Maps payment_hash values to commitment numbers for remote transactions for non-revoked
269
270
/// remote transactions (ie should remain pretty small).
@@ -290,37 +291,6 @@ pub struct ChannelMonitor {
290
291
secp_ctx : Secp256k1 < secp256k1:: All > , //TODO: dedup this a bit...
291
292
logger : Arc < Logger > ,
292
293
}
293
- impl Clone for ChannelMonitor {
294
- fn clone ( & self ) -> Self {
295
- ChannelMonitor {
296
- funding_txo : self . funding_txo . clone ( ) ,
297
- commitment_transaction_number_obscure_factor : self . commitment_transaction_number_obscure_factor . clone ( ) ,
298
-
299
- key_storage : self . key_storage . clone ( ) ,
300
- their_htlc_base_key : self . their_htlc_base_key . clone ( ) ,
301
- their_delayed_payment_base_key : self . their_delayed_payment_base_key . clone ( ) ,
302
- their_cur_revocation_points : self . their_cur_revocation_points . clone ( ) ,
303
-
304
- our_to_self_delay : self . our_to_self_delay ,
305
- their_to_self_delay : self . their_to_self_delay ,
306
-
307
- old_secrets : self . old_secrets . clone ( ) ,
308
- remote_claimable_outpoints : self . remote_claimable_outpoints . clone ( ) ,
309
- remote_commitment_txn_on_chain : Mutex :: new ( ( * self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ) . clone ( ) ) ,
310
- remote_hash_commitment_number : self . remote_hash_commitment_number . clone ( ) ,
311
-
312
- prev_local_signed_commitment_tx : self . prev_local_signed_commitment_tx . clone ( ) ,
313
- current_local_signed_commitment_tx : self . current_local_signed_commitment_tx . clone ( ) ,
314
-
315
- payment_preimages : self . payment_preimages . clone ( ) ,
316
-
317
- destination_script : self . destination_script . clone ( ) ,
318
- last_block_hash : self . last_block_hash . clone ( ) ,
319
- secp_ctx : self . secp_ctx . clone ( ) ,
320
- logger : self . logger . clone ( ) ,
321
- }
322
- }
323
- }
324
294
325
295
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
326
296
/// Used only in testing and fuzztarget to check serialization roundtrips don't change the
@@ -336,6 +306,7 @@ impl PartialEq for ChannelMonitor {
336
306
self . our_to_self_delay != other. our_to_self_delay ||
337
307
self . their_to_self_delay != other. their_to_self_delay ||
338
308
self . remote_claimable_outpoints != other. remote_claimable_outpoints ||
309
+ self . remote_commitment_txn_on_chain != other. remote_commitment_txn_on_chain ||
339
310
self . remote_hash_commitment_number != other. remote_hash_commitment_number ||
340
311
self . prev_local_signed_commitment_tx != other. prev_local_signed_commitment_tx ||
341
312
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
@@ -349,9 +320,7 @@ impl PartialEq for ChannelMonitor {
349
320
return false
350
321
}
351
322
}
352
- let us = self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
353
- let them = other. remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
354
- * us == * them
323
+ true
355
324
}
356
325
}
357
326
}
@@ -378,7 +347,7 @@ impl ChannelMonitor {
378
347
379
348
old_secrets : [ ( [ 0 ; 32 ] , 1 << 48 ) ; 49 ] ,
380
349
remote_claimable_outpoints : HashMap :: new ( ) ,
381
- remote_commitment_txn_on_chain : Mutex :: new ( HashMap :: new ( ) ) ,
350
+ remote_commitment_txn_on_chain : HashMap :: new ( ) ,
382
351
remote_hash_commitment_number : HashMap :: new ( ) ,
383
352
384
353
prev_local_signed_commitment_tx : None ,
@@ -613,6 +582,20 @@ impl ChannelMonitor {
613
582
}
614
583
}
615
584
585
+ /// Gets the sets of all outpoints which this ChannelMonitor expects to hear about spends of.
586
+ /// Generally useful when deserializing as during normal operation the return values of
587
+ /// block_connected are sufficient to ensure all relevant outpoints are being monitored (note
588
+ /// that the get_funding_txo outpoint and transaction must also be monitored for!).
589
+ pub fn get_monitored_outpoints ( & self ) -> Vec < ( Sha256dHash , u32 , & Script ) > {
590
+ let mut res = Vec :: with_capacity ( self . remote_commitment_txn_on_chain . len ( ) * 2 ) ;
591
+ for ( ref txid, & ( _, ref outputs) ) in self . remote_commitment_txn_on_chain . iter ( ) {
592
+ for ( idx, output) in outputs. iter ( ) . enumerate ( ) {
593
+ res. push ( ( ( * txid) . clone ( ) , idx as u32 , output) ) ;
594
+ }
595
+ }
596
+ res
597
+ }
598
+
616
599
/// Serializes into a vec, with various modes for the exposed pub fns
617
600
fn write < W : Writer > ( & self , writer : & mut W , for_local_storage : bool ) -> Result < ( ) , :: std:: io:: Error > {
618
601
//TODO: We still write out all the serialization here manually instead of using the fancy
@@ -707,12 +690,13 @@ impl ChannelMonitor {
707
690
}
708
691
}
709
692
710
- {
711
- let remote_commitment_txn_on_chain = self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
712
- writer. write_all ( & byte_utils:: be64_to_array ( remote_commitment_txn_on_chain. len ( ) as u64 ) ) ?;
713
- for ( txid, commitment_number) in remote_commitment_txn_on_chain. iter ( ) {
714
- writer. write_all ( & txid[ ..] ) ?;
715
- writer. write_all ( & byte_utils:: be48_to_array ( * commitment_number) ) ?;
693
+ writer. write_all ( & byte_utils:: be64_to_array ( self . remote_commitment_txn_on_chain . len ( ) as u64 ) ) ?;
694
+ for ( txid, ( commitment_number, txouts) ) in self . remote_commitment_txn_on_chain . iter ( ) {
695
+ writer. write_all ( & txid[ ..] ) ?;
696
+ writer. write_all ( & byte_utils:: be48_to_array ( * commitment_number) ) ?;
697
+ ( txouts. len ( ) as u64 ) . write ( writer) ?;
698
+ for script in txouts. iter ( ) {
699
+ script. write ( writer) ?;
716
700
}
717
701
}
718
702
@@ -826,7 +810,7 @@ impl ChannelMonitor {
826
810
/// data in remote_claimable_outpoints. Will directly claim any HTLC outputs which expire at a
827
811
/// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for
828
812
/// HTLC-Success/HTLC-Timeout transactions.
829
- fn check_spend_remote_transaction ( & self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > ) {
813
+ fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > ) {
830
814
// Most secp and related errors trying to create keys means we have no hope of constructing
831
815
// a spend transaction...so we return no transactions to broadcast
832
816
let mut txn_to_broadcast = Vec :: new ( ) ;
@@ -966,7 +950,7 @@ impl ChannelMonitor {
966
950
if !inputs. is_empty ( ) || !txn_to_broadcast. is_empty ( ) { // ie we're confident this is actually ours
967
951
// We're definitely a remote commitment transaction!
968
952
watch_outputs. append ( & mut tx. output . clone ( ) ) ;
969
- self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) . insert ( commitment_txid , commitment_number ) ;
953
+ self . remote_commitment_txn_on_chain . insert ( commitment_txid , ( commitment_number , tx . output . iter ( ) . map ( |output| { output . script_pubkey . clone ( ) } ) . collect ( ) ) ) ;
970
954
}
971
955
if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
972
956
@@ -1003,7 +987,7 @@ impl ChannelMonitor {
1003
987
// not being generated by the above conditional. Thus, to be safe, we go ahead and
1004
988
// insert it here.
1005
989
watch_outputs. append ( & mut tx. output . clone ( ) ) ;
1006
- self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) . insert ( commitment_txid , commitment_number ) ;
990
+ self . remote_commitment_txn_on_chain . insert ( commitment_txid , ( commitment_number , tx . output . iter ( ) . map ( |output| { output . script_pubkey . clone ( ) } ) . collect ( ) ) ) ;
1007
991
1008
992
if let Some ( revocation_points) = self . their_cur_revocation_points {
1009
993
let revocation_point_option =
@@ -1330,9 +1314,8 @@ impl ChannelMonitor {
1330
1314
txn = remote_txn;
1331
1315
}
1332
1316
} else {
1333
- let remote_commitment_txn_on_chain = self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
1334
- if let Some ( commitment_number) = remote_commitment_txn_on_chain. get ( & prevout. txid ) {
1335
- let ( tx, spendable_output) = self . check_spend_remote_htlc ( tx, * commitment_number) ;
1317
+ if let Some ( & ( commitment_number, _) ) = self . remote_commitment_txn_on_chain . get ( & prevout. txid ) {
1318
+ let ( tx, spendable_output) = self . check_spend_remote_htlc ( tx, commitment_number) ;
1336
1319
if let Some ( tx) = tx {
1337
1320
txn. push ( tx) ;
1338
1321
}
@@ -1521,7 +1504,12 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
1521
1504
for _ in 0 ..remote_commitment_txn_on_chain_len {
1522
1505
let txid: Sha256dHash = Readable :: read ( reader) ?;
1523
1506
let commitment_number = <U48 as Readable < R > >:: read ( reader) ?. 0 ;
1524
- if let Some ( _) = remote_commitment_txn_on_chain. insert ( txid, commitment_number) {
1507
+ let outputs_count = <u64 as Readable < R > >:: read ( reader) ?;
1508
+ let mut outputs = Vec :: with_capacity ( cmp:: min ( outputs_count as usize , MAX_ALLOC_SIZE / 8 ) ) ;
1509
+ for _ in 0 ..outputs_count {
1510
+ outputs. push ( Readable :: read ( reader) ?) ;
1511
+ }
1512
+ if let Some ( _) = remote_commitment_txn_on_chain. insert ( txid, ( commitment_number, outputs) ) {
1525
1513
return Err ( DecodeError :: InvalidValue ) ;
1526
1514
}
1527
1515
}
@@ -1619,7 +1607,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
1619
1607
1620
1608
old_secrets,
1621
1609
remote_claimable_outpoints,
1622
- remote_commitment_txn_on_chain : Mutex :: new ( remote_commitment_txn_on_chain ) ,
1610
+ remote_commitment_txn_on_chain,
1623
1611
remote_hash_commitment_number,
1624
1612
1625
1613
prev_local_signed_commitment_tx,
0 commit comments