X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=f3632b41b471098392bf357e3a9e7220995588ce;hb=fba99b73bf5d23cb0ca554997dcb92dbaddd9cfc;hp=a61a8de82debecd5906c0ee95bdcdb420aae48f4;hpb=e0fe325402862978c66603e598cdf7f6fa628606;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index a61a8de8..f3632b41 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -7,6 +7,7 @@ // You may not use this file except in accordance with one or both of these // licenses. +use bitcoin::blockdata::constants::ChainHash; use bitcoin::blockdata::script::{Script,Builder}; use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType}; use bitcoin::util::sighash; @@ -723,7 +724,7 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { cur_holder_commitment_transaction_number: u64, cur_counterparty_commitment_transaction_number: u64, - value_to_self_msat: u64, // Excluding all pending_htlcs, excluding fees + value_to_self_msat: u64, // Excluding all pending_htlcs, fees, and anchor outputs pending_inbound_htlcs: Vec, pending_outbound_htlcs: Vec, holding_cell_htlc_updates: Vec, @@ -1168,7 +1169,7 @@ impl ChannelContext where SP::Target: SignerProvider { match self.config.options.max_dust_htlc_exposure { MaxDustHTLCExposure::FeeRateMultiplier(multiplier) => { let feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight( - ConfirmationTarget::HighPriority); + ConfirmationTarget::OnChainSweep); feerate_per_kw as u64 * multiplier }, MaxDustHTLCExposure::FixedLimitMsat(limit) => limit, @@ -1672,6 +1673,11 @@ impl ChannelContext where SP::Target: SignerProvider { let mut available_capacity_msat = outbound_capacity_msat; + let anchor_outputs_value_msat = if context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { + ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000 + } else { + 0 + }; if context.is_outbound() { // We should mind channel commit tx fee when computing how much of the available capacity // can be used in the next htlc. Mirrors the logic in send_htlc. @@ -1686,14 +1692,19 @@ impl ChannelContext where SP::Target: SignerProvider { } let htlc_above_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000, HTLCInitiator::LocalOffered); - let max_reserved_commit_tx_fee_msat = FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE * context.next_local_commit_tx_fee_msat(htlc_above_dust, Some(())); + let mut max_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(htlc_above_dust, Some(())); let htlc_dust = HTLCCandidate::new(real_dust_limit_timeout_sat * 1000 - 1, HTLCInitiator::LocalOffered); - let min_reserved_commit_tx_fee_msat = FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE * context.next_local_commit_tx_fee_msat(htlc_dust, Some(())); + let mut min_reserved_commit_tx_fee_msat = context.next_local_commit_tx_fee_msat(htlc_dust, Some(())); + if !context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { + max_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE; + min_reserved_commit_tx_fee_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE; + } // We will first subtract the fee as if we were above-dust. Then, if the resulting // value ends up being below dust, we have this fee available again. In that case, // match the value to right-below-dust. - let mut capacity_minus_commitment_fee_msat: i64 = (available_capacity_msat as i64) - (max_reserved_commit_tx_fee_msat as i64); + let mut capacity_minus_commitment_fee_msat: i64 = available_capacity_msat as i64 - + max_reserved_commit_tx_fee_msat as i64 - anchor_outputs_value_msat as i64; if capacity_minus_commitment_fee_msat < (real_dust_limit_timeout_sat as i64) * 1000 { let one_htlc_difference_msat = max_reserved_commit_tx_fee_msat - min_reserved_commit_tx_fee_msat; debug_assert!(one_htlc_difference_msat != 0); @@ -1718,7 +1729,7 @@ impl ChannelContext where SP::Target: SignerProvider { let remote_balance_msat = (context.channel_value_satoshis * 1000 - context.value_to_self_msat) .saturating_sub(inbound_stats.pending_htlcs_value_msat); - if remote_balance_msat < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat { + if remote_balance_msat < max_reserved_commit_tx_fee_msat + holder_selected_chan_reserve_msat + anchor_outputs_value_msat { // If another HTLC's fee would reduce the remote's balance below the reserve limit // we've selected for them, we can only send dust HTLCs. available_capacity_msat = cmp::min(available_capacity_msat, real_dust_limit_success_sat * 1000 - 1); @@ -2118,7 +2129,7 @@ fn commit_tx_fee_sat(feerate_per_kw: u32, num_htlcs: usize, channel_type_feature // Get the fee cost in MSATS of a commitment tx with a given number of HTLC outputs. // Note that num_htlcs should not include dust HTLCs. -fn commit_tx_fee_msat(feerate_per_kw: u32, num_htlcs: usize, channel_type_features: &ChannelTypeFeatures) -> u64 { +pub(crate) fn commit_tx_fee_msat(feerate_per_kw: u32, num_htlcs: usize, channel_type_features: &ChannelTypeFeatures) -> u64 { // Note that we need to divide before multiplying to round properly, // since the lowest denomination of bitcoin on-chain is the satoshi. (commitment_tx_base_weight(channel_type_features) + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC) * feerate_per_kw as u64 / 1000 * 1000 @@ -2155,28 +2166,20 @@ impl Channel where // apply to channels supporting anchor outputs since HTLC transactions are pre-signed with a // zero fee, so their fee is no longer considered to determine dust limits. if !channel_type.supports_anchors_zero_fee_htlc_tx() { - let upper_limit = cmp::max(250 * 25, - fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::HighPriority) as u64 * 10); + let upper_limit = + fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee) as u64; if feerate_per_kw as u64 > upper_limit { return Err(ChannelError::Close(format!("Peer's feerate much too high. Actual: {}. Our expected upper limit: {}", feerate_per_kw, upper_limit))); } } - // We can afford to use a lower bound with anchors than previously since we can now bump - // fees when broadcasting our commitment. However, we must still make sure we meet the - // minimum mempool feerate, until package relay is deployed, such that we can ensure the - // commitment transaction propagates throughout node mempools on its own. let lower_limit_conf_target = if channel_type.supports_anchors_zero_fee_htlc_tx() { - ConfirmationTarget::MempoolMinimum + ConfirmationTarget::MinAllowedAnchorChannelRemoteFee } else { - ConfirmationTarget::Background + ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee }; let lower_limit = fee_estimator.bounded_sat_per_1000_weight(lower_limit_conf_target); - // Some fee estimators round up to the next full sat/vbyte (ie 250 sats per kw), causing - // occasional issues with feerate disagreements between an initiator that wants a feerate - // of 1.1 sat/vbyte and a receiver that wants 1.1 rounded up to 2. Thus, we always add 250 - // sat/kw before the comparison here. - if feerate_per_kw + 250 < lower_limit { + if feerate_per_kw < lower_limit { if let Some(cur_feerate) = cur_feerate_per_kw { if feerate_per_kw > cur_feerate { log_warn!(logger, @@ -2185,7 +2188,7 @@ impl Channel where return Ok(()); } } - return Err(ChannelError::Close(format!("Peer's feerate much too low. Actual: {}. Our expected lower limit: {} (- 250)", feerate_per_kw, lower_limit))); + return Err(ChannelError::Close(format!("Peer's feerate much too low. Actual: {}. Our expected lower limit: {}", feerate_per_kw, lower_limit))); } Ok(()) } @@ -2661,7 +2664,7 @@ impl Channel where /// and the channel is now usable (and public), this may generate an announcement_signatures to /// reply with. pub fn channel_ready( - &mut self, msg: &msgs::ChannelReady, node_signer: &NS, genesis_block_hash: BlockHash, + &mut self, msg: &msgs::ChannelReady, node_signer: &NS, chain_hash: ChainHash, user_config: &UserConfig, best_block: &BestBlock, logger: &L ) -> Result, ChannelError> where @@ -2732,7 +2735,7 @@ impl Channel where log_info!(logger, "Received channel_ready from peer for channel {}", &self.context.channel_id()); - Ok(self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger)) + Ok(self.get_announcement_sigs(node_signer, chain_hash, user_config, best_block.height(), logger)) } pub fn update_add_htlc( @@ -2773,6 +2776,7 @@ impl Channel where if inbound_stats.pending_htlcs_value_msat + msg.amount_msat > self.context.holder_max_htlc_value_in_flight_msat { return Err(ChannelError::Close(format!("Remote HTLC add would put them over our max HTLC value ({})", self.context.holder_max_htlc_value_in_flight_msat))); } + // Check holder_selected_channel_reserve_satoshis (we're getting paid, so they have to at least meet // the reserve_satoshis we told them to always have as direct payment so that they lose // something if we punish them for broadcasting an old state). @@ -2832,30 +2836,40 @@ impl Channel where // Check that the remote can afford to pay for this HTLC on-chain at the current // feerate_per_kw, while maintaining their channel reserve (as required by the spec). - let remote_commit_tx_fee_msat = if self.context.is_outbound() { 0 } else { - let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered); - self.context.next_remote_commit_tx_fee_msat(htlc_candidate, None) // Don't include the extra fee spike buffer HTLC in calculations - }; - if pending_remote_value_msat - msg.amount_msat < remote_commit_tx_fee_msat { - return Err(ChannelError::Close("Remote HTLC add would not leave enough to pay for fees".to_owned())); - }; - - if pending_remote_value_msat - msg.amount_msat - remote_commit_tx_fee_msat < self.context.holder_selected_channel_reserve_satoshis * 1000 { - return Err(ChannelError::Close("Remote HTLC add would put them under remote reserve value".to_owned())); + { + let remote_commit_tx_fee_msat = if self.context.is_outbound() { 0 } else { + let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered); + self.context.next_remote_commit_tx_fee_msat(htlc_candidate, None) // Don't include the extra fee spike buffer HTLC in calculations + }; + let anchor_outputs_value_msat = if !self.context.is_outbound() && self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { + ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000 + } else { + 0 + }; + if pending_remote_value_msat.saturating_sub(msg.amount_msat).saturating_sub(anchor_outputs_value_msat) < remote_commit_tx_fee_msat { + return Err(ChannelError::Close("Remote HTLC add would not leave enough to pay for fees".to_owned())); + }; + if pending_remote_value_msat.saturating_sub(msg.amount_msat).saturating_sub(remote_commit_tx_fee_msat).saturating_sub(anchor_outputs_value_msat) < self.context.holder_selected_channel_reserve_satoshis * 1000 { + return Err(ChannelError::Close("Remote HTLC add would put them under remote reserve value".to_owned())); + } } + let anchor_outputs_value_msat = if self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { + ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000 + } else { + 0 + }; if !self.context.is_outbound() { - // `2 *` and `Some(())` is for the fee spike buffer we keep for the remote. This deviates from - // the spec because in the spec, the fee spike buffer requirement doesn't exist on the - // receiver's side, only on the sender's. - // Note that when we eventually remove support for fee updates and switch to anchor output - // fees, we will drop the `2 *`, since we no longer be as sensitive to fee spikes. But, keep - // the extra htlc when calculating the next remote commitment transaction fee as we should - // still be able to afford adding this HTLC plus one more future HTLC, regardless of being - // sensitive to fee spikes. + // `Some(())` is for the fee spike buffer we keep for the remote. This deviates from + // the spec because the fee spike buffer requirement doesn't exist on the receiver's + // side, only on the sender's. Note that with anchor outputs we are no longer as + // sensitive to fee spikes, so we need to account for them. let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered); - let remote_fee_cost_incl_stuck_buffer_msat = 2 * self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(())); - if pending_remote_value_msat - msg.amount_msat - self.context.holder_selected_channel_reserve_satoshis * 1000 < remote_fee_cost_incl_stuck_buffer_msat { + let mut remote_fee_cost_incl_stuck_buffer_msat = self.context.next_remote_commit_tx_fee_msat(htlc_candidate, Some(())); + if !self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { + remote_fee_cost_incl_stuck_buffer_msat *= FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE; + } + if pending_remote_value_msat.saturating_sub(msg.amount_msat).saturating_sub(self.context.holder_selected_channel_reserve_satoshis * 1000).saturating_sub(anchor_outputs_value_msat) < remote_fee_cost_incl_stuck_buffer_msat { // Note that if the pending_forward_status is not updated here, then it's because we're already failing // the HTLC, i.e. its status is already set to failing. log_info!(logger, "Attempting to fail HTLC due to fee spike buffer violation in channel {}. Rebalancing is required.", &self.context.channel_id()); @@ -2865,7 +2879,7 @@ impl Channel where // Check that they won't violate our local required channel reserve by adding this HTLC. let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered); let local_commit_tx_fee_msat = self.context.next_local_commit_tx_fee_msat(htlc_candidate, None); - if self.context.value_to_self_msat < self.context.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 + local_commit_tx_fee_msat { + if self.context.value_to_self_msat < self.context.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 + local_commit_tx_fee_msat + anchor_outputs_value_msat { return Err(ChannelError::Close("Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value".to_owned())); } } @@ -3766,7 +3780,7 @@ impl Channel where /// successfully and we should restore normal operation. Returns messages which should be sent /// to the remote side. pub fn monitor_updating_restored( - &mut self, logger: &L, node_signer: &NS, genesis_block_hash: BlockHash, + &mut self, logger: &L, node_signer: &NS, chain_hash: ChainHash, user_config: &UserConfig, best_block_height: u32 ) -> MonitorRestoreUpdates where @@ -3807,7 +3821,7 @@ impl Channel where }) } else { None }; - let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block_height, logger); + let announcement_sigs = self.get_announcement_sigs(node_signer, chain_hash, user_config, best_block_height, logger); let mut accepted_htlcs = Vec::new(); mem::swap(&mut accepted_htlcs, &mut self.context.monitor_pending_forwards); @@ -3977,7 +3991,7 @@ impl Channel where /// [`super::channelmanager::ChannelManager::force_close_all_channels_without_broadcasting_txn`]. pub fn channel_reestablish( &mut self, msg: &msgs::ChannelReestablish, logger: &L, node_signer: &NS, - genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock + chain_hash: ChainHash, user_config: &UserConfig, best_block: &BestBlock ) -> Result where L::Target: Logger, @@ -3992,7 +4006,7 @@ impl Channel where if msg.next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg.next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg.next_local_commitment_number == 0 { - return Err(ChannelError::Close("Peer sent a garbage channel_reestablish (usually an lnd node with lost state asking us to force-close for them)".to_owned())); + return Err(ChannelError::Close("Peer sent an invalid channel_reestablish to force close in a non-standard way".to_owned())); } if msg.next_remote_commitment_number > 0 { @@ -4036,7 +4050,7 @@ impl Channel where let shutdown_msg = self.get_outbound_shutdown(); - let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger); + let announcement_sigs = self.get_announcement_sigs(node_signer, chain_hash, user_config, best_block.height(), logger); if self.context.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 { // If we're waiting on a monitor update, we shouldn't re-send any channel_ready's. @@ -4155,8 +4169,10 @@ impl Channel where // Propose a range from our current Background feerate to our Normal feerate plus our // force_close_avoidance_max_fee_satoshis. // If we fail to come to consensus, we'll have to force-close. - let mut proposed_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Background); - let normal_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal); + let mut proposed_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::ChannelCloseMinimum); + // Use NonAnchorChannelFee because this should be an estimate for a channel close + // that we don't expect to need fee bumping + let normal_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee); let mut proposed_max_feerate = if self.context.is_outbound() { normal_feerate } else { u32::max_value() }; // The spec requires that (when the channel does not have anchors) we only send absolute @@ -4813,7 +4829,7 @@ impl Channel where /// In the second, we simply return an Err indicating we need to be force-closed now. pub fn transactions_confirmed( &mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData, - genesis_block_hash: BlockHash, node_signer: &NS, user_config: &UserConfig, logger: &L + chain_hash: ChainHash, node_signer: &NS, user_config: &UserConfig, logger: &L ) -> Result<(Option, Option), ClosureReason> where NS::Target: NodeSigner, @@ -4874,7 +4890,7 @@ impl Channel where // may have already happened for this block). if let Some(channel_ready) = self.check_get_channel_ready(height) { log_info!(logger, "Sending a channel_ready to our peer for channel {}", &self.context.channel_id); - let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger); + let announcement_sigs = self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger); msgs = (Some(channel_ready), announcement_sigs); } } @@ -4901,19 +4917,19 @@ impl Channel where /// May return some HTLCs (and their payment_hash) which have timed out and should be failed /// back. pub fn best_block_updated( - &mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash, + &mut self, height: u32, highest_header_time: u32, chain_hash: ChainHash, node_signer: &NS, user_config: &UserConfig, logger: &L ) -> Result<(Option, Vec<(HTLCSource, PaymentHash)>, Option), ClosureReason> where NS::Target: NodeSigner, L::Target: Logger { - self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_signer, user_config)), logger) + self.do_best_block_updated(height, highest_header_time, Some((chain_hash, node_signer, user_config)), logger) } fn do_best_block_updated( &mut self, height: u32, highest_header_time: u32, - genesis_node_signer: Option<(BlockHash, &NS, &UserConfig)>, logger: &L + chain_node_signer: Option<(ChainHash, &NS, &UserConfig)>, logger: &L ) -> Result<(Option, Vec<(HTLCSource, PaymentHash)>, Option), ClosureReason> where NS::Target: NodeSigner, @@ -4939,8 +4955,8 @@ impl Channel where self.context.update_time_counter = cmp::max(self.context.update_time_counter, highest_header_time); if let Some(channel_ready) = self.check_get_channel_ready(height) { - let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer { - self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger) + let announcement_sigs = if let Some((chain_hash, node_signer, user_config)) = chain_node_signer { + self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger) } else { None }; log_info!(logger, "Sending a channel_ready to our peer for channel {}", &self.context.channel_id); return Ok((Some(channel_ready), timed_out_htlcs, announcement_sigs)); @@ -4980,8 +4996,8 @@ impl Channel where return Err(ClosureReason::FundingTimedOut); } - let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer { - self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger) + let announcement_sigs = if let Some((chain_hash, node_signer, user_config)) = chain_node_signer { + self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger) } else { None }; Ok((None, timed_out_htlcs, announcement_sigs)) } @@ -4998,7 +5014,7 @@ impl Channel where // larger. If we don't know that time has moved forward, we can just set it to the last // time we saw and it will be ignored. let best_time = self.context.update_time_counter; - match self.do_best_block_updated(reorg_height, best_time, None::<(BlockHash, &&NodeSigner, &UserConfig)>, logger) { + match self.do_best_block_updated(reorg_height, best_time, None::<(ChainHash, &&NodeSigner, &UserConfig)>, logger) { Ok((channel_ready, timed_out_htlcs, announcement_sigs)) => { assert!(channel_ready.is_none(), "We can't generate a funding with 0 confirmations?"); assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?"); @@ -5028,7 +5044,7 @@ impl Channel where /// /// [`ChannelReady`]: crate::ln::msgs::ChannelReady fn get_channel_announcement( - &self, node_signer: &NS, chain_hash: BlockHash, user_config: &UserConfig, + &self, node_signer: &NS, chain_hash: ChainHash, user_config: &UserConfig, ) -> Result where NS::Target: NodeSigner { if !self.context.config.announced_channel { return Err(ChannelError::Ignore("Channel is not available for public announcements".to_owned())); @@ -5059,7 +5075,7 @@ impl Channel where } fn get_announcement_sigs( - &mut self, node_signer: &NS, genesis_block_hash: BlockHash, user_config: &UserConfig, + &mut self, node_signer: &NS, chain_hash: ChainHash, user_config: &UserConfig, best_block_height: u32, logger: &L ) -> Option where @@ -5084,7 +5100,7 @@ impl Channel where } log_trace!(logger, "Creating an announcement_signatures message for channel {}", &self.context.channel_id()); - let announcement = match self.get_channel_announcement(node_signer, genesis_block_hash, user_config) { + let announcement = match self.get_channel_announcement(node_signer, chain_hash, user_config) { Ok(a) => a, Err(e) => { log_trace!(logger, "{:?}", e); @@ -5158,7 +5174,7 @@ impl Channel where /// channel_announcement message which we can broadcast and storing our counterparty's /// signatures for later reconstruction/rebroadcast of the channel_announcement. pub fn announcement_signatures( - &mut self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32, + &mut self, node_signer: &NS, chain_hash: ChainHash, best_block_height: u32, msg: &msgs::AnnouncementSignatures, user_config: &UserConfig ) -> Result where NS::Target: NodeSigner { let announcement = self.get_channel_announcement(node_signer, chain_hash, user_config)?; @@ -5188,7 +5204,7 @@ impl Channel where /// Gets a signed channel_announcement for this channel, if we previously received an /// announcement_signatures from our counterparty. pub fn get_signed_channel_announcement( - &self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32, user_config: &UserConfig + &self, node_signer: &NS, chain_hash: ChainHash, best_block_height: u32, user_config: &UserConfig ) -> Option where NS::Target: NodeSigner { if self.context.funding_tx_confirmation_height == 0 || self.context.funding_tx_confirmation_height + 5 > best_block_height { return None; @@ -5726,16 +5742,16 @@ impl OutboundV1Channel where SP::Target: SignerProvider { let channel_type = Self::get_initial_channel_type(&config, their_features); debug_assert!(channel_type.is_subset(&channelmanager::provided_channel_type_features(&config))); - let commitment_conf_target = if channel_type.supports_anchors_zero_fee_htlc_tx() { - ConfirmationTarget::MempoolMinimum + let (commitment_conf_target, anchor_outputs_value_msat) = if channel_type.supports_anchors_zero_fee_htlc_tx() { + (ConfirmationTarget::AnchorChannelFee, ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000) } else { - ConfirmationTarget::Normal + (ConfirmationTarget::NonAnchorChannelFee, 0) }; let commitment_feerate = fee_estimator.bounded_sat_per_1000_weight(commitment_conf_target); let value_to_self_msat = channel_value_satoshis * 1000 - push_msat; let commitment_tx_fee = commit_tx_fee_msat(commitment_feerate, MIN_AFFORDABLE_HTLC_COUNT, &channel_type); - if value_to_self_msat < commitment_tx_fee { + if value_to_self_msat.saturating_sub(anchor_outputs_value_msat) < commitment_tx_fee { return Err(APIError::APIMisuseError{ err: format!("Funding amount ({}) can't even pay fee for initial commitment transaction fee of {}.", value_to_self_msat / 1000, commitment_tx_fee / 1000) }); } @@ -5998,7 +6014,7 @@ impl OutboundV1Channel where SP::Target: SignerProvider { /// not of our ability to open any channel at all. Thus, on error, we should first call this /// and see if we get a new `OpenChannel` message, otherwise the channel is failed. pub(crate) fn maybe_handle_error_without_close( - &mut self, chain_hash: BlockHash, fee_estimator: &LowerBoundedFeeEstimator + &mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator ) -> Result where F::Target: FeeEstimator @@ -6019,7 +6035,7 @@ impl OutboundV1Channel where SP::Target: SignerProvider { // whatever reason. if self.context.channel_type.supports_anchors_zero_fee_htlc_tx() { self.context.channel_type.clear_anchors_zero_fee_htlc_tx(); - self.context.feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal); + self.context.feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee); assert!(!self.context.channel_transaction_parameters.channel_type_features.supports_anchors_nonzero_fee_htlc_tx()); } else if self.context.channel_type.supports_scid_privacy() { self.context.channel_type.clear_scid_privacy(); @@ -6030,7 +6046,7 @@ impl OutboundV1Channel where SP::Target: SignerProvider { Ok(self.get_open_channel(chain_hash)) } - pub fn get_open_channel(&self, chain_hash: BlockHash) -> msgs::OpenChannel { + pub fn get_open_channel(&self, chain_hash: ChainHash) -> msgs::OpenChannel { if !self.context.is_outbound() { panic!("Tried to open a channel for an inbound channel?"); } @@ -6352,13 +6368,18 @@ impl InboundV1Channel where SP::Target: SignerProvider { // check if the funder's amount for the initial commitment tx is sufficient // for full fee payment plus a few HTLCs to ensure the channel will be useful. + let anchor_outputs_value = if channel_type.supports_anchors_zero_fee_htlc_tx() { + ANCHOR_OUTPUT_VALUE_SATOSHI * 2 + } else { + 0 + }; let funders_amount_msat = msg.funding_satoshis * 1000 - msg.push_msat; let commitment_tx_fee = commit_tx_fee_msat(msg.feerate_per_kw, MIN_AFFORDABLE_HTLC_COUNT, &channel_type) / 1000; - if funders_amount_msat / 1000 < commitment_tx_fee { - return Err(ChannelError::Close(format!("Funding amount ({} sats) can't even pay fee for initial commitment transaction fee of {} sats.", funders_amount_msat / 1000, commitment_tx_fee))); + if (funders_amount_msat / 1000).saturating_sub(anchor_outputs_value) < commitment_tx_fee { + return Err(ChannelError::Close(format!("Funding amount ({} sats) can't even pay fee for initial commitment transaction fee of {} sats.", (funders_amount_msat / 1000).saturating_sub(anchor_outputs_value), commitment_tx_fee))); } - let to_remote_satoshis = funders_amount_msat / 1000 - commitment_tx_fee; + let to_remote_satoshis = funders_amount_msat / 1000 - commitment_tx_fee - anchor_outputs_value; // While it's reasonable for us to not meet the channel reserve initially (if they don't // want to push much to us), our counterparty should always have more than our reserve. if to_remote_satoshis < holder_selected_channel_reserve_satoshis { @@ -7633,9 +7654,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch #[cfg(test)] mod tests { use std::cmp; + use bitcoin::blockdata::constants::ChainHash; use bitcoin::blockdata::script::{Script, Builder}; use bitcoin::blockdata::transaction::{Transaction, TxOut}; - use bitcoin::blockdata::constants::genesis_block; use bitcoin::blockdata::opcodes; use bitcoin::network::constants::Network; use hex; @@ -7779,7 +7800,7 @@ mod tests { // Now change the fee so we can check that the fee in the open_channel message is the // same as the old fee. fee_est.fee_est = 500; - let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash()); + let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network)); assert_eq!(open_channel_msg.feerate_per_kw, original_fee); } @@ -7805,7 +7826,7 @@ mod tests { // Create Node B's channel by receiving Node A's open_channel message // Make sure A's dust limit is as we expect. - let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash()); + let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network)); let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false).unwrap(); @@ -7923,7 +7944,7 @@ mod tests { let seed = [42; 32]; let network = Network::Testnet; let best_block = BestBlock::from_network(network); - let chain_hash = best_block.block_hash(); + let chain_hash = ChainHash::using_genesis_block(network); let keys_provider = test_utils::TestKeysInterface::new(&seed, network); // Go through the flow of opening a channel between two nodes. @@ -8003,7 +8024,7 @@ mod tests { let chan_2_value_msat = chan_2.context.channel_value_satoshis * 1000; assert_eq!(chan_2.context.holder_max_htlc_value_in_flight_msat, (chan_2_value_msat as f64 * 0.99) as u64); - let chan_1_open_channel_msg = chan_1.get_open_channel(genesis_block(network).header.block_hash()); + let chan_1_open_channel_msg = chan_1.get_open_channel(ChainHash::using_genesis_block(network)); // Test that `InboundV1Channel::new` creates a channel with the correct value for // `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value, @@ -8084,7 +8105,7 @@ mod tests { let expected_outbound_selected_chan_reserve = cmp::max(MIN_THEIR_CHAN_RESERVE_SATOSHIS, (chan.context.channel_value_satoshis as f64 * outbound_selected_channel_reserve_perc) as u64); assert_eq!(chan.context.holder_selected_channel_reserve_satoshis, expected_outbound_selected_chan_reserve); - let chan_open_channel_msg = chan.get_open_channel(genesis_block(network).header.block_hash()); + let chan_open_channel_msg = chan.get_open_channel(ChainHash::using_genesis_block(network)); let mut inbound_node_config = UserConfig::default(); inbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (inbound_selected_channel_reserve_perc * 1_000_000.0) as u32; @@ -8110,7 +8131,7 @@ mod tests { let seed = [42; 32]; let network = Network::Testnet; let best_block = BestBlock::from_network(network); - let chain_hash = genesis_block(network).header.block_hash(); + let chain_hash = ChainHash::using_genesis_block(network); let keys_provider = test_utils::TestKeysInterface::new(&seed, network); // Create Node A's channel pointing to Node B's pubkey @@ -8120,7 +8141,7 @@ mod tests { // Create Node B's channel by receiving Node A's open_channel message // Make sure A's dust limit is as we expect. - let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash()); + let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network)); let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false).unwrap(); @@ -8957,7 +8978,7 @@ mod tests { let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key(); channel_type_features.set_zero_conf_required(); - let mut open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash()); + let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network)); open_channel_msg.channel_type = Some(channel_type_features); let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); let res = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, @@ -9000,7 +9021,7 @@ mod tests { &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42 ).unwrap(); - let open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash()); + let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network)); let channel_b = InboundV1Channel::<&TestKeysInterface>::new( &fee_estimator, &&keys_provider, &&keys_provider, node_id_a, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), @@ -9038,7 +9059,7 @@ mod tests { ).unwrap(); // Set `channel_type` to `None` to force the implicit feature negotiation. - let mut open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash()); + let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network)); open_channel_msg.channel_type = None; // Since A supports both `static_remote_key` and `option_anchors`, but B only accepts @@ -9083,7 +9104,7 @@ mod tests { &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42 ).unwrap(); - let mut open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash()); + let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network)); open_channel_msg.channel_type = Some(simple_anchors_channel_type.clone()); let res = InboundV1Channel::<&TestKeysInterface>::new( @@ -9102,7 +9123,7 @@ mod tests { 10000000, 100000, 42, &config, 0, 42 ).unwrap(); - let open_channel_msg = channel_a.get_open_channel(genesis_block(network).header.block_hash()); + let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network)); let channel_b = InboundV1Channel::<&TestKeysInterface>::new( &fee_estimator, &&keys_provider, &&keys_provider, node_id_a, @@ -9127,7 +9148,7 @@ mod tests { let seed = [42; 32]; let network = Network::Testnet; let best_block = BestBlock::from_network(network); - let chain_hash = genesis_block(network).header.block_hash(); + let chain_hash = ChainHash::using_genesis_block(network); let keys_provider = test_utils::TestKeysInterface::new(&seed, network); let mut config = UserConfig::default(); @@ -9151,7 +9172,7 @@ mod tests { 42, ).unwrap(); - let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash()); + let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network)); let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap()); let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new( &feeest,