]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Allow sending RAA upon unblocking the signer
authorAlec Chen <alecchendev@gmail.com>
Sun, 30 Jun 2024 20:54:20 +0000 (13:54 -0700)
committerAlec Chen <alecchendev@gmail.com>
Wed, 3 Jul 2024 02:11:44 +0000 (19:11 -0700)
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs

index 4d166cd60f5c84ed6312592b3e59d5783d501914..8d83bf46025abb253b1f93d3bb69c4f7bb690542 100644 (file)
@@ -906,8 +906,10 @@ pub(super) struct MonitorRestoreUpdates {
 #[allow(unused)]
 pub(super) struct SignerResumeUpdates {
        pub commitment_update: Option<msgs::CommitmentUpdate>,
+       pub revoke_and_ack: Option<msgs::RevokeAndACK>,
        pub funding_signed: Option<msgs::FundingSigned>,
        pub channel_ready: Option<msgs::ChannelReady>,
+       pub order: RAACommitmentOrder,
 }
 
 /// The return value of `channel_reestablish`
@@ -1215,6 +1217,14 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
        monitor_pending_finalized_fulfills: Vec<HTLCSource>,
        monitor_pending_update_adds: Vec<msgs::UpdateAddHTLC>,
 
+       /// 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<SP: Deref> ChannelContext<SP> 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<SP: Deref> ChannelContext<SP> 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<SP: Deref> Channel<SP> where
        /// blocked.
        #[cfg(async_signing)]
        pub fn signer_maybe_unblocked<L: Deref>(&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<SP: Deref> Channel<SP> 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,
 
index d3550d10b50b0cc7cdb86f2d6d46fc074b9c5300..622cd10e6bc0bb1df649f6e23bbf21cb3d219cb1 100644 (file)
@@ -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 {