Skip to content

Commit a889bac

Browse files
committed
Send 0conf splice_locked upon tx_signatures exchange
Splices negotiated with 0 confirmations require that we immediately lock it after exchanging `tx_signatures`.
1 parent 3a6eb74 commit a889bac

File tree

3 files changed

+197
-85
lines changed

3 files changed

+197
-85
lines changed

lightning/src/ln/channel.rs

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8636,16 +8636,38 @@ where
86368636
}
86378637
}
86388638

8639-
fn on_tx_signatures_exchange(&mut self, funding_tx: Transaction) {
8639+
fn on_tx_signatures_exchange<'a, L: Deref>(
8640+
&mut self, funding_tx: Transaction, best_block_height: u32,
8641+
logger: &WithChannelContext<'a, L>,
8642+
) -> Option<msgs::SpliceLocked>
8643+
where
8644+
L::Target: Logger,
8645+
{
86408646
debug_assert!(!self.context.channel_state.is_monitor_update_in_progress());
86418647
debug_assert!(!self.context.channel_state.is_awaiting_remote_revoke());
86428648

8649+
let mut splice_locked = None;
86438650
if let Some(pending_splice) = self.pending_splice.as_mut() {
86448651
if let Some(FundingNegotiation::AwaitingSignatures { mut funding }) =
86458652
pending_splice.funding_negotiation.take()
86468653
{
86478654
funding.funding_transaction = Some(funding_tx);
86488655
pending_splice.negotiated_candidates.push(funding);
8656+
splice_locked = pending_splice.check_get_splice_locked(
8657+
&self.context,
8658+
pending_splice.negotiated_candidates.len() - 1,
8659+
best_block_height,
8660+
);
8661+
if let Some(splice_txid) =
8662+
splice_locked.as_ref().map(|splice_locked| splice_locked.splice_txid)
8663+
{
8664+
log_info!(
8665+
logger,
8666+
"Sending 0conf splice_locked txid {} to our peer for channel {}",
8667+
splice_txid,
8668+
&self.context.channel_id
8669+
);
8670+
}
86498671
} else {
86508672
debug_assert!(false);
86518673
}
@@ -8655,11 +8677,20 @@ where
86558677
self.context.channel_state =
86568678
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
86578679
}
8680+
8681+
splice_locked
86588682
}
86598683

