Skip to content

Commit e1fd19d

Browse files
committed
Handle receiving channel_reestablish with next_funding_txid
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
1 parent 5692231 commit e1fd19d

File tree

3 files changed

+76
-8
lines changed

3 files changed

+76
-8
lines changed

lightning/src/ln/channel.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,8 @@ pub(super) struct ReestablishResponses {
925925
pub order: RAACommitmentOrder,
926926
pub announcement_sigs: Option<msgs::AnnouncementSignatures>,
927927
pub shutdown_msg: Option<msgs::Shutdown>,
928+
pub tx_signatures: Option<msgs::TxSignatures>,
929+
pub tx_abort: Option<msgs::TxAbort>,
928930
}
929931

930932
/// The result of a shutdown that should be handled.
@@ -6388,6 +6390,8 @@ impl<SP: Deref> Channel<SP> where
63886390
raa: None, commitment_update: None,
63896391
order: RAACommitmentOrder::CommitmentFirst,
63906392
shutdown_msg, announcement_sigs,
6393+
tx_signatures: None,
6394+
tx_abort: None,
63916395
});
63926396
}
63936397

@@ -6397,6 +6401,8 @@ impl<SP: Deref> Channel<SP> where
63976401
raa: None, commitment_update: None,
63986402
order: RAACommitmentOrder::CommitmentFirst,
63996403
shutdown_msg, announcement_sigs,
6404+
tx_signatures: None,
6405+
tx_abort: None,
64006406
});
64016407
}
64026408

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

6438-
if msg.next_local_commitment_number == next_counterparty_commitment_number {
6444+
// if next_funding_txid is set:
6445+
if let Some(next_funding_txid) = msg.next_funding_txid {
6446+
let (commitment_update, tx_signatures, tx_abort) = if let Some(session) = &self.interactive_tx_signing_session {
6447+
// if next_funding_txid matches the latest interactive funding transaction:
6448+
if session.unsigned_tx.compute_txid() == next_funding_txid {
6449+
// if it has not received tx_signatures for that funding transaction:
6450+
if !session.counterparty_sent_tx_signatures {
6451+
// MUST retransmit its commitment_signed for that funding transaction.
6452+
let commitment_signed = self.context.get_initial_commitment_signed(logger)?;
6453+
let commitment_update = Some(msgs::CommitmentUpdate {
6454+
commitment_signed,
6455+
update_add_htlcs: vec![],
6456+
update_fulfill_htlcs: vec![],
6457+
update_fail_htlcs: vec![],
6458+
update_fail_malformed_htlcs: vec![],
6459+
update_fee: None,
6460+
});
6461+
// if it has already received commitment_signed and it should sign first, as specified in the tx_signatures requirements:
6462+
if session.received_commitment_signed && session.holder_sends_tx_signatures_first {
6463+
// MUST send its tx_signatures for that funding transaction.
6464+
(commitment_update, session.holder_tx_signatures.clone(), None)
6465+
} else {
6466+
(commitment_update, None, None)
6467+
}
6468+
} else {
6469+
// if it has already received tx_signatures for that funding transaction:
6470+
// MUST send its tx_signatures for that funding transaction.
6471+
(None, session.holder_tx_signatures.clone(), None)
6472+
}
6473+
} else {
6474+
// MUST send tx_abort to let the sending node know that they can forget this funding transaction.
6475+
(None, None, Some(msgs::TxAbort { channel_id: self.context.channel_id(), data: vec![] }))
6476+
}
6477+
} else {
6478+
// Counterparty set `next_funding_txid` at incorrect state.
6479+
// TODO(dual_funding): Should probably error here (or send tx_abort) but not in spec.
6480+
(None, None, None)
6481+
};
6482+
Ok(ReestablishResponses {
6483+
channel_ready,
6484+
commitment_update,
6485+
announcement_sigs,
6486+
shutdown_msg,
6487+
tx_signatures,
6488+
tx_abort,
6489+
raa: None,
6490+
order: self.context.resend_order.clone(),
6491+
})
6492+
} else if msg.next_local_commitment_number == next_counterparty_commitment_number {
64396493
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
64406494
log_debug!(logger, "Reconnected channel {} with only lost outbound RAA", &self.context.channel_id());
64416495
} else {
@@ -6447,6 +6501,8 @@ impl<SP: Deref> Channel<SP> where
64476501
raa: required_revoke,
64486502
commitment_update: None,
64496503
order: self.context.resend_order.clone(),
6504+
tx_signatures: None,
6505+
tx_abort: None,
64506506
})
64516507
} else if msg.next_local_commitment_number == next_counterparty_commitment_number - 1 {
64526508
if required_revoke.is_some() || self.context.signer_pending_revoke_and_ack {
@@ -6461,6 +6517,8 @@ impl<SP: Deref> Channel<SP> where
64616517
channel_ready, shutdown_msg, announcement_sigs,
64626518
commitment_update: None, raa: None,
64636519
order: self.context.resend_order.clone(),
6520+
tx_signatures: None,
6521+
tx_abort: None,
64646522
})
64656523
} else {
64666524
let commitment_update = if self.context.resend_order == RAACommitmentOrder::RevokeAndACKFirst
@@ -6483,6 +6541,8 @@ impl<SP: Deref> Channel<SP> where
64836541
channel_ready, shutdown_msg, announcement_sigs,
64846542
raa, commitment_update,
64856543
order: self.context.resend_order.clone(),
6544+
tx_signatures: None,
6545+
tx_abort: None,
64866546
})
64876547
}
64886548
} else if msg.next_local_commitment_number < next_counterparty_commitment_number {

lightning/src/ln/channelmanager.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,7 +3169,7 @@ macro_rules! handle_monitor_update_completion {
31693169
&mut $peer_state.pending_msg_events, $chan, updates.raa,
31703170
updates.commitment_update, updates.order, updates.accepted_htlcs, updates.pending_update_adds,
31713171
updates.funding_broadcastable, updates.channel_ready,
3172-
updates.announcement_sigs, updates.tx_signatures);
3172+
updates.announcement_sigs, updates.tx_signatures, None);
31733173
if let Some(upd) = channel_update {
31743174
$peer_state.pending_msg_events.push(upd);
31753175
}
@@ -7403,10 +7403,10 @@ where
74037403
pending_forwards: Vec<(PendingHTLCInfo, u64)>, pending_update_adds: Vec<msgs::UpdateAddHTLC>,
74047404
funding_broadcastable: Option<Transaction>,
74057405
channel_ready: Option<msgs::ChannelReady>, announcement_sigs: Option<msgs::AnnouncementSignatures>,
7406-
tx_signatures: Option<msgs::TxSignatures>
7406+
tx_signatures: Option<msgs::TxSignatures>, tx_abort: Option<msgs::TxAbort>,
74077407
) -> (Option<(u64, Option<PublicKey>, OutPoint, ChannelId, u128, Vec<(PendingHTLCInfo, u64)>)>, Option<(u64, Vec<msgs::UpdateAddHTLC>)>) {
74087408
let logger = WithChannelContext::from(&self.logger, &channel.context, None);
7409-
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",
7409+
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",
74107410
&channel.context.channel_id(),
74117411
if raa.is_some() { "an" } else { "no" },
74127412
if commitment_update.is_some() { "a" } else { "no" },
@@ -7415,6 +7415,7 @@ where
74157415
if channel_ready.is_some() { "sending" } else { "without" },
74167416
if announcement_sigs.is_some() { "sending" } else { "without" },
74177417
if tx_signatures.is_some() { "sending" } else { "without" },
7418+
if tx_abort.is_some() { "sending" } else { "without" },
74187419
);
74197420

