X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=21eab0c48df447e5a2df0eab7947737043db697c;hb=7591eda7a80ba7ef7d66d03dc409542a3f284bdb;hp=33f9441cf6c17e80edadbc12060ef3b851618ede;hpb=be7d3d17ac4c8f45f8ac80e11368c62b423f8318;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 33f9441c..21eab0c4 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -318,6 +318,12 @@ const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assum /// the "reorg path" (ie call block_disconnected() until you get to a common block and then call /// block_connected() to step towards your best block) upon deserialization before using the /// object! +/// +/// Note that ChannelManager is responsible for tracking liveness of its channels and generating +/// ChannelUpdate messages informing peers that the channel is temporarily disabled. To avoid +/// spam due to quick disconnection/reconnection, updates are not sent until the channel has been +/// offline for a full minute. In order to track this, you must call +/// timer_chan_freshness_every_min roughly once per minute, though it doesn't have to be perfec. pub struct ChannelManager<'a> { default_configuration: UserConfig, genesis_hash: Sha256dHash, @@ -1488,6 +1494,31 @@ impl<'a> ChannelManager<'a> { events.append(&mut new_events); } + /// If a peer is disconnected we mark any channels with that peer as 'disabled'. + /// After some time, if channels are still disabled we need to broadcast a ChannelUpdate + /// to inform the network about the uselessness of these channels. + /// + /// This method handles all the details, and must be called roughly once per minute. + pub fn timer_chan_freshness_every_min(&self) { + let _ = self.total_consistency_lock.read().unwrap(); + let mut channel_state_lock = self.channel_state.lock().unwrap(); + let channel_state = channel_state_lock.borrow_parts(); + for (_, chan) in channel_state.by_id { + if chan.is_disabled_staged() && !chan.is_live() { + if let Ok(update) = self.get_channel_update(&chan) { + channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { + msg: update + }); + } + chan.to_fresh(); + } else if chan.is_disabled_staged() && chan.is_live() { + chan.to_fresh(); + } else if chan.is_disabled_marked() { + chan.to_disabled_staged(); + } + } + } + /// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect /// after a PaymentReceived event, failing the HTLC back to its origin and freeing resources /// along the path (including in our own channel on which we received it). @@ -2797,8 +2828,8 @@ impl<'a> ChannelMessageHandler for ChannelManager<'a> { log_debug!(self, "Marking channels with {} disconnected and generating channel_updates", log_pubkey!(their_node_id)); channel_state.by_id.retain(|_, chan| { if chan.get_their_node_id() == *their_node_id { - //TODO: mark channel disabled (and maybe announce such after a timeout). let failed_adds = chan.remove_uncommitted_htlcs_and_mark_paused(); + chan.to_disabled_marked(); if !failed_adds.is_empty() { let chan_update = self.get_channel_update(&chan).map(|u| u.encode_with_len()).unwrap(); // Cannot add/recv HTLCs before we have a short_id so unwrap is safe failed_payments.push((chan_update, failed_adds));