X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=134be90ea1986fec44c291d1523caeb39894f652;hb=8d01309555097d361bc0f9b03e99e4f9b7a73d90;hp=332cd2a24b3b6ca25c8b2a1ca9e5485037169013;hpb=0e3f6b60297101d0a9d451bddf84197d69df6dda;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 332cd2a2..134be90e 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -533,6 +533,15 @@ pub(super) struct MonitorRestoreUpdates { pub announcement_sigs: Option, } +/// The return value of `signer_maybe_unblocked` +#[allow(unused)] +pub(super) struct SignerResumeUpdates { + pub commitment_update: Option, + pub funding_signed: Option, + pub funding_created: Option, + pub channel_ready: Option, +} + /// The return value of `channel_reestablish` pub(super) struct ReestablishResponses { pub channel_ready: Option, @@ -2091,6 +2100,35 @@ impl ChannelContext where SP::Target: SignerProvider { unbroadcasted_batch_funding_txid, } } + + /// Only allowed after [`Self::channel_transaction_parameters`] is set. + fn get_funding_created_msg(&mut self, logger: &L) -> Option where L::Target: Logger { + let counterparty_keys = self.build_remote_transaction_keys(); + let counterparty_initial_commitment_tx = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx; + let signature = match &self.holder_signer { + // TODO (taproot|arik): move match into calling method for Taproot + ChannelSignerType::Ecdsa(ecdsa) => { + ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx) + .map(|(sig, _)| sig).ok()? + } + }; + + if self.signer_pending_funding { + log_trace!(logger, "Counterparty commitment signature ready for funding_created message: clearing signer_pending_funding"); + self.signer_pending_funding = false; + } + + Some(msgs::FundingCreated { + temporary_channel_id: self.temporary_channel_id.unwrap(), + funding_txid: self.channel_transaction_parameters.funding_outpoint.as_ref().unwrap().txid, + funding_output_index: self.channel_transaction_parameters.funding_outpoint.as_ref().unwrap().index, + signature, + #[cfg(taproot)] + partial_signature_with_nonce: None, + #[cfg(taproot)] + next_local_nonce: None, + }) + } } // Internal utility functions for channels @@ -3912,6 +3950,33 @@ impl Channel where Ok(()) } + /// Indicates that the signer may have some signatures for us, so we should retry if we're + /// blocked. + #[allow(unused)] + pub fn signer_maybe_unblocked(&mut self, logger: &L) -> SignerResumeUpdates where L::Target: Logger { + let commitment_update = if self.context.signer_pending_commitment_update { + self.get_last_commitment_update_for_send(logger).ok() + } else { None }; + let funding_signed = None; + let channel_ready = None; + let funding_created = if self.context.signer_pending_funding && self.context.is_outbound() { + self.context.get_funding_created_msg(logger) + } else { None }; + + log_trace!(logger, "Signer unblocked with {} commitment_update, {} funding_signed, {} funding_created, and {} channel_ready", + if commitment_update.is_some() { "a" } else { "no" }, + if funding_signed.is_some() { "a" } else { "no" }, + if funding_created.is_some() { "a" } else { "no" }, + if channel_ready.is_some() { "a" } else { "no" }); + + SignerResumeUpdates { + commitment_update, + funding_signed, + funding_created, + channel_ready, + } + } + fn get_last_revoke_and_ack(&self) -> msgs::RevokeAndACK { let next_per_commitment_point = self.context.holder_signer.as_ref().get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx); let per_commitment_secret = self.context.holder_signer.as_ref().release_commitment_secret(self.context.cur_holder_commitment_transaction_number + 2); @@ -5966,18 +6031,6 @@ impl OutboundV1Channel where SP::Target: SignerProvider { }) } - fn get_funding_created_signature(&mut self, logger: &L) -> Result where L::Target: Logger { - let counterparty_keys = self.context.build_remote_transaction_keys(); - let counterparty_initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx; - match &self.context.holder_signer { - // TODO (taproot|arik): move match into calling method for Taproot - ChannelSignerType::Ecdsa(ecdsa) => { - ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.context.secp_ctx) - .map(|(sig, _)| sig) - } - } - } - /// Updates channel state with knowledge of the funding transaction's txid/index, and generates /// a funding_created message for the remote peer. /// Panics if called at some time other than immediately after initial handshake, if called twice, @@ -6002,8 +6055,6 @@ impl OutboundV1Channel where SP::Target: SignerProvider { self.context.channel_transaction_parameters.funding_outpoint = Some(funding_txo); self.context.holder_signer.as_mut().provide_channel_parameters(&self.context.channel_transaction_parameters); - let temporary_channel_id = self.context.channel_id; - // Now that we're past error-generating stuff, update our local state: self.context.channel_state = ChannelState::FundingCreated as u32; @@ -6020,21 +6071,13 @@ impl OutboundV1Channel where SP::Target: SignerProvider { self.context.funding_transaction = Some(funding_transaction); self.context.is_batch_funding = Some(()).filter(|_| is_batch_funding); - let funding_created = if let Ok(signature) = self.get_funding_created_signature(logger) { - Some(msgs::FundingCreated { - temporary_channel_id, - funding_txid: funding_txo.txid, - funding_output_index: funding_txo.index, - signature, - #[cfg(taproot)] - partial_signature_with_nonce: None, - #[cfg(taproot)] - next_local_nonce: None, - }) - } else { - self.context.signer_pending_funding = true; - None - }; + let funding_created = self.context.get_funding_created_msg(logger); + if funding_created.is_none() { + if !self.context.signer_pending_funding { + log_trace!(logger, "funding_created awaiting signer; setting signer_pending_funding"); + self.context.signer_pending_funding = true; + } + } let channel = Channel { context: self.context,