X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fchannelmonitor.rs;h=904d9941349804f99cb31127e2757fcc51bbf473;hb=189b070f626d9223271895473c04b31695ff3e35;hp=e3f6f428eb3aba1fd56a3ae95245f61a64e9b083;hpb=17a74fcfc74936b48923bba5a416be73a01d2367;p=rust-lightning diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index e3f6f428..904d9941 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -43,16 +43,13 @@ use crate::chain::{BestBlock, WatchedOutput}; use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator}; use crate::chain::transaction::{OutPoint, TransactionData}; use crate::sign::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource}; -#[cfg(anchors)] -use crate::chain::onchaintx::ClaimEvent; -use crate::chain::onchaintx::OnchainTxHandler; +use crate::chain::onchaintx::{ClaimEvent, OnchainTxHandler}; use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput}; use crate::chain::Filter; use crate::util::logger::Logger; use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48}; use crate::util::byte_utils; use crate::events::Event; -#[cfg(anchors)] use crate::events::bump_transaction::{AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent}; use crate::prelude::*; @@ -268,7 +265,6 @@ impl_writeable_tlv_based!(HolderSignedTx, { (14, htlc_outputs, vec_type) }); -#[cfg(anchors)] impl HolderSignedTx { fn non_dust_htlcs(&self) -> Vec { self.htlc_outputs.iter().filter_map(|(htlc, _, _)| { @@ -651,6 +647,40 @@ pub enum Balance { }, } +impl Balance { + /// The amount claimable, in satoshis. This excludes balances that we are unsure if we are able + /// to claim, this is because we are waiting for a preimage or for a timeout to expire. For more + /// information on these balances see [`Balance::MaybeTimeoutClaimableHTLC`] and + /// [`Balance::MaybePreimageClaimableHTLC`]. + /// + /// On-chain fees required to claim the balance are not included in this amount. + pub fn claimable_amount_satoshis(&self) -> u64 { + match self { + Balance::ClaimableOnChannelClose { + claimable_amount_satoshis, + } => *claimable_amount_satoshis, + Balance::ClaimableAwaitingConfirmations { + claimable_amount_satoshis, + .. + } => *claimable_amount_satoshis, + Balance::ContentiousClaimable { + claimable_amount_satoshis, + .. + } => *claimable_amount_satoshis, + Balance::MaybeTimeoutClaimableHTLC { + .. + } => 0, + Balance::MaybePreimageClaimableHTLC { + .. + } => 0, + Balance::CounterpartyRevokedOutputClaimable { + claimable_amount_satoshis, + .. + } => *claimable_amount_satoshis, + } + } +} + /// An HTLC which has been irrevocably resolved on-chain, and has reached ANTI_REORG_DELAY. #[derive(PartialEq, Eq)] struct IrrevocablyResolvedHTLC { @@ -1566,7 +1596,7 @@ impl ChannelMonitorImpl { debug_assert!(htlc_input_idx_opt.is_some()); BitcoinOutPoint::new(*txid, htlc_input_idx_opt.unwrap_or(0)) } else { - debug_assert!(!self.onchain_tx_handler.opt_anchors()); + debug_assert!(!self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx()); BitcoinOutPoint::new(*txid, 0) } } else { @@ -2327,10 +2357,13 @@ impl ChannelMonitorImpl { where B::Target: BroadcasterInterface, L::Target: Logger, { - for tx in self.get_latest_holder_commitment_txn(logger).iter() { + let commit_txs = self.get_latest_holder_commitment_txn(logger); + let mut txs = vec![]; + for tx in commit_txs.iter() { log_info!(logger, "Broadcasting local {}", log_tx!(tx)); - broadcaster.broadcast_transaction(tx); + txs.push(tx); } + broadcaster.broadcast_transactions(&txs); self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0)); } @@ -2422,16 +2455,16 @@ impl ChannelMonitorImpl { // If the channel supports anchor outputs, we'll need to emit an external // event to be consumed such that a child transaction is broadcast with a // high enough feerate for the parent commitment transaction to confirm. - if self.onchain_tx_handler.opt_anchors() { + if self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() { let funding_output = HolderFundingOutput::build( self.funding_redeemscript.clone(), self.channel_value_satoshis, - self.onchain_tx_handler.opt_anchors(), + self.onchain_tx_handler.channel_type_features().clone(), ); let best_block_height = 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_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, @@ -2501,8 +2534,7 @@ impl ChannelMonitorImpl { pub fn get_and_clear_pending_events(&mut self) -> Vec { let mut ret = Vec::new(); mem::swap(&mut ret, &mut self.pending_events); - #[cfg(anchors)] - for claim_event in self.onchain_tx_handler.get_and_clear_pending_claim_events().drain(..) { + for (claim_id, claim_event) in self.onchain_tx_handler.get_and_clear_pending_claim_events().drain(..) { match claim_event { ClaimEvent::BumpCommitment { package_target_feerate_sat_per_1000_weight, commitment_tx, anchor_output_idx, @@ -2513,6 +2545,7 @@ impl ChannelMonitorImpl { let commitment_tx_fee_satoshis = self.channel_value_satoshis - commitment_tx.output.iter().fold(0u64, |sum, output| sum + output.value); ret.push(Event::BumpTransaction(BumpTransactionEvent::ChannelClose { + claim_id, package_target_feerate_sat_per_1000_weight, commitment_tx, commitment_tx_fee_satoshis, @@ -2544,6 +2577,7 @@ impl ChannelMonitorImpl { }); } ret.push(Event::BumpTransaction(BumpTransactionEvent::HTLCResolution { + claim_id, target_feerate_sat_per_1000_weight, htlc_descriptors, tx_lock_time, @@ -2614,8 +2648,8 @@ impl ChannelMonitorImpl { // 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.channel_type_features().supports_anchors_zero_fee_htlc_tx()); + 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)); @@ -2632,8 +2666,8 @@ impl ChannelMonitorImpl { return (claimable_outpoints, (commitment_txid, watch_outputs), 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 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.channel_type_features); + 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,16 +2784,15 @@ impl ChannelMonitorImpl { CounterpartyOfferedHTLCOutput::build(*per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, - preimage.unwrap(), htlc.clone(), self.onchain_tx_handler.opt_anchors())) + preimage.unwrap(), htlc.clone(), self.onchain_tx_handler.channel_type_features().clone())) } else { PackageSolvingData::CounterpartyReceivedHTLCOutput( CounterpartyReceivedHTLCOutput::build(*per_commitment_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, - htlc.clone(), self.onchain_tx_handler.opt_anchors())) + htlc.clone(), self.onchain_tx_handler.channel_type_features().clone())) }; - 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); } } @@ -2798,11 +2831,12 @@ impl ChannelMonitorImpl { 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() { @@ -2825,11 +2859,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.amount_msat, htlc.cltv_expiry, self.onchain_tx_handler.channel_type_features().clone() ); - (htlc_output, false) + htlc_output } else { let payment_preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { preimage.clone() @@ -2838,14 +2872,14 @@ impl ChannelMonitorImpl { continue; }; let htlc_output = HolderHTLCOutput::build_accepted( - payment_preimage, htlc.amount_msat, self.onchain_tx_handler.opt_anchors() + payment_preimage, htlc.amount_msat, self.onchain_tx_handler.channel_type_features().clone() ); - (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); } @@ -2922,7 +2956,7 @@ impl ChannelMonitorImpl { let mut holder_transactions = vec![commitment_tx]; // When anchor outputs are present, the HTLC transactions are only valid once the commitment // transaction confirms. - if self.onchain_tx_handler.opt_anchors() { + if self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() { return holder_transactions; } for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() { @@ -2960,7 +2994,7 @@ impl ChannelMonitorImpl { let mut holder_transactions = vec![commitment_tx]; // When anchor outputs are present, the HTLC transactions are only final once the commitment // transaction confirms due to the CSV 1 encumberance. - if self.onchain_tx_handler.opt_anchors() { + if self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() { return holder_transactions; } for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() { @@ -3184,8 +3218,8 @@ 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 funding_outp = HolderFundingOutput::build(self.funding_redeemscript.clone(), self.channel_value_satoshis, self.onchain_tx_handler.channel_type_features().clone()); + 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); @@ -3193,7 +3227,7 @@ impl ChannelMonitorImpl { // We can't broadcast our HTLC transactions while the commitment transaction is // unconfirmed. We'll delay doing so until we detect the confirmed commitment in // `transactions_confirmed`. - if !self.onchain_tx_handler.opt_anchors() { + if !self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() { // Because we're broadcasting a commitment transaction, we should construct the package // assuming it gets confirmed in the next block. Sadly, we have code which considers // "not yet confirmed" things as discardable, so we cannot do that here. @@ -4121,6 +4155,7 @@ mod tests { use crate::sync::{Arc, Mutex}; use crate::io; use bitcoin::{PackedLockTime, Sequence, Witness}; + use crate::ln::features::ChannelTypeFeatures; use crate::prelude::*; fn do_test_funding_spend_refuses_updates(use_local_txn: bool) { @@ -4294,8 +4329,7 @@ mod tests { selected_contest_delay: 67, }), funding_outpoint: Some(funding_outpoint), - opt_anchors: None, - opt_non_zero_fee_anchors: None, + channel_type_features: ChannelTypeFeatures::only_static_remote_key() }; // Prune with one old state and a holder commitment tx holding a few overlaps with the // old state. @@ -4411,7 +4445,7 @@ mod tests { let txid = Txid::from_hex("56944c5d3f98413ef45cf54545538103cc9f298e0575820ad3591376e2e0f65d").unwrap(); // Justice tx with 1 to_holder, 2 revoked offered HTLCs, 1 revoked received HTLCs - for &opt_anchors in [false, true].iter() { + for channel_type_features in [ChannelTypeFeatures::only_static_remote_key(), ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies()].iter() { let mut claim_tx = Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() }; let mut sum_actual_sigs = 0; for i in 0..4 { @@ -4430,12 +4464,12 @@ mod tests { value: 0, }); let base_weight = claim_tx.weight(); - let inputs_weight = vec![WEIGHT_REVOKED_OUTPUT, weight_revoked_offered_htlc(opt_anchors), weight_revoked_offered_htlc(opt_anchors), weight_revoked_received_htlc(opt_anchors)]; + let inputs_weight = vec![WEIGHT_REVOKED_OUTPUT, weight_revoked_offered_htlc(channel_type_features), weight_revoked_offered_htlc(channel_type_features), weight_revoked_received_htlc(channel_type_features)]; let mut inputs_total_weight = 2; // count segwit flags { let mut sighash_parts = sighash::SighashCache::new(&mut claim_tx); for (idx, inp) in inputs_weight.iter().enumerate() { - sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors); + sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, channel_type_features); inputs_total_weight += inp; } } @@ -4443,7 +4477,7 @@ mod tests { } // Claim tx with 1 offered HTLCs, 3 received HTLCs - for &opt_anchors in [false, true].iter() { + for channel_type_features in [ChannelTypeFeatures::only_static_remote_key(), ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies()].iter() { let mut claim_tx = Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() }; let mut sum_actual_sigs = 0; for i in 0..4 { @@ -4462,12 +4496,12 @@ mod tests { value: 0, }); let base_weight = claim_tx.weight(); - let inputs_weight = vec![weight_offered_htlc(opt_anchors), weight_received_htlc(opt_anchors), weight_received_htlc(opt_anchors), weight_received_htlc(opt_anchors)]; + let inputs_weight = vec![weight_offered_htlc(channel_type_features), weight_received_htlc(channel_type_features), weight_received_htlc(channel_type_features), weight_received_htlc(channel_type_features)]; let mut inputs_total_weight = 2; // count segwit flags { let mut sighash_parts = sighash::SighashCache::new(&mut claim_tx); for (idx, inp) in inputs_weight.iter().enumerate() { - sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors); + sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, channel_type_features); inputs_total_weight += inp; } } @@ -4475,7 +4509,7 @@ mod tests { } // Justice tx with 1 revoked HTLC-Success tx output - for &opt_anchors in [false, true].iter() { + for channel_type_features in [ChannelTypeFeatures::only_static_remote_key(), ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies()].iter() { let mut claim_tx = Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() }; let mut sum_actual_sigs = 0; claim_tx.input.push(TxIn { @@ -4497,7 +4531,7 @@ mod tests { { let mut sighash_parts = sighash::SighashCache::new(&mut claim_tx); for (idx, inp) in inputs_weight.iter().enumerate() { - sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors); + sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, channel_type_features); inputs_total_weight += inp; } }