Skip to content

Commit 1a0b87a

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 8a15587 commit 1a0b87a

File tree

3 files changed

+195
-83
lines changed

3 files changed

+195
-83
lines changed

lightning/src/ln/channel.rs

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8568,16 +8568,38 @@ where
85688568
}
85698569
}
85708570

8571-
fn on_tx_signatures_exchange(&mut self, funding_tx: Transaction) {
8571+
fn on_tx_signatures_exchange<'a, L: Deref>(
8572+
&mut self, funding_tx: Transaction, best_block_height: u32,
8573+
logger: &WithChannelContext<'a, L>,
8574+
) -> Option<msgs::SpliceLocked>
8575+
where
8576+
L::Target: Logger,
8577+
{
85728578
debug_assert!(!self.context.channel_state.is_monitor_update_in_progress());
85738579
debug_assert!(!self.context.channel_state.is_awaiting_remote_revoke());
85748580

8581+
let mut splice_locked = None;
85758582
if let Some(pending_splice) = self.pending_splice.as_mut() {
85768583
if let Some(FundingNegotiation::AwaitingSignatures { mut funding }) =
85778584
pending_splice.funding_negotiation.take()
85788585
{
85798586
funding.funding_transaction = Some(funding_tx);
85808587
pending_splice.negotiated_candidates.push(funding);
8588+
splice_locked = pending_splice.check_get_splice_locked(
8589+
&self.context,
8590+
pending_splice.negotiated_candidates.len() - 1,
8591+
best_block_height,
8592+
);
8593+
if let Some(splice_txid) =
8594+
splice_locked.as_ref().map(|splice_locked| splice_locked.splice_txid)
8595+
{
8596+
log_info!(
8597+
logger,
8598+
"Sending 0conf splice_locked txid {} to our peer for channel {}",
8599+
splice_txid,
8600+
&self.context.channel_id
8601+
);
8602+
}
85818603
} else {
85828604
debug_assert!(false);
85838605
}
@@ -8587,11 +8609,20 @@ where
85878609
self.context.channel_state =
85888610
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
85898611
}
8612+
8613+
splice_locked
85908614
}
85918615

