@@ -218,6 +218,7 @@ const MIN_SERIALIZATION_VERSION: u8 = 1;
218218///
219219/// You MUST ensure that no ChannelMonitors for a given channel anywhere contain out-of-date
220220/// information and are actively monitoring the chain.
221+ #[ derive( Clone ) ]
221222pub struct ChannelMonitor {
222223 funding_txo : Option < ( OutPoint , Script ) > ,
223224 commitment_transaction_number_obscure_factor : u64 ,
@@ -239,7 +240,7 @@ pub struct ChannelMonitor {
239240 /// spending. Thus, in order to claim them via revocation key, we track all the remote
240241 /// commitment transactions which we find on-chain, mapping them to the commitment number which
241242 /// can be used to derive the revocation key and claim the transactions.
242- remote_commitment_txn_on_chain : Mutex < HashMap < Sha256dHash , u64 > > ,
243+ remote_commitment_txn_on_chain : HashMap < Sha256dHash , ( u64 , Vec < Script > ) > ,
243244 /// Cache used to make pruning of payment_preimages faster.
244245 /// Maps payment_hash values to commitment numbers for remote transactions for non-revoked
245246 /// remote transactions (ie should remain pretty small).
@@ -266,38 +267,6 @@ pub struct ChannelMonitor {
266267 secp_ctx : Secp256k1 < secp256k1:: All > , //TODO: dedup this a bit...
267268 logger : Arc < Logger > ,
268269}
269- impl Clone for ChannelMonitor {
270- fn clone ( & self ) -> Self {
271- ChannelMonitor {
272- funding_txo : self . funding_txo . clone ( ) ,
273- commitment_transaction_number_obscure_factor : self . commitment_transaction_number_obscure_factor . clone ( ) ,
274-
275- key_storage : self . key_storage . clone ( ) ,
276- delayed_payment_base_key : self . delayed_payment_base_key . clone ( ) ,
277- their_htlc_base_key : self . their_htlc_base_key . clone ( ) ,
278- their_delayed_payment_base_key : self . their_delayed_payment_base_key . clone ( ) ,
279- their_cur_revocation_points : self . their_cur_revocation_points . clone ( ) ,
280-
281- our_to_self_delay : self . our_to_self_delay ,
282- their_to_self_delay : self . their_to_self_delay ,
283-
284- old_secrets : self . old_secrets . clone ( ) ,
285- remote_claimable_outpoints : self . remote_claimable_outpoints . clone ( ) ,
286- remote_commitment_txn_on_chain : Mutex :: new ( ( * self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ) . clone ( ) ) ,
287- remote_hash_commitment_number : self . remote_hash_commitment_number . clone ( ) ,
288-
289- prev_local_signed_commitment_tx : self . prev_local_signed_commitment_tx . clone ( ) ,
290- current_local_signed_commitment_tx : self . current_local_signed_commitment_tx . clone ( ) ,
291-
292- payment_preimages : self . payment_preimages . clone ( ) ,
293-
294- destination_script : self . destination_script . clone ( ) ,
295- last_block_hash : self . last_block_hash . clone ( ) ,
296- secp_ctx : self . secp_ctx . clone ( ) ,
297- logger : self . logger . clone ( ) ,
298- }
299- }
300- }
301270
302271#[ cfg( any( test, feature = "fuzztarget" ) ) ]
303272/// Used only in testing and fuzztarget to check serialization roundtrips don't change the
@@ -314,6 +283,7 @@ impl PartialEq for ChannelMonitor {
314283 self . our_to_self_delay != other. our_to_self_delay ||
315284 self . their_to_self_delay != other. their_to_self_delay ||
316285 self . remote_claimable_outpoints != other. remote_claimable_outpoints ||
286+ self . remote_commitment_txn_on_chain != other. remote_commitment_txn_on_chain ||
317287 self . remote_hash_commitment_number != other. remote_hash_commitment_number ||
318288 self . prev_local_signed_commitment_tx != other. prev_local_signed_commitment_tx ||
319289 self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
@@ -327,9 +297,7 @@ impl PartialEq for ChannelMonitor {
327297 return false
328298 }
329299 }
330- let us = self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
331- let them = other. remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
332- * us == * them
300+ true
333301 }
334302 }
335303}
@@ -354,7 +322,7 @@ impl ChannelMonitor {
354322
355323 old_secrets : [ ( [ 0 ; 32 ] , 1 << 48 ) ; 49 ] ,
356324 remote_claimable_outpoints : HashMap :: new ( ) ,
357- remote_commitment_txn_on_chain : Mutex :: new ( HashMap :: new ( ) ) ,
325+ remote_commitment_txn_on_chain : HashMap :: new ( ) ,
358326 remote_hash_commitment_number : HashMap :: new ( ) ,
359327
360328 prev_local_signed_commitment_tx : None ,
@@ -578,6 +546,20 @@ impl ChannelMonitor {
578546 }
579547 }
580548
549+ /// Gets the sets of all outpoints which this ChannelMonitor expects to hear about spends of.
550+ /// Generally useful when deserializing as during normal operation the return values of
551+ /// block_connected are sufficient to ensure all relevant outpoints are being monitored (note
552+ /// that the get_funding_txo outpoint and transaction must also be monitored for!).
553+ pub fn get_monitored_outpoints ( & self ) -> Vec < ( Sha256dHash , u32 , & Script ) > {
554+ let mut res = Vec :: with_capacity ( self . remote_commitment_txn_on_chain . len ( ) * 2 ) ;
555+ for ( ref txid, & ( _, ref outputs) ) in self . remote_commitment_txn_on_chain . iter ( ) {
556+ for ( idx, output) in outputs. iter ( ) . enumerate ( ) {
557+ res. push ( ( ( * txid) . clone ( ) , idx as u32 , output) ) ;
558+ }
559+ }
560+ res
561+ }
562+
581563 /// Serializes into a vec, with various modes for the exposed pub fns
582564 fn write < W : Writer > ( & self , writer : & mut W , for_local_storage : bool ) -> Result < ( ) , :: std:: io:: Error > {
583565 //TODO: We still write out all the serialization here manually instead of using the fancy
@@ -659,12 +641,13 @@ impl ChannelMonitor {
659641 }
660642 }
661643
662- {
663- let remote_commitment_txn_on_chain = self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
664- writer. write_all ( & byte_utils:: be64_to_array ( remote_commitment_txn_on_chain. len ( ) as u64 ) ) ?;
665- for ( txid, commitment_number) in remote_commitment_txn_on_chain. iter ( ) {
666- writer. write_all ( & txid[ ..] ) ?;
667- writer. write_all ( & byte_utils:: be48_to_array ( * commitment_number) ) ?;
644+ writer. write_all ( & byte_utils:: be64_to_array ( self . remote_commitment_txn_on_chain . len ( ) as u64 ) ) ?;
645+ for ( txid, ( commitment_number, txouts) ) in self . remote_commitment_txn_on_chain . iter ( ) {
646+ writer. write_all ( & txid[ ..] ) ?;
647+ writer. write_all ( & byte_utils:: be48_to_array ( * commitment_number) ) ?;
648+ ( txouts. len ( ) as u64 ) . write ( writer) ?;
649+ for script in txouts. iter ( ) {
650+ script. write ( writer) ?;
668651 }
669652 }
670653
@@ -778,7 +761,7 @@ impl ChannelMonitor {
778761 /// data in remote_claimable_outpoints. Will directly claim any HTLC outputs which expire at a
779762 /// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for
780763 /// HTLC-Success/HTLC-Timeout transactions.
781- fn check_spend_remote_transaction ( & self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) ) {
764+ fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) ) {
782765 // Most secp and related errors trying to create keys means we have no hope of constructing
783766 // a spend transaction...so we return no transactions to broadcast
784767 let mut txn_to_broadcast = Vec :: new ( ) ;
@@ -917,7 +900,7 @@ impl ChannelMonitor {
917900 if !inputs. is_empty ( ) || !txn_to_broadcast. is_empty ( ) { // ie we're confident this is actually ours
918901 // We're definitely a remote commitment transaction!
919902 watch_outputs. append ( & mut tx. output . clone ( ) ) ;
920- self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) . insert ( commitment_txid , commitment_number ) ;
903+ self . remote_commitment_txn_on_chain . insert ( commitment_txid , ( commitment_number , tx . output . iter ( ) . map ( |output| { output . script_pubkey . clone ( ) } ) . collect ( ) ) ) ;
921904 }
922905 if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) ) ; } // Nothing to be done...probably a false positive/local tx
923906
@@ -950,7 +933,7 @@ impl ChannelMonitor {
950933 // not being generated by the above conditional. Thus, to be safe, we go ahead and
951934 // insert it here.
952935 watch_outputs. append ( & mut tx. output . clone ( ) ) ;
953- self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) . insert ( commitment_txid , commitment_number ) ;
936+ self . remote_commitment_txn_on_chain . insert ( commitment_txid , ( commitment_number , tx . output . iter ( ) . map ( |output| { output . script_pubkey . clone ( ) } ) . collect ( ) ) ) ;
954937
955938 if let Some ( revocation_points) = self . their_cur_revocation_points {
956939 let revocation_point_option =
@@ -1224,9 +1207,8 @@ impl ChannelMonitor {
12241207 txn = self . check_spend_local_transaction ( tx, height) ;
12251208 }
12261209 } else {
1227- let remote_commitment_txn_on_chain = self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
1228- if let Some ( commitment_number) = remote_commitment_txn_on_chain. get ( & prevout. txid ) {
1229- if let Some ( tx) = self . check_spend_remote_htlc ( tx, * commitment_number) {
1210+ if let Some ( & ( commitment_number, _) ) = self . remote_commitment_txn_on_chain . get ( & prevout. txid ) {
1211+ if let Some ( tx) = self . check_spend_remote_htlc ( tx, commitment_number) {
12301212 txn. push ( tx) ;
12311213 }
12321214 }
@@ -1383,7 +1365,12 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
13831365 for _ in 0 ..remote_commitment_txn_on_chain_len {
13841366 let txid: Sha256dHash = Readable :: read ( reader) ?;
13851367 let commitment_number = <U48 as Readable < R > >:: read ( reader) ?. 0 ;
1386- if let Some ( _) = remote_commitment_txn_on_chain. insert ( txid, commitment_number) {
1368+ let outputs_count = <u64 as Readable < R > >:: read ( reader) ?;
1369+ let mut outputs = Vec :: with_capacity ( cmp:: min ( outputs_count as usize , MAX_ALLOC_SIZE / 8 ) ) ;
1370+ for _ in 0 ..outputs_count {
1371+ outputs. push ( Readable :: read ( reader) ?) ;
1372+ }
1373+ if let Some ( _) = remote_commitment_txn_on_chain. insert ( txid, ( commitment_number, outputs) ) {
13871374 return Err ( DecodeError :: InvalidValue ) ;
13881375 }
13891376 }
@@ -1482,7 +1469,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
14821469
14831470 old_secrets,
14841471 remote_claimable_outpoints,
1485- remote_commitment_txn_on_chain : Mutex :: new ( remote_commitment_txn_on_chain ) ,
1472+ remote_commitment_txn_on_chain,
14861473 remote_hash_commitment_number,
14871474
14881475 prev_local_signed_commitment_tx,
0 commit comments