- // Normally only the latest commitment tx and HTLCs need to be signed. However, in some
- // configurations we may have updated our holder commitment but a replica of the ChannelMonitor
- // broadcast the previous one before we sync with it. We handle that case here.
- fn sign_prev_holder_htlcs(&mut self) {
- if self.prev_holder_htlc_sigs.is_none() {
- if let Some(ref holder_commitment) = self.prev_holder_commitment {
- let (_sig, sigs) = self.signer.sign_holder_commitment_and_htlcs(holder_commitment, &self.secp_ctx).expect("sign previous holder commitment");
- self.prev_holder_htlc_sigs = Some(Self::extract_holder_sigs(holder_commitment, sigs));
- }
- }
- }
-
- fn extract_holder_sigs(holder_commitment: &HolderCommitmentTransaction, sigs: Vec<Signature>) -> Vec<Option<(usize, Signature)>> {
- let mut ret = Vec::new();
- for (htlc_idx, (holder_sig, htlc)) in sigs.iter().zip(holder_commitment.htlcs().iter()).enumerate() {
- let tx_idx = htlc.transaction_output_index.unwrap();
- if ret.len() <= tx_idx as usize { ret.resize(tx_idx as usize + 1, None); }
- ret[tx_idx as usize] = Some((htlc_idx, holder_sig.clone()));
- }
- ret
- }
-
- //TODO: getting lastest holder transactions should be infallible and result in us "force-closing the channel", but we may
- // have empty holder commitment transaction if a ChannelMonitor is asked to force-close just after Channel::get_outbound_funding_created,
- // before providing a initial commitment transaction. For outbound channel, init ChannelMonitor at Channel::funding_signed, there is nothing
- // to monitor before.
- pub(crate) fn get_fully_signed_holder_tx(&mut self, funding_redeemscript: &Script) -> Transaction {
- let (sig, htlc_sigs) = self.signer.sign_holder_commitment_and_htlcs(&self.holder_commitment, &self.secp_ctx).expect("signing holder commitment");
- self.holder_htlc_sigs = Some(Self::extract_holder_sigs(&self.holder_commitment, htlc_sigs));
- self.holder_commitment.add_holder_sig(funding_redeemscript, sig)
+ pub(crate) fn get_maybe_signed_holder_tx(&mut self, funding_redeemscript: &Script) -> MaybeSignedTransaction {
+ let tx = self.signer.sign_holder_commitment(&self.holder_commitment, &self.secp_ctx)
+ .map(|sig| self.holder_commitment.add_holder_sig(funding_redeemscript, sig))
+ .unwrap_or_else(|_| self.get_unsigned_holder_commitment_tx().clone());
+ MaybeSignedTransaction(tx)