74207421
let counterparty_node_id = channel.context.get_counterparty_node_id();
@@ -7448,6 +7449,12 @@ where
74487449
msg,
74497450
});
74507451
}
7452+
if let Some(msg) = tx_abort {
7453+
pending_msg_events.push(events::MessageSendEvent::SendTxAbort {
7454+
node_id: counterparty_node_id,
7455+
msg,
7456+
});
7457+
}
74517458

74527459
macro_rules! handle_cs { () => {
74537460
if let Some(update) = commitment_update {
@@ -9246,7 +9253,8 @@ where
92469253
let need_lnd_workaround = chan.context.workaround_lnd_bug_4006.take();
92479254
let (htlc_forwards, decode_update_add_htlcs) = self.handle_channel_resumption(
92489255
&mut peer_state.pending_msg_events, chan, responses.raa, responses.commitment_update, responses.order,
9249-
Vec::new(), Vec::new(), None, responses.channel_ready, responses.announcement_sigs, None);
9256+
Vec::new(), Vec::new(), None, responses.channel_ready, responses.announcement_sigs,
9257+
responses.tx_signatures, responses.tx_abort);
92509258
debug_assert!(htlc_forwards.is_none());
92519259
debug_assert!(decode_update_add_htlcs.is_none());
92529260
if let Some(upd) = channel_update {

lightning/src/ln/interactivetxs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,9 @@ impl ConstructedTransaction {
291291
pub(crate) struct InteractiveTxSigningSession {
292292
pub unsigned_tx: ConstructedTransaction,
293293
pub counterparty_sent_tx_signatures: bool,
294-
holder_sends_tx_signatures_first: bool,
295-
received_commitment_signed: bool,
296-
holder_tx_signatures: Option<TxSignatures>,
294+
pub holder_sends_tx_signatures_first: bool,
295+
pub received_commitment_signed: bool,
296+
pub holder_tx_signatures: Option<TxSignatures>,
297297
}
298298

299299
impl InteractiveTxSigningSession {

0 commit comments

Comments
 (0)