#[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`
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.
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,
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,
/// 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 };
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,
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,
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 {