X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=8b5e89d9441ace4510bddd65f877fc7355f94604;hb=ec3aa494953c7d720370119f673e8e6b3a2155d5;hp=f1c5cae25ae8bbfbc84b85640c3367de18aa56c1;hpb=a9534fe6b53ee5a35bcedb897f03804dc17f2d39;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index f1c5cae2..8b5e89d9 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -312,9 +312,9 @@ pub(super) enum ChannelUpdateStatus { /// We've announced the channel as enabled and are connected to our peer. Enabled, /// Our channel is no longer live, but we haven't announced the channel as disabled yet. - DisabledStaged, + DisabledStaged(u8), /// Our channel is live again, but we haven't announced the channel as enabled yet. - EnabledStaged, + EnabledStaged(u8), /// We've announced the channel as disabled. Disabled, } @@ -499,6 +499,7 @@ pub(super) struct Channel { user_id: u128, channel_id: [u8; 32], + temporary_channel_id: Option<[u8; 32]>, // Will be `None` for channels created prior to 0.0.115. channel_state: u32, // When we reach max(6 blocks, minimum_depth), we need to send an AnnouncementSigs message to @@ -652,7 +653,7 @@ pub(super) struct Channel { pub counterparty_max_accepted_htlcs: u16, #[cfg(not(test))] counterparty_max_accepted_htlcs: u16, - //implied by OUR_MAX_HTLCS: max_accepted_htlcs: u16, + holder_max_accepted_htlcs: u16, minimum_depth: Option, counterparty_forwarding_info: Option, @@ -729,6 +730,9 @@ pub(super) struct Channel { // blinded paths instead of simple scid+node_id aliases. outbound_scid_alias: u64, + // We track whether we already emitted a `ChannelPending` event. + channel_pending_event_emitted: bool, + // We track whether we already emitted a `ChannelReady` event. channel_ready_event_emitted: bool, @@ -752,7 +756,7 @@ struct CommitmentTxInfoCached { feerate: u32, } -pub const OUR_MAX_HTLCS: u16 = 50; //TODO +pub const DEFAULT_MAX_HTLCS: u16 = 50; pub(crate) fn commitment_tx_base_weight(opt_anchors: bool) -> u64 { const COMMITMENT_TX_BASE_WEIGHT: u64 = 724; @@ -991,6 +995,8 @@ impl Channel { } } + let temporary_channel_id = entropy_source.get_secure_random_bytes(); + Ok(Channel { user_id, @@ -1004,7 +1010,8 @@ impl Channel { inbound_handshake_limits_override: Some(config.channel_handshake_limits.clone()), - channel_id: entropy_source.get_secure_random_bytes(), + channel_id: temporary_channel_id, + temporary_channel_id: Some(temporary_channel_id), channel_state: ChannelState::OurInitSent as u32, announcement_sigs_state: AnnouncementSigsState::NotSent, secp_ctx, @@ -1065,6 +1072,7 @@ impl Channel { counterparty_htlc_minimum_msat: 0, holder_htlc_minimum_msat: if config.channel_handshake_config.our_htlc_minimum_msat == 0 { 1 } else { config.channel_handshake_config.our_htlc_minimum_msat }, counterparty_max_accepted_htlcs: 0, + holder_max_accepted_htlcs: cmp::min(config.channel_handshake_config.our_max_accepted_htlcs, MAX_HTLCS), minimum_depth: None, // Filled in in accept_channel counterparty_forwarding_info: None, @@ -1103,6 +1111,7 @@ impl Channel { latest_inbound_scid_alias: None, outbound_scid_alias, + channel_pending_event_emitted: false, channel_ready_event_emitted: false, #[cfg(any(test, fuzzing))] @@ -1350,6 +1359,7 @@ impl Channel { inbound_handshake_limits_override: None, channel_id: msg.temporary_channel_id, + temporary_channel_id: Some(msg.temporary_channel_id), channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32), announcement_sigs_state: AnnouncementSigsState::NotSent, secp_ctx, @@ -1410,6 +1420,7 @@ impl Channel { counterparty_htlc_minimum_msat: msg.htlc_minimum_msat, holder_htlc_minimum_msat: if config.channel_handshake_config.our_htlc_minimum_msat == 0 { 1 } else { config.channel_handshake_config.our_htlc_minimum_msat }, counterparty_max_accepted_htlcs: msg.max_accepted_htlcs, + holder_max_accepted_htlcs: cmp::min(config.channel_handshake_config.our_max_accepted_htlcs, MAX_HTLCS), minimum_depth: Some(cmp::max(config.channel_handshake_config.minimum_depth, 1)), counterparty_forwarding_info: None, @@ -1451,6 +1462,7 @@ impl Channel { latest_inbound_scid_alias: None, outbound_scid_alias, + channel_pending_event_emitted: false, channel_ready_event_emitted: false, #[cfg(any(test, fuzzing))] @@ -2352,7 +2364,9 @@ impl Channel { Ok((msgs::FundingSigned { channel_id: self.channel_id, - signature + signature, + #[cfg(taproot)] + partial_signature_with_nonce: None, }, channel_monitor)) } @@ -2862,8 +2876,8 @@ impl Channel { let inbound_stats = self.get_inbound_pending_htlc_stats(None); let outbound_stats = self.get_outbound_pending_htlc_stats(None); - if inbound_stats.pending_htlcs + 1 > OUR_MAX_HTLCS as u32 { - return Err(ChannelError::Close(format!("Remote tried to push more than our max accepted HTLCs ({})", OUR_MAX_HTLCS))); + if inbound_stats.pending_htlcs + 1 > self.holder_max_accepted_htlcs as u32 { + return Err(ChannelError::Close(format!("Remote tried to push more than our max accepted HTLCs ({})", self.holder_max_accepted_htlcs))); } if inbound_stats.pending_htlcs_value_msat + msg.amount_msat > self.holder_max_htlc_value_in_flight_msat { return Err(ChannelError::Close(format!("Remote HTLC add would put them over our max HTLC value ({})", self.holder_max_htlc_value_in_flight_msat))); @@ -3122,9 +3136,24 @@ impl Channel { return Err(ChannelError::Close(format!("Got wrong number of HTLC signatures ({}) from remote. It must be {}", msg.htlc_signatures.len(), commitment_stats.num_nondust_htlcs))); } - // TODO: Sadly, we pass HTLCs twice to ChannelMonitor: once via the HolderCommitmentTransaction and once via the update + // Up to LDK 0.0.115, HTLC information was required to be duplicated in the + // `htlcs_and_sigs` vec and in the `holder_commitment_tx` itself, both of which were passed + // in the `ChannelMonitorUpdate`. In 0.0.115, support for having a separate set of + // outbound-non-dust-HTLCSources in the `ChannelMonitorUpdate` was added, however for + // backwards compatibility, we never use it in production. To provide test coverage, here, + // we randomly decide (in test/fuzzing builds) to use the new vec sometimes. + #[allow(unused_assignments, unused_mut)] + let mut separate_nondust_htlc_sources = false; + #[cfg(all(feature = "std", any(test, fuzzing)))] { + use core::hash::{BuildHasher, Hasher}; + // Get a random value using the only std API to do so - the DefaultHasher + let rand_val = std::collections::hash_map::RandomState::new().build_hasher().finish(); + separate_nondust_htlc_sources = rand_val % 2 == 0; + } + + let mut nondust_htlc_sources = Vec::with_capacity(htlcs_cloned.len()); let mut htlcs_and_sigs = Vec::with_capacity(htlcs_cloned.len()); - for (idx, (htlc, source)) in htlcs_cloned.drain(..).enumerate() { + for (idx, (htlc, mut source_opt)) in htlcs_cloned.drain(..).enumerate() { if let Some(_) = htlc.transaction_output_index { let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_stats.feerate_per_kw, self.get_counterparty_selected_contest_delay().unwrap(), &htlc, self.opt_anchors(), @@ -3139,10 +3168,18 @@ impl Channel { if let Err(_) = self.secp_ctx.verify_ecdsa(&htlc_sighash, &msg.htlc_signatures[idx], &keys.countersignatory_htlc_key) { return Err(ChannelError::Close("Invalid HTLC tx signature from peer".to_owned())); } - htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source)); + if !separate_nondust_htlc_sources { + htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source_opt.take())); + } } else { - htlcs_and_sigs.push((htlc, None, source)); + htlcs_and_sigs.push((htlc, None, source_opt.take())); } + if separate_nondust_htlc_sources { + if let Some(source) = source_opt.take() { + nondust_htlc_sources.push(source); + } + } + debug_assert!(source_opt.is_none(), "HTLCSource should have been put somewhere"); } let holder_commitment_tx = HolderCommitmentTransaction::new( @@ -3205,6 +3242,7 @@ impl Channel { commitment_tx: holder_commitment_tx, htlc_outputs: htlcs_and_sigs, claimed_htlcs, + nondust_htlc_sources, }] }; @@ -3908,6 +3946,8 @@ impl Channel { channel_id: self.channel_id, per_commitment_secret, next_per_commitment_point, + #[cfg(taproot)] + next_local_nonce: None, } } @@ -4550,6 +4590,13 @@ impl Channel { self.channel_id } + // Return the `temporary_channel_id` used during channel establishment. + // + // Will return `None` for channels created prior to LDK version 0.0.115. + pub fn temporary_channel_id(&self) -> Option<[u8; 32]> { + self.temporary_channel_id + } + pub fn minimum_depth(&self) -> Option { self.minimum_depth } @@ -4694,6 +4741,21 @@ impl Channel { self.prev_config.map(|prev_config| prev_config.0) } + // Checks whether we should emit a `ChannelPending` event. + pub(crate) fn should_emit_channel_pending_event(&mut self) -> bool { + self.is_funding_initiated() && !self.channel_pending_event_emitted + } + + // Returns whether we already emitted a `ChannelPending` event. + pub(crate) fn channel_pending_event_emitted(&self) -> bool { + self.channel_pending_event_emitted + } + + // Remembers that we already emitted a `ChannelPending` event. + pub(crate) fn set_channel_pending_event_emitted(&mut self) { + self.channel_pending_event_emitted = true; + } + // Checks whether we should emit a `ChannelReady` event. pub(crate) fn should_emit_channel_ready_event(&mut self) -> bool { self.is_usable() && !self.channel_ready_event_emitted @@ -5253,7 +5315,7 @@ impl Channel { htlc_minimum_msat: self.holder_htlc_minimum_msat, feerate_per_kw: self.feerate_per_kw as u32, to_self_delay: self.get_holder_selected_contest_delay(), - max_accepted_htlcs: OUR_MAX_HTLCS, + max_accepted_htlcs: self.holder_max_accepted_htlcs, funding_pubkey: keys.funding_pubkey, revocation_basepoint: keys.revocation_basepoint, payment_point: keys.payment_point, @@ -5320,7 +5382,7 @@ impl Channel { htlc_minimum_msat: self.holder_htlc_minimum_msat, minimum_depth: self.minimum_depth.unwrap(), to_self_delay: self.get_holder_selected_contest_delay(), - max_accepted_htlcs: OUR_MAX_HTLCS, + max_accepted_htlcs: self.holder_max_accepted_htlcs, funding_pubkey: keys.funding_pubkey, revocation_basepoint: keys.revocation_basepoint, payment_point: keys.payment_point, @@ -5332,6 +5394,8 @@ impl Channel { None => Builder::new().into_script(), }), channel_type: Some(self.channel_type.clone()), + #[cfg(taproot)] + next_local_nonce: None, } } @@ -5396,7 +5460,11 @@ impl Channel { temporary_channel_id, funding_txid: funding_txo.txid, funding_output_index: funding_txo.index, - signature + signature, + #[cfg(taproot)] + partial_signature_with_nonce: None, + #[cfg(taproot)] + next_local_nonce: None, }) } @@ -5915,6 +5983,8 @@ impl Channel { channel_id: self.channel_id, signature, htlc_signatures, + #[cfg(taproot)] + partial_signature_with_nonce: None, }, (counterparty_commitment_txid, commitment_stats.htlcs_included))) } @@ -6123,8 +6193,8 @@ impl Writeable for ChannelUpdateStatus { // channel as enabled, so we write 0. For EnabledStaged, we similarly write a 1. match self { ChannelUpdateStatus::Enabled => 0u8.write(writer)?, - ChannelUpdateStatus::DisabledStaged => 0u8.write(writer)?, - ChannelUpdateStatus::EnabledStaged => 1u8.write(writer)?, + ChannelUpdateStatus::DisabledStaged(_) => 0u8.write(writer)?, + ChannelUpdateStatus::EnabledStaged(_) => 1u8.write(writer)?, ChannelUpdateStatus::Disabled => 1u8.write(writer)?, } Ok(()) @@ -6420,6 +6490,7 @@ impl Writeable for Channel { if self.holder_max_htlc_value_in_flight_msat != Self::get_holder_max_htlc_value_in_flight_msat(self.channel_value_satoshis, &old_max_in_flight_percent_config) { Some(self.holder_max_htlc_value_in_flight_msat) } else { None }; + let channel_pending_event_emitted = Some(self.channel_pending_event_emitted); let channel_ready_event_emitted = Some(self.channel_ready_event_emitted); // `user_id` used to be a single u64 value. In order to remain backwards compatible with @@ -6427,6 +6498,8 @@ impl Writeable for Channel { // we write the high bytes as an option here. let user_id_high_opt = Some((self.user_id >> 64) as u64); + let holder_max_accepted_htlcs = if self.holder_max_accepted_htlcs == DEFAULT_MAX_HTLCS { None } else { Some(self.holder_max_accepted_htlcs) }; + write_tlv_fields!(writer, { (0, self.announcement_sigs, option), // minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a @@ -6452,6 +6525,9 @@ impl Writeable for Channel { (23, channel_ready_event_emitted, option), (25, user_id_high_opt, option), (27, self.channel_keys_id, required), + (28, holder_max_accepted_htlcs, option), + (29, self.temporary_channel_id, option), + (31, channel_pending_event_emitted, option), }); Ok(()) @@ -6518,7 +6594,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch let value_to_self_msat = Readable::read(reader)?; let pending_inbound_htlc_count: u64 = Readable::read(reader)?; - let mut pending_inbound_htlcs = Vec::with_capacity(cmp::min(pending_inbound_htlc_count as usize, OUR_MAX_HTLCS as usize)); + + let mut pending_inbound_htlcs = Vec::with_capacity(cmp::min(pending_inbound_htlc_count as usize, DEFAULT_MAX_HTLCS as usize)); for _ in 0..pending_inbound_htlc_count { pending_inbound_htlcs.push(InboundHTLCOutput { htlc_id: Readable::read(reader)?, @@ -6536,7 +6613,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch } let pending_outbound_htlc_count: u64 = Readable::read(reader)?; - let mut pending_outbound_htlcs = Vec::with_capacity(cmp::min(pending_outbound_htlc_count as usize, OUR_MAX_HTLCS as usize)); + let mut pending_outbound_htlcs = Vec::with_capacity(cmp::min(pending_outbound_htlc_count as usize, DEFAULT_MAX_HTLCS as usize)); for _ in 0..pending_outbound_htlc_count { pending_outbound_htlcs.push(OutboundHTLCOutput { htlc_id: Readable::read(reader)?, @@ -6565,7 +6642,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch } let holding_cell_htlc_update_count: u64 = Readable::read(reader)?; - let mut holding_cell_htlc_updates = Vec::with_capacity(cmp::min(holding_cell_htlc_update_count as usize, OUR_MAX_HTLCS as usize*2)); + let mut holding_cell_htlc_updates = Vec::with_capacity(cmp::min(holding_cell_htlc_update_count as usize, DEFAULT_MAX_HTLCS as usize*2)); for _ in 0..holding_cell_htlc_update_count { holding_cell_htlc_updates.push(match ::read(reader)? { 0 => HTLCUpdateAwaitingACK::AddHTLC { @@ -6598,13 +6675,13 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch let monitor_pending_commitment_signed = Readable::read(reader)?; let monitor_pending_forwards_count: u64 = Readable::read(reader)?; - let mut monitor_pending_forwards = Vec::with_capacity(cmp::min(monitor_pending_forwards_count as usize, OUR_MAX_HTLCS as usize)); + let mut monitor_pending_forwards = Vec::with_capacity(cmp::min(monitor_pending_forwards_count as usize, DEFAULT_MAX_HTLCS as usize)); for _ in 0..monitor_pending_forwards_count { monitor_pending_forwards.push((Readable::read(reader)?, Readable::read(reader)?)); } let monitor_pending_failures_count: u64 = Readable::read(reader)?; - let mut monitor_pending_failures = Vec::with_capacity(cmp::min(monitor_pending_failures_count as usize, OUR_MAX_HTLCS as usize)); + let mut monitor_pending_failures = Vec::with_capacity(cmp::min(monitor_pending_failures_count as usize, DEFAULT_MAX_HTLCS as usize)); for _ in 0..monitor_pending_failures_count { monitor_pending_failures.push((Readable::read(reader)?, Readable::read(reader)?, Readable::read(reader)?)); } @@ -6719,10 +6796,13 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch let mut announcement_sigs_state = Some(AnnouncementSigsState::NotSent); let mut latest_inbound_scid_alias = None; let mut outbound_scid_alias = None; + let mut channel_pending_event_emitted = None; let mut channel_ready_event_emitted = None; let mut user_id_high_opt: Option = None; let mut channel_keys_id: Option<[u8; 32]> = None; + let mut temporary_channel_id: Option<[u8; 32]> = None; + let mut holder_max_accepted_htlcs: Option = None; read_tlv_fields!(reader, { (0, announcement_sigs, option), @@ -6743,6 +6823,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch (23, channel_ready_event_emitted, option), (25, user_id_high_opt, option), (27, channel_keys_id, option), + (28, holder_max_accepted_htlcs, option), + (29, temporary_channel_id, option), + (31, channel_pending_event_emitted, option), }); let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id { @@ -6795,6 +6878,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch // separate u64 values. let user_id = user_id_low as u128 + ((user_id_high_opt.unwrap_or(0) as u128) << 64); + let holder_max_accepted_htlcs = holder_max_accepted_htlcs.unwrap_or(DEFAULT_MAX_HTLCS); + Ok(Channel { user_id, @@ -6807,6 +6892,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch inbound_handshake_limits_override: None, channel_id, + temporary_channel_id, channel_state, announcement_sigs_state: announcement_sigs_state.unwrap(), secp_ctx, @@ -6822,6 +6908,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch cur_counterparty_commitment_transaction_number, value_to_self_msat, + holder_max_accepted_htlcs, pending_inbound_htlcs, pending_outbound_htlcs, holding_cell_htlc_updates, @@ -6899,6 +6986,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch // Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing outbound_scid_alias: outbound_scid_alias.unwrap_or(0), + channel_pending_event_emitted: channel_pending_event_emitted.unwrap_or(true), channel_ready_event_emitted: channel_ready_event_emitted.unwrap_or(true), #[cfg(any(test, fuzzing))] @@ -6936,6 +7024,7 @@ mod tests { use crate::chain::chaininterface::{FeeEstimator, LowerBoundedFeeEstimator, ConfirmationTarget}; use crate::chain::keysinterface::{ChannelSigner, InMemorySigner, EntropySource, SignerProvider}; use crate::chain::transaction::OutPoint; + use crate::routing::router::Path; use crate::util::config::UserConfig; use crate::util::enforcing_trait_impls::EnforcingSigner; use crate::util::errors::APIError; @@ -7113,11 +7202,10 @@ mod tests { cltv_expiry: 200000000, state: OutboundHTLCState::Committed, source: HTLCSource::OutboundRoute { - path: Vec::new(), + path: Path { hops: Vec::new(), blinded_tail: None }, session_priv: SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(), first_hop_htlc_msat: 548, payment_id: PaymentId([42; 32]), - payment_secret: None, } }); @@ -7429,7 +7517,7 @@ mod tests { } } - #[cfg(not(feature = "grind_signatures"))] + #[cfg(feature = "_test_vectors")] #[test] fn outbound_commitment_test() { use bitcoin::util::sighash; @@ -7462,6 +7550,7 @@ mod tests { [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], 10_000_000, [0; 32], + [0; 32], ); assert_eq!(signer.pubkeys().funding_pubkey.serialize()[..],