Skip to content

Commit 681e715

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 f72b7ea commit 681e715

File tree

4 files changed

+75
-27
lines changed

4 files changed

+75
-27
lines changed

lightning/src/ln/channel.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ use crate::ln::channelmanager::{
5858
};
5959
use crate::ln::funding::FundingTxInput;
6060
#[cfg(splicing)]
61+
use crate::ln::funding::SpliceContribution;
62+
#[cfg(splicing)]
6163
use crate::ln::interactivetxs::{
6264
calculate_change_output_value, AbortReason, InteractiveTxMessageSend,
6365
};
@@ -10605,8 +10607,7 @@ where
1060510607
/// generated by `SignerProvider::get_destination_script`.
1060610608
#[cfg(splicing)]
1060710609
pub fn splice_channel(
10608-
&mut self, our_funding_contribution_satoshis: i64, our_funding_inputs: Vec<FundingTxInput>,
10609-
change_script: Option<ScriptBuf>, funding_feerate_per_kw: u32, locktime: u32,
10610+
&mut self, contribution: SpliceContribution, funding_feerate_per_kw: u32, locktime: u32,
1061010611
) -> Result<msgs::SpliceInit, APIError> {
1061110612
// Check if a splice has been initiated already.
1061210613
// Note: only a single outstanding splice is supported (per spec)
@@ -10630,7 +10631,7 @@ where
1063010631

1063110632
// TODO(splicing): check for quiescence
1063210633

10633-
let our_funding_contribution = SignedAmount::from_sat(our_funding_contribution_satoshis);
10634+
let our_funding_contribution = contribution.value();
1063410635
if our_funding_contribution > SignedAmount::MAX_MONEY {
1063510636
return Err(APIError::APIMisuseError {
1063610637
err: format!(
@@ -10659,7 +10660,7 @@ where
1065910660
// Check that inputs are sufficient to cover our contribution.
1066010661
let _fee = check_v2_funding_inputs_sufficient(
1066110662
our_funding_contribution.to_sat(),
10662-
&our_funding_inputs,
10663+
contribution.inputs(),
1066310664
true,
1066410665
true,
1066510666
funding_feerate_per_kw,
@@ -10672,7 +10673,7 @@ where
1067210673
),
1067310674
})?;
1067410675

10675-
for FundingTxInput { utxo, prevtx, .. } in our_funding_inputs.iter() {
10676+
for FundingTxInput { utxo, prevtx, .. } in contribution.inputs().iter() {
1067610677
const MESSAGE_TEMPLATE: msgs::TxAddInput = msgs::TxAddInput {
1067710678
channel_id: ChannelId([0; 32]),
1067810679
serial_id: 0,
@@ -10694,6 +10695,7 @@ where
1069410695
}
1069510696

1069610697
let prev_funding_input = self.funding.to_splice_funding_input();
10698+
let (our_funding_inputs, change_script) = contribution.into_tx_parts();
1069710699
let funding_negotiation_context = FundingNegotiationContext {
1069810700
is_initiator: true,
1069910701
our_funding_contribution,

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ 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};
3634

3735
use crate::blinded_path::message::MessageForwardNode;
@@ -66,7 +64,7 @@ use crate::ln::channel::{
6664
};
6765
use crate::ln::channel_state::ChannelDetails;
6866
#[cfg(splicing)]
69-
use crate::ln::funding::FundingTxInput;
67+
use crate::ln::funding::SpliceContribution;
7068
use crate::ln::inbound_payment;
7169
use crate::ln::interactivetxs::{HandleTxCompleteResult, InteractiveTxMessageSendResult};
7270
use crate::ln::msgs;
@@ -4460,14 +4458,13 @@ where
44604458
#[cfg(splicing)]
44614459
#[rustfmt::skip]
44624460
pub fn splice_channel(
4463-
&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey, our_funding_contribution_satoshis: i64,
4464-
our_funding_inputs: Vec<FundingTxInput>, change_script: Option<ScriptBuf>,
4465-
funding_feerate_per_kw: u32, locktime: Option<u32>,
4461+
&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
4462+
contribution: SpliceContribution, funding_feerate_per_kw: u32, locktime: Option<u32>,
44664463
) -> Result<(), APIError> {
44674464
let mut res = Ok(());
44684465
PersistenceNotifierGuard::optionally_notify(self, || {
44694466
let result = self.internal_splice_channel(
4470-
channel_id, counterparty_node_id, our_funding_contribution_satoshis, our_funding_inputs, change_script, funding_feerate_per_kw, locktime
4467+
channel_id, counterparty_node_id, contribution, funding_feerate_per_kw, locktime
44714468
);
44724469
res = result;
44734470
match res {
@@ -4482,8 +4479,7 @@ where
44824479
#[cfg(splicing)]
44834480
fn internal_splice_channel(
44844481
&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey,
4485-
our_funding_contribution_satoshis: i64, our_funding_inputs: Vec<FundingTxInput>,
4486-
change_script: Option<ScriptBuf>, funding_feerate_per_kw: u32, locktime: Option<u32>,
4482+
contribution: SpliceContribution, funding_feerate_per_kw: u32, locktime: Option<u32>,
44874483
) -> Result<(), APIError> {
44884484
let per_peer_state = self.per_peer_state.read().unwrap();
44894485

@@ -4504,13 +4500,8 @@ where
45044500
hash_map::Entry::Occupied(mut chan_phase_entry) => {
45054501
let locktime = locktime.unwrap_or_else(|| self.current_best_block().height);
45064502
if let Some(chan) = chan_phase_entry.get_mut().as_funded_mut() {
4507-
let msg = chan.splice_channel(
4508-
our_funding_contribution_satoshis,
4509-
our_funding_inputs,
4510-
change_script,
4511-
funding_feerate_per_kw,
4512-
locktime,
4513-
)?;
4503+
let msg =
4504+
chan.splice_channel(contribution, funding_feerate_per_kw, locktime)?;
45144505
peer_state.pending_msg_events.push(MessageSendEvent::SendSpliceInit {
45154506
node_id: *counterparty_node_id,
45164507
msg,

lightning/src/ln/funding.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,54 @@
99

1010
//! Types pertaining to funding channels.
1111
12+
#[cfg(splicing)]
13+
use bitcoin::{Amount, ScriptBuf, SignedAmount};
1214
use bitcoin::{Script, Sequence, Transaction, Weight};
1315

1416
use crate::events::bump_transaction::{Utxo, EMPTY_SCRIPT_SIG_WEIGHT};
1517
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};
1618

19+
/// The components of a splice's funding transaction that are contributed by one party.
20+
#[cfg(splicing)]
21+
pub enum SpliceContribution {
22+
/// When funds are added to a channel.
23+
SpliceIn {
24+
/// The amount to contribute to the splice.
25+
value: Amount,
26+
27+
/// The inputs included in the splice's funding transaction to meet the contributed amount.
28+
/// Any excess amount will be sent to a change output.
29+
inputs: Vec<FundingTxInput>,
30+
31+
/// An optional change output script. This will be used if needed or, when not set,
32+
/// generated using [`SignerProvider::get_destination_script`].
33+
change_script: Option<ScriptBuf>,
34+
},
35+
}
36+
37+
#[cfg(splicing)]
38+
impl SpliceContribution {
39+
pub(super) fn value(&self) -> SignedAmount {
40+
match self {
41+
SpliceContribution::SpliceIn { value, .. } => {
42+
value.to_signed().unwrap_or(SignedAmount::MAX)
43+
},
44+
}
45+
}
46+
47+
pub(super) fn inputs(&self) -> &[FundingTxInput] {
48+
match self {
49+
SpliceContribution::SpliceIn { inputs, .. } => &inputs[..],
50+
}
51+
}
52+
53+
pub(super) fn into_tx_parts(self) -> (Vec<FundingTxInput>, Option<ScriptBuf>) {
54+
match self {
55+
SpliceContribution::SpliceIn { inputs, change_script, .. } => (inputs, change_script),
56+
}
57+
}
58+
}
59+
1760
/// An input to contribute to a channel's funding transaction either when using the v2 channel
1861
/// establishment protocol or when splicing.
1962
#[derive(Clone)]

lightning/src/ln/splicing_tests.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
// licenses.
99

1010
use crate::ln::functional_test_utils::*;
11+
use crate::ln::funding::SpliceContribution;
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
)
@@ -295,13 +303,17 @@ fn test_v1_splice_in_negative_insufficient_inputs() {
295303
let funding_inputs =
296304
create_dual_funding_utxos_with_prev_txs(&nodes[0], &[extra_splice_funding_input_sats]);
297305

306+
let contribution = SpliceContribution::SpliceIn {
307+
value: Amount::from_sat(splice_in_sats),
308+
inputs: funding_inputs,
309+
change_script: None,
310+
};
311+
298312
// Initiate splice-in, with insufficient input contribution
299313
let res = nodes[0].node.splice_channel(
300314
&channel_id,
301315
&nodes[1].node.get_our_node_id(),
302-
splice_in_sats as i64,
303-
funding_inputs,
304-
None, // change_script
316+
contribution,
305317
1024, // funding_feerate_per_kw,
306318
None, // locktime
307319
);

0 commit comments

Comments
 (0)