Skip to content

Commit 1f699d5

Browse files
committed
Use a SpliceContribution enum for passing splice-in params
ChannelManager::splice_channel takes individual parameters to support splice-in. Change these to an enum such that it can be used for splice-out as well.
1 parent 4a655b1 commit 1f699d5

File tree

3 files changed

+74
-26
lines changed

3 files changed

+74
-26
lines changed

lightning/src/ln/channel.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ use crate::ln::channel_state::{
5151
ChannelShutdownState, CounterpartyForwardingInfo, InboundHTLCDetails, InboundHTLCStateDetails,
5252
OutboundHTLCDetails, OutboundHTLCStateDetails,
5353
};
54+
#[cfg(splicing)]
55+
use crate::ln::channelmanager::SpliceContribution;
5456
use crate::ln::channelmanager::{
5557
self, FundingConfirmedMessage, FundingTxInput, HTLCFailureMsg, HTLCSource, OpenChannelMessage,
5658
PaymentClaimDetails, PendingHTLCInfo, PendingHTLCStatus, RAACommitmentOrder, SentHTLCId,
@@ -10614,8 +10616,7 @@ where
1061410616
/// generated by `SignerProvider::get_destination_script`.
1061510617
#[cfg(splicing)]
1061610618
pub fn splice_channel(
10617-
&mut self, our_funding_contribution_satoshis: i64, our_funding_inputs: Vec<FundingTxInput>,
10618-
change_script: Option<ScriptBuf>, funding_feerate_per_kw: u32, locktime: u32,
10619+
&mut self, contribution: SpliceContribution, funding_feerate_per_kw: u32, locktime: u32,
1061910620
) -> Result<msgs::SpliceInit, APIError> {
1062010621
// Check if a splice has been initiated already.
1062110622
// Note: only a single outstanding splice is supported (per spec)
@@ -10639,7 +10640,7 @@ where
1063910640

1064010641
// TODO(splicing): check for quiescence
1064110642

10642-
let our_funding_contribution = SignedAmount::from_sat(our_funding_contribution_satoshis);
10643+
let our_funding_contribution = contribution.value();
1064310644
if our_funding_contribution > SignedAmount::MAX_MONEY {
1064410645
return Err(APIError::APIMisuseError {
1064510646
err: format!(
@@ -10668,7 +10669,7 @@ where
1066810669
// Check that inputs are sufficient to cover our contribution.
1066910670
let _fee = check_v2_funding_inputs_sufficient(
1067010671
our_funding_contribution.to_sat(),
10671-
&our_funding_inputs,
10672+
contribution.inputs(),
1067210673
true,
1067310674
true,
1067410675
funding_feerate_per_kw,
@@ -10681,7 +10682,7 @@ where
1068110682
),
1068210683
})?;
1068310684

10684-
for FundingTxInput { txin, prevtx, .. } in our_funding_inputs.iter() {
10685+
for FundingTxInput { txin, prevtx, .. } in contribution.inputs().iter() {
1068510686
const MESSAGE_TEMPLATE: msgs::TxAddInput = msgs::TxAddInput {
1068610687
channel_id: ChannelId([0; 32]),
1068710688
serial_id: 0,
@@ -10702,6 +10703,7 @@ where
1070210703
}
1070310704

1070410705
let prev_funding_input = self.funding.to_splice_funding_input();
10706+
let (our_funding_inputs, change_script) = contribution.into_tx_parts();
1070510707
let funding_negotiation_context = FundingNegotiationContext {
1070610708
is_initiator: true,
1070710709
our_funding_contribution,

lightning/src/ln/channelmanager.rs

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ use bitcoin::hashes::{Hash, HashEngine, HmacEngine};
3030

3131
use bitcoin::secp256k1::Secp256k1;
3232
use bitcoin::secp256k1::{PublicKey, SecretKey};
33-
#[cfg(splicing)]
34-
use bitcoin::ScriptBuf;
3533
use bitcoin::{secp256k1, Sequence, SignedAmount, TxIn, Weight};
34+
#[cfg(splicing)]
35+
use bitcoin::{Amount, ScriptBuf};
3636

3737
use crate::blinded_path::message::MessageForwardNode;
3838
use crate::blinded_path::message::{AsyncPaymentsContext, OffersContext};
@@ -200,6 +200,47 @@ pub use crate::ln::outbound_payment::{
200200
};
201201
use crate::ln::script::ShutdownScript;
202202

203+
/// The components of a splice's funding transaction that are contributed by one party.
204+
#[cfg(splicing)]
205+
pub enum SpliceContribution {
206+
/// When only inputs -- except for a possible change output -- are contributed to the splice.
207+
SpliceIn {
208+
/// The amount to contribute to the splice.
209+
value: Amount,
210+
211+
/// The inputs used to meet the contributed amount. Any excess amount will be sent to a
212+
/// change output.
213+
inputs: Vec<FundingTxInput>,
214+
215+
/// An optional change output script. This will be used if needed or, if not set, generated
216+
/// using `SignerProvider::get_destination_script`.
217+
change_script: Option<ScriptBuf>,
218+
},
219+
}
220+
221+
#[cfg(splicing)]
222+
impl SpliceContribution {
223+
pub(super) fn value(&self) -> SignedAmount {
224+
match self {
225+
SpliceContribution::SpliceIn { value, .. } => {
226+
value.to_signed().unwrap_or(SignedAmount::MAX)
227+
},
228+
}
229+
}
230+
231+
pub(super) fn inputs(&self) -> &[FundingTxInput] {
232+
match self {
233+
SpliceContribution::SpliceIn { inputs, .. } => &inputs[..],
234+
}
235+
}
236+
237+
pub(super) fn into_tx_parts(self) -> (Vec<FundingTxInput>, Option<ScriptBuf>) {
238+
match self {
239+
SpliceContribution::SpliceIn { inputs, change_script, .. } => (inputs, change_script),
240+
}
241+
}
242+
}
243+
203244
/// An input to contribute to a channel's funding transaction either when using the v2 channel
204245
/// establishment protocol or when splicing.
205246
#[derive(Clone)]
@@ -4452,14 +4493,13 @@ where
44524493
#[cfg(splicing)]
44534494
#[rustfmt::skip]
44544495
pub fn splice_channel(
4455-
&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey, our_funding_contribution_satoshis: i64,
4456-
our_funding_inputs: Vec<FundingTxInput>, change_script: Option<ScriptBuf>,
4457-
funding_feerate_per_kw: u32, locktime: Option<u32>,
4496+
&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
4497+
contribution: SpliceContribution, funding_feerate_per_kw: u32, locktime: Option<u32>,
44584498
) -> Result<(), APIError> {
44594499
let mut res = Ok(());
44604500
PersistenceNotifierGuard::optionally_notify(self, || {
44614501
let result = self.internal_splice_channel(
4462-
channel_id, counterparty_node_id, our_funding_contribution_satoshis, our_funding_inputs, change_script, funding_feerate_per_kw, locktime
4502+
channel_id, counterparty_node_id, contribution, funding_feerate_per_kw, locktime
44634503
);
44644504
res = result;
44654505
match res {
@@ -4474,8 +4514,7 @@ where
44744514
#[cfg(splicing)]
44754515
fn internal_splice_channel(
44764516
&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
4477-
our_funding_contribution_satoshis: i64, our_funding_inputs: Vec<FundingTxInput>,
4478-
change_script: Option<ScriptBuf>, funding_feerate_per_kw: u32, locktime: Option<u32>,
4517+
contribution: SpliceContribution, funding_feerate_per_kw: u32, locktime: Option<u32>,
44794518
) -> Result<(), APIError> {
44804519
let per_peer_state = self.per_peer_state.read().unwrap();
44814520

@@ -4496,13 +4535,8 @@ where
44964535
hash_map::Entry::Occupied(mut chan_phase_entry) => {
44974536
let locktime = locktime.unwrap_or_else(|| self.current_best_block().height);
44984537
if let Some(chan) = chan_phase_entry.get_mut().as_funded_mut() {
4499-
let msg = chan.splice_channel(
4500-
our_funding_contribution_satoshis,
4501-
our_funding_inputs,
4502-
change_script,
4503-
funding_feerate_per_kw,
4504-
locktime,
4505-
)?;
4538+
let msg =
4539+
chan.splice_channel(contribution, funding_feerate_per_kw, locktime)?;
45064540
peer_state.pending_msg_events.push(MessageSendEvent::SendSpliceInit {
45074541
node_id: *counterparty_node_id,
45084542
msg,

lightning/src/ln/splicing_tests.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
// You may not use this file except in accordance with one or both of these
88
// licenses.
99

10+
use crate::ln::channelmanager::SpliceContribution;
1011
use crate::ln::functional_test_utils::*;
1112
use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, MessageSendEvent};
1213
use crate::util::errors::APIError;
1314

15+
use bitcoin::Amount;
16+
1417
/// Splicing test, simple splice-in flow. Starts with opening a V1 channel first.
1518
/// Builds on test_channel_open_simple()
1619
#[test]
@@ -66,15 +69,20 @@ fn test_v1_splice_in() {
6669
&initiator_node,
6770
&[extra_splice_funding_input_sats],
6871
);
72+
73+
let contribution = SpliceContribution::SpliceIn {
74+
value: Amount::from_sat(splice_in_sats),
75+
inputs: funding_inputs,
76+
change_script: None,
77+
};
78+
6979
// Initiate splice-in
7080
let _res = initiator_node
7181
.node
7282
.splice_channel(
7383
&channel_id,
7484
&acceptor_node.node.get_our_node_id(),
75-
splice_in_sats as i64,
76-
funding_inputs,
77-
None, // change_script
85+
contribution,
7886
funding_feerate_per_kw,
7987
None, // locktime
8088
)
@@ -317,13 +325,17 @@ fn test_v1_splice_in_negative_insufficient_inputs() {
317325
let funding_inputs =
318326
create_dual_funding_utxos_with_prev_txs(&nodes[0], &[extra_splice_funding_input_sats]);
319327

328+
let contribution = SpliceContribution::SpliceIn {
329+
value: Amount::from_sat(splice_in_sats),
330+
inputs: funding_inputs,
331+
change_script: None,
332+
};
333+
320334
// Initiate splice-in, with insufficient input contribution
321335
let res = nodes[0].node.splice_channel(
322336
&channel_id,
323337
&nodes[1].node.get_our_node_id(),
324-
splice_in_sats as i64,
325-
funding_inputs,
326-
None, // change_script
338+
contribution,
327339
1024, // funding_feerate_per_kw,
328340
None, // locktime
329341
);

0 commit comments

Comments
 (0)