Skip to content

Commit d8e8496

Browse files
author
Antoine Riard
committed
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 28b1ae0 commit d8e8496

File tree

2 files changed

+47
-20
lines changed

2 files changed

+47
-20
lines changed

src/ln/channelmanager.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5310,7 +5310,11 @@ mod tests {
53105310
false
53115311
} else { true }
53125312
});
5313-
assert_eq!(res.len(), 2);
5313+
assert!(res.len() >= 2);
5314+
assert!(res.len() == 2 || res.len() == 3);
5315+
if res.len() == 3 {
5316+
assert_eq!(res[1], res[2]);
5317+
}
53145318
}
53155319

53165320
assert!(node_txn.is_empty());
@@ -7936,10 +7940,12 @@ mod tests {
79367940
_ => panic!("Unexpected event"),
79377941
}
79387942
let revoked_htlc_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
7939-
assert_eq!(revoked_htlc_txn.len(), 2);
7943+
assert_eq!(revoked_htlc_txn.len(), 3);
7944+
assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]);
79407945
assert_eq!(revoked_htlc_txn[0].input.len(), 1);
79417946
assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), 133);
79427947
check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone());
7948+
check_spends!(revoked_htlc_txn[1], chan_1.3.clone());
79437949

79447950
// B will generate justice tx from A's revoked commitment/HTLC tx
79457951
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1);
@@ -7986,7 +7992,8 @@ mod tests {
79867992
}
79877993
let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
79887994

7989-
assert_eq!(revoked_htlc_txn.len(), 2);
7995+
assert_eq!(revoked_htlc_txn.len(), 3);
7996+
assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]);
79907997
assert_eq!(revoked_htlc_txn[0].input.len(), 1);
79917998
assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), 138);
79927999
check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone());
@@ -8047,8 +8054,9 @@ mod tests {
80478054

80488055
// Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor
80498056
let spend_txn = check_spendable_outputs!(nodes[1], 1);
8050-
assert_eq!(spend_txn.len(), 1);
8057+
assert_eq!(spend_txn.len(), 2);
80518058
check_spends!(spend_txn[0], node_txn[0].clone());
8059+
check_spends!(spend_txn[1], node_txn[2].clone());
80528060
}
80538061

80548062
#[test]
@@ -8078,9 +8086,13 @@ mod tests {
80788086

80798087
// Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor
80808088
let spend_txn = check_spendable_outputs!(nodes[0], 1);
8081-
assert_eq!(spend_txn.len(), 4);
8089+
assert_eq!(spend_txn.len(), 8);
80828090
assert_eq!(spend_txn[0], spend_txn[2]);
8091+
assert_eq!(spend_txn[0], spend_txn[4]);
8092+
assert_eq!(spend_txn[0], spend_txn[6]);
80838093
assert_eq!(spend_txn[1], spend_txn[3]);
8094+
assert_eq!(spend_txn[1], spend_txn[5]);
8095+
assert_eq!(spend_txn[1], spend_txn[7]);
80848096
check_spends!(spend_txn[0], local_txn[0].clone());
80858097
check_spends!(spend_txn[1], node_txn[0].clone());
80868098
}

src/ln/channelmonitor.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,9 +1402,10 @@ impl ChannelMonitor {
14021402
} else { (None, None) }
14031403
}
14041404

1405-
fn broadcast_by_local_state(&self, local_tx: &LocalSignedTx, per_commitment_point: &Option<PublicKey>, delayed_payment_base_key: &Option<SecretKey>) -> (Vec<Transaction>, Vec<SpendableOutputDescriptor>) {
1405+
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>) {
14061406
let mut res = Vec::with_capacity(local_tx.htlc_outputs.len());
14071407
let mut spendable_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
1408+
let mut watch_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
14081409

14091410
macro_rules! add_dynamic_output {
14101411
($father_tx: expr, $vout: expr) => {
@@ -1468,24 +1469,27 @@ impl ChannelMonitor {
14681469
res.push(htlc_success_tx);
14691470
}
14701471
}
1472+
watch_outputs.push(local_tx.tx.output[htlc.transaction_output_index as usize].clone());
14711473
}
14721474

1473-
(res, spendable_outputs)
1475+
(res, spendable_outputs, watch_outputs)
14741476
}
14751477

