X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmonitor.rs;h=0dbf98c72df96e2b7b12a49afc497d54b785a58b;hb=7159d1546ae92281a7e0533813a6e7558f16354a;hp=d24a5f528c0a2c45339bd8c537c29a051970a72a;hpb=ba75b3ecd7f88a79ff6392a5229c4ab6c14a8591;p=rust-lightning diff --git a/lightning/src/ln/channelmonitor.rs b/lightning/src/ln/channelmonitor.rs index d24a5f52..0dbf98c7 100644 --- a/lightning/src/ln/channelmonitor.rs +++ b/lightning/src/ln/channelmonitor.rs @@ -383,6 +383,28 @@ pub(crate) const LATENCY_GRACE_PERIOD_BLOCKS: u32 = 3; /// solved by a previous claim tx. What we want to avoid is reorg evicting our claim tx and us not /// keeping bumping another claim tx to solve the outpoint. pub(crate) const ANTI_REORG_DELAY: u32 = 6; +/// Number of blocks before confirmation at which we fail back an un-relayed HTLC or at which we +/// refuse to accept a new HTLC. +/// +/// This is used for a few separate purposes: +/// 1) if we've received an MPP HTLC to us and it expires within this many blocks and we are +/// waiting on additional parts (or waiting on the preimage for any HTLC from the user), we will +/// fail this HTLC, +/// 2) if we receive an HTLC within this many blocks of its expiry (plus one to avoid a race +/// condition with the above), we will fail this HTLC without telling the user we received it, +/// 3) if we are waiting on a connection or a channel state update to send an HTLC to a peer, and +/// that HTLC expires within this many blocks, we will simply fail the HTLC instead. +/// +/// (1) is all about protecting us - we need enough time to update the channel state before we hit +/// CLTV_CLAIM_BUFFER, at which point we'd go on chain to claim the HTLC with the preimage. +/// +/// (2) is the same, but with an additional buffer to avoid accepting an HTLC which is immediately +/// in a race condition between the user connecting a block (which would fail it) and the user +/// providing us the preimage (which would claim it). +/// +/// (3) is about our counterparty - we don't want to relay an HTLC to a counterparty when they may +/// end up force-closing the channel on us to claim it. +pub(crate) const HTLC_FAIL_BACK_BUFFER: u32 = CLTV_CLAIM_BUFFER + LATENCY_GRACE_PERIOD_BLOCKS; #[derive(Clone, PartialEq)] struct LocalSignedTx { @@ -421,7 +443,7 @@ pub(crate) enum InputMaterial { amount: u64, }, Funding { - channel_value: u64, + funding_redeemscript: Script, } } @@ -449,9 +471,9 @@ impl Writeable for InputMaterial { preimage.write(writer)?; writer.write_all(&byte_utils::be64_to_array(*amount))?; }, - &InputMaterial::Funding { ref channel_value } => { + &InputMaterial::Funding { ref funding_redeemscript } => { writer.write_all(&[3; 1])?; - channel_value.write(writer)?; + funding_redeemscript.write(writer)?; } } Ok(()) @@ -498,9 +520,8 @@ impl Readable for InputMaterial { } }, 3 => { - let channel_value = Readable::read(reader)?; InputMaterial::Funding { - channel_value + funding_redeemscript: Readable::read(reader)?, } } _ => return Err(DecodeError::InvalidValue), @@ -553,12 +574,7 @@ const MIN_SERIALIZATION_VERSION: u8 = 1; #[derive(Clone)] pub(super) enum ChannelMonitorUpdateStep { LatestLocalCommitmentTXInfo { - // TODO: We really need to not be generating a fully-signed transaction in Channel and - // passing it here, we need to hold off so that the ChanSigner can enforce a - // only-sign-local-state-for-broadcast once invariant: commitment_tx: LocalCommitmentTransaction, - local_keys: chan_utils::TxCreationKeys, - feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>, }, LatestRemoteCommitmentTXInfo { @@ -591,11 +607,9 @@ pub(super) enum ChannelMonitorUpdateStep { impl Writeable for ChannelMonitorUpdateStep { fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { match self { - &ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { ref commitment_tx, ref local_keys, ref feerate_per_kw, ref htlc_outputs } => { + &ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { ref commitment_tx, ref htlc_outputs } => { 0u8.write(w)?; commitment_tx.write(w)?; - local_keys.write(w)?; - feerate_per_kw.write(w)?; (htlc_outputs.len() as u64).write(w)?; for &(ref output, ref signature, ref source) in htlc_outputs.iter() { output.write(w)?; @@ -641,8 +655,6 @@ impl Readable for ChannelMonitorUpdateStep { 0u8 => { Ok(ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx: Readable::read(r)?, - local_keys: Readable::read(r)?, - feerate_per_kw: Readable::read(r)?, htlc_outputs: { let len: u64 = Readable::read(r)?; let mut res = Vec::new(); @@ -747,7 +759,7 @@ pub struct ChannelMonitor { // various monitors for one channel being out of sync, and us broadcasting a local // transaction for which we have deleted claim information on some watchtowers. prev_local_signed_commitment_tx: Option, - current_local_signed_commitment_tx: Option, + current_local_commitment_tx: LocalSignedTx, // Used just for ChannelManager to make sure it has the latest channel data during // deserialization @@ -777,9 +789,16 @@ pub struct ChannelMonitor { #[cfg(not(test))] onchain_tx_handler: OnchainTxHandler, - // Used to detect programming bug due to unsafe monitor update sequence { ChannelForceClosed, LatestLocalCommitmentTXInfo } + // This is set when the Channel[Manager] generated a ChannelMonitorUpdate which indicated the + // channel has been force-closed. After this is set, no further local commitment transaction + // updates may occur, and we panic!() if one is provided. lockdown_from_offchain: bool, + // Set once we've signed a local commitment transaction and handed it over to our + // OnchainTxHandler. After this is set, no future updates to our local commitment transactions + // may occur, and we fail any such monitor updates. + local_tx_signed: bool, + // We simply modify last_block_hash in Channel's block_connected so that serialization is // consistent but hopefully the users' copy handles block_connected in a consistent way. // (we do *not*, however, update them in update_monitor to ensure any local user copies keep @@ -818,12 +837,14 @@ impl PartialEq for ChannelMonitor { self.prev_local_signed_commitment_tx != other.prev_local_signed_commitment_tx || self.current_remote_commitment_number != other.current_remote_commitment_number || self.current_local_commitment_number != other.current_local_commitment_number || - self.current_local_signed_commitment_tx != other.current_local_signed_commitment_tx || + self.current_local_commitment_tx != other.current_local_commitment_tx || self.payment_preimages != other.payment_preimages || self.pending_htlcs_updated != other.pending_htlcs_updated || self.pending_events.len() != other.pending_events.len() || // We trust events to round-trip properly self.onchain_events_waiting_threshold_conf != other.onchain_events_waiting_threshold_conf || - self.outputs_to_watch != other.outputs_to_watch + self.outputs_to_watch != other.outputs_to_watch || + self.lockdown_from_offchain != other.lockdown_from_offchain || + self.local_tx_signed != other.local_tx_signed { false } else { @@ -972,12 +993,7 @@ impl ChannelMonitor { writer.write_all(&[0; 1])?; } - if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx { - writer.write_all(&[1; 1])?; - serialize_local_tx!(cur_local_tx); - } else { - writer.write_all(&[0; 1])?; - } + serialize_local_tx!(self.current_local_commitment_tx); writer.write_all(&byte_utils::be48_to_array(self.current_remote_commitment_number))?; writer.write_all(&byte_utils::be48_to_array(self.current_local_commitment_number))?; @@ -1029,6 +1045,7 @@ impl ChannelMonitor { self.onchain_tx_handler.write(writer)?; self.lockdown_from_offchain.write(writer)?; + self.local_tx_signed.write(writer)?; Ok(()) } @@ -1040,12 +1057,34 @@ impl ChannelMonitor { their_htlc_base_key: &PublicKey, their_delayed_payment_base_key: &PublicKey, their_to_self_delay: u16, funding_redeemscript: Script, channel_value_satoshis: u64, commitment_transaction_number_obscure_factor: u64, + initial_local_commitment_tx: LocalCommitmentTransaction, logger: Arc) -> ChannelMonitor { assert!(commitment_transaction_number_obscure_factor <= (1 << 48)); let our_channel_close_key_hash = Hash160::hash(&shutdown_pubkey.serialize()); let shutdown_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_close_key_hash[..]).into_script(); + let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys.clone(), their_to_self_delay, logger.clone()); + + let local_tx_sequence = initial_local_commitment_tx.without_valid_witness().input[0].sequence as u64; + let local_tx_locktime = initial_local_commitment_tx.without_valid_witness().lock_time as u64; + let local_commitment_tx = LocalSignedTx { + txid: initial_local_commitment_tx.txid(), + revocation_key: initial_local_commitment_tx.local_keys.revocation_key, + a_htlc_key: initial_local_commitment_tx.local_keys.a_htlc_key, + b_htlc_key: initial_local_commitment_tx.local_keys.b_htlc_key, + delayed_payment_key: initial_local_commitment_tx.local_keys.a_delayed_payment_key, + per_commitment_point: initial_local_commitment_tx.local_keys.per_commitment_point, + feerate_per_kw: initial_local_commitment_tx.feerate_per_kw, + htlc_outputs: Vec::new(), // There are never any HTLCs in the initial commitment transactions + }; + // Returning a monitor error before updating tracking points means in case of using + // a concurrent watchtower implementation for same channel, if this one doesn't + // reject update as we do, you MAY have the latest local valid commitment tx onchain + // for which you want to spend outputs. We're NOT robust again this scenario right + // now but we should consider it later. + onchain_tx_handler.provide_latest_local_tx(initial_local_commitment_tx).unwrap(); + ChannelMonitor { latest_update_id: 0, commitment_transaction_number_obscure_factor, @@ -1055,14 +1094,14 @@ impl ChannelMonitor { broadcasted_remote_payment_script: None, shutdown_script, - keys: keys.clone(), + keys, funding_info, current_remote_commitment_txid: None, prev_remote_commitment_txid: None, their_htlc_base_key: their_htlc_base_key.clone(), their_delayed_payment_base_key: their_delayed_payment_base_key.clone(), - funding_redeemscript: funding_redeemscript.clone(), + funding_redeemscript, channel_value_satoshis: channel_value_satoshis, their_cur_revocation_points: None, @@ -1075,9 +1114,9 @@ impl ChannelMonitor { remote_hash_commitment_number: HashMap::new(), prev_local_signed_commitment_tx: None, - current_local_signed_commitment_tx: None, + current_local_commitment_tx: local_commitment_tx, current_remote_commitment_number: 1 << 48, - current_local_commitment_number: 0xffff_ffff_ffff, + current_local_commitment_number: 0xffff_ffff_ffff - ((((local_tx_sequence & 0xffffff) << 3*8) | (local_tx_locktime as u64 & 0xffffff)) ^ commitment_transaction_number_obscure_factor), payment_preimages: HashMap::new(), pending_htlcs_updated: Vec::new(), @@ -1086,9 +1125,10 @@ impl ChannelMonitor { onchain_events_waiting_threshold_conf: HashMap::new(), outputs_to_watch: HashMap::new(), - onchain_tx_handler: OnchainTxHandler::new(destination_script.clone(), keys, their_to_self_delay, logger.clone()), + onchain_tx_handler, lockdown_from_offchain: false, + local_tx_signed: false, last_block_hash: Default::default(), secp_ctx: Secp256k1::new(), @@ -1113,13 +1153,13 @@ impl ChannelMonitor { } if !self.payment_preimages.is_empty() { - let local_signed_commitment_tx = self.current_local_signed_commitment_tx.as_ref().expect("Channel needs at least an initial commitment tx !"); + let cur_local_signed_commitment_tx = &self.current_local_commitment_tx; let prev_local_signed_commitment_tx = self.prev_local_signed_commitment_tx.as_ref(); let min_idx = self.get_min_seen_secret(); let remote_hash_commitment_number = &mut self.remote_hash_commitment_number; self.payment_preimages.retain(|&k, _| { - for &(ref htlc, _, _) in &local_signed_commitment_tx.htlc_outputs { + for &(ref htlc, _, _) in cur_local_signed_commitment_tx.htlc_outputs.iter() { if k == htlc.payment_hash { return true } @@ -1204,17 +1244,23 @@ impl ChannelMonitor { /// is important that any clones of this channel monitor (including remote clones) by kept /// up-to-date as our local commitment transaction is updated. /// Panics if set_their_to_self_delay has never been called. - pub(super) fn provide_latest_local_commitment_tx_info(&mut self, mut commitment_tx: LocalCommitmentTransaction, local_keys: chan_utils::TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>) -> Result<(), MonitorUpdateError> { + pub(super) fn provide_latest_local_commitment_tx_info(&mut self, commitment_tx: LocalCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>) -> Result<(), MonitorUpdateError> { + if self.local_tx_signed { + return Err(MonitorUpdateError("A local commitment tx has already been signed, no new local commitment txn can be sent to our counterparty")); + } let txid = commitment_tx.txid(); let sequence = commitment_tx.without_valid_witness().input[0].sequence as u64; let locktime = commitment_tx.without_valid_witness().lock_time as u64; - let mut htlcs = Vec::with_capacity(htlc_outputs.len()); - for htlc in htlc_outputs.clone() { - if let Some(_) = htlc.0.transaction_output_index { - htlcs.push((htlc.0, htlc.1, None)); - } - } - commitment_tx.set_htlc_cache(local_keys.clone(), feerate_per_kw, htlcs); + let mut new_local_commitment_tx = LocalSignedTx { + txid, + revocation_key: commitment_tx.local_keys.revocation_key, + a_htlc_key: commitment_tx.local_keys.a_htlc_key, + b_htlc_key: commitment_tx.local_keys.b_htlc_key, + delayed_payment_key: commitment_tx.local_keys.a_delayed_payment_key, + per_commitment_point: commitment_tx.local_keys.per_commitment_point, + feerate_per_kw: commitment_tx.feerate_per_kw, + htlc_outputs: htlc_outputs, + }; // Returning a monitor error before updating tracking points means in case of using // a concurrent watchtower implementation for same channel, if this one doesn't // reject update as we do, you MAY have the latest local valid commitment tx onchain @@ -1224,17 +1270,8 @@ impl ChannelMonitor { return Err(MonitorUpdateError("Local commitment signed has already been signed, no further update of LOCAL commitment transaction is allowed")); } self.current_local_commitment_number = 0xffff_ffff_ffff - ((((sequence & 0xffffff) << 3*8) | (locktime as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor); - self.prev_local_signed_commitment_tx = self.current_local_signed_commitment_tx.take(); - self.current_local_signed_commitment_tx = Some(LocalSignedTx { - txid, - revocation_key: local_keys.revocation_key, - a_htlc_key: local_keys.a_htlc_key, - b_htlc_key: local_keys.b_htlc_key, - delayed_payment_key: local_keys.a_delayed_payment_key, - per_commitment_point: local_keys.per_commitment_point, - feerate_per_kw, - htlc_outputs: htlc_outputs, - }); + mem::swap(&mut new_local_commitment_tx, &mut self.current_local_commitment_tx); + self.prev_local_signed_commitment_tx = Some(new_local_commitment_tx); Ok(()) } @@ -1256,9 +1293,9 @@ impl ChannelMonitor { pub(super) fn update_monitor_ooo(&mut self, mut updates: ChannelMonitorUpdate) -> Result<(), MonitorUpdateError> { for update in updates.updates.drain(..) { match update { - ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => { + ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, htlc_outputs } => { if self.lockdown_from_offchain { panic!(); } - self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)? + self.provide_latest_local_commitment_tx_info(commitment_tx, htlc_outputs)? }, ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } => self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point), @@ -1287,9 +1324,9 @@ impl ChannelMonitor { } for update in updates.updates.drain(..) { match update { - ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, local_keys, feerate_per_kw, htlc_outputs } => { + ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo { commitment_tx, htlc_outputs } => { if self.lockdown_from_offchain { panic!(); } - self.provide_latest_local_commitment_tx_info(commitment_tx, local_keys, feerate_per_kw, htlc_outputs)? + self.provide_latest_local_commitment_tx_info(commitment_tx, htlc_outputs)? }, ChannelMonitorUpdateStep::LatestRemoteCommitmentTXInfo { unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point } => self.provide_latest_remote_commitment_tx_info(&unsigned_commitment_tx, htlc_outputs, commitment_number, their_revocation_point), @@ -1640,8 +1677,18 @@ impl ChannelMonitor { for &(ref htlc, _, _) in local_tx.htlc_outputs.iter() { if let Some(transaction_output_index) = htlc.transaction_output_index { - let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { Some(*preimage) } else { None }; - claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: local_tx.txid, vout: transaction_output_index as u32 }, witness_data: InputMaterial::LocalHTLC { preimage, amount: htlc.amount_msat / 1000 }}); + claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: local_tx.txid, vout: transaction_output_index as u32 }, + witness_data: InputMaterial::LocalHTLC { + preimage: if !htlc.offered { + if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { + Some(preimage.clone()) + } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { None }, + amount: htlc.amount_msat, + }}); watch_outputs.push(commitment_tx.output[transaction_output_index as usize].clone()); } } @@ -1691,15 +1738,12 @@ impl ChannelMonitor { // HTLCs set may differ between last and previous local commitment txn, in case of one them hitting chain, ensure we cancel all HTLCs backward let mut is_local_tx = false; - if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { - if local_tx.txid == commitment_txid { - is_local_tx = true; - log_trace!(self, "Got latest local commitment tx broadcast, searching for available HTLCs to claim"); - let mut res = self.broadcast_by_local_state(tx, local_tx); - append_onchain_update!(res); - } - } - if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx { + if self.current_local_commitment_tx.txid == commitment_txid { + is_local_tx = true; + log_trace!(self, "Got latest local commitment tx broadcast, searching for available HTLCs to claim"); + let mut res = self.broadcast_by_local_state(tx, &self.current_local_commitment_tx); + append_onchain_update!(res); + } else if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx { if local_tx.txid == commitment_txid { is_local_tx = true; log_trace!(self, "Got previous local commitment tx broadcast, searching for available HTLCs to claim"); @@ -1721,9 +1765,7 @@ impl ChannelMonitor { } if is_local_tx { - if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { - fail_dust_htlcs_after_threshold_conf!(local_tx); - } + fail_dust_htlcs_after_threshold_conf!(self.current_local_commitment_tx); if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx { fail_dust_htlcs_after_threshold_conf!(local_tx); } @@ -1743,21 +1785,26 @@ impl ChannelMonitor { /// In any-case, choice is up to the user. pub fn get_latest_local_commitment_txn(&mut self) -> Vec { log_trace!(self, "Getting signed latest local commitment transaction!"); - if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx() { + self.local_tx_signed = true; + if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(&self.funding_redeemscript) { let txid = commitment_tx.txid(); let mut res = vec![commitment_tx]; - if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { - for htlc in local_tx.htlc_outputs.iter() { - if let Some(htlc_index) = htlc.0.transaction_output_index { - let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None }; - if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) { - res.push(htlc_tx); - } + for htlc in self.current_local_commitment_tx.htlc_outputs.iter() { + if let Some(vout) = htlc.0.transaction_output_index { + let preimage = if !htlc.0.offered { + if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { None }; + if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx( + &::bitcoin::OutPoint { txid, vout }, &preimage) { + res.push(htlc_tx); } } - // We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do. - // The data will be re-generated and tracked in check_spend_local_transaction if we get a confirmation. } + // We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do. + // The data will be re-generated and tracked in check_spend_local_transaction if we get a confirmation. return res } Vec::new() @@ -1769,16 +1816,20 @@ impl ChannelMonitor { #[cfg(test)] pub fn unsafe_get_latest_local_commitment_txn(&mut self) -> Vec { log_trace!(self, "Getting signed copy of latest local commitment transaction!"); - if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx() { + if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx(&self.funding_redeemscript) { let txid = commitment_tx.txid(); let mut res = vec![commitment_tx]; - if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx { - for htlc in local_tx.htlc_outputs.iter() { - if let Some(htlc_index) = htlc.0.transaction_output_index { - let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None }; - if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) { - res.push(htlc_tx); - } + for htlc in self.current_local_commitment_tx.htlc_outputs.iter() { + if let Some(vout) = htlc.0.transaction_output_index { + let preimage = if !htlc.0.offered { + if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + } + } else { None }; + if let Some(htlc_tx) = self.onchain_tx_handler.unsafe_get_fully_signed_htlc_tx( + &::bitcoin::OutPoint { txid, vout }, &preimage) { + res.push(htlc_tx); } } } @@ -1847,21 +1898,17 @@ impl ChannelMonitor { self.is_paying_spendable_output(&tx, height); } - let should_broadcast = if let Some(_) = self.current_local_signed_commitment_tx { - self.would_broadcast_at_height(height) - } else { false }; + let should_broadcast = self.would_broadcast_at_height(height); if should_broadcast { - claimable_outpoints.push(ClaimRequest { absolute_timelock: height, aggregable: false, outpoint: BitcoinOutPoint { txid: self.funding_info.0.txid.clone(), vout: self.funding_info.0.index as u32 }, witness_data: InputMaterial::Funding { channel_value: self.channel_value_satoshis }}); - } - if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx { - if should_broadcast { - if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx() { - let (mut new_outpoints, new_outputs, _) = self.broadcast_by_local_state(&commitment_tx, cur_local_tx); - if !new_outputs.is_empty() { - watch_outputs.push((cur_local_tx.txid.clone(), new_outputs)); - } - claimable_outpoints.append(&mut new_outpoints); + claimable_outpoints.push(ClaimRequest { absolute_timelock: height, aggregable: false, outpoint: BitcoinOutPoint { txid: self.funding_info.0.txid.clone(), vout: self.funding_info.0.index as u32 }, witness_data: InputMaterial::Funding { funding_redeemscript: self.funding_redeemscript.clone() }}); + } + if should_broadcast { + if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(&self.funding_redeemscript) { + let (mut new_outpoints, new_outputs, _) = self.broadcast_by_local_state(&commitment_tx, &self.current_local_commitment_tx); + if !new_outputs.is_empty() { + watch_outputs.push((self.current_local_commitment_tx.txid.clone(), new_outputs)); } + claimable_outpoints.append(&mut new_outpoints); } } if let Some(events) = self.onchain_events_waiting_threshold_conf.remove(&height) { @@ -1957,9 +2004,7 @@ impl ChannelMonitor { } } - if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx { - scan_commitment!(cur_local_tx.htlc_outputs.iter().map(|&(ref a, _, _)| a), true); - } + scan_commitment!(self.current_local_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, _)| a), true); if let Some(ref txid) = self.current_remote_commitment_txid { if let Some(ref htlc_outputs) = self.remote_claimable_outpoints.get(txid) { @@ -2050,11 +2095,9 @@ impl ChannelMonitor { } } - if let Some(ref current_local_signed_commitment_tx) = self.current_local_signed_commitment_tx { - if input.previous_output.txid == current_local_signed_commitment_tx.txid { - scan_commitment!(current_local_signed_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, ref b)| (a, b.as_ref())), - "our latest local commitment tx", true); - } + if input.previous_output.txid == self.current_local_commitment_tx.txid { + scan_commitment!(self.current_local_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, ref b)| (a, b.as_ref())), + "our latest local commitment tx", true); } if let Some(ref prev_local_signed_commitment_tx) = self.prev_local_signed_commitment_tx { if input.previous_output.txid == prev_local_signed_commitment_tx.txid { @@ -2339,14 +2382,7 @@ impl ReadableArgs> for (Sha256dH }, _ => return Err(DecodeError::InvalidValue), }; - - let current_local_signed_commitment_tx = match ::read(reader)? { - 0 => None, - 1 => { - Some(read_local_tx!()) - }, - _ => return Err(DecodeError::InvalidValue), - }; + let current_local_commitment_tx = read_local_tx!(); let current_remote_commitment_number = ::read(reader)?.0; let current_local_commitment_number = ::read(reader)?.0; @@ -2421,6 +2457,7 @@ impl ReadableArgs> for (Sha256dH let onchain_tx_handler = ReadableArgs::read(reader, logger.clone())?; let lockdown_from_offchain = Readable::read(reader)?; + let local_tx_signed = Readable::read(reader)?; Ok((last_block_hash.clone(), ChannelMonitor { latest_update_id, @@ -2451,7 +2488,7 @@ impl ReadableArgs> for (Sha256dH remote_hash_commitment_number, prev_local_signed_commitment_tx, - current_local_signed_commitment_tx, + current_local_commitment_tx, current_remote_commitment_number, current_local_commitment_number, @@ -2465,6 +2502,7 @@ impl ReadableArgs> for (Sha256dH onchain_tx_handler, lockdown_from_offchain, + local_tx_signed, last_block_hash, secp_ctx: Secp256k1::new(), @@ -2490,7 +2528,7 @@ mod tests { use ln::channelmonitor::ChannelMonitor; use ln::onchaintx::{OnchainTxHandler, InputDescriptors}; use ln::chan_utils; - use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, LocalCommitmentTransaction}; + use ln::chan_utils::{HTLCOutputInCommitment, LocalCommitmentTransaction}; use util::test_utils::TestLogger; use secp256k1::key::{SecretKey,PublicKey}; use secp256k1::Secp256k1; @@ -2504,20 +2542,6 @@ mod tests { let logger = Arc::new(TestLogger::new()); let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); - macro_rules! dummy_keys { - () => { - { - TxCreationKeys { - per_commitment_point: dummy_key.clone(), - revocation_key: dummy_key.clone(), - a_htlc_key: dummy_key.clone(), - b_htlc_key: dummy_key.clone(), - a_delayed_payment_key: dummy_key.clone(), - b_payment_key: dummy_key.clone(), - } - } - } - } let dummy_tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: Vec::new() }; let mut preimages = Vec::new(); @@ -2584,9 +2608,9 @@ mod tests { (OutPoint { txid: Sha256dHash::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()), &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[44; 32]).unwrap()), &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[45; 32]).unwrap()), - 10, Script::new(), 46, 0, logger.clone()); + 10, Script::new(), 46, 0, LocalCommitmentTransaction::dummy(), logger.clone()); - monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::dummy(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..10])).unwrap(); + monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::dummy(), preimages_to_local_htlcs!(preimages[0..10])).unwrap(); monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key); monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key); monitor.provide_latest_remote_commitment_tx_info(&dummy_tx, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key); @@ -2612,7 +2636,7 @@ mod tests { // Now update local commitment tx info, pruning only element 18 as we still care about the // previous commitment tx's preimages too - monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::dummy(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..5])).unwrap(); + monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::dummy(), preimages_to_local_htlcs!(preimages[0..5])).unwrap(); secret[0..32].clone_from_slice(&hex::decode("2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8").unwrap()); monitor.provide_secret(281474976710653, secret.clone()).unwrap(); assert_eq!(monitor.payment_preimages.len(), 12); @@ -2620,7 +2644,7 @@ mod tests { test_preimages_exist!(&preimages[18..20], monitor); // But if we do it again, we'll prune 5-10 - monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::dummy(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..3])).unwrap(); + monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::dummy(), preimages_to_local_htlcs!(preimages[0..3])).unwrap(); secret[0..32].clone_from_slice(&hex::decode("27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116").unwrap()); monitor.provide_secret(281474976710652, secret.clone()).unwrap(); assert_eq!(monitor.payment_preimages.len(), 5);