@@ -243,6 +243,7 @@ const MIN_SERIALIZATION_VERSION: u8 = 1;
243243///
244244/// You MUST ensure that no ChannelMonitors for a given channel anywhere contain out-of-date
245245/// information and are actively monitoring the chain.
246+ #[ derive( Clone ) ]
246247pub struct ChannelMonitor {
247248 funding_txo : Option < ( OutPoint , Script ) > ,
248249 commitment_transaction_number_obscure_factor : u64 ,
@@ -263,7 +264,7 @@ pub struct ChannelMonitor {
263264 /// spending. Thus, in order to claim them via revocation key, we track all the remote
264265 /// commitment transactions which we find on-chain, mapping them to the commitment number which
265266 /// 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 > ) > ,
267268 /// Cache used to make pruning of payment_preimages faster.
268269 /// Maps payment_hash values to commitment numbers for remote transactions for non-revoked
269270 /// remote transactions (ie should remain pretty small).
@@ -290,37 +291,6 @@ pub struct ChannelMonitor {
290291 secp_ctx : Secp256k1 < secp256k1:: All > , //TODO: dedup this a bit...
291292 logger : Arc < Logger > ,
292293}
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- }
324294
325295#[ cfg( any( test, feature = "fuzztarget" ) ) ]
326296/// Used only in testing and fuzztarget to check serialization roundtrips don't change the
@@ -336,6 +306,7 @@ impl PartialEq for ChannelMonitor {
336306 self . our_to_self_delay != other. our_to_self_delay ||
337307 self . their_to_self_delay != other. their_to_self_delay ||
338308 self . remote_claimable_outpoints != other. remote_claimable_outpoints ||
309+ self . remote_commitment_txn_on_chain != other. remote_commitment_txn_on_chain ||
339310 self . remote_hash_commitment_number != other. remote_hash_commitment_number ||
340311 self . prev_local_signed_commitment_tx != other. prev_local_signed_commitment_tx ||
341312 self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
@@ -349,9 +320,7 @@ impl PartialEq for ChannelMonitor {
349320 return false
350321 }
351322 }
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
355324 }
356325 }
357326}
@@ -378,7 +347,7 @@ impl ChannelMonitor {
378347
379348 old_secrets : [ ( [ 0 ; 32 ] , 1 << 48 ) ; 49 ] ,
380349 remote_claimable_outpoints : HashMap :: new ( ) ,
381- remote_commitment_txn_on_chain : Mutex :: new ( HashMap :: new ( ) ) ,
350+ remote_commitment_txn_on_chain : HashMap :: new ( ) ,
382351 remote_hash_commitment_number : HashMap :: new ( ) ,
383352
384353 prev_local_signed_commitment_tx : None ,
@@ -613,6 +582,20 @@ impl ChannelMonitor {
613582 }
614583 }
615584
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+
616599 /// Serializes into a vec, with various modes for the exposed pub fns
617600 fn write < W : Writer > ( & self , writer : & mut W , for_local_storage : bool ) -> Result < ( ) , :: std:: io:: Error > {
618601 //TODO: We still write out all the serialization here manually instead of using the fancy
@@ -707,12 +690,13 @@ impl ChannelMonitor {
707690 }
708691 }
709692
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) ?;
716700 }
717701 }
718702
@@ -826,7 +810,7 @@ impl ChannelMonitor {
826810 /// data in remote_claimable_outpoints. Will directly claim any HTLC outputs which expire at a
827811 /// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for
828812 /// 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 > ) {
830814 // Most secp and related errors trying to create keys means we have no hope of constructing
831815 // a spend transaction...so we return no transactions to broadcast
832816 let mut txn_to_broadcast = Vec :: new ( ) ;
@@ -966,7 +950,7 @@ impl ChannelMonitor {
966950 if !inputs. is_empty ( ) || !txn_to_broadcast. is_empty ( ) { // ie we're confident this is actually ours
967951 // We're definitely a remote commitment transaction!
968952 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 ( ) ) ) ;
970954 }
971955 if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
972956
@@ -1003,7 +987,7 @@ impl ChannelMonitor {
1003987 // not being generated by the above conditional. Thus, to be safe, we go ahead and
1004988 // insert it here.
1005989 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 ( ) ) ) ;
1007991
1008992 if let Some ( revocation_points) = self . their_cur_revocation_points {
1009993 let revocation_point_option =
@@ -1330,9 +1314,8 @@ impl ChannelMonitor {
13301314 txn = remote_txn;
13311315 }
13321316 } 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) ;
13361319 if let Some ( tx) = tx {
13371320 txn. push ( tx) ;
13381321 }
@@ -1521,7 +1504,12 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
15211504 for _ in 0 ..remote_commitment_txn_on_chain_len {
15221505 let txid: Sha256dHash = Readable :: read ( reader) ?;
15231506 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) ) {
15251513 return Err ( DecodeError :: InvalidValue ) ;
15261514 }
15271515 }
@@ -1619,7 +1607,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
16191607
16201608 old_secrets,
16211609 remote_claimable_outpoints,
1622- remote_commitment_txn_on_chain : Mutex :: new ( remote_commitment_txn_on_chain ) ,
1610+ remote_commitment_txn_on_chain,
16231611 remote_hash_commitment_number,
16241612
16251613 prev_local_signed_commitment_tx,
0 commit comments