X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannel.rs;h=6172c5fff149094880e8b15129914ca6b3cdd284;hb=3518f1f85d8a3daff451b3fe56cc7854b833e2bd;hp=1fbc605bb3baa34491bf0d4d034f0a3de805503f;hpb=d9d8ea3f65500c59e06f7f291c034d35bb08b502;p=rust-lightning diff --git a/src/ln/channel.rs b/src/ln/channel.rs index 1fbc605b..6172c5ff 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -2,11 +2,9 @@ use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::script::{Script,Builder}; use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType}; use bitcoin::blockdata::opcodes; -use bitcoin::util::hash::{Sha256dHash, Hash160}; +use bitcoin::util::hash::{BitcoinHash, Sha256dHash, Hash160}; use bitcoin::util::bip143; -use bitcoin::network; -use bitcoin::network::serialize::{BitcoinHash, RawDecoder, RawEncoder}; -use bitcoin::network::encodable::{ConsensusEncodable, ConsensusDecodable}; +use bitcoin::consensus::encode::{self, Encodable, Decodable}; use secp256k1::key::{PublicKey,SecretKey}; use secp256k1::{Secp256k1,Message,Signature}; @@ -438,7 +436,7 @@ impl Channel { let secp_ctx = Secp256k1::new(); let channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key, - &chan_keys.htlc_base_key, BREAKDOWN_TIMEOUT, + &chan_keys.htlc_base_key, &chan_keys.payment_base_key, BREAKDOWN_TIMEOUT, keys_provider.get_destination_script(), logger.clone()); Ok(Channel { @@ -626,9 +624,10 @@ impl Channel { let secp_ctx = Secp256k1::new(); let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key, - &chan_keys.htlc_base_key, BREAKDOWN_TIMEOUT, + &chan_keys.htlc_base_key, &chan_keys.payment_base_key, BREAKDOWN_TIMEOUT, keys_provider.get_destination_script(), logger.clone()); channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint); + channel_monitor.provide_their_next_revocation_point(Some((INITIAL_COMMITMENT_NUMBER, msg.first_per_commitment_point))); channel_monitor.set_their_to_self_delay(msg.to_self_delay); let mut chan = Channel { @@ -1349,6 +1348,7 @@ impl Channel { } self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint); + self.channel_monitor.provide_their_next_revocation_point(Some((INITIAL_COMMITMENT_NUMBER, msg.first_per_commitment_point))); self.their_dust_limit_satoshis = msg.dust_limit_satoshis; self.their_max_htlc_value_in_flight_msat = cmp::min(msg.max_htlc_value_in_flight_msat, self.channel_value_satoshis * 1000); @@ -1373,22 +1373,25 @@ impl Channel { Ok(()) } - fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, Signature), HandleError> { + fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, Transaction, Signature, TxCreationKeys), HandleError> { let funding_script = self.get_funding_redeemscript(); let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?; - let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0; + let mut local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0; let local_sighash = Message::from_slice(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap(); - // They sign the "local" commitment transaction, allowing us to broadcast the tx if we wish. + // They sign the "local" commitment transaction... secp_call!(self.secp_ctx.verify(&local_sighash, &sig, &self.their_funding_pubkey.unwrap()), "Invalid funding_created signature from peer", self.channel_id()); + // ...and we sign it, allowing us to broadcast the tx if we wish + self.sign_commitment_transaction(&mut local_initial_commitment_tx, sig); + 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).0; let remote_sighash = Message::from_slice(&bip143::SighashComponents::new(&remote_initial_commitment_tx).sighash_all(&remote_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap(); // We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish. - Ok((remote_initial_commitment_tx, self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key))) + Ok((remote_initial_commitment_tx, local_initial_commitment_tx, self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key), local_keys)) } pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<(msgs::FundingSigned, ChannelMonitor), HandleError> { @@ -1411,7 +1414,7 @@ impl Channel { let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh(); self.channel_monitor.set_funding_info((funding_txo, funding_txo_script)); - let (remote_initial_commitment_tx, our_signature) = match self.funding_created_signature(&msg.signature) { + let (remote_initial_commitment_tx, local_initial_commitment_tx, our_signature, local_keys) = match self.funding_created_signature(&msg.signature) { Ok(res) => res, Err(e) => { self.channel_monitor.unset_funding_info(); @@ -1422,6 +1425,8 @@ impl Channel { // Now that we're past error-generating stuff, update our local state: self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number); + self.last_local_commitment_txn = vec![local_initial_commitment_tx.clone()]; + self.channel_monitor.provide_latest_local_commitment_tx_info(local_initial_commitment_tx, local_keys, self.feerate_per_kw, Vec::new()); self.channel_state = ChannelState::FundingSent as u32; self.channel_id = funding_txo.to_channel_id(); self.cur_remote_commitment_transaction_number -= 1; @@ -1491,6 +1496,7 @@ impl Channel { return Err(ChannelError::Close("Peer sent a funding_locked at a strange time")); } + self.channel_monitor.provide_their_next_revocation_point(Some((INITIAL_COMMITMENT_NUMBER - 1 , msg.next_per_commitment_point))); self.their_prev_commitment_point = self.their_cur_commitment_point; self.their_cur_commitment_point = Some(msg.next_per_commitment_point); Ok(()) @@ -1553,6 +1559,12 @@ impl Channel { //TODO: Check msg.cltv_expiry further? Do this in channel manager? + if self.channel_state & ChannelState::LocalShutdownSent as u32 != 0 { + if let PendingHTLCStatus::Forward(_) = pending_forward_state { + panic!("ChannelManager shouldn't be trying to add a forwardable HTLC after we've started closing"); + } + } + // Now update local state: self.next_remote_htlc_id += 1; self.pending_inbound_htlcs.push(InboundHTLCOutput { @@ -1632,13 +1644,16 @@ impl Channel { self.mark_outbound_htlc_removed(msg.htlc_id, None, Some(fail_reason)) } - pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Option, ChannelMonitor), HandleError> { + pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned, fee_estimator: &FeeEstimator) -> Result<(msgs::RevokeAndACK, Option, Option, ChannelMonitor), HandleError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(HandleError{err: "Got commitment signed message when channel was not in an operational state", action: None}); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(HandleError{err: "Peer sent commitment_signed when we needed a channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent commitment_signed when we needed a channel_reestablish".to_string(), channel_id: msg.channel_id}})}); } + if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK == BOTH_SIDES_SHUTDOWN_MASK && self.last_sent_closing_fee.is_some() { + return Err(HandleError{err: "Peer sent commitment_signed after we'd started exchanging closing_signeds", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent commitment_signed after we'd started exchanging closing_signeds".to_string(), channel_id: msg.channel_id}})}); + } let funding_script = self.get_funding_redeemscript(); @@ -1730,19 +1745,21 @@ impl Channel { return Err(HandleError{err: "Previous monitor update failure prevented generation of RAA", action: Some(ErrorAction::IgnoreError)}); } - let (our_commitment_signed, monitor_update) = if need_our_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 { + let (our_commitment_signed, monitor_update, closing_signed) = if need_our_commitment && (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == 0 { // If we're AwaitingRemoteRevoke we can't send a new commitment here, but that's ok - // we'll send one right away when we get the revoke_and_ack when we // free_holding_cell_htlcs(). let (msg, monitor) = self.send_commitment_no_status_check()?; - (Some(msg), monitor) - } else { (None, self.channel_monitor.clone()) }; + (Some(msg), monitor, None) + } else if !need_our_commitment { + (None, self.channel_monitor.clone(), self.maybe_propose_first_closing_signed(fee_estimator)) + } else { (None, self.channel_monitor.clone(), None) }; Ok((msgs::RevokeAndACK { channel_id: self.channel_id, per_commitment_secret: per_commitment_secret, next_per_commitment_point: next_per_commitment_point, - }, our_commitment_signed, monitor_update)) + }, our_commitment_signed, closing_signed, monitor_update)) } /// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them @@ -1843,20 +1860,24 @@ 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) -> Result<(Option, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, [u8; 32], HTLCFailReason)>, ChannelMonitor), HandleError> { + pub fn revoke_and_ack(&mut self, msg: &msgs::RevokeAndACK, fee_estimator: &FeeEstimator) -> Result<(Option, Vec<(PendingForwardHTLCInfo, u64)>, Vec<(HTLCSource, [u8; 32], HTLCFailReason)>, Option, ChannelMonitor), HandleError> { if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) { return Err(HandleError{err: "Got revoke/ACK message when channel was not in an operational state", action: None}); } if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { return Err(HandleError{err: "Peer sent revoke_and_ack when we needed a channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent revoke_and_ack when we needed a channel_reestablish".to_string(), channel_id: msg.channel_id}})}); } + if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK == BOTH_SIDES_SHUTDOWN_MASK && self.last_sent_closing_fee.is_some() { + return Err(HandleError{err: "Peer sent revoke_and_ack after we'd started exchanging closing_signeds", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent revoke_and_ack after we'd started exchanging closing_signeds".to_string(), channel_id: msg.channel_id}})}); + } if let Some(their_prev_commitment_point) = self.their_prev_commitment_point { if PublicKey::from_secret_key(&self.secp_ctx, &secp_call!(SecretKey::from_slice(&self.secp_ctx, &msg.per_commitment_secret), "Peer provided an invalid per_commitment_secret", self.channel_id())) != their_prev_commitment_point { return Err(HandleError{err: "Got a revoke commitment secret which didn't correspond to their current pubkey", action: None}); } } - self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret, Some((self.cur_remote_commitment_transaction_number - 1, msg.next_per_commitment_point)))?; + self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret)?; + self.channel_monitor.provide_their_next_revocation_point(Some((self.cur_remote_commitment_transaction_number - 1, msg.next_per_commitment_point))); // Update state now that we've passed all the can-fail calls... // (note that we may still fail to generate the new commitment_signed message, but that's @@ -1971,7 +1992,7 @@ 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(), self.channel_monitor.clone())); + return Ok((None, Vec::new(), Vec::new(), None, self.channel_monitor.clone())); } match self.free_holding_cell_htlcs()? { @@ -1984,7 +2005,7 @@ impl Channel { for fail_msg in update_fail_malformed_htlcs.drain(..) { commitment_update.0.update_fail_malformed_htlcs.push(fail_msg); } - Ok((Some(commitment_update.0), to_forward_infos, revoked_htlcs, commitment_update.1)) + Ok((Some(commitment_update.0), to_forward_infos, revoked_htlcs, None, commitment_update.1)) }, None => { if require_commitment { @@ -1996,9 +2017,9 @@ impl Channel { update_fail_malformed_htlcs, update_fee: None, commitment_signed - }), to_forward_infos, revoked_htlcs, monitor_update)) + }), to_forward_infos, revoked_htlcs, None, monitor_update)) } else { - Ok((None, to_forward_infos, revoked_htlcs, self.channel_monitor.clone())) + Ok((None, to_forward_infos, revoked_htlcs, self.maybe_propose_first_closing_signed(fee_estimator), self.channel_monitor.clone())) } } } @@ -2057,6 +2078,9 @@ impl Channel { self.channel_state = ChannelState::ShutdownComplete as u32; return outbound_drops; } + // Upon reconnect we have to start the closing_signed dance over, but shutdown messages + // will be retransmitted. + self.last_sent_closing_fee = None; let mut inbound_drop_count = 0; self.pending_inbound_htlcs.retain(|htlc| { @@ -2244,7 +2268,7 @@ impl Channel { /// May panic if some calls other than message-handling calls (which will all Err immediately) /// have been called between remove_uncommitted_htlcs_and_mark_paused and this call. - pub fn channel_reestablish(&mut self, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option, Option, RAACommitmentOrder), ChannelError> { + pub fn channel_reestablish(&mut self, msg: &msgs::ChannelReestablish) -> Result<(Option, Option, Option, Option, RAACommitmentOrder, Option), ChannelError> { if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 { // While BOLT 2 doesn't indicate explicitly we should error this channel here, it // almost certainly indicates we are going to end up out-of-sync in some way, so we @@ -2260,9 +2284,16 @@ impl Channel { // remaining cases either succeed or ErrorMessage-fail). self.channel_state &= !(ChannelState::PeerDisconnected as u32); + let shutdown_msg = if self.channel_state & (ChannelState::LocalShutdownSent as u32) != 0 { + Some(msgs::Shutdown { + channel_id: self.channel_id, + scriptpubkey: self.get_closing_scriptpubkey(), + }) + } else { None }; + if self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) == ChannelState::FundingSent as u32 { // Short circuit the whole handler as there is nothing we can resend them - return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst)); + return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg)); } if msg.next_local_commitment_number == 0 || msg.next_remote_commitment_number == 0 { @@ -2275,7 +2306,7 @@ impl Channel { return Ok((Some(msgs::FundingLocked { channel_id: self.channel_id(), next_per_commitment_point: next_per_commitment_point, - }), None, None, None, RAACommitmentOrder::CommitmentFirst)); + }), None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg)); } let required_revoke = if msg.next_remote_commitment_number == INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number { @@ -2338,11 +2369,11 @@ impl Channel { panic!("Got non-channel-failing result from free_holding_cell_htlcs"); } }, - Ok(Some((commitment_update, channel_monitor))) => return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(channel_monitor), order)), - Ok(None) => return Ok((resend_funding_locked, required_revoke, None, None, order)), + Ok(Some((commitment_update, channel_monitor))) => return Ok((resend_funding_locked, required_revoke, Some(commitment_update), Some(channel_monitor), order, shutdown_msg)), + Ok(None) => return Ok((resend_funding_locked, required_revoke, None, None, order, shutdown_msg)), } } else { - return Ok((resend_funding_locked, required_revoke, None, None, order)); + return Ok((resend_funding_locked, required_revoke, None, None, order, shutdown_msg)); } } else if msg.next_local_commitment_number == our_next_remote_commitment_number - 1 { if required_revoke.is_some() { @@ -2356,71 +2387,78 @@ impl Channel { if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 { self.monitor_pending_commitment_signed = true; - return Ok((resend_funding_locked, None, None, None, order)); + return Ok((resend_funding_locked, None, None, None, order, shutdown_msg)); } - return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update()), None, order)); + return Ok((resend_funding_locked, required_revoke, Some(self.get_last_commitment_update()), None, order, shutdown_msg)); } else { return Err(ChannelError::Close("Peer attempted to reestablish channel with a very old remote commitment transaction")); } } - pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option, Option, Vec<(HTLCSource, [u8; 32])>), HandleError> { + fn maybe_propose_first_closing_signed(&mut self, fee_estimator: &FeeEstimator) -> Option { + if !self.channel_outbound || !self.pending_inbound_htlcs.is_empty() || !self.pending_outbound_htlcs.is_empty() || + self.channel_state & (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::AwaitingRemoteRevoke as u32) != BOTH_SIDES_SHUTDOWN_MASK || + self.last_sent_closing_fee.is_some() || + self.cur_remote_commitment_transaction_number != self.cur_local_commitment_transaction_number{ + return None; + } + + let mut proposed_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background); + if self.feerate_per_kw > proposed_feerate { + proposed_feerate = self.feerate_per_kw; + } + let tx_weight = Self::get_closing_transaction_weight(&self.get_closing_scriptpubkey(), self.their_shutdown_scriptpubkey.as_ref().unwrap()); + let proposed_total_fee_satoshis = proposed_feerate * tx_weight / 1000; + + let (closing_tx, total_fee_satoshis) = self.build_closing_transaction(proposed_total_fee_satoshis, false); + let funding_redeemscript = self.get_funding_redeemscript(); + let sighash = Message::from_slice(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]).unwrap(); + + self.last_sent_closing_fee = Some((proposed_feerate, total_fee_satoshis)); + Some(msgs::ClosingSigned { + channel_id: self.channel_id, + fee_satoshis: total_fee_satoshis, + signature: self.secp_ctx.sign(&sighash, &self.local_keys.funding_key), + }) + } + + pub fn shutdown(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::Shutdown) -> Result<(Option, Option, Vec<(HTLCSource, [u8; 32])>), ChannelError> { if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 { - return Err(HandleError{err: "Peer sent shutdown when we needed a channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent shutdown when we needed a channel_reestablish".to_string(), channel_id: msg.channel_id}})}); + return Err(ChannelError::Close("Peer sent shutdown when we needed a channel_reestablish")); } if self.channel_state < ChannelState::FundingSent as u32 { - self.channel_state = ChannelState::ShutdownComplete as u32; - self.channel_update_count += 1; - return Ok((None, None, Vec::new())); + // Spec says we should fail the connection, not the channel, but that's nonsense, there + // are plenty of reasons you may want to fail a channel pre-funding, and spec says you + // can do that via error message without getting a connection fail anyway... + return Err(ChannelError::Close("Peer sent shutdown pre-funding generation")); } for htlc in self.pending_inbound_htlcs.iter() { if let InboundHTLCState::RemoteAnnounced(_) = htlc.state { - return Err(HandleError{err: "Got shutdown with remote pending HTLCs", action: None}); + return Err(ChannelError::Close("Got shutdown with remote pending HTLCs")); } } - if (self.channel_state & ChannelState::RemoteShutdownSent as u32) == ChannelState::RemoteShutdownSent as u32 { - return Err(HandleError{err: "Remote peer sent duplicate shutdown message", action: None}); - } assert_eq!(self.channel_state & ChannelState::ShutdownComplete as u32, 0); // BOLT 2 says we must only send a scriptpubkey of certain standard forms, which are up to // 34 bytes in length, so dont let the remote peer feed us some super fee-heavy script. if self.channel_outbound && msg.scriptpubkey.len() > 34 { - return Err(HandleError{err: "Got shutdown_scriptpubkey of absurd length from remote peer", action: None}); + return Err(ChannelError::Close("Got shutdown_scriptpubkey of absurd length from remote peer")); } //Check shutdown_scriptpubkey form as BOLT says we must - if !(msg.scriptpubkey.is_p2pkh()) && !(msg.scriptpubkey.is_p2sh()) - && !(msg.scriptpubkey.is_v0_p2wpkh()) && !(msg.scriptpubkey.is_v0_p2wsh()){ - return Err(HandleError{err: "Got an invalid scriptpubkey from remote peer", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })}); + if !msg.scriptpubkey.is_p2pkh() && !msg.scriptpubkey.is_p2sh() && !msg.scriptpubkey.is_v0_p2wpkh() && !msg.scriptpubkey.is_v0_p2wsh() { + return Err(ChannelError::Close("Got a nonstandard scriptpubkey from remote peer")); } if self.their_shutdown_scriptpubkey.is_some() { if Some(&msg.scriptpubkey) != self.their_shutdown_scriptpubkey.as_ref() { - return Err(HandleError{err: "Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey", action: None}); + return Err(ChannelError::Close("Got shutdown request with a scriptpubkey which did not match their previous scriptpubkey")); } } else { self.their_shutdown_scriptpubkey = Some(msg.scriptpubkey.clone()); } - let our_closing_script = self.get_closing_scriptpubkey(); - - let (proposed_feerate, proposed_fee, our_sig) = if self.channel_outbound && self.pending_inbound_htlcs.is_empty() && self.pending_outbound_htlcs.is_empty() { - let mut proposed_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background); - if self.feerate_per_kw > proposed_feerate { - proposed_feerate = self.feerate_per_kw; - } - let tx_weight = Self::get_closing_transaction_weight(&our_closing_script, &msg.scriptpubkey); - let proposed_total_fee_satoshis = proposed_feerate * tx_weight / 1000; - - let (closing_tx, total_fee_satoshis) = self.build_closing_transaction(proposed_total_fee_satoshis, false); - let funding_redeemscript = self.get_funding_redeemscript(); - let sighash = Message::from_slice(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]).unwrap(); - - (Some(proposed_feerate), Some(total_fee_satoshis), Some(self.secp_ctx.sign(&sighash, &self.local_keys.funding_key))) - } else { (None, None, None) }; - // From here on out, we may not fail! self.channel_state |= ChannelState::RemoteShutdownSent as u32; @@ -2429,6 +2467,7 @@ impl Channel { // We can't send our shutdown until we've committed all of our pending HTLCs, but the // remote side is unlikely to accept any new HTLCs, so we go ahead and "free" any holding // cell HTLCs and return them to fail the payment. + self.holding_cell_update_fee = None; let mut dropped_outbound_htlcs = Vec::with_capacity(self.holding_cell_htlc_updates.len()); self.holding_cell_htlc_updates.retain(|htlc_update| { match htlc_update { @@ -2439,35 +2478,22 @@ impl Channel { _ => true } }); - for htlc in self.pending_outbound_htlcs.iter() { - if let OutboundHTLCState::LocalAnnounced(_) = htlc.state { - return Ok((None, None, dropped_outbound_htlcs)); - } - } + // If we have any LocalAnnounced updates we'll probably just get back a update_fail_htlc + // immediately after the commitment dance, but we can send a Shutdown cause we won't send + // any further commitment updates after we set LocalShutdownSent. let our_shutdown = if (self.channel_state & ChannelState::LocalShutdownSent as u32) == ChannelState::LocalShutdownSent as u32 { None } else { Some(msgs::Shutdown { channel_id: self.channel_id, - scriptpubkey: our_closing_script, + scriptpubkey: self.get_closing_scriptpubkey(), }) }; self.channel_state |= ChannelState::LocalShutdownSent as u32; self.channel_update_count += 1; - if self.pending_inbound_htlcs.is_empty() && self.pending_outbound_htlcs.is_empty() && self.channel_outbound { - // There are no more HTLCs and we're the funder, this means we start the closing_signed - // dance with an initial fee proposal! - self.last_sent_closing_fee = Some((proposed_feerate.unwrap(), proposed_fee.unwrap())); - Ok((our_shutdown, Some(msgs::ClosingSigned { - channel_id: self.channel_id, - fee_satoshis: proposed_fee.unwrap(), - signature: our_sig.unwrap(), - }), dropped_outbound_htlcs)) - } else { - Ok((our_shutdown, None, dropped_outbound_htlcs)) - } + Ok((our_shutdown, self.maybe_propose_first_closing_signed(fee_estimator), dropped_outbound_htlcs)) } pub fn closing_signed(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::ClosingSigned) -> Result<(Option, Option), HandleError> { @@ -3250,9 +3276,9 @@ impl Channel { } self.channel_update_count += 1; - // We can't send our shutdown until we've committed all of our pending HTLCs, but the - // remote side is unlikely to accept any new HTLCs, so we go ahead and "free" any holding - // cell HTLCs and return them to fail the payment. + // Go ahead and drop holding cell updates as we'd rather fail payments than wait to send + // our shutdown until we've committed all of the pending changes. + self.holding_cell_update_fee = None; let mut dropped_outbound_htlcs = Vec::with_capacity(self.holding_cell_htlc_updates.len()); self.holding_cell_htlc_updates.retain(|htlc_update| { match htlc_update { @@ -3492,9 +3518,9 @@ impl Writeable for Channel { (self.last_local_commitment_txn.len() as u64).write(writer)?; for tx in self.last_local_commitment_txn.iter() { - if let Err(e) = tx.consensus_encode(&mut RawEncoder::new(WriterWriteAdaptor(writer))) { + if let Err(e) = tx.consensus_encode(&mut WriterWriteAdaptor(writer)) { match e { - network::serialize::Error::Io(e) => return Err(e), + encode::Error::Io(e) => return Err(e), _ => panic!("last_local_commitment_txn must have been well-formed!"), } } @@ -3671,7 +3697,7 @@ impl ReadableArgs> for Channel { let last_local_commitment_txn_count: u64 = Readable::read(reader)?; let mut last_local_commitment_txn = Vec::with_capacity(cmp::min(last_local_commitment_txn_count as usize, OUR_MAX_HTLCS as usize*2 + 1)); for _ in 0..last_local_commitment_txn_count { - last_local_commitment_txn.push(match Transaction::consensus_decode(&mut RawDecoder::new(reader.by_ref())) { + last_local_commitment_txn.push(match Transaction::consensus_decode(reader.by_ref()) { Ok(tx) => tx, Err(_) => return Err(DecodeError::InvalidValue), }); @@ -3799,7 +3825,7 @@ impl ReadableArgs> for Channel { mod tests { use bitcoin::util::hash::{Sha256dHash, Hash160}; use bitcoin::util::bip143; - use bitcoin::network::serialize::serialize; + use bitcoin::consensus::encode::serialize; use bitcoin::blockdata::script::{Script, Builder}; use bitcoin::blockdata::transaction::Transaction; use bitcoin::blockdata::opcodes; @@ -3921,7 +3947,7 @@ mod tests { chan.sign_commitment_transaction(&mut unsigned_tx.0, &their_signature); - assert_eq!(serialize(&unsigned_tx.0).unwrap()[..], + assert_eq!(serialize(&unsigned_tx.0)[..], hex::decode($tx_hex).unwrap()[..]); }; } @@ -3954,7 +3980,7 @@ mod tests { } chan.sign_htlc_transaction(&mut htlc_tx, &remote_signature, &preimage, &htlc, &keys).unwrap(); - assert_eq!(serialize(&htlc_tx).unwrap()[..], + assert_eq!(serialize(&htlc_tx)[..], hex::decode($tx_hex).unwrap()[..]); }; }