X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fchannelmonitor.rs;h=a9ef37564277143c3bd4742c2d3376322ae01e55;hb=534d7317cf7ee4dd9294b6c028eaa470fb9257db;hp=53b53797acad625093951753790528a352a3fc79;hpb=b9aa902e51abc1c7d1f7c3a36cbb254c40f90739;p=rust-lightning diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 53b53797..a9ef3756 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -2339,8 +2339,16 @@ impl ChannelMonitorImpl { F::Target: FeeEstimator, L::Target: Logger, { - log_info!(logger, "Applying update to monitor {}, bringing update_id from {} to {} with {} changes.", - log_funding_info!(self), self.latest_update_id, updates.update_id, updates.updates.len()); + if self.latest_update_id == CLOSED_CHANNEL_UPDATE_ID && updates.update_id == CLOSED_CHANNEL_UPDATE_ID { + log_info!(logger, "Applying post-force-closed update to monitor {} with {} change(s).", + log_funding_info!(self), updates.updates.len()); + } else if updates.update_id == CLOSED_CHANNEL_UPDATE_ID { + log_info!(logger, "Applying force close update to monitor {} with {} change(s).", + log_funding_info!(self), updates.updates.len()); + } else { + log_info!(logger, "Applying update to monitor {}, bringing update_id from {} to {} with {} change(s).", + log_funding_info!(self), self.latest_update_id, updates.update_id, updates.updates.len()); + } // ChannelMonitor updates may be applied after force close if we receive a preimage for a // broadcasted commitment transaction HTLC output that we'd like to claim on-chain. If this // is the case, we no longer have guaranteed access to the monitor's update ID, so we use a @@ -2407,6 +2415,7 @@ impl ChannelMonitorImpl { _ => false, }).is_some(); if detected_funding_spend { + log_trace!(logger, "Avoiding commitment broadcast, already detected confirmed spend onchain"); continue; } self.broadcast_latest_holder_commitment_txn(broadcaster, logger); @@ -2422,7 +2431,7 @@ impl ChannelMonitorImpl { let commitment_package = PackageTemplate::build_package( self.funding_info.0.txid.clone(), self.funding_info.0.index as u32, PackageSolvingData::HolderFundingOutput(funding_output), - best_block_height, false, best_block_height, + best_block_height, best_block_height ); self.onchain_tx_handler.update_claims_view_from_requests( vec![commitment_package], best_block_height, best_block_height, @@ -2457,7 +2466,9 @@ impl ChannelMonitorImpl { self.latest_update_id = updates.update_id; - if ret.is_ok() && self.funding_spend_seen { + // Refuse updates after we've detected a spend onchain, but only if we haven't processed a + // force closed monitor update yet. + if ret.is_ok() && self.funding_spend_seen && self.latest_update_id != CLOSED_CHANNEL_UPDATE_ID { log_error!(logger, "Refusing Channel Monitor Update as counterparty attempted to update commitment after funding was spent"); Err(()) } else { ret } @@ -2604,9 +2615,7 @@ impl ChannelMonitorImpl { for (idx, outp) in tx.output.iter().enumerate() { if outp.script_pubkey == revokeable_p2wsh { let revk_outp = RevokedOutput::build(per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, per_commitment_key, outp.value, self.counterparty_commitment_params.on_counterparty_tx_csv, self.onchain_tx_handler.opt_anchors()); - // Post-anchor, aggregation of outputs of different types is unsafe. See https://github.com/lightning/bolts/pull/803. - let aggregation = if self.onchain_tx_handler.opt_anchors() { false } else { true }; - let justice_package = PackageTemplate::build_package(commitment_txid, idx as u32, PackageSolvingData::RevokedOutput(revk_outp), height + self.counterparty_commitment_params.on_counterparty_tx_csv as u32, aggregation, height); + let justice_package = PackageTemplate::build_package(commitment_txid, idx as u32, PackageSolvingData::RevokedOutput(revk_outp), height + self.counterparty_commitment_params.on_counterparty_tx_csv as u32, height); claimable_outpoints.push(justice_package); to_counterparty_output_info = Some((idx.try_into().expect("Txn can't have more than 2^32 outputs"), outp.value)); @@ -2624,7 +2633,7 @@ impl ChannelMonitorImpl { to_counterparty_output_info); } let revk_htlc_outp = RevokedHTLCOutput::build(per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, per_commitment_key, htlc.amount_msat / 1000, htlc.clone(), self.onchain_tx_handler.channel_transaction_parameters.opt_anchors.is_some()); - let justice_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, PackageSolvingData::RevokedHTLCOutput(revk_htlc_outp), htlc.cltv_expiry, true, height); + let justice_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, PackageSolvingData::RevokedHTLCOutput(revk_htlc_outp), htlc.cltv_expiry, height); claimable_outpoints.push(justice_package); } } @@ -2749,8 +2758,7 @@ impl ChannelMonitorImpl { self.counterparty_commitment_params.counterparty_htlc_base_key, htlc.clone(), self.onchain_tx_handler.opt_anchors())) }; - let aggregation = if !htlc.offered { false } else { true }; - let counterparty_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc.cltv_expiry,aggregation, 0); + let counterparty_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc.cltv_expiry, 0); claimable_outpoints.push(counterparty_package); } } @@ -2794,7 +2802,7 @@ impl ChannelMonitorImpl { ); let justice_package = PackageTemplate::build_package( htlc_txid, idx as u32, PackageSolvingData::RevokedOutput(revk_outp), - height + self.counterparty_commitment_params.on_counterparty_tx_csv as u32, true, height + height + self.counterparty_commitment_params.on_counterparty_tx_csv as u32, height ); claimable_outpoints.push(justice_package); if outputs_to_watch.is_none() { @@ -2817,11 +2825,11 @@ impl ChannelMonitorImpl { for &(ref htlc, _, _) in holder_tx.htlc_outputs.iter() { if let Some(transaction_output_index) = htlc.transaction_output_index { - let (htlc_output, aggregable) = if htlc.offered { + let htlc_output = if htlc.offered { let htlc_output = HolderHTLCOutput::build_offered( htlc.amount_msat, htlc.cltv_expiry, self.onchain_tx_handler.opt_anchors() ); - (htlc_output, false) + htlc_output } else { let payment_preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { preimage.clone() @@ -2832,12 +2840,12 @@ impl ChannelMonitorImpl { let htlc_output = HolderHTLCOutput::build_accepted( payment_preimage, htlc.amount_msat, self.onchain_tx_handler.opt_anchors() ); - (htlc_output, self.onchain_tx_handler.opt_anchors()) + htlc_output }; let htlc_package = PackageTemplate::build_package( holder_tx.txid, transaction_output_index, PackageSolvingData::HolderHTLCOutput(htlc_output), - htlc.cltv_expiry, aggregable, conf_height + htlc.cltv_expiry, conf_height ); claim_requests.push(htlc_package); } @@ -3177,7 +3185,7 @@ impl ChannelMonitorImpl { let should_broadcast = self.should_broadcast_holder_commitment_txn(logger); if should_broadcast { let funding_outp = HolderFundingOutput::build(self.funding_redeemscript.clone(), self.channel_value_satoshis, self.onchain_tx_handler.opt_anchors()); - let commitment_package = PackageTemplate::build_package(self.funding_info.0.txid.clone(), self.funding_info.0.index as u32, PackageSolvingData::HolderFundingOutput(funding_outp), self.best_block.height(), false, self.best_block.height()); + let commitment_package = PackageTemplate::build_package(self.funding_info.0.txid.clone(), self.funding_info.0.index as u32, PackageSolvingData::HolderFundingOutput(funding_outp), self.best_block.height(), self.best_block.height()); claimable_outpoints.push(commitment_package); self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0)); let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript); @@ -4076,7 +4084,6 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP #[cfg(test)] mod tests { - use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::script::{Script, Builder}; use bitcoin::blockdata::opcodes; use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, EcdsaSighashType}; @@ -4113,7 +4120,7 @@ mod tests { use crate::util::ser::{ReadableArgs, Writeable}; use crate::sync::{Arc, Mutex}; use crate::io; - use bitcoin::{PackedLockTime, Sequence, TxMerkleNode, Witness}; + use bitcoin::{PackedLockTime, Sequence, Witness}; use crate::prelude::*; fn do_test_funding_spend_refuses_updates(use_local_txn: bool) { @@ -4152,10 +4159,7 @@ mod tests { // Connect a commitment transaction, but only to the ChainMonitor/ChannelMonitor. The // channel is now closed, but the ChannelManager doesn't know that yet. - let new_header = BlockHeader { - version: 2, time: 0, bits: 0, nonce: 0, - prev_blockhash: nodes[0].best_block_info().0, - merkle_root: TxMerkleNode::all_zeros() }; + let new_header = create_dummy_header(nodes[0].best_block_info().0, 0); let conf_height = nodes[0].best_block_info().1 + 1; nodes[1].chain_monitor.chain_monitor.transactions_confirmed(&new_header, &[(0, broadcast_tx)], conf_height);