Skip to content

Commit 51418ab

Browse files
committed
f! cache txid + debug assert + avoid clones + sighash_single note
1 parent c4d1dc6 commit 51418ab

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,6 +1515,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
15151515
let htlc_commitment_tx_output_idx =
15161516
if let Some(v) = htlc.transaction_output_index { v } else { return None; };
15171517

1518+
let mut htlc_spend_txid_opt = None;
15181519
let mut htlc_spend_tx_opt = None;
15191520
let mut holder_timeout_spend_pending = None;
15201521
let mut htlc_spend_pending = None;
@@ -1523,16 +1524,18 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
15231524
match event.event {
15241525
OnchainEvent::HTLCUpdate { commitment_tx_output_idx, htlc_value_satoshis, .. }
15251526
if commitment_tx_output_idx == Some(htlc_commitment_tx_output_idx) => {
1527+
htlc_spend_txid_opt = Some(&event.txid);
15261528
debug_assert!(htlc_spend_tx_opt.is_none());
1527-
htlc_spend_tx_opt = event.transaction.clone();
1529+
htlc_spend_tx_opt = event.transaction.as_ref();
15281530
debug_assert!(holder_timeout_spend_pending.is_none());
15291531
debug_assert_eq!(htlc_value_satoshis.unwrap(), htlc.amount_msat / 1000);
15301532
holder_timeout_spend_pending = Some(event.confirmation_threshold());
15311533
},
15321534
OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. }
15331535
if commitment_tx_output_idx == htlc_commitment_tx_output_idx => {
1536+
htlc_spend_txid_opt = Some(&event.txid);
15341537
debug_assert!(htlc_spend_tx_opt.is_none());
1535-
htlc_spend_tx_opt = event.transaction.clone();
1538+
htlc_spend_tx_opt = event.transaction.as_ref();
15361539
debug_assert!(htlc_spend_pending.is_none());
15371540
htlc_spend_pending = Some((event.confirmation_threshold(), preimage.is_some()));
15381541
},
@@ -1547,20 +1550,23 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
15471550
}
15481551
let htlc_resolved = self.htlcs_resolved_on_chain.iter()
15491552
.find(|v| if v.commitment_tx_output_idx == Some(htlc_commitment_tx_output_idx) {
1553+
htlc_spend_txid_opt = v.resolving_txid.as_ref();
15501554
debug_assert!(htlc_spend_tx_opt.is_none());
1551-
htlc_spend_tx_opt = v.resolving_tx.clone();
1555+
htlc_spend_tx_opt = v.resolving_tx.as_ref();
15521556
true
15531557
} else { false });
15541558
debug_assert!(holder_timeout_spend_pending.is_some() as u8 + htlc_spend_pending.is_some() as u8 + htlc_resolved.is_some() as u8 <= 1);
15551559

15561560
let htlc_commitment_outpoint = BitcoinOutPoint::new(confirmed_txid.unwrap(), htlc_commitment_tx_output_idx);
15571561
let htlc_output_to_spend =
15581562
if let Some(ref tx) = htlc_spend_tx_opt {
1559-
let htlc_input_idx = tx.input.iter().enumerate()
1563+
// Because HTLCs are signed with SIGHASH_SINGLE, we can locate the correct output
1564+
// by ensuring its adjacent input spends the HTLC output in the commitment.
1565+
let htlc_input_idx_opt = tx.input.iter().enumerate()
15601566
.find(|(_, input)| input.previous_output == htlc_commitment_outpoint)
1561-
.map(|(idx, _)| idx as u32)
1562-
.unwrap();
1563-
BitcoinOutPoint::new(tx.txid(), htlc_input_idx)
1567+
.map(|(idx, _)| idx as u32);
1568+
debug_assert!(htlc_input_idx_opt.is_some());
1569+
BitcoinOutPoint::new(*htlc_spend_txid_opt.unwrap(), htlc_input_idx_opt.unwrap_or(0))
15641570
} else {
15651571
htlc_commitment_outpoint
15661572
};
@@ -1585,9 +1591,8 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
15851591
descriptor: SpendableOutputDescriptor::StaticOutput { .. }
15861592
} = &event.event {
15871593
if event.transaction.as_ref().map(|tx| tx.input.iter().any(|inp| {
1588-
if let Some(ref htlc_spend_tx) = htlc_spend_tx_opt {
1589-
let htlc_spend_txid = htlc_spend_tx.txid();
1590-
tx.txid() == htlc_spend_txid || inp.previous_output.txid == htlc_spend_txid
1594+
if let Some(htlc_spend_txid) = htlc_spend_txid_opt {
1595+
tx.txid() == *htlc_spend_txid || inp.previous_output.txid == *htlc_spend_txid
15911596
} else {
15921597
Some(inp.previous_output.txid) == confirmed_txid &&
15931598
inp.previous_output.vout == htlc_commitment_tx_output_idx

0 commit comments

Comments
 (0)