X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=cf593068947478d7060b7603b93f13400e31bda2;hb=44fa3acae85888982b2c808bc4b401e96d33822f;hp=17a52e29e4a5eecb210fe9d3f10c2edc4306f233;hpb=f84ce03cab66d63c4a5590a93364077d87fd6acf;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 17a52e29..cf593068 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -13,10 +13,11 @@ //! responsible for tracking which channels are open, HTLCs are in flight and reestablishing those //! upon reconnect to the relevant peer(s). //! -//! It does not manage routing logic (see routing::router::get_route for that) nor does it manage constructing +//! It does not manage routing logic (see [`find_route`] for that) nor does it manage constructing //! on-chain transactions (it only monitors the chain to watch for any force-closes that might //! imply it needs to fail HTLCs/payments/channels it manages). //! +//! [`find_route`]: crate::routing::router::find_route use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::transaction::Transaction; @@ -1777,12 +1778,14 @@ impl ChannelMana self.list_channels_with_filter(|_| true) } - /// Gets the list of usable channels, in random order. Useful as an argument to - /// get_route to ensure non-announced channels are used. + /// Gets the list of usable channels, in random order. Useful as an argument to [`find_route`] + /// to ensure non-announced channels are used. /// /// These are guaranteed to have their [`ChannelDetails::is_usable`] value set to true, see the /// documentation for [`ChannelDetails::is_usable`] for more info on exactly what the criteria /// are. + /// + /// [`find_route`]: crate::routing::router::find_route pub fn list_usable_channels(&self) -> Vec { // Note we use is_live here instead of usable which leads to somewhat confused // internal/external nomenclature, but that's ok cause that's probably what the user @@ -2526,12 +2529,6 @@ impl ChannelMana if route.paths.len() < 1 { return Err(PaymentSendFailure::ParameterError(APIError::RouteError{err: "There must be at least one path to send over"})); } - if route.paths.len() > 10 { - // This limit is completely arbitrary - there aren't any real fundamental path-count - // limits. After we support retrying individual paths we should likely bump this, but - // for now more than 10 paths likely carries too much one-path failure. - return Err(PaymentSendFailure::ParameterError(APIError::RouteError{err: "Sending over more than 10 paths is not currently supported"})); - } if payment_secret.is_none() && route.paths.len() > 1 { return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError{err: "Payment secret is required for multi-path payments".to_string()})); } @@ -3617,7 +3614,10 @@ impl ChannelMana // Fail a list of HTLCs that were just freed from the holding cell. The HTLCs need to be // failed backwards or, if they were one of our outgoing HTLCs, then their failure needs to // be surfaced to the user. - fn fail_holding_cell_htlcs(&self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32]) { + fn fail_holding_cell_htlcs( + &self, mut htlcs_to_fail: Vec<(HTLCSource, PaymentHash)>, channel_id: [u8; 32], + _counterparty_node_id: &PublicKey + ) { for (htlc_src, payment_hash) in htlcs_to_fail.drain(..) { match htlc_src { HTLCSource::PreviousHopData(HTLCPreviousHopData { .. }) => { @@ -3765,7 +3765,7 @@ impl ChannelMana .. } => { // we get a fail_malformed_htlc from the first hop // TODO: We'd like to generate a NetworkUpdate for temporary - // failures here, but that would be insufficient as get_route + // failures here, but that would be insufficient as find_route // generally ignores its view of our own channels as we provide them via // ChannelDetails. // TODO: For non-temporary failures, we really should be closing the @@ -4211,6 +4211,10 @@ impl ChannelMana /// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond /// with which `accept_inbound_channel`/`accept_inbound_channel_from_trusted_peer_0conf` call. /// + /// Note that this method will return an error and reject the channel, if it requires support + /// for zero confirmations. Instead, `accept_inbound_channel_from_trusted_peer_0conf` must be + /// used to accept such channels. + /// /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> { @@ -4252,7 +4256,20 @@ impl ChannelMana if *counterparty_node_id != channel.get().get_counterparty_node_id() { return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() }); } - if accept_0conf { channel.get_mut().set_0conf(); } + if accept_0conf { + channel.get_mut().set_0conf(); + } else if channel.get().get_channel_type().requires_zero_conf() { + let send_msg_err_event = events::MessageSendEvent::HandleError { + node_id: channel.get().get_counterparty_node_id(), + action: msgs::ErrorAction::SendErrorMessage{ + msg: msgs::ErrorMessage { channel_id: temporary_channel_id.clone(), data: "No zero confirmation channels accepted".to_owned(), } + } + }; + channel_state.pending_msg_events.push(send_msg_err_event); + let _ = remove_channel!(self, channel_state, channel); + return Err(APIError::APIMisuseError { err: "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned() }); + } + channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel { node_id: channel.get().get_counterparty_node_id(), msg: channel.get_mut().accept_inbound_channel(user_channel_id), @@ -4294,6 +4311,9 @@ impl ChannelMana }, hash_map::Entry::Vacant(entry) => { if !self.default_configuration.manually_accept_inbound_channels { + if channel.get_channel_type().requires_zero_conf() { + return Err(MsgHandleErrInternal::send_err_msg_no_close("No zero confirmation channels accepted".to_owned(), msg.temporary_channel_id.clone())); + } channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel { node_id: counterparty_node_id.clone(), msg: channel.accept_inbound_channel(0), @@ -4326,7 +4346,7 @@ impl ChannelMana if chan.get().get_counterparty_node_id() != *counterparty_node_id { return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.temporary_channel_id)); } - try_chan_entry!(self, chan.get_mut().accept_channel(&msg, &self.default_configuration.peer_channel_config_limits, &their_features), channel_state, chan); + try_chan_entry!(self, chan.get_mut().accept_channel(&msg, &self.default_configuration.channel_handshake_limits, &their_features), channel_state, chan); (chan.get().get_value_satoshis(), chan.get().get_funding_redeemscript().to_v0_p2wsh(), chan.get().get_user_id()) }, hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.temporary_channel_id)) @@ -4805,7 +4825,7 @@ impl ChannelMana hash_map::Entry::Vacant(_) => break Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id)) } }; - self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id); + self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id, counterparty_node_id); match res { Ok((pending_forwards, mut pending_failures, finalized_claim_htlcs, short_channel_id, channel_outpoint)) => @@ -4945,7 +4965,7 @@ impl ChannelMana } }; post_handle_chan_restoration!(self, chan_restoration_res); - self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id); + self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id, counterparty_node_id); if let Some(channel_ready_msg) = need_lnd_workaround { self.internal_channel_ready(counterparty_node_id, &channel_ready_msg)?; @@ -5043,7 +5063,11 @@ impl ChannelMana match chan.maybe_free_holding_cell_htlcs(&self.logger) { Ok((commitment_opt, holding_cell_failed_htlcs)) => { if !holding_cell_failed_htlcs.is_empty() { - failed_htlcs.push((holding_cell_failed_htlcs, *channel_id)); + failed_htlcs.push(( + holding_cell_failed_htlcs, + *channel_id, + chan.get_counterparty_node_id() + )); } if let Some((commitment_update, monitor_update)) = commitment_opt { if let Err(e) = self.chain_monitor.update_channel(chan.get_funding_txo().unwrap(), monitor_update) { @@ -5071,8 +5095,8 @@ impl ChannelMana } let has_update = has_monitor_update || !failed_htlcs.is_empty() || !handle_errors.is_empty(); - for (failures, channel_id) in failed_htlcs.drain(..) { - self.fail_holding_cell_htlcs(failures, channel_id); + for (failures, channel_id, counterparty_node_id) in failed_htlcs.drain(..) { + self.fail_holding_cell_htlcs(failures, channel_id, &counterparty_node_id); } for (counterparty_node_id, err) in handle_errors.drain(..) { @@ -7335,8 +7359,8 @@ mod tests { final_cltv_expiry_delta: TEST_FINAL_CLTV, }; let route = find_route( - &nodes[0].node.get_our_node_id(), &route_params, nodes[0].network_graph, None, - nodes[0].logger, &scorer, &random_seed_bytes + &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(), + None, nodes[0].logger, &scorer, &random_seed_bytes ).unwrap(); nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -7366,8 +7390,8 @@ mod tests { // To start (2), send a keysend payment but don't claim it. let payment_preimage = PaymentPreimage([42; 32]); let route = find_route( - &nodes[0].node.get_our_node_id(), &route_params, nodes[0].network_graph, None, - nodes[0].logger, &scorer, &random_seed_bytes + &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(), + None, nodes[0].logger, &scorer, &random_seed_bytes ).unwrap(); let (payment_hash, _) = nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -7430,8 +7454,9 @@ mod tests { let scorer = test_utils::TestScorer::with_penalty(0); let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes(); let route = find_route( - &payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::>()), - nodes[0].logger, &scorer, &random_seed_bytes + &payer_pubkey, &route_params, &network_graph.read_only(), + Some(&first_hops.iter().collect::>()), nodes[0].logger, &scorer, + &random_seed_bytes ).unwrap(); let test_preimage = PaymentPreimage([42; 32]); @@ -7474,8 +7499,9 @@ mod tests { let scorer = test_utils::TestScorer::with_penalty(0); let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes(); let route = find_route( - &payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::>()), - nodes[0].logger, &scorer, &random_seed_bytes + &payer_pubkey, &route_params, &network_graph.read_only(), + Some(&first_hops.iter().collect::>()), nodes[0].logger, &scorer, + &random_seed_bytes ).unwrap(); let test_preimage = PaymentPreimage([42; 32]); @@ -7564,7 +7590,7 @@ pub mod bench { use ln::features::{InitFeatures, InvoiceFeatures}; use ln::functional_test_utils::*; use ln::msgs::{ChannelMessageHandler, Init}; - use routing::network_graph::NetworkGraph; + use routing::gossip::NetworkGraph; use routing::router::{PaymentParameters, get_route}; use util::test_utils; use util::config::UserConfig; @@ -7604,7 +7630,7 @@ pub mod bench { let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) }; let mut config: UserConfig = Default::default(); - config.own_channel_config.minimum_depth = 1; + config.channel_handshake_config.minimum_depth = 1; let logger_a = test_utils::TestLogger::with_id("node a".to_owned()); let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a); @@ -7667,7 +7693,7 @@ pub mod bench { _ => panic!(), } - let dummy_graph = NetworkGraph::new(genesis_hash); + let dummy_graph = NetworkGraph::new(genesis_hash, &logger_a); let mut payment_count: u64 = 0; macro_rules! send_payment {