X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=fd0d94d3eb6381fb97dadcd49184d554c42aa94a;hb=7cfafc98ba2429c6505ad11d9296e1ffe35cf60f;hp=db38588230b77e153f967aba6781296fe459967d;hpb=0f2c4c0d7008b2af3165859b1c6dec8d16a672c4;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index db385882..fd0d94d3 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -27,7 +27,7 @@ use crate::ln::features::{ChannelTypeFeatures, InitFeatures}; use crate::ln::msgs; use crate::ln::msgs::DecodeError; use crate::ln::script::{self, ShutdownScript}; -use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, SentHTLCId, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT}; +use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, SentHTLCId, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT, ChannelShutdownState}; use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, htlc_success_tx_weight, htlc_timeout_tx_weight, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor, ClosingTransaction}; use crate::ln::chan_utils; use crate::ln::onion_utils::HTLCFailReason; @@ -41,7 +41,7 @@ use crate::routing::gossip::NodeId; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter}; use crate::util::logger::Logger; use crate::util::errors::APIError; -use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits}; +use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits, MaxDustHTLCExposure}; use crate::util::scid_utils::scid_from_parts; use crate::io; @@ -250,38 +250,38 @@ enum HTLCUpdateAwaitingACK { } /// There are a few "states" and then a number of flags which can be applied: -/// We first move through init with OurInitSent -> TheirInitSent -> FundingCreated -> FundingSent. -/// TheirChannelReady and OurChannelReady then get set on FundingSent, and when both are set we -/// move on to ChannelReady. -/// Note that PeerDisconnected can be set on both ChannelReady and FundingSent. -/// ChannelReady can then get all remaining flags set on it, until we finish shutdown, then we -/// move on to ShutdownComplete, at which point most calls into this channel are disallowed. +/// We first move through init with `OurInitSent` -> `TheirInitSent` -> `FundingCreated` -> `FundingSent`. +/// `TheirChannelReady` and `OurChannelReady` then get set on `FundingSent`, and when both are set we +/// move on to `ChannelReady`. +/// Note that `PeerDisconnected` can be set on both `ChannelReady` and `FundingSent`. +/// `ChannelReady` can then get all remaining flags set on it, until we finish shutdown, then we +/// move on to `ShutdownComplete`, at which point most calls into this channel are disallowed. enum ChannelState { /// Implies we have (or are prepared to) send our open_channel/accept_channel message OurInitSent = 1 << 0, - /// Implies we have received their open_channel/accept_channel message + /// Implies we have received their `open_channel`/`accept_channel` message TheirInitSent = 1 << 1, - /// We have sent funding_created and are awaiting a funding_signed to advance to FundingSent. - /// Note that this is nonsense for an inbound channel as we immediately generate funding_signed - /// upon receipt of funding_created, so simply skip this state. + /// We have sent `funding_created` and are awaiting a `funding_signed` to advance to `FundingSent`. + /// Note that this is nonsense for an inbound channel as we immediately generate `funding_signed` + /// upon receipt of `funding_created`, so simply skip this state. FundingCreated = 4, - /// Set when we have received/sent funding_created and funding_signed and are thus now waiting - /// on the funding transaction to confirm. The ChannelReady flags are set to indicate when we + /// Set when we have received/sent `funding_created` and `funding_signed` and are thus now waiting + /// on the funding transaction to confirm. The `ChannelReady` flags are set to indicate when we /// and our counterparty consider the funding transaction confirmed. FundingSent = 8, - /// Flag which can be set on FundingSent to indicate they sent us a channel_ready message. - /// Once both TheirChannelReady and OurChannelReady are set, state moves on to ChannelReady. + /// Flag which can be set on `FundingSent` to indicate they sent us a `channel_ready` message. + /// Once both `TheirChannelReady` and `OurChannelReady` are set, state moves on to `ChannelReady`. TheirChannelReady = 1 << 4, - /// Flag which can be set on FundingSent to indicate we sent them a channel_ready message. - /// Once both TheirChannelReady and OurChannelReady are set, state moves on to ChannelReady. + /// Flag which can be set on `FundingSent` to indicate we sent them a `channel_ready` message. + /// Once both `TheirChannelReady` and `OurChannelReady` are set, state moves on to `ChannelReady`. OurChannelReady = 1 << 5, ChannelReady = 64, - /// Flag which is set on ChannelReady and FundingSent indicating remote side is considered - /// "disconnected" and no updates are allowed until after we've done a channel_reestablish + /// Flag which is set on `ChannelReady` and `FundingSent` indicating remote side is considered + /// "disconnected" and no updates are allowed until after we've done a `channel_reestablish` /// dance. PeerDisconnected = 1 << 7, - /// Flag which is set on ChannelReady, FundingCreated, and FundingSent indicating the user has - /// told us a ChannelMonitor update is pending async persistence somewhere and we should pause + /// Flag which is set on `ChannelReady`, FundingCreated, and `FundingSent` indicating the user has + /// told us a `ChannelMonitor` update is pending async persistence somewhere and we should pause /// sending any outbound messages until they've managed to finish. MonitorUpdateInProgress = 1 << 8, /// Flag which implies that we have sent a commitment_signed but are awaiting the responding @@ -289,13 +289,13 @@ enum ChannelState { /// messages as then we will be unable to determine which HTLCs they included in their /// revoke_and_ack implicit ACK, so instead we have to hold them away temporarily to be sent /// later. - /// Flag is set on ChannelReady. + /// Flag is set on `ChannelReady`. AwaitingRemoteRevoke = 1 << 9, - /// Flag which is set on ChannelReady or FundingSent after receiving a shutdown message from + /// Flag which is set on `ChannelReady` or `FundingSent` after receiving a shutdown message from /// the remote end. If set, they may not add any new HTLCs to the channel, and we are expected /// to respond with our own shutdown message when possible. RemoteShutdownSent = 1 << 10, - /// Flag which is set on ChannelReady or FundingSent after sending a shutdown message. At this + /// Flag which is set on `ChannelReady` or `FundingSent` after sending a shutdown message. At this /// point, we may not add any new HTLCs to the channel. LocalShutdownSent = 1 << 11, /// We've successfully negotiated a closing_signed dance. At this point ChannelManager is about @@ -527,6 +527,10 @@ pub(super) struct ReestablishResponses { } /// The return type of `force_shutdown` +/// +/// Contains a (counterparty_node_id, funding_txo, [`ChannelMonitorUpdate`]) tuple +/// followed by a list of HTLCs to fail back in the form of the (source, payment hash, and this +/// channel's counterparty_node_id and channel_id). pub(crate) type ShutdownResult = ( Option<(PublicKey, OutPoint, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash, PublicKey, [u8; 32])> @@ -586,6 +590,11 @@ pub(crate) const EXPIRE_PREV_CONFIG_TICKS: usize = 5; /// See [`ChannelContext::sent_message_awaiting_response`] for more information. pub(crate) const DISCONNECT_PEER_AWAITING_RESPONSE_TICKS: usize = 2; +/// The number of ticks that may elapse while we're waiting for an unfunded outbound/inbound channel +/// to be promoted to a [`Channel`] since the unfunded channel was created. An unfunded channel +/// exceeding this age limit will be force-closed and purged from memory. +pub(crate) const UNFUNDED_CHANNEL_AGE_LIMIT_TICKS: usize = 60; + struct PendingChannelMonitorUpdate { update: ChannelMonitorUpdate, } @@ -594,6 +603,28 @@ impl_writeable_tlv_based!(PendingChannelMonitorUpdate, { (0, update, required), }); +/// Contains all state common to unfunded inbound/outbound channels. +pub(super) struct UnfundedChannelContext { + /// A counter tracking how many ticks have elapsed since this unfunded channel was + /// created. If this unfunded channel reaches peer has yet to respond after reaching + /// `UNFUNDED_CHANNEL_AGE_LIMIT_TICKS`, it will be force-closed and purged from memory. + /// + /// This is so that we don't keep channels around that haven't progressed to a funded state + /// in a timely manner. + unfunded_channel_age_ticks: usize, +} + +impl UnfundedChannelContext { + /// Determines whether we should force-close and purge this unfunded channel from memory due to it + /// having reached the unfunded channel age limit. + /// + /// This should be called on every [`super::channelmanager::ChannelManager::timer_tick_occurred`]. + pub fn should_expire_unfunded_channel(&mut self) -> bool { + self.unfunded_channel_age_ticks += 1; + self.unfunded_channel_age_ticks >= UNFUNDED_CHANNEL_AGE_LIMIT_TICKS + } +} + /// Contains everything about the channel including state, and various flags. pub(super) struct ChannelContext { config: LegacyChannelConfig, @@ -903,6 +934,34 @@ impl ChannelContext { (self.channel_state & mask) == (ChannelState::ChannelReady as u32) && !self.monitor_pending_channel_ready } + /// shutdown state returns the state of the channel in its various stages of shutdown + pub fn shutdown_state(&self) -> ChannelShutdownState { + if self.channel_state & (ChannelState::ShutdownComplete as u32) != 0 { + return ChannelShutdownState::ShutdownComplete; + } + if self.channel_state & (ChannelState::LocalShutdownSent as u32) != 0 && self.channel_state & (ChannelState::RemoteShutdownSent as u32) == 0 { + return ChannelShutdownState::ShutdownInitiated; + } + if (self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != 0) && !self.closing_negotiation_ready() { + return ChannelShutdownState::ResolvingHTLCs; + } + if (self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != 0) && self.closing_negotiation_ready() { + return ChannelShutdownState::NegotiatingClosingFee; + } + return ChannelShutdownState::NotShuttingDown; + } + + fn closing_negotiation_ready(&self) -> bool { + self.pending_inbound_htlcs.is_empty() && + self.pending_outbound_htlcs.is_empty() && + self.pending_update_fee.is_none() && + self.channel_state & + (BOTH_SIDES_SHUTDOWN_MASK | + ChannelState::AwaitingRemoteRevoke as u32 | + ChannelState::PeerDisconnected as u32 | + ChannelState::MonitorUpdateInProgress as u32) == BOTH_SIDES_SHUTDOWN_MASK + } + /// Returns true if this channel is currently available for use. This is a superset of /// is_usable() and considers things like the channel being temporarily disabled. /// Allowed in any state (including after shutdown) @@ -938,9 +997,9 @@ impl ChannelContext { &self.channel_type } - /// Guaranteed to be Some after both ChannelReady messages have been exchanged (and, thus, - /// is_usable() returns true). - /// Allowed in any state (including after shutdown) + /// Gets the channel's `short_channel_id`. + /// + /// Will return `None` if the channel hasn't been confirmed yet. pub fn get_short_channel_id(&self) -> Option { self.short_channel_id } @@ -963,7 +1022,7 @@ impl ChannelContext { } /// Returns the funding_txo we either got from our peer, or were given by - /// get_outbound_funding_created. + /// get_funding_created. pub fn get_funding_txo(&self) -> Option { self.channel_transaction_parameters.funding_outpoint } @@ -1059,8 +1118,18 @@ impl ChannelContext { cmp::max(self.config.options.cltv_expiry_delta, MIN_CLTV_EXPIRY_DELTA) } - pub fn get_max_dust_htlc_exposure_msat(&self) -> u64 { - self.config.options.max_dust_htlc_exposure_msat + pub fn get_max_dust_htlc_exposure_msat(&self, + fee_estimator: &LowerBoundedFeeEstimator) -> u64 + where F::Target: FeeEstimator + { + match self.config.options.max_dust_htlc_exposure { + MaxDustHTLCExposure::FeeRateMultiplier(multiplier) => { + let feerate_per_kw = fee_estimator.bounded_sat_per_1000_weight( + ConfirmationTarget::HighPriority); + feerate_per_kw as u64 * multiplier + }, + MaxDustHTLCExposure::FixedLimitMsat(limit) => limit, + } } /// Returns the previous [`ChannelConfig`] applied to this channel, if any. @@ -1398,7 +1467,7 @@ impl ChannelContext { #[inline] /// Creates a set of keys for build_commitment_transaction to generate a transaction which we /// will sign and send to our counterparty. - /// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created) + /// If an Err is returned, it is a ChannelError::Close (for get_funding_created) fn build_remote_transaction_keys(&self) -> TxCreationKeys { //TODO: Ensure that the payment_key derived here ends up in the library users' wallet as we //may see payments to it! @@ -1533,7 +1602,10 @@ impl ChannelContext { /// Doesn't bother handling the /// if-we-removed-it-already-but-haven't-fully-resolved-they-can-still-send-an-inbound-HTLC /// corner case properly. - pub fn get_available_balances(&self) -> AvailableBalances { + pub fn get_available_balances(&self, fee_estimator: &LowerBoundedFeeEstimator) + -> AvailableBalances + where F::Target: FeeEstimator + { let context = &self; // Note that we have to handle overflow due to the above case. let inbound_stats = context.get_inbound_pending_htlc_stats(None); @@ -1615,6 +1687,7 @@ impl ChannelContext { // send above the dust limit (as the router can always overpay to meet the dust limit). let mut remaining_msat_below_dust_exposure_limit = None; let mut dust_exposure_dust_limit_msat = 0; + let max_dust_htlc_exposure_msat = context.get_max_dust_htlc_exposure_msat(fee_estimator); let (htlc_success_dust_limit, htlc_timeout_dust_limit) = if context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { (context.counterparty_dust_limit_satoshis, context.holder_dust_limit_satoshis) @@ -1624,17 +1697,17 @@ impl ChannelContext { context.holder_dust_limit_satoshis + dust_buffer_feerate * htlc_timeout_tx_weight(context.get_channel_type()) / 1000) }; let on_counterparty_dust_htlc_exposure_msat = inbound_stats.on_counterparty_tx_dust_exposure_msat + outbound_stats.on_counterparty_tx_dust_exposure_msat; - if on_counterparty_dust_htlc_exposure_msat as i64 + htlc_success_dust_limit as i64 * 1000 - 1 > context.get_max_dust_htlc_exposure_msat() as i64 { + if on_counterparty_dust_htlc_exposure_msat as i64 + htlc_success_dust_limit as i64 * 1000 - 1 > max_dust_htlc_exposure_msat as i64 { remaining_msat_below_dust_exposure_limit = - Some(context.get_max_dust_htlc_exposure_msat().saturating_sub(on_counterparty_dust_htlc_exposure_msat)); + Some(max_dust_htlc_exposure_msat.saturating_sub(on_counterparty_dust_htlc_exposure_msat)); dust_exposure_dust_limit_msat = cmp::max(dust_exposure_dust_limit_msat, htlc_success_dust_limit * 1000); } let on_holder_dust_htlc_exposure_msat = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat; - if on_holder_dust_htlc_exposure_msat as i64 + htlc_timeout_dust_limit as i64 * 1000 - 1 > context.get_max_dust_htlc_exposure_msat() as i64 { + if on_holder_dust_htlc_exposure_msat as i64 + htlc_timeout_dust_limit as i64 * 1000 - 1 > max_dust_htlc_exposure_msat as i64 { remaining_msat_below_dust_exposure_limit = Some(cmp::min( remaining_msat_below_dust_exposure_limit.unwrap_or(u64::max_value()), - context.get_max_dust_htlc_exposure_msat().saturating_sub(on_holder_dust_htlc_exposure_msat))); + max_dust_htlc_exposure_msat.saturating_sub(on_holder_dust_htlc_exposure_msat))); dust_exposure_dust_limit_msat = cmp::max(dust_exposure_dust_limit_msat, htlc_timeout_dust_limit * 1000); } @@ -1980,7 +2053,7 @@ fn commit_tx_fee_msat(feerate_per_kw: u32, num_htlcs: usize, channel_type_featur // TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking // has been completed, and then turn into a Channel to get compiler-time enforcement of things like -// calling channel_id() before we're set up or things like get_outbound_funding_signed on an +// calling channel_id() before we're set up or things like get_funding_signed on an // inbound channel. // // Holder designates channel data owned for the benefit of the user client. @@ -1999,20 +2072,35 @@ struct CommitmentTxInfoCached { } impl Channel { - fn check_remote_fee(fee_estimator: &LowerBoundedFeeEstimator, - feerate_per_kw: u32, cur_feerate_per_kw: Option, logger: &L) - -> Result<(), ChannelError> where F::Target: FeeEstimator, L::Target: Logger, + fn check_remote_fee( + channel_type: &ChannelTypeFeatures, fee_estimator: &LowerBoundedFeeEstimator, + feerate_per_kw: u32, cur_feerate_per_kw: Option, logger: &L + ) -> Result<(), ChannelError> where F::Target: FeeEstimator, L::Target: Logger, { // We only bound the fee updates on the upper side to prevent completely absurd feerates, // always accepting up to 25 sat/vByte or 10x our fee estimator's "High Priority" fee. // We generally don't care too much if they set the feerate to something very high, but it - // could result in the channel being useless due to everything being dust. - let upper_limit = cmp::max(250 * 25, - fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::HighPriority) as u64 * 10); - 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))); - } - let lower_limit = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Background); + // could result in the channel being useless due to everything being dust. This doesn't + // 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); + 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 + } else { + ConfirmationTarget::Background + }; + 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 @@ -2552,8 +2640,13 @@ impl Channel { Ok(self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger)) } - pub fn update_add_htlc(&mut self, msg: &msgs::UpdateAddHTLC, mut pending_forward_status: PendingHTLCStatus, create_pending_htlc_status: F, logger: &L) -> Result<(), ChannelError> - where F: for<'a> Fn(&'a Self, PendingHTLCStatus, u16) -> PendingHTLCStatus, L::Target: Logger { + pub fn update_add_htlc( + &mut self, msg: &msgs::UpdateAddHTLC, mut pending_forward_status: PendingHTLCStatus, + create_pending_htlc_status: F, fee_estimator: &LowerBoundedFeeEstimator, logger: &L + ) -> Result<(), ChannelError> + where F: for<'a> Fn(&'a Self, PendingHTLCStatus, u16) -> PendingHTLCStatus, + FE::Target: FeeEstimator, L::Target: Logger, + { // We can't accept HTLCs sent after we've sent a shutdown. let local_sent_shutdown = (self.context.channel_state & (ChannelState::ChannelReady as u32 | ChannelState::LocalShutdownSent as u32)) != (ChannelState::ChannelReady as u32); if local_sent_shutdown { @@ -2606,6 +2699,7 @@ impl Channel { } } + let max_dust_htlc_exposure_msat = self.context.get_max_dust_htlc_exposure_msat(fee_estimator); let (htlc_timeout_dust_limit, htlc_success_dust_limit) = if self.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { (0, 0) } else { @@ -2616,9 +2710,9 @@ impl Channel { let exposure_dust_limit_timeout_sats = htlc_timeout_dust_limit + self.context.counterparty_dust_limit_satoshis; if msg.amount_msat / 1000 < exposure_dust_limit_timeout_sats { let on_counterparty_tx_dust_htlc_exposure_msat = inbound_stats.on_counterparty_tx_dust_exposure_msat + outbound_stats.on_counterparty_tx_dust_exposure_msat + msg.amount_msat; - if on_counterparty_tx_dust_htlc_exposure_msat > self.context.get_max_dust_htlc_exposure_msat() { + if on_counterparty_tx_dust_htlc_exposure_msat > max_dust_htlc_exposure_msat { log_info!(logger, "Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on counterparty commitment tx", - on_counterparty_tx_dust_htlc_exposure_msat, self.context.get_max_dust_htlc_exposure_msat()); + on_counterparty_tx_dust_htlc_exposure_msat, max_dust_htlc_exposure_msat); pending_forward_status = create_pending_htlc_status(self, pending_forward_status, 0x1000|7); } } @@ -2626,9 +2720,9 @@ impl Channel { let exposure_dust_limit_success_sats = htlc_success_dust_limit + self.context.holder_dust_limit_satoshis; if msg.amount_msat / 1000 < exposure_dust_limit_success_sats { let on_holder_tx_dust_htlc_exposure_msat = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat + msg.amount_msat; - if on_holder_tx_dust_htlc_exposure_msat > self.context.get_max_dust_htlc_exposure_msat() { + if on_holder_tx_dust_htlc_exposure_msat > max_dust_htlc_exposure_msat { log_info!(logger, "Cannot accept value that would put our exposure to dust HTLCs at {} over the limit {} on holder commitment tx", - on_holder_tx_dust_htlc_exposure_msat, self.context.get_max_dust_htlc_exposure_msat()); + on_holder_tx_dust_htlc_exposure_msat, max_dust_htlc_exposure_msat); pending_forward_status = create_pending_htlc_status(self, pending_forward_status, 0x1000|7); } } @@ -2995,16 +3089,24 @@ impl Channel { /// Public version of the below, checking relevant preconditions first. /// If we're not in a state where freeing the holding cell makes sense, this is a no-op and /// returns `(None, Vec::new())`. - pub fn maybe_free_holding_cell_htlcs(&mut self, logger: &L) -> (Option, Vec<(HTLCSource, PaymentHash)>) where L::Target: Logger { + pub fn maybe_free_holding_cell_htlcs( + &mut self, fee_estimator: &LowerBoundedFeeEstimator, logger: &L + ) -> (Option, Vec<(HTLCSource, PaymentHash)>) + where F::Target: FeeEstimator, L::Target: Logger + { if self.context.channel_state >= ChannelState::ChannelReady as u32 && (self.context.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)) == 0 { - self.free_holding_cell_htlcs(logger) + self.free_holding_cell_htlcs(fee_estimator, logger) } else { (None, Vec::new()) } } /// Frees any pending commitment updates in the holding cell, generating the relevant messages /// for our counterparty. - fn free_holding_cell_htlcs(&mut self, logger: &L) -> (Option, Vec<(HTLCSource, PaymentHash)>) where L::Target: Logger { + fn free_holding_cell_htlcs( + &mut self, fee_estimator: &LowerBoundedFeeEstimator, logger: &L + ) -> (Option, Vec<(HTLCSource, PaymentHash)>) + where F::Target: FeeEstimator, L::Target: Logger + { assert_eq!(self.context.channel_state & ChannelState::MonitorUpdateInProgress as u32, 0); if self.context.holding_cell_htlc_updates.len() != 0 || self.context.holding_cell_update_fee.is_some() { log_trace!(logger, "Freeing holding cell with {} HTLC updates{} in channel {}", self.context.holding_cell_htlc_updates.len(), @@ -3033,7 +3135,7 @@ impl Channel { skimmed_fee_msat, .. } => { match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), - onion_routing_packet.clone(), false, skimmed_fee_msat, logger) + onion_routing_packet.clone(), false, skimmed_fee_msat, fee_estimator, logger) { Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()), Err(e) => { @@ -3093,7 +3195,7 @@ impl Channel { return (None, htlcs_to_fail); } let update_fee = if let Some(feerate) = self.context.holding_cell_update_fee.take() { - self.send_update_fee(feerate, false, logger) + self.send_update_fee(feerate, false, fee_estimator, logger) } else { None }; @@ -3120,8 +3222,10 @@ impl Channel { /// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail, /// generating an appropriate error *after* the channel state has been updated based on the /// revoke_and_ack message. - pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, logger: &L) -> Result<(Vec<(HTLCSource, PaymentHash)>, Option), ChannelError> - where L::Target: Logger, + pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, + fee_estimator: &LowerBoundedFeeEstimator, logger: &L + ) -> Result<(Vec<(HTLCSource, PaymentHash)>, Option), ChannelError> + where F::Target: FeeEstimator, L::Target: Logger, { if (self.context.channel_state & (ChannelState::ChannelReady as u32)) != (ChannelState::ChannelReady as u32) { return Err(ChannelError::Close("Got revoke/ACK message when channel was not in an operational state".to_owned())); @@ -3321,7 +3425,7 @@ impl Channel { return Ok((Vec::new(), self.push_ret_blockable_mon_update(monitor_update))); } - match self.free_holding_cell_htlcs(logger) { + match self.free_holding_cell_htlcs(fee_estimator, logger) { (Some(mut additional_update), htlcs_to_fail) => { // free_holding_cell_htlcs may bump latest_monitor_id multiple times but we want them to be // strictly increasing by one, so decrement it here. @@ -3356,8 +3460,11 @@ impl Channel { /// Queues up an outbound update fee by placing it in the holding cell. You should call /// [`Self::maybe_free_holding_cell_htlcs`] in order to actually generate and send the /// commitment update. - pub fn queue_update_fee(&mut self, feerate_per_kw: u32, logger: &L) where L::Target: Logger { - let msg_opt = self.send_update_fee(feerate_per_kw, true, logger); + pub fn queue_update_fee(&mut self, feerate_per_kw: u32, + fee_estimator: &LowerBoundedFeeEstimator, logger: &L) + where F::Target: FeeEstimator, L::Target: Logger + { + let msg_opt = self.send_update_fee(feerate_per_kw, true, fee_estimator, logger); assert!(msg_opt.is_none(), "We forced holding cell?"); } @@ -3368,7 +3475,12 @@ impl Channel { /// /// You MUST call [`Self::send_commitment_no_state_update`] prior to any other calls on this /// [`Channel`] if `force_holding_cell` is false. - fn send_update_fee(&mut self, feerate_per_kw: u32, mut force_holding_cell: bool, logger: &L) -> Option where L::Target: Logger { + fn send_update_fee( + &mut self, feerate_per_kw: u32, mut force_holding_cell: bool, + fee_estimator: &LowerBoundedFeeEstimator, logger: &L + ) -> Option + where F::Target: FeeEstimator, L::Target: Logger + { if !self.context.is_outbound() { panic!("Cannot send fee from inbound channel"); } @@ -3395,11 +3507,12 @@ impl Channel { // Note, we evaluate pending htlc "preemptive" trimmed-to-dust threshold at the proposed `feerate_per_kw`. let holder_tx_dust_exposure = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat; let counterparty_tx_dust_exposure = inbound_stats.on_counterparty_tx_dust_exposure_msat + outbound_stats.on_counterparty_tx_dust_exposure_msat; - if holder_tx_dust_exposure > self.context.get_max_dust_htlc_exposure_msat() { + let max_dust_htlc_exposure_msat = self.context.get_max_dust_htlc_exposure_msat(fee_estimator); + if holder_tx_dust_exposure > max_dust_htlc_exposure_msat { log_debug!(logger, "Cannot afford to send new feerate at {} without infringing max dust htlc exposure", feerate_per_kw); return None; } - if counterparty_tx_dust_exposure > self.context.get_max_dust_htlc_exposure_msat() { + if counterparty_tx_dust_exposure > max_dust_htlc_exposure_msat { log_debug!(logger, "Cannot afford to send new feerate at {} without infringing max dust htlc exposure", feerate_per_kw); return None; } @@ -3617,7 +3730,7 @@ impl Channel { if self.context.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(ChannelError::Close("Peer sent update_fee when we needed a channel_reestablish".to_owned())); } - Channel::::check_remote_fee(fee_estimator, msg.feerate_per_kw, Some(self.context.feerate_per_kw), logger)?; + Channel::::check_remote_fee(&self.context.channel_type, fee_estimator, msg.feerate_per_kw, Some(self.context.feerate_per_kw), logger)?; let feerate_over_dust_buffer = msg.feerate_per_kw > self.context.get_dust_buffer_feerate(None); self.context.pending_update_fee = Some((msg.feerate_per_kw, FeeUpdateState::RemoteAnnounced)); @@ -3630,11 +3743,12 @@ impl Channel { let outbound_stats = self.context.get_outbound_pending_htlc_stats(None); let holder_tx_dust_exposure = inbound_stats.on_holder_tx_dust_exposure_msat + outbound_stats.on_holder_tx_dust_exposure_msat; let counterparty_tx_dust_exposure = inbound_stats.on_counterparty_tx_dust_exposure_msat + outbound_stats.on_counterparty_tx_dust_exposure_msat; - if holder_tx_dust_exposure > self.context.get_max_dust_htlc_exposure_msat() { + let max_dust_htlc_exposure_msat = self.context.get_max_dust_htlc_exposure_msat(fee_estimator); + if holder_tx_dust_exposure > max_dust_htlc_exposure_msat { return Err(ChannelError::Close(format!("Peer sent update_fee with a feerate ({}) which may over-expose us to dust-in-flight on our own transactions (totaling {} msat)", msg.feerate_per_kw, holder_tx_dust_exposure))); } - if counterparty_tx_dust_exposure > self.context.get_max_dust_htlc_exposure_msat() { + if counterparty_tx_dust_exposure > max_dust_htlc_exposure_msat { return Err(ChannelError::Close(format!("Peer sent update_fee with a feerate ({}) which may over-expose us to dust-in-flight on our counterparty's transactions (totaling {} msat)", msg.feerate_per_kw, counterparty_tx_dust_exposure))); } @@ -3956,12 +4070,7 @@ impl Channel { /// this point if we're the funder we should send the initial closing_signed, and in any case /// shutdown should complete within a reasonable timeframe. fn closing_negotiation_ready(&self) -> bool { - self.context.pending_inbound_htlcs.is_empty() && self.context.pending_outbound_htlcs.is_empty() && - self.context.channel_state & - (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::AwaitingRemoteRevoke as u32 | - ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32) - == BOTH_SIDES_SHUTDOWN_MASK && - self.context.pending_update_fee.is_none() + self.context.closing_negotiation_ready() } /// Checks if the closing_signed negotiation is making appropriate progress, possibly returning @@ -4760,7 +4869,7 @@ impl Channel { // something in the handler for the message that prompted this message): /// Gets an UnsignedChannelAnnouncement for this channel. The channel must be publicly - /// announceable and available for use (have exchanged ChannelReady messages in both + /// announceable and available for use (have exchanged [`ChannelReady`] messages in both /// directions). Should be used for both broadcasted announcements and in response to an /// AnnouncementSignatures message from the remote peer. /// @@ -4768,6 +4877,8 @@ impl Channel { /// closing). /// /// This will only return ChannelError::Ignore upon failure. + /// + /// [`ChannelReady`]: crate::ln::msgs::ChannelReady fn get_channel_announcement( &self, node_signer: &NS, chain_hash: BlockHash, user_config: &UserConfig, ) -> Result where NS::Target: NodeSigner { @@ -4778,6 +4889,8 @@ impl Channel { return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement if the channel is not currently usable".to_owned())); } + let short_channel_id = self.context.get_short_channel_id() + .ok_or(ChannelError::Ignore("Cannot get a ChannelAnnouncement if the channel has not been confirmed yet".to_owned()))?; let node_id = NodeId::from_pubkey(&node_signer.get_node_id(Recipient::Node) .map_err(|_| ChannelError::Ignore("Failed to retrieve own public key".to_owned()))?); let counterparty_node_id = NodeId::from_pubkey(&self.context.get_counterparty_node_id()); @@ -4786,7 +4899,7 @@ impl Channel { let msg = msgs::UnsignedChannelAnnouncement { features: channelmanager::provided_channel_features(&user_config), chain_hash, - short_channel_id: self.context.get_short_channel_id().unwrap(), + short_channel_id, node_id_1: if were_node_one { node_id } else { counterparty_node_id }, node_id_2: if were_node_one { counterparty_node_id } else { node_id }, bitcoin_key_1: NodeId::from_pubkey(if were_node_one { &self.context.get_holder_pubkeys().funding_pubkey } else { self.context.counterparty_funding_pubkey() }), @@ -4844,11 +4957,16 @@ impl Channel { }, Ok(v) => v }; + let short_channel_id = match self.context.get_short_channel_id() { + Some(scid) => scid, + None => return None, + }; + self.context.announcement_sigs_state = AnnouncementSigsState::MessageSent; Some(msgs::AnnouncementSignatures { channel_id: self.context.channel_id(), - short_channel_id: self.context.get_short_channel_id().unwrap(), + short_channel_id, node_signature: our_node_sig, bitcoin_signature: our_bitcoin_sig, }) @@ -4988,13 +5106,16 @@ impl Channel { /// commitment update. /// /// `Err`s will only be [`ChannelError::Ignore`]. - pub fn queue_add_htlc( + pub fn queue_add_htlc( &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, - onion_routing_packet: msgs::OnionPacket, skimmed_fee_msat: Option, logger: &L - ) -> Result<(), ChannelError> where L::Target: Logger { + onion_routing_packet: msgs::OnionPacket, skimmed_fee_msat: Option, + fee_estimator: &LowerBoundedFeeEstimator, logger: &L + ) -> Result<(), ChannelError> + where F::Target: FeeEstimator, L::Target: Logger + { self .send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, true, - skimmed_fee_msat, logger) + skimmed_fee_msat, fee_estimator, logger) .map(|msg_opt| assert!(msg_opt.is_none(), "We forced holding cell?")) .map_err(|err| { if let ChannelError::Ignore(_) = err { /* fine */ } @@ -5019,11 +5140,13 @@ impl Channel { /// on this [`Channel`] if `force_holding_cell` is false. /// /// `Err`s will only be [`ChannelError::Ignore`]. - fn send_htlc( + fn send_htlc( &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, mut force_holding_cell: bool, - skimmed_fee_msat: Option, logger: &L - ) -> Result, ChannelError> where L::Target: Logger { + skimmed_fee_msat: Option, fee_estimator: &LowerBoundedFeeEstimator, logger: &L + ) -> Result, ChannelError> + where F::Target: FeeEstimator, L::Target: Logger + { if (self.context.channel_state & (ChannelState::ChannelReady as u32 | BOTH_SIDES_SHUTDOWN_MASK)) != (ChannelState::ChannelReady as u32) { return Err(ChannelError::Ignore("Cannot send HTLC until channel is fully established and we haven't started shutting down".to_owned())); } @@ -5036,7 +5159,7 @@ impl Channel { return Err(ChannelError::Ignore("Cannot send 0-msat HTLC".to_owned())); } - let available_balances = self.context.get_available_balances(); + let available_balances = self.context.get_available_balances(fee_estimator); if amount_msat < available_balances.next_outbound_htlc_minimum_msat { return Err(ChannelError::Ignore(format!("Cannot send less than our next-HTLC minimum - {} msat", available_balances.next_outbound_htlc_minimum_msat))); @@ -5236,12 +5359,15 @@ impl Channel { /// /// Shorthand for calling [`Self::send_htlc`] followed by a commitment update, see docs on /// [`Self::send_htlc`] and [`Self::build_commitment_no_state_update`] for more info. - pub fn send_htlc_and_commit( - &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, - onion_routing_packet: msgs::OnionPacket, skimmed_fee_msat: Option, logger: &L - ) -> Result, ChannelError> where L::Target: Logger { + pub fn send_htlc_and_commit( + &mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, + source: HTLCSource, onion_routing_packet: msgs::OnionPacket, skimmed_fee_msat: Option, + fee_estimator: &LowerBoundedFeeEstimator, logger: &L + ) -> Result, ChannelError> + where F::Target: FeeEstimator, L::Target: Logger + { let send_res = self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, - onion_routing_packet, false, skimmed_fee_msat, logger); + onion_routing_packet, false, skimmed_fee_msat, fee_estimator, logger); if let Err(e) = &send_res { if let ChannelError::Ignore(_) = e {} else { debug_assert!(false, "Sending cannot trigger channel failure"); } } match send_res? { Some(_) => { @@ -5387,6 +5513,7 @@ impl Channel { /// A not-yet-funded outbound (from holder) channel using V1 channel establishment. pub(super) struct OutboundV1Channel { pub context: ChannelContext, + pub unfunded_context: UnfundedChannelContext, } impl OutboundV1Channel { @@ -5427,10 +5554,15 @@ impl OutboundV1Channel { let channel_type = Self::get_initial_channel_type(&config, their_features); debug_assert!(channel_type.is_subset(&channelmanager::provided_channel_type_features(&config))); - let feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal); + let commitment_conf_target = if channel_type.supports_anchors_zero_fee_htlc_tx() { + ConfirmationTarget::MempoolMinimum + } else { + ConfirmationTarget::Normal + }; + 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(feerate, MIN_AFFORDABLE_HTLC_COUNT, &channel_type); + let commitment_tx_fee = commit_tx_fee_msat(commitment_feerate, MIN_AFFORDABLE_HTLC_COUNT, &channel_type); if value_to_self_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) }); } @@ -5524,7 +5656,7 @@ impl OutboundV1Channel { short_channel_id: None, channel_creation_height: current_chain_height, - feerate_per_kw: feerate, + feerate_per_kw: commitment_feerate, counterparty_dust_limit_satoshis: 0, holder_dust_limit_satoshis: MIN_CHAN_DUST_LIMIT_SATOSHIS, counterparty_max_htlc_value_in_flight_msat: 0, @@ -5583,12 +5715,13 @@ impl OutboundV1Channel { channel_keys_id, blocked_monitor_updates: Vec::new(), - } + }, + unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 } }) } - /// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created) - fn get_outbound_funding_created_signature(&mut self, logger: &L) -> Result where L::Target: Logger { + /// If an Err is returned, it is a ChannelError::Close (for get_funding_created) + fn get_funding_created_signature(&mut self, logger: &L) -> Result where L::Target: Logger { let counterparty_keys = self.context.build_remote_transaction_keys(); let counterparty_initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx; Ok(self.context.holder_signer.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.context.secp_ctx) @@ -5602,7 +5735,7 @@ impl OutboundV1Channel { /// Note that channel_id changes during this call! /// Do NOT broadcast the funding transaction until after a successful funding_signed call! /// If an Err is returned, it is a ChannelError::Close. - pub fn get_outbound_funding_created(mut self, funding_transaction: Transaction, funding_txo: OutPoint, logger: &L) + pub fn get_funding_created(mut self, funding_transaction: Transaction, funding_txo: OutPoint, logger: &L) -> Result<(Channel, msgs::FundingCreated), (Self, ChannelError)> where L::Target: Logger { if !self.context.is_outbound() { panic!("Tried to create outbound funding_created message on an inbound channel!"); @@ -5619,7 +5752,7 @@ impl OutboundV1Channel { self.context.channel_transaction_parameters.funding_outpoint = Some(funding_txo); self.context.holder_signer.provide_channel_parameters(&self.context.channel_transaction_parameters); - let signature = match self.get_outbound_funding_created_signature(logger) { + let signature = match self.get_funding_created_signature(logger) { Ok(res) => res, Err(e) => { log_error!(logger, "Got bad signatures: {:?}!", e); @@ -5678,7 +5811,12 @@ impl OutboundV1Channel { /// If we receive an error message, it may only be a rejection of the channel type we tried, /// 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) -> Result { + pub(crate) fn maybe_handle_error_without_close( + &mut self, chain_hash: BlockHash, fee_estimator: &LowerBoundedFeeEstimator + ) -> Result + where + F::Target: FeeEstimator + { if !self.context.is_outbound() || self.context.channel_state != ChannelState::OurInitSent as u32 { return Err(()); } if self.context.channel_type == ChannelTypeFeatures::only_static_remote_key() { // We've exhausted our options @@ -5695,6 +5833,7 @@ impl OutboundV1Channel { // 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); 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(); @@ -5882,6 +6021,7 @@ impl OutboundV1Channel { /// A not-yet-funded inbound (from counterparty) channel using V1 channel establishment. pub(super) struct InboundV1Channel { pub context: ChannelContext, + pub unfunded_context: UnfundedChannelContext, } impl InboundV1Channel { @@ -5964,7 +6104,7 @@ impl InboundV1Channel { if msg.htlc_minimum_msat >= full_channel_value_msat { return Err(ChannelError::Close(format!("Minimum htlc value ({}) was larger than full channel value ({})", msg.htlc_minimum_msat, full_channel_value_msat))); } - Channel::::check_remote_fee(fee_estimator, msg.feerate_per_kw, None, logger)?; + Channel::::check_remote_fee(&channel_type, fee_estimator, msg.feerate_per_kw, None, logger)?; let max_counterparty_selected_contest_delay = u16::min(config.channel_handshake_limits.their_to_self_delay, MAX_LOCAL_BREAKDOWN_TIMEOUT); if msg.to_self_delay > max_counterparty_selected_contest_delay { @@ -6209,7 +6349,8 @@ impl InboundV1Channel { channel_keys_id, blocked_monitor_updates: Vec::new(), - } + }, + unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 } }; Ok(chan) @@ -6781,10 +6922,11 @@ impl Writeable for Channel { (5, self.context.config, required), (6, serialized_holder_htlc_max_in_flight, option), (7, self.context.shutdown_scriptpubkey, option), + (8, self.context.blocked_monitor_updates, optional_vec), (9, self.context.target_closing_feerate_sats_per_kw, option), - (11, self.context.monitor_pending_finalized_fulfills, vec_type), + (11, self.context.monitor_pending_finalized_fulfills, required_vec), (13, self.context.channel_creation_height, required), - (15, preimages, vec_type), + (15, preimages, required_vec), (17, self.context.announcement_sigs_state, required), (19, self.context.latest_inbound_scid_alias, option), (21, self.context.outbound_scid_alias, required), @@ -6794,7 +6936,6 @@ impl Writeable for Channel { (28, holder_max_accepted_htlcs, option), (29, self.context.temporary_channel_id, option), (31, channel_pending_event_emitted, option), - (33, self.context.blocked_monitor_updates, vec_type), (35, pending_outbound_skimmed_fees, optional_vec), (37, holding_cell_skimmed_fees, optional_vec), }); @@ -7089,10 +7230,11 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch (5, config, option), // Note that if none is provided we will *not* overwrite the existing one. (6, holder_max_htlc_value_in_flight_msat, option), (7, shutdown_scriptpubkey, option), + (8, blocked_monitor_updates, optional_vec), (9, target_closing_feerate_sats_per_kw, option), - (11, monitor_pending_finalized_fulfills, vec_type), + (11, monitor_pending_finalized_fulfills, optional_vec), (13, channel_creation_height, option), - (15, preimages_opt, vec_type), + (15, preimages_opt, optional_vec), (17, announcement_sigs_state, option), (19, latest_inbound_scid_alias, option), (21, outbound_scid_alias, option), @@ -7102,7 +7244,6 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch (28, holder_max_accepted_htlcs, option), (29, temporary_channel_id, option), (31, channel_pending_event_emitted, option), - (33, blocked_monitor_updates, vec_type), (35, pending_outbound_skimmed_fees_opt, optional_vec), (37, holding_cell_skimmed_fees_opt, optional_vec), }); @@ -7366,7 +7507,8 @@ mod tests { // arithmetic, causing a panic with debug assertions enabled. let fee_est = TestFeeEstimator { fee_est: 42 }; let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_est); - assert!(Channel::::check_remote_fee(&bounded_fee_estimator, + assert!(Channel::::check_remote_fee( + &ChannelTypeFeatures::only_static_remote_key(), &bounded_fee_estimator, u32::max_value(), None, &&test_utils::TestLogger::new()).is_err()); } @@ -7496,7 +7638,7 @@ mod tests { value: 10000000, script_pubkey: output_script.clone(), }]}; let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 }; - let (mut node_a_chan, funding_created_msg) = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap(); + let (mut node_a_chan, funding_created_msg) = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap(); let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap(); // Node B --> Node A: funding signed @@ -7623,7 +7765,7 @@ mod tests { value: 10000000, script_pubkey: output_script.clone(), }]}; let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 }; - let (mut node_a_chan, funding_created_msg) = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap(); + let (mut node_a_chan, funding_created_msg) = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap(); let (mut node_b_chan, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap(); // Node B --> Node A: funding signed @@ -7811,7 +7953,7 @@ mod tests { value: 10000000, script_pubkey: output_script.clone(), }]}; let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 }; - let (mut node_a_chan, funding_created_msg) = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap(); + let (mut node_a_chan, funding_created_msg) = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap(); let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap(); // Node B --> Node A: funding signed