From d271d74bc71cf8a825be38734aaceb57e2d5d0a3 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 6 Feb 2020 00:03:32 -0500 Subject: [PATCH] Use Channel::funding_txo instead of its channel_monitor.funding_txo Currently Channel relies on its own internal channel_monitor copy to keep track of funding_txo information, which is both a bit awkward and not ideal if we want to get rid of the ChannelMonitor copy in Channel. Instead, just duplicate it (its small) and keep it directly in Channel, allowing us to remove the (super awkward) ChannelMonitor::unset_funding_txo(). --- lightning/src/chain/transaction.rs | 2 ++ lightning/src/ln/channel.rs | 35 +++++++++++++++++++----------- lightning/src/ln/channelmanager.rs | 2 +- lightning/src/ln/channelmonitor.rs | 15 ++----------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lightning/src/chain/transaction.rs b/lightning/src/chain/transaction.rs index ce43984eb..0f479ff91 100644 --- a/lightning/src/chain/transaction.rs +++ b/lightning/src/chain/transaction.rs @@ -39,6 +39,8 @@ impl OutPoint { } } +impl_writeable!(OutPoint, 0, { txid, index }); + #[cfg(test)] mod tests { use chain::transaction::OutPoint; diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 5a1e6f264..a4abd32ad 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -303,6 +303,8 @@ pub(super) struct Channel { last_sent_closing_fee: Option<(u64, u64, Signature)>, // (feerate, fee, our_sig) + funding_txo: Option, + /// The hash of the block in which the funding transaction reached our CONF_TARGET. We use this /// to detect unconfirmation after a serialize-unserialize roundtrip where we may not see a full /// series of block_connected/block_disconnected calls. Obviously this is not a guarantee as we @@ -498,6 +500,7 @@ impl Channel { last_sent_closing_fee: None, + funding_txo: None, funding_tx_confirmed_in: None, short_channel_id: None, last_block_connected: Default::default(), @@ -718,6 +721,7 @@ impl Channel { last_sent_closing_fee: None, + funding_txo: None, funding_tx_confirmed_in: None, short_channel_id: None, last_block_connected: Default::default(), @@ -814,7 +818,7 @@ impl Channel { let txins = { let mut ins: Vec = Vec::new(); ins.push(TxIn { - previous_output: self.channel_monitor.get_funding_txo().unwrap().into_bitcoin_outpoint(), + previous_output: self.funding_txo.unwrap().into_bitcoin_outpoint(), script_sig: Script::new(), sequence: ((0x80 as u32) << 8*3) | ((obscured_commitment_transaction_number >> 3*8) as u32), witness: Vec::new(), @@ -1033,7 +1037,7 @@ impl Channel { let txins = { let mut ins: Vec = Vec::new(); ins.push(TxIn { - previous_output: self.channel_monitor.get_funding_txo().unwrap().into_bitcoin_outpoint(), + previous_output: self.funding_txo.unwrap().into_bitcoin_outpoint(), script_sig: Script::new(), sequence: 0xffffffff, witness: Vec::new(), @@ -1461,17 +1465,19 @@ impl Channel { } let funding_txo = OutPoint::new(msg.funding_txid, msg.funding_output_index); - let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh(); - self.channel_monitor.set_funding_info((funding_txo, funding_txo_script)); + self.funding_txo = Some(funding_txo.clone()); let (remote_initial_commitment_tx, local_initial_commitment_tx, our_signature, local_keys) = match self.funding_created_signature(&msg.signature) { Ok(res) => res, Err(e) => { - self.channel_monitor.unset_funding_info(); + self.funding_txo = None; return Err(e); } }; + let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh(); + self.channel_monitor.set_funding_info((funding_txo, funding_txo_script)); + // Now that we're past error-generating stuff, update our local state: self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap()); @@ -2825,7 +2831,7 @@ impl Channel { /// Returns the funding_txo we either got from our peer, or were given by /// get_outbound_funding_created. pub fn get_funding_txo(&self) -> Option { - self.channel_monitor.get_funding_txo() + self.funding_txo } /// Allowed in any state (including after shutdown) @@ -3005,8 +3011,8 @@ impl Channel { } if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 { for (ref tx, index_in_block) in txn_matched.iter().zip(indexes_of_txn_matched) { - if tx.txid() == self.channel_monitor.get_funding_txo().unwrap().txid { - let txo_idx = self.channel_monitor.get_funding_txo().unwrap().index as usize; + if tx.txid() == self.funding_txo.unwrap().txid { + let txo_idx = self.funding_txo.unwrap().index as usize; if txo_idx >= tx.output.len() || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() || tx.output[txo_idx].value != self.channel_value_satoshis { if self.channel_outbound { @@ -3209,18 +3215,18 @@ impl Channel { panic!("Should not have advanced channel commitment tx numbers prior to funding_created"); } - let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh(); - self.channel_monitor.set_funding_info((funding_txo, funding_txo_script)); - + self.funding_txo = Some(funding_txo.clone()); let (our_signature, commitment_tx) = match self.get_outbound_funding_created_signature() { Ok(res) => res, Err(e) => { log_error!(self, "Got bad signatures: {:?}!", e); - self.channel_monitor.unset_funding_info(); + self.funding_txo = None; return Err(e); } }; + let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh(); + self.channel_monitor.set_funding_info((funding_txo, funding_txo_script)); let temporary_channel_id = self.channel_id; // Now that we're past error-generating stuff, update our local state: @@ -3815,6 +3821,7 @@ impl Writeable for Channel { None => 0u8.write(writer)?, } + write_option!(self.funding_txo); write_option!(self.funding_tx_confirmed_in); write_option!(self.short_channel_id); @@ -3967,6 +3974,7 @@ impl> ReadableArgs return Err(DecodeError::InvalidValue), }; + let funding_txo = Readable::read(reader)?; let funding_tx_confirmed_in = Readable::read(reader)?; let short_channel_id = Readable::read(reader)?; @@ -4043,6 +4051,7 @@ impl> ReadableArgs, M: Deref, T return Err(DecodeError::InvalidValue); } - let funding_txo = channel.channel_monitor().get_funding_txo().ok_or(DecodeError::InvalidValue)?; + let funding_txo = channel.get_funding_txo().ok_or(DecodeError::InvalidValue)?; funding_txo_set.insert(funding_txo.clone()); if let Some(ref mut monitor) = args.channel_monitors.get_mut(&funding_txo) { if channel.get_cur_local_commitment_transaction_number() != monitor.get_cur_local_commitment_number() || diff --git a/lightning/src/ln/channelmonitor.rs b/lightning/src/ln/channelmonitor.rs index 2736a425a..f65b5e7f1 100644 --- a/lightning/src/ln/channelmonitor.rs +++ b/lightning/src/ln/channelmonitor.rs @@ -1293,8 +1293,8 @@ impl ChannelMonitor { /// Allows this monitor to scan only for transactions which are applicable. Note that this is /// optional, without it this monitor cannot be used in an SPV client, but you may wish to - /// avoid this (or call unset_funding_info) on a monitor you wish to send to a watchtower as it - /// provides slightly better privacy. + /// avoid this on a monitor you wish to send to a watchtower as it provides slightly better + /// privacy. /// It's the responsibility of the caller to register outpoint and script with passing the former /// value as key to add_update_monitor. pub(super) fn set_funding_info(&mut self, new_funding_info: (OutPoint, Script)) { @@ -1320,17 +1320,6 @@ impl ChannelMonitor { self.commitment_transaction_number_obscure_factor = commitment_transaction_number_obscure_factor; } - pub(super) fn unset_funding_info(&mut self) { - match self.key_storage { - Storage::Local { ref mut funding_info, .. } => { - *funding_info = None; - }, - Storage::Watchtower { .. } => { - panic!("Channel somehow ended up with its internal ChannelMonitor being in Watchtower mode?"); - }, - } - } - /// Gets the funding transaction outpoint of the channel this ChannelMonitor is monitoring for. pub fn get_funding_txo(&self) -> Option { match self.key_storage { -- 2.39.5