@@ -926,8 +926,7 @@ impl ChannelMonitor {
926
926
/// Attempts to claim a remote commitment transaction's outputs using the revocation key and
927
927
/// data in remote_claimable_outpoints. Will directly claim any HTLC outputs which expire at a
928
928
/// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for
929
- /// HTLC-Success/HTLC-Timeout transactions, and claim them using the revocation key (if
930
- /// applicable) as well.
929
+ /// HTLC-Success/HTLC-Timeout transactions.
931
930
fn check_spend_remote_transaction ( & self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) ) {
932
931
// Most secp and related errors trying to create keys means we have no hope of constructing
933
932
// a spend transaction...so we return no transactions to broadcast
@@ -1207,13 +1206,98 @@ impl ChannelMonitor {
1207
1206
txn_to_broadcast. push ( spend_tx) ;
1208
1207
}
1209
1208
}
1210
- } else {
1211
- //TODO: For each input check if its in our remote_commitment_txn_on_chain map!
1212
1209
}
1213
1210
1214
1211
( txn_to_broadcast, ( commitment_txid, watch_outputs) )
1215
1212
}
1216
1213
1214
+ /// Attempst to claim a remote HTLC-Success/HTLC-Timeout s outputs using the revocation key
1215
+ fn check_spend_remote_htlc ( & self , tx : & Transaction , commitment_number : u64 ) -> Vec < Transaction > {
1216
+
1217
+ let mut txn_to_broadcast = Vec :: new ( ) ;
1218
+
1219
+ let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
1220
+
1221
+ macro_rules! ignore_error {
1222
+ ( $thing : expr ) => {
1223
+ match $thing {
1224
+ Ok ( a) => a,
1225
+ Err ( _) => return txn_to_broadcast
1226
+ }
1227
+ } ;
1228
+ }
1229
+
1230
+ let secret = self . get_secret ( commitment_number) . unwrap ( ) ;
1231
+ let per_commitment_key = ignore_error ! ( SecretKey :: from_slice( & self . secp_ctx, & secret) ) ;
1232
+ let revocation_pubkey = match self . key_storage {
1233
+ KeyStorage :: PrivMode { ref revocation_base_key, .. } => {
1234
+ let per_commitment_point = PublicKey :: from_secret_key ( & self . secp_ctx , & per_commitment_key) ;
1235
+ ignore_error ! ( chan_utils:: derive_public_revocation_key( & self . secp_ctx, & per_commitment_point, & PublicKey :: from_secret_key( & self . secp_ctx, & revocation_base_key) ) )
1236
+ } ,
1237
+ KeyStorage :: SigsMode { ref revocation_base_key, .. } => {
1238
+ let per_commitment_point = PublicKey :: from_secret_key ( & self . secp_ctx , & per_commitment_key) ;
1239
+ ignore_error ! ( chan_utils:: derive_public_revocation_key( & self . secp_ctx, & per_commitment_point, & revocation_base_key) )
1240
+ } ,
1241
+ } ;
1242
+ let delayed_key = match self . their_delayed_payment_base_key {
1243
+ None => return txn_to_broadcast,
1244
+ Some ( their_delayed_payment_base_key) => ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, & PublicKey :: from_secret_key( & self . secp_ctx, & per_commitment_key) , & their_delayed_payment_base_key) ) ,
1245
+ } ;
1246
+ let redeemscript = chan_utils:: get_revokeable_redeemscript ( & revocation_pubkey, self . their_to_self_delay . unwrap ( ) , & delayed_key) ;
1247
+ let revokeable_p2wsh = redeemscript. to_v0_p2wsh ( ) ;
1248
+
1249
+ let mut inputs = Vec :: new ( ) ;
1250
+ let mut amount = 0 ;
1251
+
1252
+ if tx. output [ 0 ] . script_pubkey == revokeable_p2wsh { //HTLC transactions have one txin, one txout
1253
+ inputs. push ( TxIn {
1254
+ previous_output : BitcoinOutPoint {
1255
+ txid : commitment_txid,
1256
+ vout : 0 ,
1257
+ } ,
1258
+ script_sig : Script :: new ( ) ,
1259
+ sequence : 0xfffffffd ,
1260
+ witness : Vec :: new ( ) ,
1261
+ } ) ;
1262
+ amount = tx. output [ 0 ] . value ;
1263
+ }
1264
+
1265
+ if !inputs. is_empty ( ) {
1266
+ let outputs = vec ! ( TxOut {
1267
+ script_pubkey: self . destination_script. clone( ) ,
1268
+ value: amount, //TODO: - fee
1269
+ } ) ;
1270
+
1271
+ let mut spend_tx = Transaction {
1272
+ version : 2 ,
1273
+ lock_time : 0 ,
1274
+ input : inputs,
1275
+ output : outputs,
1276
+ } ;
1277
+
1278
+
1279
+ let sighash_parts = bip143:: SighashComponents :: new ( & spend_tx) ;
1280
+
1281
+ let sig = match self . key_storage {
1282
+ KeyStorage :: PrivMode { ref revocation_base_key, .. } => {
1283
+ let sighash = ignore_error ! ( Message :: from_slice( & sighash_parts. sighash_all( & spend_tx. input[ 0 ] , & redeemscript, amount) [ ..] ) ) ;
1284
+ let revocation_key = ignore_error ! ( chan_utils:: derive_private_revocation_key( & self . secp_ctx, & per_commitment_key, & revocation_base_key) ) ;
1285
+ self . secp_ctx . sign ( & sighash, & revocation_key)
1286
+ }
1287
+ KeyStorage :: SigsMode { .. } => {
1288
+ unimplemented ! ( ) ;
1289
+ }
1290
+ } ;
1291
+ spend_tx. input [ 0 ] . witness . push ( sig. serialize_der ( & self . secp_ctx ) . to_vec ( ) ) ;
1292
+ spend_tx. input [ 0 ] . witness [ 0 ] . push ( SigHashType :: All as u8 ) ;
1293
+ spend_tx. input [ 0 ] . witness . push ( vec ! ( 1 ) ) ;
1294
+ spend_tx. input [ 0 ] . witness . push ( redeemscript. into_bytes ( ) ) ;
1295
+
1296
+ txn_to_broadcast. push ( spend_tx) ;
1297
+ }
1298
+ txn_to_broadcast
1299
+ }
1300
+
1217
1301
fn broadcast_by_local_state ( & self , local_tx : & LocalSignedTx ) -> Vec < Transaction > {
1218
1302
let mut res = Vec :: with_capacity ( local_tx. htlc_outputs . len ( ) ) ;
1219
1303
@@ -1274,20 +1358,29 @@ impl ChannelMonitor {
1274
1358
1275
1359
fn block_connected ( & self , txn_matched : & [ & Transaction ] , height : u32 , broadcaster : & BroadcasterInterface ) -> Vec < ( Sha256dHash , Vec < TxOut > ) > {
1276
1360
let mut watch_outputs = Vec :: new ( ) ;
1361
+ let mut txn: Vec < Transaction > = Vec :: new ( ) ;
1277
1362
for tx in txn_matched {
1278
1363
for txin in tx. input . iter ( ) {
1279
1364
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 ) {
1280
- let ( mut txn, new_outputs) = self . check_spend_remote_transaction ( tx, height) ;
1365
+ let ( mut remote_txn, new_outputs) = self . check_spend_remote_transaction ( tx, height) ;
1366
+ txn. append ( & mut remote_txn) ;
1281
1367
if !new_outputs. 1 . is_empty ( ) {
1282
1368
watch_outputs. push ( new_outputs) ;
1283
1369
}
1284
1370
if txn. is_empty ( ) {
1285
1371
txn = self . check_spend_local_transaction ( tx, height) ;
1286
1372
}
1287
- for tx in txn. iter ( ) {
1288
- broadcaster. broadcast_transaction ( tx) ;
1373
+ } else {
1374
+ let remote_commitment_txn_on_chain = self . remote_commitment_txn_on_chain . lock ( ) . unwrap ( ) ;
1375
+ for ( txid, commitment_number) in remote_commitment_txn_on_chain. iter ( ) {
1376
+ if txin. previous_output . txid == * txid {
1377
+ txn. append ( & mut self . check_spend_remote_htlc ( tx, * commitment_number) ) ;
1378
+ }
1289
1379
}
1290
1380
}
1381
+ for tx in txn. iter ( ) {
1382
+ broadcaster. broadcast_transaction ( tx) ;
1383
+ }
1291
1384
}
1292
1385
}
1293
1386
if let Some ( ref cur_local_tx) = self . current_local_signed_commitment_tx {
0 commit comments