X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fchannelmonitor.rs;h=904d9941349804f99cb31127e2757fcc51bbf473;hb=189b070f626d9223271895473c04b31695ff3e35;hp=a48f169a4d5e605b330f49896bc191779dd389d7;hpb=7a78998552b1d3c2d97f337a7d5aaf7fe1aa70b4;p=rust-lightning diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index a48f169a..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 { @@ -2425,10 +2455,10 @@ 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( @@ -2504,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, @@ -2516,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, @@ -2547,6 +2577,7 @@ impl ChannelMonitorImpl { }); } ret.push(Event::BumpTransaction(BumpTransactionEvent::HTLCResolution { + claim_id, target_feerate_sat_per_1000_weight, htlc_descriptors, tx_lock_time, @@ -2617,7 +2648,7 @@ 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, self.onchain_tx_handler.opt_anchors()); + 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 = @@ -2635,7 +2666,7 @@ 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 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); } @@ -2753,13 +2784,13 @@ 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 counterparty_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc.cltv_expiry, 0); claimable_outpoints.push(counterparty_package); @@ -2830,7 +2861,7 @@ impl ChannelMonitorImpl { if let Some(transaction_output_index) = htlc.transaction_output_index { 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 } else { @@ -2841,7 +2872,7 @@ 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 }; @@ -2925,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() { @@ -2963,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() { @@ -3187,7 +3218,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 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)); @@ -3196,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. @@ -4124,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) { @@ -4297,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. @@ -4414,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 { @@ -4433,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; } } @@ -4446,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 { @@ -4465,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; } } @@ -4478,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 { @@ -4500,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; } }