@@ -69,9 +69,11 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
69
69
fn block_connected ( & self , _header : & BlockHeader , height : u32 , txn_matched : & [ & Transaction ] , _indexes_of_txn_matched : & [ u32 ] ) {
70
70
let monitors = self . monitors . lock ( ) . unwrap ( ) ;
71
71
for monitor in monitors. values ( ) {
72
- let outputs = monitor. block_connected ( txn_matched, height, & * self . broadcaster ) ;
73
- for output in outputs {
74
- self . chain_monitor . install_watch_script ( & output. script_pubkey ) ;
72
+ let txn_outputs = monitor. block_connected ( txn_matched, height, & * self . broadcaster ) ;
73
+ for ( ref txid, ref outputs) in txn_outputs {
74
+ for ( idx, output) in outputs. iter ( ) . enumerate ( ) {
75
+ self . chain_monitor . install_watch_outpoint ( ( txid. clone ( ) , idx as u32 ) , & output. script_pubkey ) ;
76
+ }
75
77
}
76
78
}
77
79
}
@@ -467,7 +469,7 @@ impl ChannelMonitor {
467
469
/// optional, without it this monitor cannot be used in an SPV client, but you may wish to
468
470
/// avoid this (or call unset_funding_info) on a monitor you wish to send to a watchtower as it
469
471
/// provides slightly better privacy.
470
- /// It is the responsability of the caller to register outpoint and script with passing the former
472
+ /// It is the responsability of the caller to register outpoint and script with passing the former
471
473
/// value as key to update current monitor
472
474
pub ( super ) fn set_funding_info ( & mut self , funding_info : ( OutPoint , Script ) ) {
473
475
self . funding_txo = Some ( funding_info) ;
@@ -912,23 +914,24 @@ impl ChannelMonitor {
912
914
/// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for
913
915
/// HTLC-Success/HTLC-Timeout transactions, and claim them using the revocation key (if
914
916
/// applicable) as well.
915
- fn check_spend_remote_transaction ( & self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , Vec < TxOut > ) {
917
+ fn check_spend_remote_transaction ( & self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) ) {
916
918
// Most secp and related errors trying to create keys means we have no hope of constructing
917
919
// a spend transaction...so we return no transactions to broadcast
918
920
let mut txn_to_broadcast = Vec :: new ( ) ;
919
- let mut outputs = Vec :: new ( ) ;
921
+ let mut watch_outputs = Vec :: new ( ) ;
922
+
923
+ let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
924
+ let per_commitment_option = self . remote_claimable_outpoints . get ( & commitment_txid) ;
925
+
920
926
macro_rules! ignore_error {
921
927
( $thing : expr ) => {
922
928
match $thing {
923
929
Ok ( a) => a,
924
- Err ( _) => return ( txn_to_broadcast, outputs )
930
+ Err ( _) => return ( txn_to_broadcast, ( commitment_txid , watch_outputs ) )
925
931
}
926
932
} ;
927
933
}
928
934
929
- let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
930
- let per_commitment_option = self . remote_claimable_outpoints . get ( & commitment_txid) ;
931
-
932
935
let commitment_number = 0xffffffffffff - ( ( ( ( tx. input [ 0 ] . sequence as u64 & 0xffffff ) << 3 * 8 ) | ( tx. lock_time as u64 & 0xffffff ) ) ^ self . commitment_transaction_number_obscure_factor ) ;
933
936
if commitment_number >= self . get_min_seen_secret ( ) {
934
937
let secret = self . get_secret ( commitment_number) . unwrap ( ) ;
@@ -947,7 +950,7 @@ impl ChannelMonitor {
947
950
} ;
948
951
let delayed_key = ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, & PublicKey :: from_secret_key( & self . secp_ctx, & per_commitment_key) , & self . delayed_payment_base_key) ) ;
949
952
let a_htlc_key = match self . their_htlc_base_key {
950
- None => return ( txn_to_broadcast, outputs ) ,
953
+ None => return ( txn_to_broadcast, ( commitment_txid , watch_outputs ) ) ,
951
954
Some ( their_htlc_base_key) => ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, & PublicKey :: from_secret_key( & self . secp_ctx, & per_commitment_key) , & their_htlc_base_key) ) ,
952
955
} ;
953
956
@@ -1014,7 +1017,7 @@ impl ChannelMonitor {
1014
1017
if htlc. transaction_output_index as usize >= tx. output . len ( ) ||
1015
1018
tx. output [ htlc. transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1016
1019
tx. output [ htlc. transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1017
- return ( txn_to_broadcast, outputs ) ; // Corrupted per_commitment_data, fuck this user
1020
+ return ( txn_to_broadcast, ( commitment_txid , watch_outputs ) ) ; // Corrupted per_commitment_data, fuck this user
1018
1021
}
1019
1022
let input = TxIn {
1020
1023
previous_output : BitcoinOutPoint {
@@ -1049,10 +1052,10 @@ impl ChannelMonitor {
1049
1052
1050
1053
if !inputs. is_empty ( ) || !txn_to_broadcast. is_empty ( ) { // ie we're confident this is actually ours
1051
1054
// We're definitely a remote commitment transaction!
1052
- outputs . append ( & mut tx. output . clone ( ) ) ;
1055
+ watch_outputs . append ( & mut tx. output . clone ( ) ) ;
1053
1056
self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) . insert ( commitment_txid, commitment_number) ;
1054
1057
}
1055
- if inputs. is_empty ( ) { return ( txn_to_broadcast, outputs ) ; } // Nothing to be done...probably a false positive/local tx
1058
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid , watch_outputs ) ) ; } // Nothing to be done...probably a false positive/local tx
1056
1059
1057
1060
let outputs = vec ! ( TxOut {
1058
1061
script_pubkey: self . destination_script. clone( ) ,
@@ -1082,7 +1085,7 @@ impl ChannelMonitor {
1082
1085
// already processed the block, resulting in the remote_commitment_txn_on_chain entry
1083
1086
// not being generated by the above conditional. Thus, to be safe, we go ahead and
1084
1087
// insert it here.
1085
- outputs . append ( & mut tx. output . clone ( ) ) ;
1088
+ watch_outputs . append ( & mut tx. output . clone ( ) ) ;
1086
1089
self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) . insert ( commitment_txid, commitment_number) ;
1087
1090
1088
1091
if let Some ( revocation_points) = self . their_cur_revocation_points {
@@ -1103,7 +1106,7 @@ impl ChannelMonitor {
1103
1106
} ,
1104
1107
} ;
1105
1108
let a_htlc_key = match self . their_htlc_base_key {
1106
- None => return ( txn_to_broadcast, outputs ) ,
1109
+ None => return ( txn_to_broadcast, ( commitment_txid , watch_outputs ) ) ,
1107
1110
Some ( their_htlc_base_key) => ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, revocation_point, & their_htlc_base_key) ) ,
1108
1111
} ;
1109
1112
@@ -1166,7 +1169,7 @@ impl ChannelMonitor {
1166
1169
}
1167
1170
}
1168
1171
1169
- if inputs. is_empty ( ) { return ( txn_to_broadcast, outputs ) ; } // Nothing to be done...probably a false positive/local tx
1172
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid , watch_outputs ) ) ; } // Nothing to be done...probably a false positive/local tx
1170
1173
1171
1174
let outputs = vec ! ( TxOut {
1172
1175
script_pubkey: self . destination_script. clone( ) ,
@@ -1194,7 +1197,7 @@ impl ChannelMonitor {
1194
1197
//TODO: For each input check if its in our remote_commitment_txn_on_chain map!
1195
1198
}
1196
1199
1197
- ( txn_to_broadcast, outputs )
1200
+ ( txn_to_broadcast, ( commitment_txid , watch_outputs ) )
1198
1201
}
1199
1202
1200
1203
fn broadcast_by_local_state ( & self , local_tx : & LocalSignedTx ) -> Vec < Transaction > {
@@ -1255,13 +1258,15 @@ impl ChannelMonitor {
1255
1258
Vec :: new ( )
1256
1259
}
1257
1260
1258
- fn block_connected ( & self , txn_matched : & [ & Transaction ] , height : u32 , broadcaster : & BroadcasterInterface ) -> Vec < TxOut > {
1259
- let mut outputs = Vec :: new ( ) ;
1261
+ fn block_connected ( & self , txn_matched : & [ & Transaction ] , height : u32 , broadcaster : & BroadcasterInterface ) -> Vec < ( Sha256dHash , Vec < TxOut > ) > {
1262
+ let mut watch_outputs = Vec :: new ( ) ;
1260
1263
for tx in txn_matched {
1261
1264
for txin in tx. input . iter ( ) {
1262
1265
if self . funding_txo . is_none ( ) || ( txin. previous_output . txid == self . funding_txo . as_ref ( ) . unwrap ( ) . 0 . txid && txin. previous_output . vout == self . funding_txo . as_ref ( ) . unwrap ( ) . 0 . index as u32 ) {
1263
- let ( mut txn, out) = self . check_spend_remote_transaction ( tx, height) ;
1264
- outputs = out;
1266
+ let ( mut txn, new_outputs) = self . check_spend_remote_transaction ( tx, height) ;
1267
+ if !new_outputs. 1 . is_empty ( ) {
1268
+ watch_outputs. push ( new_outputs) ;
1269
+ }
1265
1270
if txn. is_empty ( ) {
1266
1271
txn = self . check_spend_local_transaction ( tx, height) ;
1267
1272
}
@@ -1288,7 +1293,7 @@ impl ChannelMonitor {
1288
1293
}
1289
1294
}
1290
1295
}
1291
- outputs
1296
+ watch_outputs
1292
1297
}
1293
1298
1294
1299
pub fn would_broadcast_at_height ( & self , height : u32 ) -> bool {
0 commit comments