X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=28c6430bbc2e35702720ac0fa9e78ac34fbfd1e9;hb=0133739e9e585ebe966ba4a1d41b003f4f4769bf;hp=709ddde2e641144f03424f85f83060e332f25fc9;hpb=d4ad57b7e65f206bc40989eaef7ce2efe9428935;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 709ddde2..28c6430b 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -370,7 +370,7 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L> = ChannelManage /// SimpleArcChannelManager when you require a ChannelManager with a static lifetime, such as when /// you're using lightning-net-tokio. pub struct ChannelManager - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, @@ -683,7 +683,7 @@ macro_rules! maybe_break_monitor_err { } impl ChannelManager - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, @@ -707,10 +707,10 @@ impl /// 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, fee_est: F, monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Result, secp256k1::Error> { + pub fn new(network: Network, fee_est: F, monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Self { let secp_ctx = Secp256k1::new(); - let res = ChannelManager { + ChannelManager { default_configuration: config.clone(), genesis_hash: genesis_block(network).header.bitcoin_hash(), fee_estimator: fee_est, @@ -740,9 +740,7 @@ impl keys_manager, logger, - }; - - Ok(res) + } } /// Creates a new outbound channel to the given remote node and with the given value. @@ -764,7 +762,7 @@ impl let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration }; let channel = Channel::new_outbound(&self.fee_estimator, &self.keys_manager, their_network_key, channel_value_satoshis, push_msat, user_id, config)?; - let res = channel.get_open_channel(self.genesis_hash.clone(), &self.fee_estimator); + let res = channel.get_open_channel(self.genesis_hash.clone()); let _ = self.total_consistency_lock.read().unwrap(); let mut channel_state = self.channel_state.lock().unwrap(); @@ -2276,7 +2274,7 @@ impl }; // Because we have exclusive ownership of the channel here we can release the channel_state // lock before add_monitor - if let Err(e) = self.monitor.add_monitor(monitor_update.get_funding_txo(), monitor_update) { + if let Err(e) = self.monitor.add_monitor(monitor_update.get_funding_txo().0, monitor_update) { match e { ChannelMonitorUpdateErr::PermanentFailure => { // Note that we reply with the new channel_id in error messages if we gave up on the @@ -2474,7 +2472,7 @@ impl //encrypted with the same key. It's not immediately obvious how to usefully exploit that, //but we should prevent it anyway. - let (mut pending_forward_info, mut channel_state_lock) = self.decode_update_add_htlc_onion(msg); + let (pending_forward_info, mut channel_state_lock) = self.decode_update_add_htlc_onion(msg); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(msg.channel_id) { @@ -2482,39 +2480,46 @@ impl if chan.get().get_their_node_id() != *their_node_id { return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id)); } - if !chan.get().is_usable() { + + let create_pending_htlc_status = |chan: &Channel, pending_forward_info: PendingHTLCStatus, error_code: u16| { + // Ensure error_code has the UPDATE flag set, since by default we send a + // channel update along as part of failing the HTLC. + assert!((error_code & 0x1000) != 0); // 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(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, - htlc_id: msg.htlc_id, - reason: if let Ok(update) = chan_update { - // TODO: Note that |20 is defined as "channel FROM the processing - // node has been disabled" (emphasis mine), which seems to imply - // that we can't return |20 for an inbound channel being disabled. - // This probably needs a spec update but should definitely be - // allowed. - onion_utils::build_first_hop_failure_packet(&incoming_shared_secret, 0x1000|20, &{ + match pending_forward_info { + PendingHTLCStatus::Forward(PendingHTLCInfo { ref incoming_shared_secret, .. }) => { + let reason = if let Ok(upd) = self.get_channel_update(chan) { + onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &{ let mut res = Vec::with_capacity(8 + 128); - res.extend_from_slice(&byte_utils::be16_to_array(update.contents.flags)); - res.extend_from_slice(&update.encode_with_len()[..]); + res.extend_from_slice(&byte_utils::be16_to_array(upd.contents.flags)); + res.extend_from_slice(&upd.encode_with_len()[..]); res }[..]) } else { - // This can only happen if the channel isn't in the fully-funded - // state yet, implying our counterparty is trying to route payments - // over the channel back to themselves (cause no one else should - // know the short_id is a lightning channel yet). We should have no - // problem just calling this unknown_next_peer - onion_utils::build_first_hop_failure_packet(&incoming_shared_secret, 0x4000|10, &[]) - }, - })); + // The only case where we'd be unable to + // successfully get a channel update is if the + // channel isn't in the fully-funded state yet, + // implying our counterparty is trying to route + // payments over the channel back to themselves + // (cause no one else should know the short_id + // is a lightning channel yet). We should have + // no problem just calling this + // unknown_next_peer (0x4000|10). + onion_utils::build_first_hop_failure_packet(incoming_shared_secret, 0x4000|10, &[]) + }; + let msg = msgs::UpdateFailHTLC { + channel_id: msg.channel_id, + htlc_id: msg.htlc_id, + reason + }; + PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msg)) + }, + _ => pending_forward_info } - } - try_chan_entry!(self, chan.get_mut().update_add_htlc(&msg, pending_forward_info), channel_state, chan); + }; + try_chan_entry!(self, chan.get_mut().update_add_htlc(&msg, pending_forward_info, create_pending_htlc_status, &self.logger), channel_state, chan); }, hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id)) } @@ -2838,7 +2843,7 @@ impl /// PeerManager::process_events afterwards. /// Note: This API is likely to change! #[doc(hidden)] - pub fn update_fee(&self, channel_id: [u8;32], feerate_per_kw: u64) -> Result<(), APIError> { + pub fn update_fee(&self, channel_id: [u8;32], feerate_per_kw: u32) -> Result<(), APIError> { let _ = self.total_consistency_lock.read().unwrap(); let their_node_id; let err: Result<(), _> = loop { @@ -2889,7 +2894,7 @@ impl } impl events::MessageSendEventsProvider for ChannelManager - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, @@ -2920,7 +2925,7 @@ impl } impl events::EventsProvider for ChannelManager - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, @@ -2952,13 +2957,13 @@ impl impl ChainListener for ChannelManager - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, L::Target: Logger, { - fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) { + fn block_connected(&self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[usize]) { let header_hash = header.bitcoin_hash(); log_trace!(self.logger, "Block {} at height {} connected with {} txn matched", header_hash, height, txn_matched.len()); let _ = self.total_consistency_lock.read().unwrap(); @@ -3120,7 +3125,7 @@ impl ChannelMessageHandler for ChannelManager - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, @@ -3559,7 +3564,7 @@ impl Readable for HTLCForwardInfo { } impl Writeable for ChannelManager - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, @@ -3643,7 +3648,7 @@ impl - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, @@ -3693,7 +3698,7 @@ pub struct ChannelManagerReadArgs<'a, ChanSigner: 'a + ChannelKeys, M: Deref, T: // SipmleArcChannelManager type: impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ReadableArgs> for (BlockHash, Arc>) - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, @@ -3707,7 +3712,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ReadableArgs> for (BlockHash, ChannelManager) - where M::Target: ManyChannelMonitor, + where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator,