@@ -31,6 +31,9 @@ use bitcoin::hash_types::{BlockHash, Txid};
31
31
use bitcoin::secp256k1::{SecretKey,PublicKey};
32
32
use bitcoin::secp256k1::Secp256k1;
33
33
use bitcoin::{secp256k1, Sequence};
34
+ #[cfg(splicing)]
35
+ use bitcoin::{TxIn, Weight};
36
+
34
37
35
38
use crate::events::FundingInfo;
36
39
use crate::blinded_path::message::{AsyncPaymentsContext, MessageContext, OffersContext};
@@ -49,7 +52,7 @@ use crate::ln::inbound_payment;
49
52
use crate::ln::types::ChannelId;
50
53
use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
51
54
use crate::ln::channel::{self, Channel, ChannelError, ChannelUpdateStatus, FundedChannel, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, ReconnectionMsg, InboundV1Channel, WithChannelContext};
52
- #[cfg(any( dual_funding, splicing) )]
55
+ #[cfg(dual_funding)]
53
56
use crate::ln::channel::PendingV2Channel;
54
57
use crate::ln::channel_state::ChannelDetails;
55
58
use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
@@ -4278,6 +4281,88 @@ where
4278
4281
}
4279
4282
}
4280
4283
4284
+ /// See [`splice_channel`]
4285
+ #[cfg(splicing)]
4286
+ fn internal_splice_channel(
4287
+ &self, channel_id: &ChannelId, counterparty_node_id: &PublicKey, our_funding_contribution_satoshis: i64,
4288
+ our_funding_inputs: &Vec<(TxIn, Transaction, Weight)>,
4289
+ funding_feerate_per_kw: u32, locktime: Option<u32>,
4290
+ ) -> (Result<(), APIError>, NotifyOption) {
4291
+ let per_peer_state = self.per_peer_state.read().unwrap();
4292
+
4293
+ let peer_state_mutex = match per_peer_state.get(counterparty_node_id)
4294
+ .ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) }) {
4295
+ Ok(p) => p,
4296
+ Err(e) => return (Err(e), NotifyOption::SkipPersistNoEvents),
4297
+ };
4298
+
4299
+ let mut peer_state_lock = peer_state_mutex.lock().unwrap();
4300
+ let peer_state = &mut *peer_state_lock;
4301
+
4302
+ // Look for the channel
4303
+ match peer_state.channel_by_id.entry(*channel_id) {
4304
+ hash_map::Entry::Occupied(mut chan_phase_entry) => {
4305
+ let locktime = locktime.unwrap_or(self.current_best_block().height);
4306
+ if let Some(chan) = chan_phase_entry.get_mut().as_funded_mut() {
4307
+ let msg = match chan.splice_channel(our_funding_contribution_satoshis, our_funding_inputs, funding_feerate_per_kw, locktime) {
4308
+ Ok(m) => m,
4309
+ Err(e) => return (Err(e), NotifyOption::SkipPersistNoEvents),
4310
+ };
4311
+
4312
+ peer_state.pending_msg_events.push(events::MessageSendEvent::SendSpliceInit {
4313
+ node_id: *counterparty_node_id,
4314
+ msg,
4315
+ });
4316
+
4317
+ (Ok(()), NotifyOption::SkipPersistHandleEvents)
4318
+ } else {
4319
+ (Err(APIError::ChannelUnavailable {
4320
+ err: format!(
4321
+ "Channel with id {} is not funded, cannot splice it",
4322
+ channel_id
4323
+ )
4324
+ }), NotifyOption::SkipPersistNoEvents)
4325
+ }
4326
+ },
4327
+ hash_map::Entry::Vacant(_) => {
4328
+ (Err(APIError::ChannelUnavailable {
4329
+ err: format!(
4330
+ "Channel with id {} not found for the passed counterparty node_id {}",
4331
+ channel_id, counterparty_node_id,
4332
+ )
4333
+ }), NotifyOption::SkipPersistNoEvents)
4334
+ },
4335
+ }
4336
+ }
4337
+
4338
+ /// Initiate a splice, to change the channel capacity of an existing funded channel.
4339
+ /// After completion of splicing, the funding transaction will be replaced by a new one, spending the old funding transaction,
4340
+ /// with optional extra inputs (splice-in) and/or extra outputs (splice-out or change).
4341
+ /// TODO(splicing): Implementation is currently incomplete.
4342
+ ///
4343
+ /// Note: Currently only splice-in is supported (increase in channel capacity), splice-out is not.
4344
+ ///
4345
+ /// - our_funding_contribution_satoshis: the amount contributed by us to the channel. This will increase our channel balance.
4346
+ /// - our_funding_inputs: the funding inputs provided by us. If our contribution is positive, our funding inputs must cover at least that amount.
4347
+ /// Includes the witness weight for this input (e.g. P2WPKH_WITNESS_WEIGHT=109 for typical P2WPKH inputs).
4348
+ /// - locktime: Optional locktime for the new funding transaction. If None, set to the current block height.
4349
+ #[cfg(splicing)]
4350
+ pub fn splice_channel(
4351
+ &self, channel_id: &ChannelId, counterparty_node_id: &PublicKey, our_funding_contribution_satoshis: i64,
4352
+ our_funding_inputs: Vec<(TxIn, Transaction, Weight)>,
4353
+ funding_feerate_per_kw: u32, locktime: Option<u32>,
4354
+ ) -> Result<(), APIError> {
4355
+ let mut res = Ok(());
4356
+ PersistenceNotifierGuard::optionally_notify(self, || {
4357
+ let (result, notify_option) = self.internal_splice_channel(
4358
+ channel_id, counterparty_node_id, our_funding_contribution_satoshis, &our_funding_inputs, funding_feerate_per_kw, locktime
4359
+ );
4360
+ res = result;
4361
+ notify_option
4362
+ });
4363
+ res
4364
+ }
4365
+
4281
4366
fn can_forward_htlc_to_outgoing_channel(
4282
4367
&self, chan: &mut FundedChannel<SP>, msg: &msgs::UpdateAddHTLC, next_packet: &NextPacketDetails
4283
4368
) -> Result<(), (&'static str, u16)> {
@@ -9466,6 +9551,83 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
9466
9551
Ok(NotifyOption::SkipPersistHandleEvents)
9467
9552
}
9468
9553
9554
+ /// Handle incoming splice request, transition channel to splice-pending (unless some check fails).
9555
+ #[cfg(splicing)]
9556
+ fn internal_splice_init(&self, counterparty_node_id: &PublicKey, msg: &msgs::SpliceInit) -> Result<(), MsgHandleErrInternal> {
9557
+ // TODO(splicing): if we accept splicing, quiescence
9558
+
9559
+ let per_peer_state = self.per_peer_state.read().unwrap();
9560
+ let peer_state_mutex = per_peer_state.get(counterparty_node_id)
9561
+ .ok_or_else(|| {
9562
+ debug_assert!(false);
9563
+ MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
9564
+ })?;
9565
+ let mut peer_state_lock = peer_state_mutex.lock().unwrap();
9566
+ let peer_state = &mut *peer_state_lock;
9567
+
9568
+ // Look for the channel
9569
+ match peer_state.channel_by_id.entry(msg.channel_id) {
9570
+ hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!(
9571
+ "Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}, channel_id {}",
9572
+ counterparty_node_id, msg.channel_id,
9573
+ ), msg.channel_id)),
9574
+ hash_map::Entry::Occupied(mut chan_entry) => {
9575
+ if let Some(chan) = chan_entry.get_mut().as_funded_mut() {
9576
+ let splice_ack_msg = try_channel_entry!(self, peer_state, chan.splice_init(msg), chan_entry);
9577
+ peer_state.pending_msg_events.push(events::MessageSendEvent::SendSpliceAck {
9578
+ node_id: *counterparty_node_id,
9579
+ msg: splice_ack_msg,
9580
+ });
9581
+ } else {
9582
+ return Err(MsgHandleErrInternal::send_err_msg_no_close("Channel is not funded, cannot be spliced".to_owned(), msg.channel_id));
9583
+ }
9584
+ },
9585
+ };
9586
+
9587
+ // TODO(splicing):
9588
+ // Change channel, change phase (remove and add)
9589
+ // Create new post-splice channel
9590
+ // etc.
9591
+
9592
+ Ok(())
9593
+ }
9594
+
9595
+ /// Handle incoming splice request ack, transition channel to splice-pending (unless some check fails).
9596
+ #[cfg(splicing)]
9597
+ fn internal_splice_ack(&self, counterparty_node_id: &PublicKey, msg: &msgs::SpliceAck) -> Result<(), MsgHandleErrInternal> {
9598
+ let per_peer_state = self.per_peer_state.read().unwrap();
9599
+ let peer_state_mutex = per_peer_state.get(counterparty_node_id)
9600
+ .ok_or_else(|| {
9601
+ debug_assert!(false);
9602
+ MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.channel_id)
9603
+ })?;
9604
+ let mut peer_state_lock = peer_state_mutex.lock().unwrap();
9605
+ let peer_state = &mut *peer_state_lock;
9606
+
9607
+ // Look for the channel
9608
+ match peer_state.channel_by_id.entry(msg.channel_id) {
9609
+ hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!(
9610
+ "Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}",
9611
+ counterparty_node_id
9612
+ ), msg.channel_id)),
9613
+ hash_map::Entry::Occupied(mut chan_entry) => {
9614
+ if let Some(chan) = chan_entry.get_mut().as_funded_mut() {
9615
+ try_channel_entry!(self, peer_state, chan.splice_ack(msg), chan_entry);
9616
+ } else {
9617
+ return Err(MsgHandleErrInternal::send_err_msg_no_close("Channel is not funded, cannot splice".to_owned(), msg.channel_id));
9618
+ }
9619
+ },
9620
+ };
9621
+
9622
+ // TODO(splicing):
9623
+ // Change channel, change phase (remove and add)
9624
+ // Create new post-splice channel
9625
+ // Start splice funding transaction negotiation
9626
+ // etc.
9627
+
9628
+ Err(MsgHandleErrInternal::send_err_msg_no_close("TODO(splicing): Splicing is not implemented (splice_ack)".to_owned(), msg.channel_id))
9629
+ }
9630
+
9469
9631
/// Process pending events from the [`chain::Watch`], returning whether any events were processed.
9470
9632
fn process_pending_monitor_events(&self) -> bool {
9471
9633
debug_assert!(self.total_consistency_lock.try_write().is_err()); // Caller holds read lock
@@ -11746,23 +11908,37 @@ where
11746
11908
11747
11909
#[cfg(splicing)]
11748
11910
fn handle_splice_init(&self, counterparty_node_id: PublicKey, msg: &msgs::SpliceInit) {
11749
- let _: Result<(), _> = handle_error!(self, Err(MsgHandleErrInternal::send_err_msg_no_close(
11750
- "Splicing not supported".to_owned(),
11751
- msg.channel_id.clone())), counterparty_node_id);
11911
+ let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
11912
+ let res = self.internal_splice_init(&counterparty_node_id, msg);
11913
+ let persist = match &res {
11914
+ Err(e) if e.closes_channel() => NotifyOption::DoPersist,
11915
+ Err(_) => NotifyOption::SkipPersistHandleEvents,
11916
+ Ok(()) => NotifyOption::SkipPersistHandleEvents,
11917
+ };
11918
+ let _ = handle_error!(self, res, counterparty_node_id);
11919
+ persist
11920
+ });
11752
11921
}
11753
11922
11754
11923
#[cfg(splicing)]
11755
11924
fn handle_splice_ack(&self, counterparty_node_id: PublicKey, msg: &msgs::SpliceAck) {
11756
- let _: Result<(), _> = handle_error!(self, Err(MsgHandleErrInternal::send_err_msg_no_close(
11757
- "Splicing not supported (splice_ack)".to_owned(),
11758
- msg.channel_id.clone())), counterparty_node_id);
11925
+ let _persistence_guard = PersistenceNotifierGuard::optionally_notify(self, || {
11926
+ let res = self.internal_splice_ack(&counterparty_node_id, msg);
11927
+ let persist = match &res {
11928
+ Err(e) if e.closes_channel() => NotifyOption::DoPersist,
11929
+ Err(_) => NotifyOption::SkipPersistHandleEvents,
11930
+ Ok(()) => NotifyOption::SkipPersistHandleEvents,
11931
+ };
11932
+ let _ = handle_error!(self, res, counterparty_node_id);
11933
+ persist
11934
+ });
11759
11935
}
11760
11936
11761
11937
#[cfg(splicing)]
11762
11938
fn handle_splice_locked(&self, counterparty_node_id: PublicKey, msg: &msgs::SpliceLocked) {
11763
11939
let _: Result<(), _> = handle_error!(self, Err(MsgHandleErrInternal::send_err_msg_no_close(
11764
11940
"Splicing not supported (splice_locked)".to_owned(),
11765
- msg.channel_id.clone() )), counterparty_node_id);
11941
+ msg.channel_id)), counterparty_node_id);
11766
11942
}
11767
11943
11768
11944
fn handle_shutdown(&self, counterparty_node_id: PublicKey, msg: &msgs::Shutdown) {
0 commit comments