Merge pull request #2272 from benthecarman/package-broadcast
[rust-lightning] / lightning / src / chain / channelmonitor.rs
index 5adc156405bf087bb03158615b4b1cfbd217f3a8..a48f169a4d5e605b330f49896bc191779dd389d7 100644 (file)
@@ -2342,8 +2342,16 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                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
@@ -2410,6 +2418,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                                                _ => 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);
@@ -2425,7 +2434,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                                        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,
@@ -2460,7 +2469,9 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
 
                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 }
@@ -2606,8 +2617,8 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                        // First, process non-htlc outputs (to_holder & to_counterparty)
                        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);
-                                       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, true, height);
+                                       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());
+                                       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));
@@ -2625,7 +2636,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                                                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);
                                        }
                                }
@@ -2750,8 +2761,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                                                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);
                                }
                        }
@@ -2790,11 +2800,12 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                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,
-                                       tx.output[idx].value, self.counterparty_commitment_params.on_counterparty_tx_csv
+                                       tx.output[idx].value, self.counterparty_commitment_params.on_counterparty_tx_csv,
+                                       false
                                );
                                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 +2828,11 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
 
                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 +2843,12 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                        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 +3188,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                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 +4087,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 +4123,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 +4162,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);