Skip to content

Commit 96d4e80

Browse files
committed
Handle splice_locked message
When receiving a splice_locked message from a counterparty, promote the corresponding FundingScope if the funding txid matches the one sent by us in splice_locked.
1 parent 8c921d3 commit 96d4e80

File tree

2 files changed

+135
-3
lines changed

2 files changed

+135
-3
lines changed

lightning/src/ln/channel.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9797,6 +9797,76 @@ where
97979797
Ok(())
97989798
}
97999799

9800+
#[cfg(splicing)]
9801+
pub fn splice_locked<NS: Deref, L: Deref>(
9802+
&mut self, msg: &msgs::SpliceLocked, node_signer: &NS, chain_hash: ChainHash,
9803+
user_config: &UserConfig, best_block: &BestBlock, logger: &L,
9804+
) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError>
9805+
where
9806+
NS::Target: NodeSigner,
9807+
L::Target: Logger,
9808+
{
9809+
log_info!(
9810+
logger,
9811+
"Received splice_locked txid {} from our peer for channel {}",
9812+
msg.splice_txid,
9813+
&self.context.channel_id,
9814+
);
9815+
9816+
let pending_splice = match self.pending_splice.as_mut() {
9817+
Some(pending_splice) => pending_splice,
9818+
None => {
9819+
return Err(ChannelError::Ignore(format!("Channel is not in pending splice")));
9820+
},
9821+
};
9822+
9823+
if let Some(sent_funding_txid) = pending_splice.sent_funding_txid {
9824+
if sent_funding_txid == msg.splice_txid {
9825+
if let Some(funding) = self
9826+
.pending_funding
9827+
.iter_mut()
9828+
.find(|funding| funding.get_funding_txid() == Some(sent_funding_txid))
9829+
{
9830+
log_info!(
9831+
logger,
9832+
"Promoting splice funding txid {} for channel {}",
9833+
msg.splice_txid,
9834+
&self.context.channel_id,
9835+
);
9836+
promote_splice_funding!(self, funding);
9837+
return Ok(self.get_announcement_sigs(
9838+
node_signer,
9839+
chain_hash,
9840+
user_config,
9841+
best_block.height,
9842+
logger,
9843+
));
9844+
}
9845+
9846+
let err = "unknown splice funding txid";
9847+
return Err(ChannelError::close(err.to_string()));
9848+
} else {
9849+
log_warn!(
9850+
logger,
9851+
"Mismatched splice_locked txid for channel {}; sent txid {}; received txid {}",
9852+
&self.context.channel_id,
9853+
sent_funding_txid,
9854+
msg.splice_txid,
9855+
);
9856+
}
9857+
} else {
9858+
log_info!(
9859+
logger,
9860+
"Waiting for enough confirmations to send splice_locked txid {} for channel {}",
9861+
msg.splice_txid,
9862+
&self.context.channel_id,
9863+
);
9864+
}
9865+
9866+
pending_splice.received_funding_txid = Some(msg.splice_txid);
9867+
Ok(None)
9868+
}
9869+
98009870
// Send stuff to our remote peers:
98019871

98029872
/// Queues up an outbound HTLC to send by placing it in the holding cell. You should call

lightning/src/ln/channelmanager.rs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10011,6 +10011,61 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1001110011
Err(MsgHandleErrInternal::send_err_msg_no_close("TODO(splicing): Splicing is not implemented (splice_ack)".to_owned(), msg.channel_id))
1001210012
}
1001310013

10014+
#[cfg(splicing)]
10015+
fn internal_splice_locked(
10016+
&self, counterparty_node_id: &PublicKey, msg: &msgs::SpliceLocked,
10017+
) -> Result<(), MsgHandleErrInternal> {
10018+
let per_peer_state = self.per_peer_state.read().unwrap();
10019+
let peer_state_mutex = per_peer_state.get(counterparty_node_id).ok_or_else(|| {
10020+
debug_assert!(false);
10021+
MsgHandleErrInternal::send_err_msg_no_close(
10022+
format!(
10023+
"Can't find a peer matching the passed counterparty node_id {}",
10024+
counterparty_node_id
10025+
),
10026+
msg.channel_id,
10027+
)
10028+
})?;
10029+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
10030+
let peer_state = &mut *peer_state_lock;
10031+
10032+
// Look for the channel
10033+
match peer_state.channel_by_id.entry(msg.channel_id) {
10034+
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!(
10035+
"Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}",
10036+
counterparty_node_id
10037+
), msg.channel_id)),
10038+
hash_map::Entry::Occupied(mut chan_entry) => {
10039+
if let Some(chan) = chan_entry.get_mut().as_funded_mut() {
10040+
let logger = WithChannelContext::from(&self.logger, &chan.context, None);
10041+
let announcement_sigs_opt = try_channel_entry!(
10042+
self, peer_state, chan.splice_locked(
10043+
msg, &self.node_signer, self.chain_hash, &self.default_configuration,
10044+
&self.best_block.read().unwrap(), &&logger,
10045+
), chan_entry
10046+
);
10047+
10048+
if !chan.has_pending_splice() {
10049+
let mut short_to_chan_info = self.short_to_chan_info.write().unwrap();
10050+
insert_short_channel_id!(short_to_chan_info, chan);
10051+
}
10052+
10053+
if let Some(announcement_sigs) = announcement_sigs_opt {
10054+
log_trace!(logger, "Sending announcement_signatures for channel {}", chan.context.channel_id());
10055+
peer_state.pending_msg_events.push(MessageSendEvent::SendAnnouncementSignatures {
10056+
node_id: counterparty_node_id.clone(),
10057+
msg: announcement_sigs,
10058+
});
10059+
}
10060+
} else {
10061+
return Err(MsgHandleErrInternal::send_err_msg_no_close("Channel is not funded, cannot splice".to_owned(), msg.channel_id));
10062+
}
10063+
},
10064+
};
10065+
10066+
Ok(())
10067+
}
10068+
1001410069
/// Process pending events from the [`chain::Watch`], returning whether any events were processed.
1001510070
#[rustfmt::skip]
1001610071
fn process_pending_monitor_events(&self) -> bool {
@@ -12464,9 +12519,16 @@ where
1246412519
#[cfg(splicing)]
1246512520
#[rustfmt::skip]
1246612521
fn handle_splice_locked(&self, counterparty_node_id: PublicKey, msg: &msgs::SpliceLocked) {
12467-
let _: Result<(), _> = handle_error!(self, Err(MsgHandleErrInternal::send_err_msg_no_close(
12468-
"Splicing not supported (splice_locked)".to_owned(),
12469-
msg.channel_id)), counterparty_node_id);
12522+
let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
12523+
let res = self.internal_splice_locked(&counterparty_node_id, msg);
12524+
let persist = match &res {
12525+
Err(e) if e.closes_channel() => NotifyOption::DoPersist,
12526+
Err(_) => NotifyOption::SkipPersistHandleEvents,
12527+
Ok(()) => NotifyOption::DoPersist,
12528+
};
12529+
let _ = handle_error!(self, res, counterparty_node_id);
12530+
persist
12531+
});
1247012532
}
1247112533

1247212534
fn handle_shutdown(&self, counterparty_node_id: PublicKey, msg: &msgs::Shutdown) {

0 commit comments

Comments
 (0)