8660-
pub fn funding_transaction_signed(
8661-
&mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>,
8662-
) -> Result<(Option<msgs::TxSignatures>, Option<Transaction>), APIError> {
8684+
pub fn funding_transaction_signed<L: Deref>(
8685+
&mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>, best_block_height: u32,
8686+
logger: &L,
8687+
) -> Result<
8688+
(Option<msgs::TxSignatures>, Option<msgs::SpliceLocked>, Option<Transaction>),
8689+
APIError,
8690+
>
8691+
where
8692+
L::Target: Logger,
8693+
{
86638694
let signing_session =
86648695
if let Some(signing_session) = self.context.interactive_tx_signing_session.as_mut() {
86658696
if let Some(pending_splice) = self.pending_splice.as_ref() {
@@ -8674,17 +8705,17 @@ where
86748705
}
86758706

86768707
if signing_session.holder_tx_signatures().is_some() {
8677-
// Our `tx_signatures` either should've been the first time we processed them,
8678-
// or we're waiting for our counterparty to send theirs first.
8679-
return Ok((None, None));
8708+
// Our `tx_signatures` either should've been sent the first time we processed
8709+
// them, or we're waiting for our counterparty to send theirs first.
8710+
return Ok((None, None, None));
86808711
}
86818712

86828713
signing_session
86838714
} else {
86848715
if Some(funding_txid_signed) == self.funding.get_funding_txid() {
86858716
// We may be handling a duplicate call and the funding was already locked so we
86868717
// no longer have the signing session present.
8687-
return Ok((None, None));
8718+
return Ok((None, None, None));
86888719
}
86898720
let err =
86908721
format!("Channel {} not expecting funding signatures", self.context.channel_id);
@@ -8726,17 +8757,31 @@ where
87268757
.provide_holder_witnesses(tx_signatures, &self.context.secp_ctx)
87278758
.map_err(|err| APIError::APIMisuseError { err })?;
87288759

8729-
if let Some(funding_tx) = funding_tx_opt.clone() {
8730-
debug_assert!(tx_signatures_opt.is_some());
8731-
self.on_tx_signatures_exchange(funding_tx);
8760+
let logger = WithChannelContext::from(logger, &self.context, None);
8761+
if tx_signatures_opt.is_some() {
8762+
log_info!(
8763+
logger,
8764+
"Sending tx_signatures for interactive funding transaction {funding_txid_signed}"
8765+
);
87328766
}
87338767

8734-
Ok((tx_signatures_opt, funding_tx_opt))
8768+
let splice_locked_opt = funding_tx_opt.clone().and_then(|funding_tx| {
8769+
debug_assert!(tx_signatures_opt.is_some());
8770+
self.on_tx_signatures_exchange(funding_tx, best_block_height, &logger)
8771+
});
8772+
8773+
Ok((tx_signatures_opt, splice_locked_opt, funding_tx_opt))
87358774
}
87368775

8737-
pub fn tx_signatures(
8738-
&mut self, msg: &msgs::TxSignatures,
8739-
) -> Result<(Option<msgs::TxSignatures>, Option<Transaction>), ChannelError> {
8776+
pub fn tx_signatures<L: Deref>(
8777+
&mut self, msg: &msgs::TxSignatures, best_block_height: u32, logger: &L,
8778+
) -> Result<
8779+
(Option<msgs::TxSignatures>, Option<msgs::SpliceLocked>, Option<Transaction>),
8780+
ChannelError,
8781+
>
8782+
where
8783+
L::Target: Logger,
8784+
{
87408785
let signing_session = if let Some(signing_session) =
87418786
self.context.interactive_tx_signing_session.as_mut()
87428787
{
@@ -8782,11 +8827,18 @@ where
87828827
let (holder_tx_signatures_opt, funding_tx_opt) =
87838828
signing_session.received_tx_signatures(msg).map_err(|msg| ChannelError::Warn(msg))?;
87848829

8785-
if let Some(funding_tx) = funding_tx_opt.clone() {
8786-
self.on_tx_signatures_exchange(funding_tx);
8787-
}
8830+
let logger = WithChannelContext::from(logger, &self.context, None);
8831+
log_info!(
8832+
logger,
8833+
"Received tx_signatures for interactive funding transaction {}",
8834+
msg.tx_hash
8835+
);
8836+
8837+
let splice_locked_opt = funding_tx_opt.clone().and_then(|funding_tx| {
8838+
self.on_tx_signatures_exchange(funding_tx, best_block_height, &logger)
8839+
});
87888840

8789-
Ok((holder_tx_signatures_opt, funding_tx_opt))
8841+
Ok((holder_tx_signatures_opt, splice_locked_opt, funding_tx_opt))
87908842
}
87918843

87928844
/// Queues up an outbound update fee by placing it in the holding cell. You should call
@@ -11113,7 +11165,11 @@ where
1111311165
confirmed_funding_index,
1111411166
height,
1111511167
) {
11116-
log_info!(logger, "Sending a splice_locked to our peer for channel {}", &self.context.channel_id);
11168+
log_info!(
11169+
logger, "Sending splice_locked txid {} to our peer for channel {}",
11170+
splice_locked.splice_txid,
11171+
&self.context.channel_id
11172+
);
1111711173

1111811174
let (funding_txo, monitor_update, announcement_sigs, discarded_funding) = chain_node_signer
1111911175
.and_then(|(chain_hash, node_signer, user_config)| {

lightning/src/ln/channelmanager.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6297,8 +6297,14 @@ where
62976297
.map(|input| input.witness)
62986298
.filter(|witness| !witness.is_empty())
62996299
.collect();
6300-
match chan.funding_transaction_signed(txid, witnesses) {
6301-
Ok((Some(tx_signatures), funding_tx_opt)) => {
6300+
let best_block_height = self.best_block.read().unwrap().height;
6301+
match chan.funding_transaction_signed(
6302+
txid,
6303+
witnesses,
6304+
best_block_height,
6305+
&self.logger,
6306+
) {
6307+
Ok((Some(tx_signatures), splice_locked_opt, funding_tx_opt)) => {
63026308
if let Some(funding_tx) = funding_tx_opt {
63036309
self.broadcast_interactive_funding(
63046310
chan,
@@ -6312,6 +6318,14 @@ where
63126318
msg: tx_signatures,
63136319
},
63146320
);
6321+
if let Some(splice_locked) = splice_locked_opt {
6322+
peer_state.pending_msg_events.push(
6323+
MessageSendEvent::SendSpliceLocked {
6324+
node_id: *counterparty_node_id,
6325+
msg: splice_locked,
6326+
},
6327+
);
6328+
}
63156329
return NotifyOption::DoPersist;
63166330
},
63176331
Err(err) => {
@@ -9422,21 +9436,27 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
94229436
}
94239437
} else {
94249438
let txid = signing_session.unsigned_tx().compute_txid();
9425-
match channel.funding_transaction_signed(txid, vec![]) {
9426-
Ok((Some(tx_signatures), funding_tx_opt)) => {
9439+
let best_block_height = self.best_block.read().unwrap().height;
9440+
match channel.funding_transaction_signed(txid, vec![], best_block_height, &self.logger) {
9441+
Ok((tx_signatures_opt, splice_locked_opt, funding_tx_opt)) => {
94279442
if let Some(funding_tx) = funding_tx_opt {
94289443
self.broadcast_interactive_funding(channel, &funding_tx, &self.logger);
94299444
}
94309445
if channel.context.is_connected() {
9431-
pending_msg_events.push(MessageSendEvent::SendTxSignatures {
9432-
node_id: counterparty_node_id,
9433-
msg: tx_signatures,
9434-
});
9446+
if let Some(tx_signatures) = tx_signatures_opt {
9447+
pending_msg_events.push(MessageSendEvent::SendTxSignatures {
9448+
node_id: counterparty_node_id,
9449+
msg: tx_signatures,
9450+
});
9451+
}
9452+
if let Some(splice_locked) = splice_locked_opt {
9453+
pending_msg_events.push(MessageSendEvent::SendSpliceLocked {
9454+
node_id: counterparty_node_id,
9455+
msg: splice_locked,
9456+
});
9457+
}
94359458
}
94369459
},
9437-
Ok((None, _)) => {
9438-
debug_assert!(false, "If our tx_signatures is empty, then we should send it first!");
9439-
},
94409460
Err(err) => {
94419461
log_warn!(logger, "Failed signing interactive funding transaction: {err:?}");
94429462
},
@@ -10383,13 +10403,20 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1038310403
hash_map::Entry::Occupied(mut chan_entry) => {
1038410404
match chan_entry.get_mut().as_funded_mut() {
1038510405
Some(chan) => {
10386-
let (tx_signatures_opt, funding_tx_opt) = try_channel_entry!(self, peer_state, chan.tx_signatures(msg), chan_entry);
10406+
let best_block_height = self.best_block.read().unwrap().height;
10407+
let (tx_signatures_opt, splice_locked_opt, funding_tx_opt) = try_channel_entry!(self, peer_state, chan.tx_signatures(msg, best_block_height, &self.logger), chan_entry);
1038710408
if let Some(tx_signatures) = tx_signatures_opt {
1038810409
peer_state.pending_msg_events.push(MessageSendEvent::SendTxSignatures {
1038910410
node_id: *counterparty_node_id,
1039010411
msg: tx_signatures,
1039110412
});
1039210413
}
10414+
if let Some(splice_locked) = splice_locked_opt {
10415+
peer_state.pending_msg_events.push(MessageSendEvent::SendSpliceLocked {
10416+
node_id: *counterparty_node_id,
10417+
msg: splice_locked,
10418+
});
10419+
}
1039310420
if let Some(ref funding_tx) = funding_tx_opt {
1039410421
self.broadcast_interactive_funding(chan, funding_tx, &self.logger);
1039510422
}

0 commit comments

Comments
 (0)