From 9115f66dbc3824b2d655eb5440d122bdd1282eff Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 13 May 2022 05:11:14 +0000 Subject: [PATCH] Store the full event transaction in `OnchainEvent` structs When we see a transaction which generates some `OnchainEvent`, its useful to have the full transaction around for later analysis. Specifically, it lets us check the list of outputs which were spent in the transaction, allowing us to look up, e.g. which HTLC outpoint was spent in a transaction. This will be used in a few commits to do exactly that - figure out which HTLC a given `OnchainEvent` corresponds with. --- lightning/src/chain/channelmonitor.rs | 28 +++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 4bb08724c..5cd031143 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -315,6 +315,7 @@ struct OnchainEventEntry { txid: Txid, height: u32, event: OnchainEvent, + transaction: Option, // Added as optional, but always filled in, in LDK 0.0.110 } impl OnchainEventEntry { @@ -395,6 +396,7 @@ impl Writeable for OnchainEventEntry { fn write(&self, writer: &mut W) -> Result<(), io::Error> { write_tlv_fields!(writer, { (0, self.txid, required), + (1, self.transaction, option), (2, self.height, required), (4, self.event, required), }); @@ -405,15 +407,17 @@ impl Writeable for OnchainEventEntry { impl MaybeReadable for OnchainEventEntry { fn read(reader: &mut R) -> Result, DecodeError> { let mut txid = Txid::all_zeros(); + let mut transaction = None; let mut height = 0; let mut event = None; read_tlv_fields!(reader, { (0, txid, required), + (1, transaction, option), (2, height, required), (4, event, ignorable), }); if let Some(ev) = event { - Ok(Some(Self { txid, height, event: ev })) + Ok(Some(Self { txid, transaction, height, event: ev })) } else { Ok(None) } @@ -1683,8 +1687,10 @@ impl ChannelMonitor { /// as long as we examine both the current counterparty commitment transaction and, if it hasn't /// been revoked yet, the previous one, we we will never "forget" to resolve an HTLC. macro_rules! fail_unbroadcast_htlcs { - ($self: expr, $commitment_tx_type: expr, $commitment_txid_confirmed: expr, + ($self: expr, $commitment_tx_type: expr, $commitment_txid_confirmed: expr, $commitment_tx_confirmed: expr, $commitment_tx_conf_height: expr, $confirmed_htlcs_list: expr, $logger: expr) => { { + debug_assert_eq!($commitment_tx_confirmed.txid(), $commitment_txid_confirmed); + macro_rules! check_htlc_fails { ($txid: expr, $commitment_tx: expr) => { if let Some(ref latest_outpoints) = $self.counterparty_claimable_outpoints.get($txid) { @@ -1724,6 +1730,7 @@ macro_rules! fail_unbroadcast_htlcs { }); let entry = OnchainEventEntry { txid: $commitment_txid_confirmed, + transaction: Some($commitment_tx_confirmed.clone()), height: $commitment_tx_conf_height, event: OnchainEvent::HTLCUpdate { source: (**source).clone(), @@ -2155,13 +2162,13 @@ impl ChannelMonitorImpl { self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number); if let Some(per_commitment_data) = per_commitment_option { - fail_unbroadcast_htlcs!(self, "revoked_counterparty", commitment_txid, height, + fail_unbroadcast_htlcs!(self, "revoked_counterparty", commitment_txid, tx, height, per_commitment_data.iter().map(|(htlc, htlc_source)| (htlc, htlc_source.as_ref().map(|htlc_source| htlc_source.as_ref())) ), logger); } else { debug_assert!(false, "We should have per-commitment option for any recognized old commitment txn"); - fail_unbroadcast_htlcs!(self, "revoked counterparty", commitment_txid, height, + fail_unbroadcast_htlcs!(self, "revoked counterparty", commitment_txid, tx, height, [].iter().map(|reference| *reference), logger); } } @@ -2179,7 +2186,7 @@ impl ChannelMonitorImpl { self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number); log_info!(logger, "Got broadcast of non-revoked counterparty commitment transaction {}", commitment_txid); - fail_unbroadcast_htlcs!(self, "counterparty", commitment_txid, height, + fail_unbroadcast_htlcs!(self, "counterparty", commitment_txid, tx, height, per_commitment_data.iter().map(|(htlc, htlc_source)| (htlc, htlc_source.as_ref().map(|htlc_source| htlc_source.as_ref())) ), logger); @@ -2338,7 +2345,7 @@ impl ChannelMonitorImpl { let res = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, height); let mut to_watch = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, tx); append_onchain_update!(res, to_watch); - fail_unbroadcast_htlcs!(self, "latest holder", commitment_txid, height, + fail_unbroadcast_htlcs!(self, "latest holder", commitment_txid, tx, height, self.current_holder_commitment_tx.htlc_outputs.iter() .map(|(htlc, _, htlc_source)| (htlc, htlc_source.as_ref())), logger); } else if let &Some(ref holder_tx) = &self.prev_holder_signed_commitment_tx { @@ -2348,7 +2355,7 @@ impl ChannelMonitorImpl { let res = self.get_broadcasted_holder_claims(holder_tx, height); let mut to_watch = self.get_broadcasted_holder_watch_outputs(holder_tx, tx); append_onchain_update!(res, to_watch); - fail_unbroadcast_htlcs!(self, "previous holder", commitment_txid, height, + fail_unbroadcast_htlcs!(self, "previous holder", commitment_txid, tx, height, holder_tx.htlc_outputs.iter().map(|(htlc, _, htlc_source)| (htlc, htlc_source.as_ref())), logger); } @@ -2514,6 +2521,7 @@ impl ChannelMonitorImpl { let txid = tx.txid(); self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry { txid, + transaction: Some((*tx).clone()), height: height, event: OnchainEvent::FundingSpendConfirmation { on_local_output_csv: balance_spendable_csv, @@ -2932,7 +2940,7 @@ impl ChannelMonitorImpl { let outbound_htlc = $holder_tx == htlc_output.offered; if !outbound_htlc || revocation_sig_claim { self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry { - txid: tx.txid(), height, + txid: tx.txid(), height, transaction: Some(tx.clone()), event: OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx: input.previous_output.vout, preimage: if accepted_preimage_claim || offered_preimage_claim { @@ -2984,6 +2992,7 @@ impl ChannelMonitorImpl { self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry { txid: tx.txid(), height, + transaction: Some(tx.clone()), event: OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx: input.previous_output.vout, preimage: Some(payment_preimage), @@ -3004,6 +3013,7 @@ impl ChannelMonitorImpl { } else { false }) { self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry { txid: tx.txid(), + transaction: Some(tx.clone()), height, event: OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx: input.previous_output.vout, @@ -3030,6 +3040,7 @@ impl ChannelMonitorImpl { }); let entry = OnchainEventEntry { txid: tx.txid(), + transaction: Some(tx.clone()), height, event: OnchainEvent::HTLCUpdate { source, payment_hash, @@ -3103,6 +3114,7 @@ impl ChannelMonitorImpl { if let Some(spendable_output) = spendable_output { let entry = OnchainEventEntry { txid: tx.txid(), + transaction: Some(tx.clone()), height: height, event: OnchainEvent::MaturingOutput { descriptor: spendable_output.clone() }, }; -- 2.39.5