Skip to content

Commit

Permalink
Handle receiving channel_reestablish with next_funding_txid
Browse files Browse the repository at this point in the history
This follows the the specification closely in branching without being
too verbose, so that it should be easy to follow the logic.

See: https://github.com/lightning/bolts/blob/aa5207a/02-peer-protocol.md?plain=1#L2520-L2531
  • Loading branch information
dunxen committed Nov 29, 2024
1 parent 5c0e9ed commit ccff641
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 8 deletions.
62 changes: 61 additions & 1 deletion lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,8 @@ pub(super) struct ReestablishResponses {
pub order: RAACommitmentOrder,
pub announcement_sigs: Option<msgs::AnnouncementSignatures>,
pub shutdown_msg: Option<msgs::Shutdown>,
pub tx_signatures: Option<msgs::TxSignatures>,
pub tx_abort: Option<msgs::TxAbort>,
}

/// The result of a shutdown that should be handled.
Expand Down Expand Up @@ -6388,6 +6390,8 @@ impl<SP: Deref> Channel<SP> where
raa: None, commitment_update: None,
order: RAACommitmentOrder::CommitmentFirst,
shutdown_msg, announcement_sigs,
tx_signatures: None,
tx_abort: None,
});
}

Expand All @@ -6397,6 +6401,8 @@ impl<SP: Deref> Channel<SP> where
raa: None, commitment_update: None,
order: RAACommitmentOrder::CommitmentFirst,
shutdown_msg, announcement_sigs,
tx_signatures: None,
tx_abort: None,
});
}

Expand Down Expand Up @@ -6435,7 +6441,55 @@ impl<SP: Deref> Channel<SP> where
Some(self.get_channel_ready())
} else { None };