14761478
/// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet)
14771479
/// revoked using data in local_claimable_outpoints.
14781480
/// Should not be used if check_spend_revoked_transaction succeeds.
1479-
fn check_spend_local_transaction(&self, tx: &Transaction, _height: u32) -> (Vec<Transaction>, Vec<SpendableOutputDescriptor>) {
1481+
fn check_spend_local_transaction(&self, tx: &Transaction, _height: u32) -> (Vec<Transaction>, Vec<SpendableOutputDescriptor>, (Sha256dHash, Vec<TxOut>)) {
14801482
let commitment_txid = tx.txid();
14811483
if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
14821484
if local_tx.txid == commitment_txid {
14831485
match self.key_storage {
14841486
Storage::Local { ref delayed_payment_base_key, ref latest_per_commitment_point, .. } => {
1485-
return self.broadcast_by_local_state(local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key));
1487+
let (local_txn, spendable_outputs, watch_outputs) = self.broadcast_by_local_state(local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key));
1488+
return (local_txn, spendable_outputs, (commitment_txid, watch_outputs));
14861489
},
14871490
Storage::Watchtower { .. } => {
1488-
return self.broadcast_by_local_state(local_tx, &None, &None);
1491+
let (local_txn, spendable_outputs, watch_outputs) = self.broadcast_by_local_state(local_tx, &None, &None);
1492+
return (local_txn, spendable_outputs, (commitment_txid, watch_outputs));
14891493
}
14901494
}
14911495
}
@@ -1494,15 +1498,17 @@ impl ChannelMonitor {
14941498
if local_tx.txid == commitment_txid {
14951499
match self.key_storage {
14961500
Storage::Local { ref delayed_payment_base_key, ref prev_latest_per_commitment_point, .. } => {
1497-
return self.broadcast_by_local_state(local_tx, prev_latest_per_commitment_point, &Some(*delayed_payment_base_key));
1501+
let (local_txn, spendable_outputs, watch_outputs) = self.broadcast_by_local_state(local_tx, prev_latest_per_commitment_point, &Some(*delayed_payment_base_key));
1502+
return (local_txn, spendable_outputs, (commitment_txid, watch_outputs));
14981503
},
14991504
Storage::Watchtower { .. } => {
1500-
return self.broadcast_by_local_state(local_tx, &None, &None);
1505+
let (local_txn, spendable_outputs, watch_outputs) = self.broadcast_by_local_state(local_tx, &None, &None);
1506+
return (local_txn, spendable_outputs, (commitment_txid, watch_outputs));
15011507
}
15021508
}
15031509
}
15041510
}
1505-
(Vec::new(), Vec::new())
1511+
(Vec::new(), Vec::new(), (commitment_txid, Vec::new()))
15061512
}
15071513

15081514
/// Generate a spendable output event when closing_transaction get registered onchain.
@@ -1574,9 +1580,12 @@ impl ChannelMonitor {
15741580
watch_outputs.push(new_outputs);
15751581
}
15761582
if txn.is_empty() {
1577-
let (remote_txn, mut outputs) = self.check_spend_local_transaction(tx, height);
1578-
spendable_outputs.append(&mut outputs);
1579-
txn = remote_txn;
1583+
let (local_txn, mut spendable_output, new_outputs) = self.check_spend_local_transaction(tx, height);
1584+
spendable_outputs.append(&mut spendable_output);
1585+
txn = local_txn;
1586+
if !new_outputs.1.is_empty() {
1587+
watch_outputs.push(new_outputs);
1588+
}
15801589
}
15811590
if !funding_txo.is_none() && txn.is_empty() {
15821591
if let Some(spendable_output) = self.check_spend_closing_transaction(tx) {
@@ -1604,15 +1613,21 @@ impl ChannelMonitor {
16041613
broadcaster.broadcast_transaction(&cur_local_tx.tx);
16051614
match self.key_storage {
16061615
Storage::Local { ref delayed_payment_base_key, ref latest_per_commitment_point, .. } => {
1607-
let (txs, mut outputs) = self.broadcast_by_local_state(&cur_local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key));
1608-
spendable_outputs.append(&mut outputs);
1616+
let (txs, mut spendable_output, new_outputs) = self.broadcast_by_local_state(&cur_local_tx, latest_per_commitment_point, &Some(*delayed_payment_base_key));
1617+
spendable_outputs.append(&mut spendable_output);
1618+
if !new_outputs.is_empty() {
1619+
watch_outputs.push((cur_local_tx.txid.clone(), new_outputs));
1620+
}
16091621
for tx in txs {
16101622
broadcaster.broadcast_transaction(&tx);
16111623
}
16121624
},
16131625
Storage::Watchtower { .. } => {
1614-
let (txs, mut outputs) = self.broadcast_by_local_state(&cur_local_tx, &None, &None);
1615-
spendable_outputs.append(&mut outputs);
1626+
let (txs, mut spendable_output, new_outputs) = self.broadcast_by_local_state(&cur_local_tx, &None, &None);
1627+
spendable_outputs.append(&mut spendable_output);
1628+
if !new_outputs.is_empty() {
1629+
watch_outputs.push((cur_local_tx.txid.clone(), new_outputs));
1630+
}
16161631
for tx in txs {
16171632
broadcaster.broadcast_transaction(&tx);
16181633
}

0 commit comments

Comments
 (0)