Skip to content

Commit 0dccef6

Browse files
Antoine RiardTheBlueMatt
authored andcommitted
Track outputs fron local commitment tx
Aims to detect onchain resolution of channel Modify in consequence test_txn_broadcast to still pass channel_monitor_network_test Modify some tests due to block re-scan caused by detections extensions
1 parent 0bf783e commit 0dccef6

File tree

2 files changed

+46
-20
lines changed

2 files changed

+46
-20
lines changed

src/ln/channelmanager.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5390,7 +5390,10 @@ mod tests {
53905390
false
53915391
} else { true }
53925392
});
5393-
assert_eq!(res.len(), 2);
5393+
assert!(res.len() == 2 || res.len() == 3);
5394+
if res.len() == 3 {
5395+
assert_eq!(res[1], res[2]);
5396+
}
53945397
}
53955398

53965399
assert!(node_txn.is_empty());
@@ -8475,10 +8478,12 @@ mod tests {
84758478
_ => panic!("Unexpected event"),
84768479
}
84778480
let revoked_htlc_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
8478-
assert_eq!(revoked_htlc_txn.len(), 2);
8481+
assert_eq!(revoked_htlc_txn.len(), 3);
8482+
assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]);
84798483
assert_eq!(revoked_htlc_txn[0].input.len(), 1);
84808484
assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), 133);
84818485
check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone());
8486+
check_spends!(revoked_htlc_txn[1], chan_1.3.clone());
84828487

84838488
// B will generate justice tx from A's revoked commitment/HTLC tx
84848489
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1);
@@ -8525,7 +8530,8 @@ mod tests {
85258530
}
85268531
let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
85278532

8528-
assert_eq!(revoked_htlc_txn.len(), 2);
8533+
assert_eq!(revoked_htlc_txn.len(), 3);
8534+
assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]);
85298535
assert_eq!(revoked_htlc_txn[0].input.len(), 1);
85308536
assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), 138);
85318537
check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone());
@@ -8586,8 +8592,9 @@ mod tests {
85868592

85878593
// Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor
85888594
let spend_txn = check_spendable_outputs!(nodes[1], 1);
8589-
assert_eq!(spend_txn.len(), 1);
8595+
assert_eq!(spend_txn.len(), 2);
85908596
check_spends!(spend_txn[0], node_txn[0].clone());
8597+
check_spends!(spend_txn[1], node_txn[2].clone());
85918598
}
85928599

85938600
#[test]
@@ -8617,9 +8624,13 @@ mod tests {
86178624

86188625
// Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor
86198626
let spend_txn = check_spendable_outputs!(nodes[0], 1);
8620-
assert_eq!(spend_txn.len(), 4);
8627+
assert_eq!(spend_txn.len(), 8);
86218628
assert_eq!(spend_txn[0], spend_txn[2]);
8629+
assert_eq!(spend_txn[0], spend_txn[4]);
8630+
assert_eq!(spend_txn[0], spend_txn[6]);
86228631
assert_eq!(spend_txn[1], spend_txn[3]);
8632+
assert_eq!(spend_txn[1], spend_txn[5]);
8633+
assert_eq!(spend_txn[1], spend_txn[7]);
86238634
check_spends!(spend_txn[0], local_txn[0].clone());
86248635
check_spends!(spend_txn[1], node_txn[0].clone());
86258636
}

src/ln/channelmonitor.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,9 +1319,10 @@ impl ChannelMonitor {
13191319
} else { (None, None) }
13201320
}
13211321