if msg.next_local_commitment_number == next_counterparty_commitment_number {
// if next_funding_txid is set:
if let Some(next_funding_txid) = msg.next_funding_txid {
let (commitment_update, tx_signatures, tx_abort) = if let Some(session) = &self.interactive_tx_signing_session {
// if next_funding_txid matches the latest interactive funding transaction:
if session.unsigned_tx.compute_txid() == next_funding_txid {
// if it has not received tx_signatures for that funding transaction:
if !session.counterparty_sent_tx_signatures {
// MUST retransmit its commitment_signed for that funding transaction.
let commitment_signed = self.context.get_initial_commitment_signed(logger)?;
let commitment_update = Some(msgs::CommitmentUpdate {
commitment_signed,
update_add_htlcs: vec![],
update_fulfill_htlcs: vec![],
update_fail_htlcs: vec![],
update_fail_malformed_htlcs: vec![],
update_fee: None,
});
// if it has already received commitment_signed and it should sign first, as specified in the tx_signatures requirements:
if session.received_commitment_signed && session.holder_sends_tx_signatures_first {
// MUST send its tx_signatures for that funding transaction.
(commitment_update, session.holder_tx_signatures.clone(), None)
} else {
(commitment_update, None, None)
}
} else {
// if it has already received tx_signatures for that funding transaction:
// MUST send its tx_signatures for that funding transaction.
(None, session.holder_tx_signatures.clone(), None)
}
} else {
// MUST send tx_abort to let the sending node know that they can forget this funding transaction.
(None, None, Some(msgs::TxAbort { channel_id: self.context.channel_id(), data: vec![] }))
}
} else {
// Counterparty set `next_funding_txid` at incorrect state.
// TODO(dual_funding): Should probably error here (or send tx_abort) but not in spec.
(None, None, None)
};
Ok(ReestablishResponses {
channel_ready,
commitment_update,
announcement_sigs,
shutdown_msg,
tx_signatures,
tx_abort,
raa: None,
order: self.context.resend_order.clone(),
})
} else if msg.next_local_commitment_number == next_counterparty_commitment_number {
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
log_debug!(logger, "Reconnected channel {} with only lost outbound RAA", &self.context.channel_id());
} else {
Expand All @@ -6447,6 +6501,8 @@ impl<SP: Deref> Channel<SP> where
raa: required_revoke,
commitment_update: None,
order: self.context.resend_order.clone(),
tx_signatures: None,
tx_abort: None,
})
} else if msg.next_local_commitment_number == next_counterparty_commitment_number - 1 {
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
Expand All @@ -6461,6 +6517,8 @@ impl<SP: Deref> Channel<SP> where
channel_ready, shutdown_msg, announcement_sigs,
commitment_update: None, raa: None,
order: self.context.resend_order.clone(),
tx_signatures: None,
tx_abort: None,
})
} else {
let commitment_update = if self.context.resend_order == RAACommitmentOrder::RevokeAndACKFirst
Expand All @@ -6483,6 +6541,8 @@ impl<SP: Deref> Channel<SP> where
channel_ready, shutdown_msg, announcement_sigs,
raa, commitment_update,
order: self.context.resend_order.clone(),
tx_signatures: None,
tx_abort: None,
})
}
} else if msg.next_local_commitment_number < next_counterparty_commitment_number {
Expand Down
16 changes: 12 additions & 4 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3169,7 +3169,7 @@ macro_rules! handle_monitor_update_completion {
&mut $peer_state.pending_msg_events, $chan, updates.raa,
updates.commitment_update, updates.order, updates.accepted_htlcs, updates.pending_update_adds,
updates.funding_broadcastable, updates.channel_ready,
updates.announcement_sigs, updates.tx_signatures);
updates.announcement_sigs, updates.tx_signatures, None);
if let Some(upd) = channel_update {
$peer_state.pending_msg_events.push(upd);
}
Expand Down Expand Up @@ -7403,10 +7403,10 @@ where
pending_forwards: Vec<(PendingHTLCInfo, u64)>, pending_update_adds: Vec<msgs::UpdateAddHTLC>,
funding_broadcastable: Option<Transaction>,
channel_ready: Option<msgs::ChannelReady>, announcement_sigs: Option<msgs::AnnouncementSignatures>,
tx_signatures: Option<msgs::TxSignatures>
tx_signatures: Option<msgs::TxSignatures>, tx_abort: Option<msgs::TxAbort>,
) -> (Option<(u64, Option<PublicKey>, OutPoint, ChannelId, u128, Vec<(PendingHTLCInfo, u64)>)>, Option<(u64, Vec<msgs::UpdateAddHTLC>)>) {
let logger = WithChannelContext::from(&self.logger, &channel.context, None);
log_trace!(logger, "Handling channel resumption for channel {} with {} RAA, {} commitment update, {} pending forwards, {} pending update_add_htlcs, {}broadcasting funding, {} channel ready, {} announcement, {} tx_signatures",
log_trace!(logger, "Handling channel resumption for channel {} with {} RAA, {} commitment update, {} pending forwards, {} pending update_add_htlcs, {}broadcasting funding, {} channel ready, {} announcement, {} tx_signatures, {} tx_abort",
&channel.context.channel_id(),
if raa.is_some() { "an" } else { "no" },
if commitment_update.is_some() { "a" } else { "no" },
Expand All @@ -7415,6 +7415,7 @@ where
if channel_ready.is_some() { "sending" } else { "without" },
if announcement_sigs.is_some() { "sending" } else { "without" },
if tx_signatures.is_some() { "sending" } else { "without" },
if tx_abort.is_some() { "sending" } else { "without" },
);

let counterparty_node_id = channel.context.get_counterparty_node_id();
Expand Down Expand Up @@ -7448,6 +7449,12 @@ where
msg,
});
}
if let Some(msg) = tx_abort {
pending_msg_events.push(events::MessageSendEvent::SendTxAbort {
node_id: counterparty_node_id,
msg,
});
}

macro_rules! handle_cs { () => {
if let Some(update) = commitment_update {
Expand Down Expand Up @@ -9246,7 +9253,8 @@ where
let need_lnd_workaround = chan.context.workaround_lnd_bug_4006.take();
let (htlc_forwards, decode_update_add_htlcs) = self.handle_channel_resumption(
&mut peer_state.pending_msg_events, chan, responses.raa, responses.commitment_update, responses.order,
Vec::new(), Vec::new(), None, responses.channel_ready, responses.announcement_sigs, None);
Vec::new(), Vec::new(), None, responses.channel_ready, responses.announcement_sigs,
responses.tx_signatures, responses.tx_abort);
debug_assert!(htlc_forwards.is_none());
debug_assert!(decode_update_add_htlcs.is_none());
if let Some(upd) = channel_update {
Expand Down
6 changes: 3 additions & 3 deletions lightning/src/ln/interactivetxs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,9 @@ impl ConstructedTransaction {
pub(crate) struct InteractiveTxSigningSession {
pub unsigned_tx: ConstructedTransaction,
pub counterparty_sent_tx_signatures: bool,
holder_sends_tx_signatures_first: bool,
received_commitment_signed: bool,
holder_tx_signatures: Option<TxSignatures>,
pub holder_sends_tx_signatures_first: bool,
pub received_commitment_signed: bool,
pub holder_tx_signatures: Option<TxSignatures>,
}

impl InteractiveTxSigningSession {
Expand Down

0 comments on commit ccff641

Please sign in to comment.