X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=ab80ccaeca24e2784e27db35ff6ef9c242ec1a88;hb=3b277cc39427d1f1bdbce4a4c2eea2dee493f9f0;hp=015894e594dc1246efecef452d312171eed099ba;hpb=2f346414ade972ca54705cf9ed774a24151144de;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 015894e5..ab80ccae 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -57,15 +57,19 @@ use std::ops::Deref; // forward the HTLC with information it will give back to us when it does so, or if it should Fail // the HTLC with the relevant message for the Channel to handle giving to the remote peer. // -// When a Channel forwards an HTLC to its peer, it will give us back the PendingForwardHTLCInfo -// which we will use to construct an outbound HTLC, with a relevant HTLCSource::PreviousHopData -// filled in to indicate where it came from (which we can use to either fail-backwards or fulfill -// the HTLC backwards along the relevant path). +// Once said HTLC is committed in the Channel, if the PendingHTLCStatus indicated Forward, the +// Channel will return the PendingHTLCInfo back to us, and we will create an HTLCForwardInfo +// with it to track where it came from (in case of onwards-forward error), waiting a random delay +// before we forward it. +// +// We will then use HTLCForwardInfo's PendingHTLCInfo to construct an outbound HTLC, with a +// relevant HTLCSource::PreviousHopData filled in to indicate where it came from (which we can use +// to either fail-backwards or fulfill the HTLC backwards along the relevant path). // Alternatively, we can fill an outbound HTLC with a HTLCSource::OutboundRoute indicating this is // our payment, which we can use to decode errors or inform the user that the payment was sent. -/// Stores the info we will need to send when we want to forward an HTLC onwards + #[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug -pub(super) struct PendingForwardHTLCInfo { +pub(super) struct PendingHTLCInfo { onion_packet: Option, incoming_shared_secret: [u8; 32], payment_hash: PaymentHash, @@ -83,10 +87,22 @@ pub(super) enum HTLCFailureMsg { /// Stores whether we can't forward an HTLC or relevant forwarding info #[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug pub(super) enum PendingHTLCStatus { - Forward(PendingForwardHTLCInfo), + Forward(PendingHTLCInfo), Fail(HTLCFailureMsg), } +pub(super) enum HTLCForwardInfo { + AddHTLC { + prev_short_channel_id: u64, + prev_htlc_id: u64, + forward_info: PendingHTLCInfo, + }, + FailHTLC { + htlc_id: u64, + err_packet: msgs::OnionErrorPacket, + }, +} + /// Tracks the inbound corresponding to an outbound HTLC #[derive(Clone, PartialEq)] pub(super) struct HTLCPreviousHopData { @@ -231,18 +247,6 @@ impl MsgHandleErrInternal { /// second to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly. const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u64 = 100; -pub(super) enum HTLCForwardInfo { - AddHTLC { - prev_short_channel_id: u64, - prev_htlc_id: u64, - forward_info: PendingForwardHTLCInfo, - }, - FailHTLC { - htlc_id: u64, - err_packet: msgs::OnionErrorPacket, - }, -} - /// For events which result in both a RevokeAndACK and a CommitmentUpdate, by default they should /// be sent in the order they appear in the return value, however sometimes the order needs to be /// variable at runtime (eg Channel::channel_reestablish needs to re-send messages in the order @@ -262,7 +266,7 @@ pub(super) struct ChannelHolder { /// short channel id -> forward infos. Key of 0 means payments received /// Note that while this is held in the same mutex as the channels themselves, no consistency /// guarantees are made about the existence of a channel with the short id here, nor the short - /// ids in the PendingForwardHTLCInfo! + /// ids in the PendingHTLCInfo! pub(super) forward_htlcs: HashMap>, /// payment_hash -> Vec<(amount_received, htlc_source)> for tracking things that were to us and /// can be failed/claimed by the user @@ -289,7 +293,7 @@ const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assum /// lifetimes). Other times you can afford a reference, which is more efficient, in which case /// SimpleRefChannelManager is the more appropriate type. Defining these type aliases prevents /// issues such as overly long function definitions. -pub type SimpleArcChannelManager = Arc>>; +pub type SimpleArcChannelManager = Arc, Arc>>; /// SimpleRefChannelManager is a type alias for a ChannelManager reference, and is the reference /// counterpart to the SimpleArcChannelManager type alias. Use this type by default when you don't @@ -297,7 +301,7 @@ pub type SimpleArcChannelManager = Arc = ChannelManager; +pub type SimpleRefChannelManager<'a, 'b, M, T> = ChannelManager; /// Manager which keeps track of a number of channels and sends messages to the appropriate /// channel, also tracking HTLC preimages and forwarding onion packets appropriately. @@ -335,12 +339,15 @@ pub type SimpleRefChannelManager<'a, M> = ChannelManager where M::Target: ManyChannelMonitor { +pub struct ChannelManager + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ default_configuration: UserConfig, genesis_hash: Sha256dHash, fee_estimator: Arc, monitor: M, - tx_broadcaster: Arc, + tx_broadcaster: T, #[cfg(test)] pub(super) latest_block_height: AtomicUsize, @@ -571,7 +578,7 @@ macro_rules! handle_monitor_err { } else if $resend_commitment { "commitment" } else if $resend_raa { "RAA" } else { "nothing" }, - (&$failed_forwards as &Vec<(PendingForwardHTLCInfo, u64)>).len(), + (&$failed_forwards as &Vec<(PendingHTLCInfo, u64)>).len(), (&$failed_fails as &Vec<(HTLCSource, PaymentHash, HTLCFailReason)>).len()); if !$resend_commitment { debug_assert!($action_type == RAACommitmentOrder::RevokeAndACKFirst || !$resend_raa); @@ -607,7 +614,10 @@ macro_rules! maybe_break_monitor_err { } } -impl ChannelManager where M::Target: ManyChannelMonitor { +impl ChannelManager + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ /// Constructs a new ChannelManager to hold several channels and route between them. /// /// This is the main "logic hub" for all channel-related actions, and implements @@ -626,7 +636,7 @@ impl ChannelManager where M::T /// the ChannelManager as a listener to the BlockNotifier and call the BlockNotifier's /// `block_(dis)connected` methods, which will notify all registered listeners in one /// go. - pub fn new(network: Network, feeest: Arc, monitor: M, tx_broadcaster: Arc, logger: Arc,keys_manager: Arc>, config: UserConfig, current_blockchain_height: usize) -> Result, secp256k1::Error> { + pub fn new(network: Network, feeest: Arc, monitor: M, tx_broadcaster: T, logger: Arc,keys_manager: Arc>, config: UserConfig, current_blockchain_height: usize) -> Result, secp256k1::Error> { let secp_ctx = Secp256k1::new(); let res = ChannelManager { @@ -963,7 +973,7 @@ impl ChannelManager where M::T // instead we stay symmetric with the forwarding case, only responding (after a // delay) once they've send us a commitment_signed! - PendingHTLCStatus::Forward(PendingForwardHTLCInfo { + PendingHTLCStatus::Forward(PendingHTLCInfo { onion_packet: None, payment_hash: msg.payment_hash.clone(), short_channel_id: 0, @@ -1015,7 +1025,7 @@ impl ChannelManager where M::T }, }; - PendingHTLCStatus::Forward(PendingForwardHTLCInfo { + PendingHTLCStatus::Forward(PendingHTLCInfo { onion_packet: Some(outgoing_packet), payment_hash: msg.payment_hash.clone(), short_channel_id: short_channel_id, @@ -1026,7 +1036,7 @@ impl ChannelManager where M::T }; channel_state = Some(self.channel_state.lock().unwrap()); - if let &PendingHTLCStatus::Forward(PendingForwardHTLCInfo { ref onion_packet, ref short_channel_id, ref amt_to_forward, ref outgoing_cltv_value, .. }) = &pending_forward_info { + if let &PendingHTLCStatus::Forward(PendingHTLCInfo { ref onion_packet, ref short_channel_id, ref amt_to_forward, ref outgoing_cltv_value, .. }) = &pending_forward_info { if onion_packet.is_some() { // If short_channel_id is 0 here, we'll reject them in the body here let id_option = channel_state.as_ref().unwrap().short_to_id.get(&short_channel_id).cloned(); let forwarding_id = match id_option { @@ -1771,6 +1781,112 @@ impl ChannelManager where M::T PublicKey::from_secret_key(&self.secp_ctx, &self.our_network_key) } + /// Restores a single, given channel to normal operation after a + /// ChannelMonitorUpdateErr::TemporaryFailure was returned from a channel monitor update + /// operation. + /// + /// All ChannelMonitor updates up to and including highest_applied_update_id must have been + /// fully committed in every copy of the given channels' ChannelMonitors. + /// + /// Note that there is no effect to calling with a highest_applied_update_id other than the + /// current latest ChannelMonitorUpdate and one call to this function after multiple + /// ChannelMonitorUpdateErr::TemporaryFailures is fine. The highest_applied_update_id field + /// exists largely only to prevent races between this and concurrent update_monitor calls. + /// + /// Thus, the anticipated use is, at a high level: + /// 1) You register a ManyChannelMonitor with this ChannelManager, + /// 2) it stores each update to disk, and begins updating any remote (eg watchtower) copies of + /// said ChannelMonitors as it can, returning ChannelMonitorUpdateErr::TemporaryFailures + /// any time it cannot do so instantly, + /// 3) update(s) are applied to each remote copy of a ChannelMonitor, + /// 4) once all remote copies are updated, you call this function with the update_id that + /// completed, and once it is the latest the Channel will be re-enabled. + pub fn channel_monitor_updated(&self, funding_txo: &OutPoint, highest_applied_update_id: u64) { + let _ = self.total_consistency_lock.read().unwrap(); + + let mut close_results = Vec::new(); + let mut htlc_forwards = Vec::new(); + let mut htlc_failures = Vec::new(); + let mut pending_events = Vec::new(); + + { + let mut channel_lock = self.channel_state.lock().unwrap(); + let channel_state = &mut *channel_lock; + let short_to_id = &mut channel_state.short_to_id; + let pending_msg_events = &mut channel_state.pending_msg_events; + let channel = match channel_state.by_id.get_mut(&funding_txo.to_channel_id()) { + Some(chan) => chan, + None => return, + }; + if !channel.is_awaiting_monitor_update() || channel.get_latest_monitor_update_id() != highest_applied_update_id { + return; + } + + let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe, funding_locked) = channel.monitor_updating_restored(); + if !pending_forwards.is_empty() { + htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), pending_forwards)); + } + htlc_failures.append(&mut pending_failures); + + macro_rules! handle_cs { () => { + if let Some(update) = commitment_update { + pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { + node_id: channel.get_their_node_id(), + updates: update, + }); + } + } } + macro_rules! handle_raa { () => { + if let Some(revoke_and_ack) = raa { + pending_msg_events.push(events::MessageSendEvent::SendRevokeAndACK { + node_id: channel.get_their_node_id(), + msg: revoke_and_ack, + }); + } + } } + match order { + RAACommitmentOrder::CommitmentFirst => { + handle_cs!(); + handle_raa!(); + }, + RAACommitmentOrder::RevokeAndACKFirst => { + handle_raa!(); + handle_cs!(); + }, + } + if needs_broadcast_safe { + pending_events.push(events::Event::FundingBroadcastSafe { + funding_txo: channel.get_funding_txo().unwrap(), + user_channel_id: channel.get_user_id(), + }); + } + if let Some(msg) = funding_locked { + pending_msg_events.push(events::MessageSendEvent::SendFundingLocked { + node_id: channel.get_their_node_id(), + msg, + }); + if let Some(announcement_sigs) = self.get_announcement_sigs(channel) { + pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures { + node_id: channel.get_their_node_id(), + msg: announcement_sigs, + }); + } + short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id()); + } + } + + self.pending_events.lock().unwrap().append(&mut pending_events); + + for failure in htlc_failures.drain(..) { + self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), failure.0, &failure.1, failure.2); + } + self.forward_htlcs(&mut htlc_forwards[..]); + + for res in close_results.drain(..) { + self.finish_force_close_channel(res); + } + } + /// Used to restore channels to normal operation after a /// ChannelMonitorUpdateErr::TemporaryFailure was returned from a channel monitor update /// operation. @@ -2152,7 +2268,7 @@ impl ChannelManager where M::T // If the update_add is completely bogus, the call will Err and we will close, // but if we've sent a shutdown and they haven't acknowledged it yet, we just // want to reject the new HTLC and fail it backwards instead of forwarding. - if let PendingHTLCStatus::Forward(PendingForwardHTLCInfo { incoming_shared_secret, .. }) = pending_forward_info { + if let PendingHTLCStatus::Forward(PendingHTLCInfo { incoming_shared_secret, .. }) = pending_forward_info { let chan_update = self.get_channel_update(chan.get()); pending_forward_info = PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC { channel_id: msg.channel_id, @@ -2283,7 +2399,7 @@ impl ChannelManager where M::T } #[inline] - fn forward_htlcs(&self, per_source_pending_forwards: &mut [(u64, Vec<(PendingForwardHTLCInfo, u64)>)]) { + fn forward_htlcs(&self, per_source_pending_forwards: &mut [(u64, Vec<(PendingHTLCInfo, u64)>)]) { for &mut (prev_short_channel_id, ref mut pending_forwards) in per_source_pending_forwards { let mut forward_event = None; if !pending_forwards.is_empty() { @@ -2542,14 +2658,17 @@ impl ChannelManager where M::T } } -impl events::MessageSendEventsProvider for ChannelManager where M::Target: ManyChannelMonitor { +impl events::MessageSendEventsProvider for ChannelManager + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ fn get_and_clear_pending_msg_events(&self) -> Vec { // TODO: Event release to users and serialization is currently race-y: it's very easy for a // user to serialize a ChannelManager with pending events in it and lose those events on // restart. This is doubly true for the fail/fulfill-backs from monitor events! { //TODO: This behavior should be documented. - for htlc_update in self.monitor.fetch_pending_htlc_updated() { + for htlc_update in self.monitor.get_and_clear_pending_htlcs_updated() { if let Some(preimage) = htlc_update.payment_preimage { log_trace!(self, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0)); self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage); @@ -2567,14 +2686,17 @@ impl events::MessageSendEventsProvider for Ch } } -impl events::EventsProvider for ChannelManager where M::Target: ManyChannelMonitor { +impl events::EventsProvider for ChannelManager + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ fn get_and_clear_pending_events(&self) -> Vec { // TODO: Event release to users and serialization is currently race-y: it's very easy for a // user to serialize a ChannelManager with pending events in it and lose those events on // restart. This is doubly true for the fail/fulfill-backs from monitor events! { //TODO: This behavior should be documented. - for htlc_update in self.monitor.fetch_pending_htlc_updated() { + for htlc_update in self.monitor.get_and_clear_pending_htlcs_updated() { if let Some(preimage) = htlc_update.payment_preimage { log_trace!(self, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0)); self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage); @@ -2592,7 +2714,10 @@ impl events::EventsProvider for ChannelManage } } -impl ChainListener for ChannelManager where M::Target: ManyChannelMonitor { +impl ChainListener for ChannelManager + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) { let header_hash = header.bitcoin_hash(); log_trace!(self, "Block {} at height {} connected with {} txn matched", header_hash, height, txn_matched.len()); @@ -2709,7 +2834,10 @@ impl ChainListener for ChannelM } } -impl ChannelMessageHandler for ChannelManager where M::Target: ManyChannelMonitor { +impl ChannelMessageHandler for ChannelManager + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ fn handle_open_channel(&self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel) { let _ = self.total_consistency_lock.read().unwrap(); let res = self.internal_open_channel(their_node_id, their_features, msg); @@ -2998,7 +3126,7 @@ impl ChannelMessageHandler for const SERIALIZATION_VERSION: u8 = 1; const MIN_SERIALIZATION_VERSION: u8 = 1; -impl Writeable for PendingForwardHTLCInfo { +impl Writeable for PendingHTLCInfo { fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { self.onion_packet.write(writer)?; self.incoming_shared_secret.write(writer)?; @@ -3010,9 +3138,9 @@ impl Writeable for PendingForwardHTLCInfo { } } -impl Readable for PendingForwardHTLCInfo { - fn read(reader: &mut R) -> Result { - Ok(PendingForwardHTLCInfo { +impl Readable for PendingHTLCInfo { + fn read(reader: &mut R) -> Result { + Ok(PendingHTLCInfo { onion_packet: Readable::read(reader)?, incoming_shared_secret: Readable::read(reader)?, payment_hash: Readable::read(reader)?, @@ -3179,7 +3307,10 @@ impl Readable for HTLCForwardInfo { } } -impl Writeable for ChannelManager where M::Target: ManyChannelMonitor { +impl Writeable for ChannelManager + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { let _ = self.total_consistency_lock.write().unwrap(); @@ -3250,7 +3381,11 @@ impl Writeable for ChannelManager /// 5) Move the ChannelMonitors into your local ManyChannelMonitor. /// 6) Disconnect/connect blocks on the ChannelManager. /// 7) Register the new ChannelManager with your ChainWatchInterface. -pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref> where M::Target: ManyChannelMonitor { +pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref, T: Deref> + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ + /// The keys provider which will give us relevant keys. Some keys will be loaded during /// deserialization. pub keys_manager: Arc>, @@ -3269,7 +3404,7 @@ pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref> wh /// The BroadcasterInterface which will be used in the ChannelManager in the future and may be /// used to broadcast the latest local commitment transactions of channels which must be /// force-closed during deserialization. - pub tx_broadcaster: Arc, + pub tx_broadcaster: T, /// The Logger for use in the ChannelManager and which may be used to log information during /// deserialization. pub logger: Arc, @@ -3290,8 +3425,11 @@ pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref> wh pub channel_monitors: &'a mut HashMap>, } -impl<'a, R : ::std::io::Read, ChanSigner: ChannelKeys + Readable, M: Deref> ReadableArgs> for (Sha256dHash, ChannelManager) where M::Target: ManyChannelMonitor { - fn read(reader: &mut R, args: ChannelManagerReadArgs<'a, ChanSigner, M>) -> Result { +impl<'a, R : ::std::io::Read, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref> ReadableArgs> for (Sha256dHash, ChannelManager) + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, +{ + fn read(reader: &mut R, args: ChannelManagerReadArgs<'a, ChanSigner, M, T>) -> Result { let _ver: u8 = Readable::read(reader)?; let min_ver: u8 = Readable::read(reader)?; if min_ver > SERIALIZATION_VERSION { @@ -3314,12 +3452,13 @@ impl<'a, R : ::std::io::Read, ChanSigner: ChannelKeys + Readable, M: Deref> R return Err(DecodeError::InvalidValue); } - let funding_txo = channel.channel_monitor().get_funding_txo().ok_or(DecodeError::InvalidValue)?; + let funding_txo = channel.get_funding_txo().ok_or(DecodeError::InvalidValue)?; funding_txo_set.insert(funding_txo.clone()); if let Some(ref mut monitor) = args.channel_monitors.get_mut(&funding_txo) { if channel.get_cur_local_commitment_transaction_number() != monitor.get_cur_local_commitment_number() || channel.get_revoked_remote_commitment_transaction_number() != monitor.get_min_seen_secret() || - channel.get_cur_remote_commitment_transaction_number() != monitor.get_cur_remote_commitment_number() { + channel.get_cur_remote_commitment_transaction_number() != monitor.get_cur_remote_commitment_number() || + channel.get_latest_monitor_update_id() != monitor.get_latest_update_id() { let mut force_close_res = channel.force_shutdown(); force_close_res.0 = monitor.get_latest_local_commitment_txn(); closed_channels.push(force_close_res);