1322-
fn broadcast_by_local_state(&self, local_tx: &LocalSignedTx, per_commitment_point: &Option<PublicKey>, delayed_payment_base_key: &Option<SecretKey>) -> (Vec<Transaction>, Vec<SpendableOutputDescriptor>) {
1322+
fn broadcast_by_local_state(&self, local_tx: &LocalSignedTx, per_commitment_point: &Option<PublicKey>, delayed_payment_base_key: &Option<SecretKey>) -> (Vec<Transaction>, Vec<SpendableOutputDescriptor>, Vec<TxOut>) {
13231323
let mut res = Vec::with_capacity(local_tx.htlc_outputs.len());
13241324
let mut spendable_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
1325+
let mut watch_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
13251326

13261327
macro_rules! add_dynamic_output {
13271328
($father_tx: expr, $vout: expr) => {
@@ -1385,24 +1386,27 @@ impl ChannelMonitor {
13851386
res.push(htlc_success_tx);
13861387
}
13871388
}
1389+
watch_outputs.push(local_tx.tx.output[htlc.transaction_output_index as usize].clone());
13881390
}
13891391

1390-
(res, spendable_outputs)
1392+
(res, spendable_outputs, watch_outputs)
13911393
}
13921394

13931395
/// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet)
13941396
/// revoked using data in local_claimable_outpoints.
13951397
/// Should not be used if check_spend_revoked_transaction succeeds.
1396-
fn check_spend_local_transaction(&self, tx: &Transaction, _height: u32) -> (Vec<Transaction>, Vec<SpendableOutputDescriptor>) {
1398+
fn check_spend_local_transaction(&self, tx: &Transaction, _height: u32) -> (Vec<Transaction>, Vec<SpendableOutputDescriptor>, (Sha256dHash, Vec<TxOut>)) {
13971399
let commitment_txid = tx.txid();
13981400
if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
13991401
if local_tx.txid == commitment_txid {
14001402
match self.key_storage {
14011403
Storage::Local { ref delayed_payment_base_key, ref latest_per_commitment_point, .. } => {
1402-
return self.broadcast_by_local_state(local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key));
1404+
let (local_txn, spendable_outputs, watch_outputs) = self.broadcast_by_local_state(local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key));
1405+
return (local_txn, spendable_outputs, (commitment_txid, watch_outputs));
14031406
},
14041407
Storage::Watchtower { .. } => {
1405-
return self.broadcast_by_local_state(local_tx, &None, &None);
1408+
let (local_txn, spendable_outputs, watch_outputs) = self.broadcast_by_local_state(local_tx, &None, &None);
1409+
return (local_txn, spendable_outputs, (commitment_txid, watch_outputs));
14061410
}
14071411
}
14081412
}
@@ -1411,15 +1415,17 @@ impl ChannelMonitor {
14111415
if local_tx.txid == commitment_txid {
14121416
match self.key_storage {
14131417
Storage::Local { ref delayed_payment_base_key, ref prev_latest_per_commitment_point, .. } => {
1414-
return self.broadcast_by_local_state(local_tx, prev_latest_per_commitment_point, &Some(*delayed_payment_base_key));
1418+
let (local_txn, spendable_outputs, watch_outputs) = self.broadcast_by_local_state(local_tx, prev_latest_per_commitment_point, &Some(*delayed_payment_base_key));
1419+
return (local_txn, spendable_outputs, (commitment_txid, watch_outputs));
14151420
},
14161421
Storage::Watchtower { .. } => {
1417-
return self.broadcast_by_local_state(local_tx, &None, &None);
1422+
let (local_txn, spendable_outputs, watch_outputs) = self.broadcast_by_local_state(local_tx, &None, &None);
1423+
return (local_txn, spendable_outputs, (commitment_txid, watch_outputs));
14181424
}
14191425
}
14201426
}
14211427
}
1422-
(Vec::new(), Vec::new())
1428+
(Vec::new(), Vec::new(), (commitment_txid, Vec::new()))
14231429
}
14241430

14251431
/// Generate a spendable output event when closing_transaction get registered onchain.
@@ -1491,9 +1497,12 @@ impl ChannelMonitor {
14911497
watch_outputs.push(new_outputs);
14921498
}
14931499
if txn.is_empty() {
1494-
let (remote_txn, mut outputs) = self.check_spend_local_transaction(tx, height);
1495-
spendable_outputs.append(&mut outputs);
1496-
txn = remote_txn;
1500+
let (local_txn, mut spendable_output, new_outputs) = self.check_spend_local_transaction(tx, height);
1501+
spendable_outputs.append(&mut spendable_output);
1502+
txn = local_txn;
1503+
if !new_outputs.1.is_empty() {
1504+
watch_outputs.push(new_outputs);
1505+
}
14971506
}
14981507
if !funding_txo.is_none() && txn.is_empty() {
14991508
if let Some(spendable_output) = self.check_spend_closing_transaction(tx) {
@@ -1521,15 +1530,21 @@ impl ChannelMonitor {
15211530
broadcaster.broadcast_transaction(&cur_local_tx.tx);
15221531
match self.key_storage {
15231532
Storage::Local { ref delayed_payment_base_key, ref latest_per_commitment_point, .. } => {
1524-
let (txs, mut outputs) = self.broadcast_by_local_state(&cur_local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key));
1525-
spendable_outputs.append(&mut outputs);
1533+
let (txs, mut spendable_output, new_outputs) = self.broadcast_by_local_state(&cur_local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key));
1534+
spendable_outputs.append(&mut spendable_output);
1535+
if !new_outputs.is_empty() {
1536+
watch_outputs.push((cur_local_tx.txid.clone(), new_outputs));
1537+
}
15261538
for tx in txs {
15271539
broadcaster.broadcast_transaction(&tx);
15281540
}
15291541
},
15301542
Storage::Watchtower { .. } => {
1531-
let (txs, mut outputs) = self.broadcast_by_local_state(&cur_local_tx, &None, &None);
1532-
spendable_outputs.append(&mut outputs);
1543+
let (txs, mut spendable_output, new_outputs) = self.broadcast_by_local_state(&cur_local_tx, &None, &None);
1544+
spendable_outputs.append(&mut spendable_output);
1545+
if !new_outputs.is_empty() {
1546+
watch_outputs.push((cur_local_tx.txid.clone(), new_outputs));
1547+
}
15331548
for tx in txs {
15341549
broadcaster.broadcast_transaction(&tx);
15351550
}

0 commit comments

Comments
 (0)