X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=c05ca2a8f16656dd03a3ca2fb531859175b71a39;hb=99eef23f4ef0c53e2b047261a4495d2c2f7bbe20;hp=fc3b4fd81746f7dc878a0bf138735ee805026c01;hpb=ed84b02a0aef7d97a887d187ea0429dcd780a6b3;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index fc3b4fd8..c05ca2a8 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -458,6 +458,7 @@ impl Channel { where K::Target: KeysInterface, F::Target: FeeEstimator, { + let our_to_self_delay = config.own_channel_config.our_to_self_delay; let chan_keys = keys_provider.get_channel_keys(false, channel_value_satoshis); if channel_value_satoshis >= MAX_FUNDING_SATOSHIS { @@ -467,8 +468,8 @@ impl Channel { if push_msat > channel_value_msat { return Err(APIError::APIMisuseError { err: format!("Push value ({}) was larger than channel_value ({})", push_msat, channel_value_msat) }); } - if config.own_channel_config.our_to_self_delay < BREAKDOWN_TIMEOUT { - return Err(APIError::APIMisuseError {err: format!("Configured with an unreasonable our_to_self_delay ({}) putting user funds at risks", config.own_channel_config.our_to_self_delay)}); + if our_to_self_delay < BREAKDOWN_TIMEOUT { + return Err(APIError::APIMisuseError {err: format!("Configured with an unreasonable our_to_self_delay ({}) putting user funds at risks", our_to_self_delay)}); } let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background); if Channel::::get_remote_channel_reserve_satoshis(channel_value_satoshis) < Channel::::derive_our_dust_limit_satoshis(background_feerate) { @@ -535,7 +536,7 @@ impl Channel { their_htlc_minimum_msat: 0, our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat }, their_to_self_delay: 0, - our_to_self_delay: config.own_channel_config.our_to_self_delay, + our_to_self_delay, their_max_accepted_htlcs: 0, minimum_depth: 0, // Filled in in accept_channel @@ -582,7 +583,7 @@ impl Channel { delayed_payment_basepoint: msg.delayed_payment_basepoint, htlc_basepoint: msg.htlc_basepoint }; - chan_keys.set_remote_channel_pubkeys(&their_pubkeys); + chan_keys.on_accept(&their_pubkeys, msg.to_self_delay, config.own_channel_config.our_to_self_delay); let mut local_config = (*config).channel_options.clone(); if config.own_channel_config.our_to_self_delay < BREAKDOWN_TIMEOUT { @@ -1457,7 +1458,7 @@ impl Channel { htlc_basepoint: msg.htlc_basepoint }; - self.local_keys.set_remote_channel_pubkeys(&their_pubkeys); + self.local_keys.on_accept(&their_pubkeys, msg.to_self_delay, self.our_to_self_delay); self.their_pubkeys = Some(their_pubkeys); self.their_cur_commitment_point = Some(msg.first_per_commitment_point); @@ -1483,7 +1484,7 @@ impl Channel { let remote_keys = self.build_remote_transaction_keys()?; let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0; - let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx) + let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx) .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0; // We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish. @@ -2117,7 +2118,7 @@ impl Channel { /// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them /// fulfilling or failing the last pending HTLC) - fn free_holding_cell_htlcs(&mut self, logger: &L) -> Result, ChannelError> where L::Target: Logger { + fn free_holding_cell_htlcs(&mut self, logger: &L) -> Result<(Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>), ChannelError> where L::Target: Logger { assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, 0); if self.holding_cell_htlc_updates.len() != 0 || self.holding_cell_update_fee.is_some() { log_trace!(logger, "Freeing holding cell with {} HTLC updates{}", self.holding_cell_htlc_updates.len(), if self.holding_cell_update_fee.is_some() { " and a fee update" } else { "" }); @@ -2132,110 +2133,94 @@ impl Channel { let mut update_add_htlcs = Vec::with_capacity(htlc_updates.len()); let mut update_fulfill_htlcs = Vec::with_capacity(htlc_updates.len()); let mut update_fail_htlcs = Vec::with_capacity(htlc_updates.len()); - let mut err = None; + let mut htlcs_to_fail = Vec::new(); for htlc_update in htlc_updates.drain(..) { // Note that this *can* fail, though it should be due to rather-rare conditions on // fee races with adding too many outputs which push our total payments just over // the limit. In case it's less rare than I anticipate, we may want to revisit // handling this case better and maybe fulfilling some of the HTLCs while attempting // to rebalance channels. - if err.is_some() { // We're back to AwaitingRemoteRevoke (or are about to fail the channel) - self.holding_cell_htlc_updates.push(htlc_update); - } else { - match &htlc_update { - &HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, ..} => { - match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone()) { - Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()), - Err(e) => { - match e { - ChannelError::Ignore(ref msg) => { - log_info!(logger, "Failed to send HTLC with payment_hash {} due to {}", log_bytes!(payment_hash.0), msg); - }, - _ => { - log_info!(logger, "Failed to send HTLC with payment_hash {} resulting in a channel closure during holding_cell freeing", log_bytes!(payment_hash.0)); - }, - } - err = Some(e); + match &htlc_update { + &HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, ..} => { + match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone()) { + Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()), + Err(e) => { + match e { + ChannelError::Ignore(ref msg) => { + log_info!(logger, "Failed to send HTLC with payment_hash {} due to {}", log_bytes!(payment_hash.0), msg); + // If we fail to send here, then this HTLC should + // be failed backwards. Failing to send here + // indicates that this HTLC may keep being put back + // into the holding cell without ever being + // successfully forwarded/failed/fulfilled, causing + // our counterparty to eventually close on us. + htlcs_to_fail.push((source.clone(), *payment_hash)); + }, + _ => { + panic!("Got a non-IgnoreError action trying to send holding cell HTLC"); + }, } } - }, - &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => { - match self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) { - Ok((update_fulfill_msg_option, additional_monitor_update_opt)) => { - update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap()); - if let Some(mut additional_monitor_update) = additional_monitor_update_opt { - monitor_update.updates.append(&mut additional_monitor_update.updates); - } - }, - Err(e) => { - if let ChannelError::Ignore(_) = e {} - else { - panic!("Got a non-IgnoreError action trying to fulfill holding cell HTLC"); - } + } + }, + &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => { + match self.get_update_fulfill_htlc(htlc_id, *payment_preimage, logger) { + Ok((update_fulfill_msg_option, additional_monitor_update_opt)) => { + update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap()); + if let Some(mut additional_monitor_update) = additional_monitor_update_opt { + monitor_update.updates.append(&mut additional_monitor_update.updates); + } + }, + Err(e) => { + if let ChannelError::Ignore(_) = e {} + else { + panic!("Got a non-IgnoreError action trying to fulfill holding cell HTLC"); } } - }, - &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, ref err_packet } => { - match self.get_update_fail_htlc(htlc_id, err_packet.clone()) { - Ok(update_fail_msg_option) => update_fail_htlcs.push(update_fail_msg_option.unwrap()), - Err(e) => { - if let ChannelError::Ignore(_) = e {} - else { - panic!("Got a non-IgnoreError action trying to fail holding cell HTLC"); - } + } + }, + &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, ref err_packet } => { + match self.get_update_fail_htlc(htlc_id, err_packet.clone()) { + Ok(update_fail_msg_option) => update_fail_htlcs.push(update_fail_msg_option.unwrap()), + Err(e) => { + if let ChannelError::Ignore(_) = e {} + else { + panic!("Got a non-IgnoreError action trying to fail holding cell HTLC"); } } - }, - } - if err.is_some() { - self.holding_cell_htlc_updates.push(htlc_update); - if let Some(ChannelError::Ignore(_)) = err { - // If we failed to add the HTLC, but got an Ignore error, we should - // still send the new commitment_signed, so reset the err to None. - err = None; } - } + }, } } - //TODO: Need to examine the type of err - if it's a fee issue or similar we may want to - //fail it back the route, if it's a temporary issue we can ignore it... - match err { - None => { - if update_add_htlcs.is_empty() && update_fulfill_htlcs.is_empty() && update_fail_htlcs.is_empty() && self.holding_cell_update_fee.is_none() { - // This should never actually happen and indicates we got some Errs back - // from update_fulfill_htlc/update_fail_htlc, but we handle it anyway in - // case there is some strange way to hit duplicate HTLC removes. - return Ok(None); - } - let update_fee = if let Some(feerate) = self.holding_cell_update_fee { - self.pending_update_fee = self.holding_cell_update_fee.take(); - Some(msgs::UpdateFee { - channel_id: self.channel_id, - feerate_per_kw: feerate as u32, - }) - } else { - None - }; + if update_add_htlcs.is_empty() && update_fulfill_htlcs.is_empty() && update_fail_htlcs.is_empty() && self.holding_cell_update_fee.is_none() { + return Ok((None, htlcs_to_fail)); + } + let update_fee = if let Some(feerate) = self.holding_cell_update_fee { + self.pending_update_fee = self.holding_cell_update_fee.take(); + Some(msgs::UpdateFee { + channel_id: self.channel_id, + feerate_per_kw: feerate as u32, + }) + } else { + None + }; - let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check(logger)?; - // send_commitment_no_status_check and get_update_fulfill_htlc may bump latest_monitor_id - // but we want them to be strictly increasing by one, so reset it here. - self.latest_monitor_update_id = monitor_update.update_id; - monitor_update.updates.append(&mut additional_update.updates); + let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check(logger)?; + // send_commitment_no_status_check and get_update_fulfill_htlc may bump latest_monitor_id + // but we want them to be strictly increasing by one, so reset it here. + self.latest_monitor_update_id = monitor_update.update_id; + monitor_update.updates.append(&mut additional_update.updates); - Ok(Some((msgs::CommitmentUpdate { - update_add_htlcs, - update_fulfill_htlcs, - update_fail_htlcs, - update_fail_malformed_htlcs: Vec::new(), - update_fee: update_fee, - commitment_signed, - }, monitor_update))) - }, - Some(e) => Err(e) - } + Ok((Some((msgs::CommitmentUpdate { + update_add_htlcs, + update_fulfill_htlcs, + update_fail_htlcs, + update_fail_malformed_htlcs: Vec::new(), + update_fee: update_fee, + commitment_signed, + }, monitor_update)), htlcs_to_fail)) } else { - Ok(None) + Ok((None, Vec::new())) } } @@ -2244,7 +2229,7 @@ impl Channel { /// waiting on this revoke_and_ack. The generation of this new commitment_signed may also fail, /// generating an appropriate error *after* the channel state has been updated based on the /// revoke_and_ack message. - pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &F, logger: &L) -> Result<(Option, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option, ChannelMonitorUpdate), ChannelError> + pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &F, logger: &L) -> Result<(Option, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option, ChannelMonitorUpdate, Vec<(HTLCSource, PaymentHash)>), ChannelError> where F::Target: FeeEstimator, L::Target: Logger, { @@ -2419,11 +2404,11 @@ impl Channel { } self.monitor_pending_forwards.append(&mut to_forward_infos); self.monitor_pending_failures.append(&mut revoked_htlcs); - return Ok((None, Vec::new(), Vec::new(), None, monitor_update)) + return Ok((None, Vec::new(), Vec::new(), None, monitor_update, Vec::new())) } match self.free_holding_cell_htlcs(logger)? { - Some((mut commitment_update, mut additional_update)) => { + (Some((mut commitment_update, mut additional_update)), htlcs_to_fail) => { commitment_update.update_fail_htlcs.reserve(update_fail_htlcs.len()); for fail_msg in update_fail_htlcs.drain(..) { commitment_update.update_fail_htlcs.push(fail_msg); @@ -2438,9 +2423,9 @@ impl Channel { self.latest_monitor_update_id = monitor_update.update_id; monitor_update.updates.append(&mut additional_update.updates); - Ok((Some(commitment_update), to_forward_infos, revoked_htlcs, None, monitor_update)) + Ok((Some(commitment_update), to_forward_infos, revoked_htlcs, None, monitor_update, htlcs_to_fail)) }, - None => { + (None, htlcs_to_fail) => { if require_commitment { let (commitment_signed, mut additional_update) = self.send_commitment_no_status_check(logger)?; @@ -2456,9 +2441,9 @@ impl Channel { update_fail_malformed_htlcs, update_fee: None, commitment_signed - }), to_forward_infos, revoked_htlcs, None, monitor_update)) + }), to_forward_infos, revoked_htlcs, None, monitor_update, htlcs_to_fail)) } else { - Ok((None, to_forward_infos, revoked_htlcs, self.maybe_propose_first_closing_signed(fee_estimator), monitor_update)) + Ok((None, to_forward_infos, revoked_htlcs, self.maybe_propose_first_closing_signed(fee_estimator), monitor_update, htlcs_to_fail)) } } } @@ -2560,6 +2545,11 @@ impl Channel { self.holding_cell_htlc_updates.retain(|htlc_update| { match htlc_update { + // Note that currently on channel reestablish we assert that there are + // no holding cell HTLC update_adds, so if in the future we stop + // dropping added HTLCs here and failing them backwards, then there will + // need to be corresponding changes made in the Channel's re-establish + // logic. &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, .. } => { outbound_drops.push((source.clone(), payment_hash.clone())); false @@ -2827,6 +2817,14 @@ impl Channel { } if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateFailed as u32)) == 0 { + // Note that if in the future we no longer drop holding cell update_adds on peer + // disconnect, this logic will need to be updated. + for htlc_update in self.holding_cell_htlc_updates.iter() { + if let &HTLCUpdateAwaitingACK::AddHTLC { .. } = htlc_update { + debug_assert!(false, "There shouldn't be any add-HTLCs in the holding cell now because they should have been dropped on peer disconnect. Panic here because said HTLCs won't be handled correctly."); + } + } + // We're up-to-date and not waiting on a remote revoke (if we are our // channel_reestablish should result in them sending a revoke_and_ack), but we may // have received some updates while we were disconnected. Free the holding cell @@ -2834,8 +2832,18 @@ impl Channel { match self.free_holding_cell_htlcs(logger) { Err(ChannelError::Close(msg)) => return Err(ChannelError::Close(msg)), Err(ChannelError::Ignore(_)) | Err(ChannelError::CloseDelayBroadcast(_)) => panic!("Got non-channel-failing result from free_holding_cell_htlcs"), - Ok(Some((commitment_update, monitor_update))) => return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(monitor_update), self.resend_order.clone(), shutdown_msg)), - Ok(None) => return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg)), + Ok((Some((commitment_update, monitor_update)), htlcs_to_fail)) => { + // If in the future we no longer drop holding cell update_adds on peer + // disconnect, we may be handed some HTLCs to fail backwards here. + assert!(htlcs_to_fail.is_empty()); + return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(monitor_update), self.resend_order.clone(), shutdown_msg)); + }, + Ok((None, htlcs_to_fail)) => { + // If in the future we no longer drop holding cell update_adds on peer + // disconnect, we may be handed some HTLCs to fail backwards here. + assert!(htlcs_to_fail.is_empty()); + return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg)); + }, } } else { return Ok((resend_funding_locked, required_revoke, None, None, self.resend_order.clone(), shutdown_msg)); @@ -3128,6 +3136,18 @@ impl Channel { self.our_htlc_minimum_msat } + /// Allowed in any state (including after shutdown) + pub fn get_announced_htlc_max_msat(&self) -> u64 { + return cmp::min( + // Upper bound by capacity. We make it a bit less than full capacity to prevent attempts + // to use full capacity. This is an effort to reduce routing failures, because in many cases + // channel might have been used to route very small values (either by honest users or as DoS). + self.channel_value_satoshis * 9 / 10, + + Channel::::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis) + ); + } + /// Allowed in any state (including after shutdown) pub fn get_their_htlc_minimum_msat(&self) -> u64 { self.our_htlc_minimum_msat @@ -3512,7 +3532,7 @@ impl Channel { fn get_outbound_funding_created_signature(&mut self, logger: &L) -> Result where L::Target: Logger { let remote_keys = self.build_remote_transaction_keys()?; let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0; - Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx) + Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx) .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0) } @@ -3865,7 +3885,7 @@ impl Channel { htlcs.push(htlc); } - let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, self.our_to_self_delay, &self.secp_ctx) + let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx) .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?; signature = res.0; htlc_signatures = res.1; @@ -4658,7 +4678,7 @@ mod tests { delayed_payment_basepoint: public_from_secret_hex(&secp_ctx, "1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e13"), htlc_basepoint: public_from_secret_hex(&secp_ctx, "4444444444444444444444444444444444444444444444444444444444444444") }; - chan_keys.set_remote_channel_pubkeys(&their_pubkeys); + chan_keys.on_accept(&their_pubkeys, chan.their_to_self_delay, chan.our_to_self_delay); assert_eq!(their_pubkeys.payment_point.serialize()[..], hex::decode("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991").unwrap()[..]); @@ -4714,7 +4734,7 @@ mod tests { assert_eq!(serialize(&localtx.add_local_sig(&redeemscript, local_sig))[..], hex::decode($tx_hex).unwrap()[..]); - let htlc_sigs = chan_keys.sign_local_commitment_htlc_transactions(&localtx, chan.their_to_self_delay, &chan.secp_ctx).unwrap(); + let htlc_sigs = chan_keys.sign_local_commitment_htlc_transactions(&localtx, &chan.secp_ctx).unwrap(); let mut htlc_sig_iter = localtx.per_htlc.iter().zip(htlc_sigs.iter().enumerate()); $({