From 3775edd7eeed0893b7c91a6b0488be8012338af8 Mon Sep 17 00:00:00 2001 From: Alec Chen Date: Sun, 30 Jun 2024 13:54:20 -0700 Subject: [PATCH] Allow sending RAA upon unblocking the signer --- lightning/src/ln/channel.rs | 46 ++++++++++++++++++++++++++---- lightning/src/ln/channelmanager.rs | 25 ++++++++++++---- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 4d166cd60..8d83bf460 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -906,8 +906,10 @@ pub(super) struct MonitorRestoreUpdates { #[allow(unused)] pub(super) struct SignerResumeUpdates { pub commitment_update: Option, + pub revoke_and_ack: Option, pub funding_signed: Option, pub channel_ready: Option, + pub order: RAACommitmentOrder, } /// The return value of `channel_reestablish` @@ -1215,6 +1217,14 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { monitor_pending_finalized_fulfills: Vec, monitor_pending_update_adds: Vec, + /// If we went to send a revoke_and_ack but our signer was unable to give us a signature, + /// we should retry at some point in the future when the signer indicates it may have a + /// signature for us. + /// + /// This may also be used to make sure we send a `revoke_and_ack` after a `commitment_signed` + /// if we need to maintain ordering of messages, but are pending the signer on a previous + /// message. + signer_pending_revoke_and_ack: bool, /// If we went to send a commitment update (ie some messages then [`msgs::CommitmentSigned`]) /// but our signer (initially) refused to give us a signature, we should retry at some point in /// the future when the signer indicates it may have a signature for us. @@ -1683,6 +1693,7 @@ impl ChannelContext where SP::Target: SignerProvider { monitor_pending_finalized_fulfills: Vec::new(), monitor_pending_update_adds: Vec::new(), + signer_pending_revoke_and_ack: false, signer_pending_commitment_update: false, signer_pending_funding: false, @@ -1908,6 +1919,7 @@ impl ChannelContext where SP::Target: SignerProvider { monitor_pending_finalized_fulfills: Vec::new(), monitor_pending_update_adds: Vec::new(), + signer_pending_revoke_and_ack: false, signer_pending_commitment_update: false, signer_pending_funding: false, @@ -5376,9 +5388,6 @@ impl Channel where /// blocked. #[cfg(async_signing)] 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 = if self.context.signer_pending_funding && !self.context.is_outbound() { self.context.get_funding_signed_msg(logger).1 } else { None }; @@ -5386,24 +5395,50 @@ impl Channel where self.check_get_channel_ready(0, logger) } else { None }; - log_trace!(logger, "Signer unblocked with {} commitment_update, {} funding_signed and {} channel_ready", + let mut commitment_update = if self.context.signer_pending_commitment_update { + log_trace!(logger, "Attempting to generate pending commitment update..."); + self.get_last_commitment_update_for_send(logger).ok() + } else { None }; + let mut revoke_and_ack = if self.context.signer_pending_revoke_and_ack { + log_trace!(logger, "Attempting to generate pending revoke and ack..."); + Some(self.get_last_revoke_and_ack()) + } else { None }; + + if self.context.resend_order == RAACommitmentOrder::CommitmentFirst + && self.context.signer_pending_commitment_update && revoke_and_ack.is_some() { + log_trace!(logger, "Signer unblocked for revoke and ack, but unable to send due to resend order, waiting on signer for commitment update"); + self.context.signer_pending_revoke_and_ack = true; + revoke_and_ack = None; + } + if self.context.resend_order == RAACommitmentOrder::RevokeAndACKFirst + && self.context.signer_pending_revoke_and_ack && commitment_update.is_some() { + log_trace!(logger, "Signer unblocked for commitment update, but unable to send due to resend order, waiting on signer for revoke and ack"); + self.context.signer_pending_commitment_update = true; + commitment_update = None; + } + + log_trace!(logger, "Signer unblocked with {} commitment_update, {} revoke_and_ack, {} funding_signed and {} channel_ready", if commitment_update.is_some() { "a" } else { "no" }, + if revoke_and_ack.is_some() { "a" } else { "no" }, if funding_signed.is_some() { "a" } else { "no" }, if channel_ready.is_some() { "a" } else { "no" }); SignerResumeUpdates { commitment_update, + revoke_and_ack, funding_signed, channel_ready, + order: self.context.resend_order.clone(), } } - fn get_last_revoke_and_ack(&self) -> msgs::RevokeAndACK { + fn get_last_revoke_and_ack(&mut self) -> msgs::RevokeAndACK { debug_assert!(self.context.holder_commitment_point.transaction_number() <= INITIAL_COMMITMENT_NUMBER + 2); // TODO: handle non-available case when get_per_commitment_point becomes async debug_assert!(self.context.holder_commitment_point.is_available()); let next_per_commitment_point = self.context.holder_commitment_point.current_point(); let per_commitment_secret = self.context.holder_signer.as_ref().release_commitment_secret(self.context.holder_commitment_point.transaction_number() + 2); + self.context.signer_pending_revoke_and_ack = false; msgs::RevokeAndACK { channel_id: self.context.channel_id, per_commitment_secret, @@ -9279,6 +9314,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch monitor_pending_finalized_fulfills: monitor_pending_finalized_fulfills.unwrap(), monitor_pending_update_adds: monitor_pending_update_adds.unwrap_or(Vec::new()), + signer_pending_revoke_and_ack: false, signer_pending_commitment_update: false, signer_pending_funding: false, diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index d3550d10b..622cd10e6 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -8196,11 +8196,26 @@ where match phase { ChannelPhase::Funded(chan) => { let msgs = chan.signer_maybe_unblocked(&self.logger); - if let Some(updates) = msgs.commitment_update { - pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs { - node_id, - updates, - }); + let cu_msg = msgs.commitment_update.map(|updates| events::MessageSendEvent::UpdateHTLCs { + node_id, + updates, + }); + let raa_msg = msgs.revoke_and_ack.map(|msg| events::MessageSendEvent::SendRevokeAndACK { + node_id, + msg, + }); + match (cu_msg, raa_msg) { + (Some(cu), Some(raa)) if msgs.order == RAACommitmentOrder::CommitmentFirst => { + pending_msg_events.push(cu); + pending_msg_events.push(raa); + }, + (Some(cu), Some(raa)) if msgs.order == RAACommitmentOrder::RevokeAndACKFirst => { + pending_msg_events.push(raa); + pending_msg_events.push(cu); + }, + (Some(cu), _) => pending_msg_events.push(cu), + (_, Some(raa)) => pending_msg_events.push(raa), + (_, _) => {}, } if let Some(msg) = msgs.funding_signed { pending_msg_events.push(events::MessageSendEvent::SendFundingSigned { -- 2.39.5