Skip to content

Commit c27d083

Browse files
committed
Use struct instead of enum for SpliceContribution
When adding support for mixed splice-in and splice-out, the contribution amount will need to be computed based on the splice-in and splice-out values. Rather than add a third variant to SpliceContribution, which could have an invalid contribution amount, use a more general struct that can represent splice-in, splice-out, and mixed. Constructors are provided for the typical splice-in and splice-out case whereas support for the mixed case will be added in an independent change.
1 parent de384ff commit c27d083

File tree

4 files changed

+159
-185
lines changed

4 files changed

+159
-185
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,11 +1860,11 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
18601860

18611861
0xa0 => {
18621862
let input = FundingTxInput::new_p2wpkh(coinbase_tx.clone(), 0).unwrap();
1863-
let contribution = SpliceContribution::SpliceIn {
1864-
value: Amount::from_sat(10_000),
1865-
inputs: vec![input],
1866-
change_script: None,
1867-
};
1863+
let contribution = SpliceContribution::splice_in(
1864+
Amount::from_sat(10_000),
1865+
vec![input],
1866+
None,
1867+
);
18681868
let funding_feerate_sat_per_kw = fee_est_a.ret_val.load(atomic::Ordering::Acquire);
18691869
if let Err(e) = nodes[0].splice_channel(
18701870
&chan_a_id,
@@ -1882,11 +1882,11 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
18821882
},
18831883
0xa1 => {
18841884
let input = FundingTxInput::new_p2wpkh(coinbase_tx.clone(), 1).unwrap();
1885-
let contribution = SpliceContribution::SpliceIn {
1886-
value: Amount::from_sat(10_000),
1887-
inputs: vec![input],
1888-
change_script: None,
1889-
};
1885+
let contribution = SpliceContribution::splice_in(
1886+
Amount::from_sat(10_000),
1887+
vec![input],
1888+
None,
1889+
);
18901890
let funding_feerate_sat_per_kw = fee_est_b.ret_val.load(atomic::Ordering::Acquire);
18911891
if let Err(e) = nodes[1].splice_channel(
18921892
&chan_a_id,
@@ -1904,11 +1904,11 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
19041904
},
19051905
0xa2 => {
19061906
let input = FundingTxInput::new_p2wpkh(coinbase_tx.clone(), 0).unwrap();
1907-
let contribution = SpliceContribution::SpliceIn {
1908-
value: Amount::from_sat(10_000),
1909-
inputs: vec![input],
1910-
change_script: None,
1911-
};
1907+
let contribution = SpliceContribution::splice_in(
1908+
Amount::from_sat(10_000),
1909+
vec![input],
1910+
None,
1911+
);
19121912
let funding_feerate_sat_per_kw = fee_est_b.ret_val.load(atomic::Ordering::Acquire);
19131913
if let Err(e) = nodes[1].splice_channel(
19141914
&chan_b_id,
@@ -1926,11 +1926,11 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
19261926
},
19271927
0xa3 => {
19281928
let input = FundingTxInput::new_p2wpkh(coinbase_tx.clone(), 1).unwrap();
1929-
let contribution = SpliceContribution::SpliceIn {
1930-
value: Amount::from_sat(10_000),
1931-
inputs: vec![input],
1932-
change_script: None,
1933-
};
1929+
let contribution = SpliceContribution::splice_in(
1930+
Amount::from_sat(10_000),
1931+
vec![input],
1932+
None,
1933+
);
19341934
let funding_feerate_sat_per_kw = fee_est_c.ret_val.load(atomic::Ordering::Acquire);
19351935
if let Err(e) = nodes[2].splice_channel(
19361936
&chan_b_id,
@@ -1958,12 +1958,12 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
19581958
.map(|chan| chan.outbound_capacity_msat)
19591959
.unwrap();
19601960
if outbound_capacity_msat >= 20_000_000 {
1961-
let contribution = SpliceContribution::SpliceOut {
1962-
outputs: vec![TxOut {
1961+
let contribution = SpliceContribution::splice_out(
1962+
vec![TxOut {
19631963
value: Amount::from_sat(MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS),
19641964
script_pubkey: coinbase_tx.output[0].script_pubkey.clone(),
19651965
}],
1966-
};
1966+
);
19671967
let funding_feerate_sat_per_kw =
19681968
fee_est_a.ret_val.load(atomic::Ordering::Acquire);
19691969
if let Err(e) = nodes[0].splice_channel(
@@ -1989,12 +1989,12 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
19891989
.map(|chan| chan.outbound_capacity_msat)
19901990
.unwrap();
19911991
if outbound_capacity_msat >= 20_000_000 {
1992-
let contribution = SpliceContribution::SpliceOut {
1993-
outputs: vec![TxOut {
1992+
let contribution = SpliceContribution::splice_out(
1993+
vec![TxOut {
19941994
value: Amount::from_sat(MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS),
19951995
script_pubkey: coinbase_tx.output[1].script_pubkey.clone(),
19961996
}],
1997-
};
1997+
);
19981998
let funding_feerate_sat_per_kw =
19991999
fee_est_b.ret_val.load(atomic::Ordering::Acquire);
20002000
if let Err(e) = nodes[1].splice_channel(
@@ -2020,12 +2020,12 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
20202020
.map(|chan| chan.outbound_capacity_msat)
20212021
.unwrap();
20222022
if outbound_capacity_msat >= 20_000_000 {
2023-
let contribution = SpliceContribution::SpliceOut {
2024-
outputs: vec![TxOut {
2023+
let contribution = SpliceContribution::splice_out(
2024+
vec![TxOut {
20252025
value: Amount::from_sat(MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS),
20262026
script_pubkey: coinbase_tx.output[1].script_pubkey.clone(),
20272027
}],
2028-
};
2028+
);
20292029
let funding_feerate_sat_per_kw =
20302030
fee_est_b.ret_val.load(atomic::Ordering::Acquire);
20312031
if let Err(e) = nodes[1].splice_channel(
@@ -2051,12 +2051,12 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
20512051
.map(|chan| chan.outbound_capacity_msat)
20522052
.unwrap();
20532053
if outbound_capacity_msat >= 20_000_000 {
2054-
let contribution = SpliceContribution::SpliceOut {
2055-
outputs: vec![TxOut {
2054+
let contribution = SpliceContribution::splice_out(
2055+
vec![TxOut {
20562056
value: Amount::from_sat(MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS),
20572057
script_pubkey: coinbase_tx.output[2].script_pubkey.clone(),
20582058
}],
2059-
};
2059+
);
20602060
let funding_feerate_sat_per_kw =
20612061
fee_est_c.ret_val.load(atomic::Ordering::Acquire);
20622062
if let Err(e) = nodes[2].splice_channel(

lightning-tests/src/upgrade_downgrade_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -441,12 +441,12 @@ fn do_test_0_1_htlc_forward_after_splice(fail_htlc: bool) {
441441
reconnect_b_c_args.send_announcement_sigs = (true, true);
442442
reconnect_nodes(reconnect_b_c_args);
443443

444-
let contribution = SpliceContribution::SpliceOut {
445-
outputs: vec![TxOut {
444+
let contribution = SpliceContribution::splice_out(
445+
vec![TxOut {
446446
value: Amount::from_sat(1_000),
447447
script_pubkey: nodes[0].wallet_source.get_change_script().unwrap(),
448448
}],
449-
};
449+
);
450450
let splice_tx = splice_channel(&nodes[0], &nodes[1], ChannelId(chan_id_bytes_a), contribution);
451451
for node in nodes.iter() {
452452
mine_transaction(node, &splice_tx);

lightning/src/ln/funding.rs

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,69 +20,62 @@ use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};
2020

2121
/// The components of a splice's funding transaction that are contributed by one party.
2222
#[derive(Debug, Clone)]
23-
pub enum SpliceContribution {
24-
/// When funds are added to a channel.
25-
SpliceIn {
26-
/// The amount to contribute to the splice.
27-
value: Amount,
28-
29-
/// The inputs included in the splice's funding transaction to meet the contributed amount
30-
/// plus fees. Any excess amount will be sent to a change output.
31-
inputs: Vec<FundingTxInput>,
32-
33-
/// An optional change output script. This will be used if needed or, when not set,
34-
/// generated using [`SignerProvider::get_destination_script`].
35-
///
36-
/// [`SignerProvider::get_destination_script`]: crate::sign::SignerProvider::get_destination_script
37-
change_script: Option<ScriptBuf>,
38-
},
39-
/// When funds are removed from a channel.
40-
SpliceOut {
41-
/// The outputs to include in the splice's funding transaction. The total value of all
42-
/// outputs plus fees will be the amount that is removed.
43-
outputs: Vec<TxOut>,
44-
},
23+
pub struct SpliceContribution {
24+
/// The amount to contribute to the splice.
25+
value: SignedAmount,
26+
27+
/// The inputs included in the splice's funding transaction to meet the contributed amount
28+
/// plus fees. Any excess amount will be sent to a change output.
29+
inputs: Vec<FundingTxInput>,
30+
31+
/// The outputs to include in the splice's funding transaction. The total value of all
32+
/// outputs plus fees will be the amount that is removed.
33+
outputs: Vec<TxOut>,
34+
35+
/// An optional change output script. This will be used if needed or, when not set,
36+
/// generated using [`SignerProvider::get_destination_script`].
37+
///
38+
/// [`SignerProvider::get_destination_script`]: crate::sign::SignerProvider::get_destination_script
39+
change_script: Option<ScriptBuf>,
4540
}
4641

4742
impl SpliceContribution {
43+
/// Creates a contribution for when funds are only added to a channel.
44+
pub fn splice_in(
45+
value: Amount, inputs: Vec<FundingTxInput>, change_script: Option<ScriptBuf>,
46+
) -> Self {
47+
let value_added = value.to_signed().unwrap_or(SignedAmount::MAX);
48+
49+
Self { value: value_added, inputs, outputs: vec![], change_script }
50+
}
51+
52+
/// Creates a contribution for when funds are only removed from a channel.
53+
pub fn splice_out(outputs: Vec<TxOut>) -> Self {
54+
let value_removed = outputs
55+
.iter()
56+
.map(|txout| txout.value)
57+
.sum::<Amount>()
58+
.to_signed()
59+
.unwrap_or(SignedAmount::MAX);
60+
61+
Self { value: -value_removed, inputs: vec![], outputs, change_script: None }
62+
}
63+
4864
pub(super) fn value(&self) -> SignedAmount {
49-
match self {
50-
SpliceContribution::SpliceIn { value, .. } => {
51-
value.to_signed().unwrap_or(SignedAmount::MAX)
52-
},
53-
SpliceContribution::SpliceOut { outputs } => {
54-
let value_removed = outputs
55-
.iter()
56-
.map(|txout| txout.value)
57-
.sum::<Amount>()
58-
.to_signed()
59-
.unwrap_or(SignedAmount::MAX);
60-
-value_removed
61-
},
62-
}
65+
self.value
6366
}
6467

6568
pub(super) fn inputs(&self) -> &[FundingTxInput] {
66-
match self {
67-
SpliceContribution::SpliceIn { inputs, .. } => &inputs[..],
68-
SpliceContribution::SpliceOut { .. } => &[],
69-
}
69+
&self.inputs[..]
7070
}
7171

7272
pub(super) fn outputs(&self) -> &[TxOut] {
73-
match self {
74-
SpliceContribution::SpliceIn { .. } => &[],
75-
SpliceContribution::SpliceOut { outputs } => &outputs[..],
76-
}
73+
&self.outputs[..]
7774
}
7875

7976
pub(super) fn into_tx_parts(self) -> (Vec<FundingTxInput>, Vec<TxOut>, Option<ScriptBuf>) {
80-
match self {
81-
SpliceContribution::SpliceIn { inputs, change_script, .. } => {
82-
(inputs, vec![], change_script)
83-
},
84-
SpliceContribution::SpliceOut { outputs } => (vec![], outputs, None),
85-
}
77+
let SpliceContribution { value: _, inputs, outputs, change_script } = self;
78+
(inputs, outputs, change_script)
8679
}
8780
}
8881

0 commit comments

Comments
 (0)