X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=d19e3008990395dc9c2d4a4eb35dc6c6e9b91f7d;hb=13b7cd503bd27981b249fabcaa4f2a12601f648b;hp=1d43fa0a460f96ec33a9a5d094a72fb9884ac53c;hpb=574870e9f8faf44244dbfec2d146eb69e245d660;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 1d43fa0a..d19e3008 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -2529,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()})); } @@ -3620,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 { .. }) => { @@ -4214,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> { @@ -4255,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), @@ -4297,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), @@ -4808,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)) => @@ -4948,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)?; @@ -5046,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) { @@ -5074,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(..) { @@ -7338,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); @@ -7369,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); @@ -7433,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]); @@ -7477,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]); @@ -7670,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 {