8592-
pub fn funding_transaction_signed(
8593-
&mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>,
8594-
) -> Result<(Option<msgs::TxSignatures>, Option<Transaction>), APIError> {
8616+
pub fn funding_transaction_signed<L: Deref>(
8617+
&mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>, best_block_height: u32,
8618+
logger: &L,
8619+
) -> Result<
8620+
(Option<msgs::TxSignatures>, Option<msgs::SpliceLocked>, Option<Transaction>),
8621+
APIError,
8622+
>
8623+
where
8624+
L::Target: Logger,
8625+
{
85958626
let signing_session =
85968627
if let Some(signing_session) = self.context.interactive_tx_signing_session.as_mut() {
85978628
if let Some(pending_splice) = self.pending_splice.as_ref() {
@@ -8606,9 +8637,9 @@ where
86068637
}
86078638

86088639
if signing_session.holder_tx_signatures().is_some() {
8609-
// Our `tx_signatures` either should've been the first time we processed them,
8610-
// or we're waiting for our counterparty to send theirs first.
8611-
return Ok((None, None));
8640+
// Our `tx_signatures` either should've been sent the first time we processed
8641+
// them, or we're waiting for our counterparty to send theirs first.
8642+
return Ok((None, None, None));
86128643
}
86138644

86148645
signing_session
@@ -8653,17 +8684,31 @@ where
86538684
.provide_holder_witnesses(tx_signatures, &self.context.secp_ctx)
86548685
.map_err(|err| APIError::APIMisuseError { err })?;
86558686

8656-
if let Some(funding_tx) = funding_tx_opt.clone() {
8657-
debug_assert!(tx_signatures_opt.is_some());
8658-
self.on_tx_signatures_exchange(funding_tx);
8687+
let logger = WithChannelContext::from(logger, &self.context, None);
8688+
if tx_signatures_opt.is_some() {
8689+
log_info!(
8690+
logger,
8691+
"Sending tx_signatures for interactive funding transaction {funding_txid_signed}"
8692+
);
86598693
}
86608694

8661-
Ok((tx_signatures_opt, funding_tx_opt))
8695+
let splice_locked_opt = funding_tx_opt.clone().and_then(|funding_tx| {
8696+
debug_assert!(tx_signatures_opt.is_some());
8697+
self.on_tx_signatures_exchange(funding_tx, best_block_height, &logger)
8698+
});
8699+
8700+
Ok((tx_signatures_opt, splice_locked_opt, funding_tx_opt))
86628701
}
86638702

8664-
pub fn tx_signatures(
8665-
&mut self, msg: &msgs::TxSignatures,
8666-
) -> Result<(Option<msgs::TxSignatures>, Option<Transaction>), ChannelError> {
8703+
pub fn tx_signatures<L: Deref>(
8704+
&mut self, msg: &msgs::TxSignatures, best_block_height: u32, logger: &L,
8705+
) -> Result<
8706+
(Option<msgs::TxSignatures>, Option<msgs::SpliceLocked>, Option<Transaction>),
8707+
ChannelError,
8708+
>
8709+
where
8710+
L::Target: Logger,
8711+
{
86678712
let signing_session = if let Some(signing_session) =
86688713
self.context.interactive_tx_signing_session.as_mut()
86698714
{
@@ -8709,11 +8754,18 @@ where
87098754
let (holder_tx_signatures_opt, funding_tx_opt) =
87108755
signing_session.received_tx_signatures(msg).map_err(|msg| ChannelError::Warn(msg))?;
87118756

8712-
if let Some(funding_tx) = funding_tx_opt.clone() {
8713-
self.on_tx_signatures_exchange(funding_tx);
8714-
}
8757+
let logger = WithChannelContext::from(logger, &self.context, None);
8758+
log_info!(
8759+
logger,
8760+
"Received tx_signatures for interactive funding transaction {}",
8761+
msg.tx_hash
8762+
);
8763+
8764+
let splice_locked_opt = funding_tx_opt.clone().and_then(|funding_tx| {
8765+
self.on_tx_signatures_exchange(funding_tx, best_block_height, &logger)
8766+
});
87158767

8716-
Ok((holder_tx_signatures_opt, funding_tx_opt))
8768+
Ok((holder_tx_signatures_opt, splice_locked_opt, funding_tx_opt))
87178769
}
87188770

87198771
/// Queues up an outbound update fee by placing it in the holding cell. You should call
@@ -11019,7 +11071,11 @@ where
1101911071
confirmed_funding_index,
1102011072
height,
1102111073
) {
11022-
log_info!(logger, "Sending a splice_locked to our peer for channel {}", &self.context.channel_id);
11074+
log_info!(
11075+
logger, "Sending splice_locked txid {} to our peer for channel {}",
11076+
splice_locked.splice_txid,
11077+
&self.context.channel_id
11078+
);
1102311079

1102411080
let (funding_txo, monitor_update, announcement_sigs, discarded_funding) = chain_node_signer
1102511081
.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
@@ -6245,8 +6245,14 @@ where
62456245
.map(|input| input.witness)
62466246
.filter(|witness| !witness.is_empty())
62476247
.collect();
6248-
match chan.funding_transaction_signed(txid, witnesses) {
6249-
Ok((Some(tx_signatures), funding_tx_opt)) => {
6248+
let best_block_height = self.best_block.read().unwrap().height;
6249+
match chan.funding_transaction_signed(
6250+
txid,
6251+
witnesses,
6252+
best_block_height,
6253+
&self.logger,
6254+
) {
6255+
Ok((Some(tx_signatures), splice_locked_opt, funding_tx_opt)) => {
62506256
if let Some(funding_tx) = funding_tx_opt {
62516257
self.broadcast_interactive_funding(
62526258
chan,
@@ -6260,6 +6266,14 @@ where
62606266
msg: tx_signatures,
62616267
},
62626268
);
6269+
if let Some(splice_locked) = splice_locked_opt {
6270+
peer_state.pending_msg_events.push(
6271+
MessageSendEvent::SendSpliceLocked {
6272+
node_id: *counterparty_node_id,
6273+
msg: splice_locked,
6274+
},
6275+
);
6276+
}
62636277
return NotifyOption::DoPersist;
62646278
},
62656279
Err(err) => {
@@ -9365,21 +9379,27 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
93659379
}
93669380
} else {
93679381
let txid = signing_session.unsigned_tx().compute_txid();
9368-
match channel.funding_transaction_signed(txid, vec![]) {
9369-
Ok((Some(tx_signatures), funding_tx_opt)) => {
9382+
let best_block_height = self.best_block.read().unwrap().height;
9383+
match channel.funding_transaction_signed(txid, vec![], best_block_height, &self.logger) {
9384+
Ok((tx_signatures_opt, splice_locked_opt, funding_tx_opt)) => {
93709385
if let Some(funding_tx) = funding_tx_opt {
93719386
self.broadcast_interactive_funding(channel, &funding_tx, &self.logger);
93729387
}
93739388
if channel.context.is_connected() {
9374-
pending_msg_events.push(MessageSendEvent::SendTxSignatures {
9375-
node_id: counterparty_node_id,
9376-
msg: tx_signatures,
9377-
});
9389+
if let Some(tx_signatures) = tx_signatures_opt {
9390+
pending_msg_events.push(MessageSendEvent::SendTxSignatures {
9391+
node_id: counterparty_node_id,
9392+
msg: tx_signatures,
9393+
});
9394+
}
9395+
if let Some(splice_locked) = splice_locked_opt {
9396+
pending_msg_events.push(MessageSendEvent::SendSpliceLocked {
9397+
node_id: counterparty_node_id,
9398+
msg: splice_locked,
9399+
});
9400+
}
93789401
}
93799402
},
9380-
Ok((None, _)) => {
9381-
debug_assert!(false, "If our tx_signatures is empty, then we should send it first!");
9382-
},
93839403
Err(err) => {
93849404
log_warn!(logger, "Failed signing interactive funding transaction: {err:?}");
93859405
},
@@ -10326,13 +10346,20 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1032610346
hash_map::Entry::Occupied(mut chan_entry) => {
1032710347
match chan_entry.get_mut().as_funded_mut() {
1032810348
Some(chan) => {
10329-
let (tx_signatures_opt, funding_tx_opt) = try_channel_entry!(self, peer_state, chan.tx_signatures(msg), chan_entry);
10349+
let best_block_height = self.best_block.read().unwrap().height;
10350+
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);
1033010351
if let Some(tx_signatures) = tx_signatures_opt {
1033110352
peer_state.pending_msg_events.push(MessageSendEvent::SendTxSignatures {
1033210353
node_id: *counterparty_node_id,
1033310354
msg: tx_signatures,
1033410355
});
1033510356
}
10357+
if let Some(splice_locked) = splice_locked_opt {
10358+
peer_state.pending_msg_events.push(MessageSendEvent::SendSpliceLocked {
10359+
node_id: *counterparty_node_id,
10360+
msg: splice_locked,
10361+
});
10362+
}
1033610363
if let Some(ref funding_tx) = funding_tx_opt {
1033710364
self.broadcast_interactive_funding(chan, funding_tx, &self.logger);
1033810365
}

0 commit comments

Comments
 (0)