X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=121c1d4c66c36cb64f21df76823f5d24ace0e97a;hb=97b210dd977af40e61210270dec6e35f014817bc;hp=91a853132064049abca699a211de956e6e5cdc22;hpb=384c4dc7753e4b7ac53ea380e52809babd8f0f9b;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 91a85313..121c1d4c 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -53,7 +53,7 @@ use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VA use crate::ln::wire::Encode; use crate::chain::keysinterface::{Sign, KeysInterface, KeysManager, Recipient}; use crate::util::config::{UserConfig, ChannelConfig}; -use crate::util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination}; +use crate::util::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination}; use crate::util::{byte_utils, events}; use crate::util::wakers::{Future, Notifier}; use crate::util::scid_utils::fake_scid; @@ -112,8 +112,8 @@ pub(super) struct PendingHTLCInfo { pub(super) routing: PendingHTLCRouting, pub(super) incoming_shared_secret: [u8; 32], payment_hash: PaymentHash, - pub(super) amt_to_forward: u64, - pub(super) amt_incoming: Option, // Added in 0.0.113 + pub(super) incoming_amt_msat: Option, // Added in 0.0.113 + pub(super) outgoing_amt_msat: u64, pub(super) outgoing_cltv_value: u32, } @@ -292,7 +292,7 @@ type ShutdownResult = (Option<(OutPoint, ChannelMonitorUpdate)>, Vec<(HTLCSource struct MsgHandleErrInternal { err: msgs::LightningError, - chan_id: Option<([u8; 32], u64)>, // If Some a channel of ours has been closed + chan_id: Option<([u8; 32], u128)>, // If Some a channel of ours has been closed shutdown_finish: Option<(ShutdownResult, Option)>, } impl MsgHandleErrInternal { @@ -328,7 +328,7 @@ impl MsgHandleErrInternal { Self { err, chan_id: None, shutdown_finish: None } } #[inline] - fn from_finish_shutdown(err: String, channel_id: [u8; 32], user_channel_id: u64, shutdown_res: ShutdownResult, channel_update: Option) -> Self { + fn from_finish_shutdown(err: String, channel_id: [u8; 32], user_channel_id: u128, shutdown_res: ShutdownResult, channel_update: Option) -> Self { Self { err: LightningError { err: err.clone(), @@ -1086,8 +1086,9 @@ pub struct ChannelDetails { /// /// [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat pub unspendable_punishment_reserve: Option, - /// The `user_channel_id` passed in to create_channel, or 0 if the channel was inbound. - pub user_channel_id: u64, + /// The `user_channel_id` passed in to create_channel, or a random value if the channel was + /// inbound. + pub user_channel_id: u128, /// Our total balance. This is the amount we would get if we close the channel. /// This value is not exact. Due to various in-flight changes and feerate changes, exactly this /// amount is not likely to be recoverable on close. @@ -1722,10 +1723,9 @@ impl ChannelManager 2**24 or `push_msat` is /// greater than `channel_value_satoshis * 1k` or `channel_value_satoshis < 1000`. @@ -1744,7 +1744,7 @@ impl ChannelManager) -> Result<[u8; 32], APIError> { + pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_channel_id: u128, override_config: Option) -> Result<[u8; 32], APIError> { if channel_value_satoshis < 1000 { return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) }); } @@ -2138,13 +2138,6 @@ impl ChannelManager { - return Err(ReceiveError { - err_code: 0x4000|0x2000|3, - err_data: Vec::new(), - msg: "We require payment_secrets", - }); - }, msgs::OnionHopDataFormat::NonFinalNode { .. } => { return Err(ReceiveError { err_code: 0x4000|22, @@ -2197,8 +2190,8 @@ impl ChannelManager ChannelManager short_channel_id, msgs::OnionHopDataFormat::NonFinalNode { short_channel_id } => short_channel_id, msgs::OnionHopDataFormat::FinalNode { .. } => { return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0;0]); @@ -2294,14 +2286,14 @@ impl ChannelManager ChannelManager ChannelManager { macro_rules! failure_handler { @@ -3220,7 +3212,7 @@ impl ChannelManager { - match self.construct_recv_pending_htlc_info(hop_data, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value, Some(phantom_shared_secret)) { + match self.construct_recv_pending_htlc_info(hop_data, incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value, Some(phantom_shared_secret)) { Ok(info) => phantom_receives.push((prev_short_channel_id, prev_funding_outpoint, vec![(info, prev_htlc_id)])), Err(ReceiveError { err_code, err_data, msg }) => failed_payment!(msg, err_code, err_data, Some(phantom_shared_secret)) } @@ -3264,8 +3256,8 @@ impl ChannelManager { log_trace!(self.logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", prev_short_channel_id, log_bytes!(payment_hash.0), short_chan_id); @@ -3277,7 +3269,7 @@ impl ChannelManager { if let ChannelError::Ignore(msg) = e { log_trace!(self.logger, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(payment_hash.0), msg); @@ -3391,7 +3383,7 @@ impl ChannelManager { let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing { @@ -3413,9 +3405,9 @@ impl ChannelManager ChannelManager ChannelManager Result<(), APIError> { + pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> { self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id) } @@ -4566,11 +4558,11 @@ impl ChannelManager Result<(), APIError> { + pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> { self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, true, user_channel_id) } - fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u64) -> Result<(), APIError> { + fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u128) -> Result<(), APIError> { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); let mut channel_state_lock = self.channel_state.lock().unwrap(); @@ -4618,9 +4610,13 @@ impl ChannelManager { @@ -5714,7 +5710,7 @@ impl ChannelManager Vec { let events = core::cell::RefCell::new(Vec::new()); - let event_handler = |event: &events::Event| events.borrow_mut().push(event.clone()); + let event_handler = |event: events::Event| events.borrow_mut().push(event); self.process_pending_events(&event_handler); events.into_inner() } @@ -5728,6 +5724,39 @@ impl ChannelManager Future>( + &self, handler: H + ) { + // We'll acquire our total consistency lock until the returned future completes so that + // we can be sure no other persists happen while processing events. + let _read_guard = self.total_consistency_lock.read().unwrap(); + + let mut result = NotifyOption::SkipPersist; + + // TODO: This behavior should be documented. It's unintuitive that we query + // ChannelMonitors when clearing other events. + if self.process_pending_monitor_events() { + result = NotifyOption::DoPersist; + } + + let pending_events = mem::replace(&mut *self.pending_events.lock().unwrap(), vec![]); + if !pending_events.is_empty() { + result = NotifyOption::DoPersist; + } + + for event in pending_events { + handler(event).await; + } + + if result == NotifyOption::DoPersist { + self.persistence_notifier.notify(); + } + } } impl MessageSendEventsProvider for ChannelManager @@ -5791,13 +5820,13 @@ where result = NotifyOption::DoPersist; } - let mut pending_events = mem::replace(&mut *self.pending_events.lock().unwrap(), vec![]); + let pending_events = mem::replace(&mut *self.pending_events.lock().unwrap(), vec![]); if !pending_events.is_empty() { result = NotifyOption::DoPersist; } - for event in pending_events.drain(..) { - handler.handle_event(&event); + for event in pending_events { + handler.handle_event(event); } result @@ -6066,18 +6095,25 @@ where /// Blocks until ChannelManager needs to be persisted or a timeout is reached. It returns a bool /// indicating whether persistence is necessary. Only one listener on - /// `await_persistable_update` or `await_persistable_update_timeout` is guaranteed to be woken - /// up. + /// [`await_persistable_update`], [`await_persistable_update_timeout`], or a future returned by + /// [`get_persistable_update_future`] is guaranteed to be woken up. /// /// Note that this method is not available with the `no-std` feature. + /// + /// [`await_persistable_update`]: Self::await_persistable_update + /// [`await_persistable_update_timeout`]: Self::await_persistable_update_timeout + /// [`get_persistable_update_future`]: Self::get_persistable_update_future #[cfg(any(test, feature = "std"))] pub fn await_persistable_update_timeout(&self, max_wait: Duration) -> bool { self.persistence_notifier.wait_timeout(max_wait) } /// Blocks until ChannelManager needs to be persisted. Only one listener on - /// `await_persistable_update` or `await_persistable_update_timeout` is guaranteed to be woken - /// up. + /// [`await_persistable_update`], `await_persistable_update_timeout`, or a future returned by + /// [`get_persistable_update_future`] is guaranteed to be woken up. + /// + /// [`await_persistable_update`]: Self::await_persistable_update + /// [`get_persistable_update_future`]: Self::get_persistable_update_future pub fn await_persistable_update(&self) { self.persistence_notifier.wait() } @@ -6418,33 +6454,108 @@ impl_writeable_tlv_based!(ChannelCounterparty, { (11, outbound_htlc_maximum_msat, option), }); -impl_writeable_tlv_based!(ChannelDetails, { - (1, inbound_scid_alias, option), - (2, channel_id, required), - (3, channel_type, option), - (4, counterparty, required), - (5, outbound_scid_alias, option), - (6, funding_txo, option), - (7, config, option), - (8, short_channel_id, option), - (10, channel_value_satoshis, required), - (12, unspendable_punishment_reserve, option), - (14, user_channel_id, required), - (16, balance_msat, required), - (18, outbound_capacity_msat, required), - // Note that by the time we get past the required read above, outbound_capacity_msat will be - // filled in, so we can safely unwrap it here. - (19, next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)), - (20, inbound_capacity_msat, required), - (22, confirmations_required, option), - (24, force_close_spend_delay, option), - (26, is_outbound, required), - (28, is_channel_ready, required), - (30, is_usable, required), - (32, is_public, required), - (33, inbound_htlc_minimum_msat, option), - (35, inbound_htlc_maximum_msat, option), -}); +impl Writeable for ChannelDetails { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { + // `user_channel_id` used to be a single u64 value. In order to remain backwards compatible with + // versions prior to 0.0.113, the u128 is serialized as two separate u64 values. + let user_channel_id_low = self.user_channel_id as u64; + let user_channel_id_high_opt = Some((self.user_channel_id >> 64) as u64); + write_tlv_fields!(writer, { + (1, self.inbound_scid_alias, option), + (2, self.channel_id, required), + (3, self.channel_type, option), + (4, self.counterparty, required), + (5, self.outbound_scid_alias, option), + (6, self.funding_txo, option), + (7, self.config, option), + (8, self.short_channel_id, option), + (10, self.channel_value_satoshis, required), + (12, self.unspendable_punishment_reserve, option), + (14, user_channel_id_low, required), + (16, self.balance_msat, required), + (18, self.outbound_capacity_msat, required), + // Note that by the time we get past the required read above, outbound_capacity_msat will be + // filled in, so we can safely unwrap it here. + (19, self.next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)), + (20, self.inbound_capacity_msat, required), + (22, self.confirmations_required, option), + (24, self.force_close_spend_delay, option), + (26, self.is_outbound, required), + (28, self.is_channel_ready, required), + (30, self.is_usable, required), + (32, self.is_public, required), + (33, self.inbound_htlc_minimum_msat, option), + (35, self.inbound_htlc_maximum_msat, option), + (37, user_channel_id_high_opt, option), + }); + Ok(()) + } +} + +impl Readable for ChannelDetails { + fn read(reader: &mut R) -> Result { + init_and_read_tlv_fields!(reader, { + (1, inbound_scid_alias, option), + (2, channel_id, required), + (3, channel_type, option), + (4, counterparty, required), + (5, outbound_scid_alias, option), + (6, funding_txo, option), + (7, config, option), + (8, short_channel_id, option), + (10, channel_value_satoshis, required), + (12, unspendable_punishment_reserve, option), + (14, user_channel_id_low, required), + (16, balance_msat, required), + (18, outbound_capacity_msat, required), + // Note that by the time we get past the required read above, outbound_capacity_msat will be + // filled in, so we can safely unwrap it here. + (19, next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)), + (20, inbound_capacity_msat, required), + (22, confirmations_required, option), + (24, force_close_spend_delay, option), + (26, is_outbound, required), + (28, is_channel_ready, required), + (30, is_usable, required), + (32, is_public, required), + (33, inbound_htlc_minimum_msat, option), + (35, inbound_htlc_maximum_msat, option), + (37, user_channel_id_high_opt, option), + }); + + // `user_channel_id` used to be a single u64 value. In order to remain backwards compatible with + // versions prior to 0.0.113, the u128 is serialized as two separate u64 values. + let user_channel_id_low: u64 = user_channel_id_low.0.unwrap(); + let user_channel_id = user_channel_id_low as u128 + + ((user_channel_id_high_opt.unwrap_or(0 as u64) as u128) << 64); + + Ok(Self { + inbound_scid_alias, + channel_id: channel_id.0.unwrap(), + channel_type, + counterparty: counterparty.0.unwrap(), + outbound_scid_alias, + funding_txo, + config, + short_channel_id, + channel_value_satoshis: channel_value_satoshis.0.unwrap(), + unspendable_punishment_reserve, + user_channel_id, + balance_msat: balance_msat.0.unwrap(), + outbound_capacity_msat: outbound_capacity_msat.0.unwrap(), + next_outbound_htlc_limit_msat: next_outbound_htlc_limit_msat.0.unwrap(), + inbound_capacity_msat: inbound_capacity_msat.0.unwrap(), + confirmations_required, + force_close_spend_delay, + is_outbound: is_outbound.0.unwrap(), + is_channel_ready: is_channel_ready.0.unwrap(), + is_usable: is_usable.0.unwrap(), + is_public: is_public.0.unwrap(), + inbound_htlc_minimum_msat, + inbound_htlc_maximum_msat, + }) + } +} impl_writeable_tlv_based!(PhantomRouteHints, { (2, channels, vec_type), @@ -6472,9 +6583,9 @@ impl_writeable_tlv_based!(PendingHTLCInfo, { (0, routing, required), (2, incoming_shared_secret, required), (4, payment_hash, required), - (6, amt_to_forward, required), + (6, outgoing_amt_msat, required), (8, outgoing_cltv_value, required), - (9, amt_incoming, option), + (9, incoming_amt_msat, option), }); @@ -6921,10 +7032,10 @@ impl Writeable for ChannelMana /// which you've already broadcasted the transaction. /// /// [`ChainMonitor`]: crate::chain::chainmonitor::ChainMonitor -pub struct ChannelManagerReadArgs<'a, Signer: 'a + Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> - where M::Target: chain::Watch, +pub struct ChannelManagerReadArgs<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> + where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, - K::Target: KeysInterface, + K::Target: KeysInterface, F::Target: FeeEstimator, L::Target: Logger, { @@ -6967,14 +7078,14 @@ pub struct ChannelManagerReadArgs<'a, Signer: 'a + Sign, M: Deref, T: Deref, K: /// this struct. /// /// (C-not exported) because we have no HashMap bindings - pub channel_monitors: HashMap>, + pub channel_monitors: HashMap::Signer>>, } -impl<'a, Signer: 'a + Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> - ChannelManagerReadArgs<'a, Signer, M, T, K, F, L> - where M::Target: chain::Watch, +impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> + ChannelManagerReadArgs<'a, M, T, K, F, L> + where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, - K::Target: KeysInterface, + K::Target: KeysInterface, F::Target: FeeEstimator, L::Target: Logger, { @@ -6982,7 +7093,7 @@ impl<'a, Signer: 'a + Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> /// HashMap for you. This is primarily useful for C bindings where it is not practical to /// populate a HashMap directly from C. pub fn new(keys_manager: K, fee_estimator: F, chain_monitor: M, tx_broadcaster: T, logger: L, default_config: UserConfig, - mut channel_monitors: Vec<&'a mut ChannelMonitor>) -> Self { + mut channel_monitors: Vec<&'a mut ChannelMonitor<::Signer>>) -> Self { Self { keys_manager, fee_estimator, chain_monitor, tx_broadcaster, logger, default_config, channel_monitors: channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect() @@ -6993,28 +7104,28 @@ impl<'a, Signer: 'a + Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> // Implement ReadableArgs for an Arc'd ChannelManager to make it a bit easier to work with the // SipmleArcChannelManager type: impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> - ReadableArgs::Signer, M, T, K, F, L>> for (BlockHash, Arc>) + ReadableArgs> for (BlockHash, Arc>) where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, L::Target: Logger, { - fn read(reader: &mut R, args: ChannelManagerReadArgs<'a, ::Signer, M, T, K, F, L>) -> Result { + fn read(reader: &mut R, args: ChannelManagerReadArgs<'a, M, T, K, F, L>) -> Result { let (blockhash, chan_manager) = <(BlockHash, ChannelManager)>::read(reader, args)?; Ok((blockhash, Arc::new(chan_manager))) } } impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> - ReadableArgs::Signer, M, T, K, F, L>> for (BlockHash, ChannelManager) + ReadableArgs> for (BlockHash, ChannelManager) where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, L::Target: Logger, { - fn read(reader: &mut R, mut args: ChannelManagerReadArgs<'a, ::Signer, M, T, K, F, L>) -> Result { + fn read(reader: &mut R, mut args: ChannelManagerReadArgs<'a, M, T, K, F, L>) -> Result { let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION); let genesis_hash: BlockHash = Readable::read(reader)?;