@@ -2448,13 +2448,46 @@ impl PendingSplice {
2448
2448
}
2449
2449
}
2450
2450
2451
+ pub(crate) struct SpliceInstructions {
2452
+ adjusted_funding_contribution: SignedAmount,
2453
+ our_funding_inputs: Vec<FundingTxInput>,
2454
+ our_funding_outputs: Vec<TxOut>,
2455
+ change_script: Option<ScriptBuf>,
2456
+ funding_feerate_per_kw: u32,
2457
+ locktime: u32,
2458
+ original_funding_txo: OutPoint,
2459
+ }
2460
+
2461
+ impl_writeable_tlv_based!(SpliceInstructions, {
2462
+ (1, adjusted_funding_contribution, required),
2463
+ (3, our_funding_inputs, required_vec),
2464
+ (5, our_funding_outputs, required_vec),
2465
+ (7, change_script, option),
2466
+ (9, funding_feerate_per_kw, required),
2467
+ (11, locktime, required),
2468
+ (13, original_funding_txo, required),
2469
+ });
2470
+
2451
2471
pub(crate) enum QuiescentAction {
2452
- // TODO: Make this test-only once we have another variant (as some code requires *a* variant).
2472
+ Splice(SpliceInstructions),
2473
+ #[cfg(any(test, fuzzing))]
2453
2474
DoNothing,
2454
2475
}
2455
2476
2477
+ pub(crate) enum StfuResponse {
2478
+ Stfu(msgs::Stfu),
2479
+ #[cfg_attr(not(splicing), allow(unused))]
2480
+ SpliceInit(msgs::SpliceInit),
2481
+ }
2482
+
2483
+ #[cfg(any(test, fuzzing))]
2456
2484
impl_writeable_tlv_based_enum_upgradable!(QuiescentAction,
2457
- (99, DoNothing) => {},
2485
+ (0, DoNothing) => {},
2486
+ {1, Splice} => (),
2487
+ );
2488
+ #[cfg(not(any(test, fuzzing)))]
2489
+ impl_writeable_tlv_based_enum_upgradable!(QuiescentAction,,
2490
+ {1, Splice} => (),
2458
2491
);
2459
2492
2460
2493
/// Wrapper around a [`Transaction`] useful for caching the result of [`Transaction::compute_txid`].
@@ -10748,9 +10781,13 @@ where
10748
10781
/// - `change_script`: an option change output script. If `None` and needed, one will be
10749
10782
/// generated by `SignerProvider::get_destination_script`.
10750
10783
#[cfg(splicing)]
10751
- pub fn splice_channel(
10784
+ pub fn splice_channel<L: Deref> (
10752
10785
&mut self, contribution: SpliceContribution, funding_feerate_per_kw: u32, locktime: u32,
10753
- ) -> Result<msgs::SpliceInit, APIError> {
10786
+ logger: &L,
10787
+ ) -> Result<Option<msgs::Stfu>, APIError>
10788
+ where
10789
+ L::Target: Logger,
10790
+ {
10754
10791
if self.holder_commitment_point.current_point().is_none() {
10755
10792
return Err(APIError::APIMisuseError {
10756
10793
err: format!(
@@ -10762,7 +10799,7 @@ where
10762
10799
10763
10800
// Check if a splice has been initiated already.
10764
10801
// Note: only a single outstanding splice is supported (per spec)
10765
- if self.pending_splice.is_some() {
10802
+ if self.pending_splice.is_some() || self.quiescent_action.is_some() {
10766
10803
return Err(APIError::APIMisuseError {
10767
10804
err: format!(
10768
10805
"Channel {} cannot be spliced, as it has already a splice pending",
@@ -10780,8 +10817,6 @@ where
10780
10817
});
10781
10818
}
10782
10819
10783
- // TODO(splicing): check for quiescence
10784
-
10785
10820
let our_funding_contribution = contribution.value();
10786
10821
if our_funding_contribution == SignedAmount::ZERO {
10787
10822
return Err(APIError::APIMisuseError {
@@ -10876,8 +10911,50 @@ where
10876
10911
}
10877
10912
}
10878
10913
10879
- let prev_funding_input = self.funding.to_splice_funding_input();
10914
+ let original_funding_txo = self.funding.get_funding_txo().ok_or_else(|| {
10915
+ debug_assert!(false);
10916
+ APIError::APIMisuseError { err: "Channel isn't yet fully funded".to_owned() }
10917
+ })?;
10918
+
10880
10919
let (our_funding_inputs, our_funding_outputs, change_script) = contribution.into_tx_parts();
10920
+
10921
+ let action = QuiescentAction::Splice(SpliceInstructions {
10922
+ adjusted_funding_contribution,
10923
+ our_funding_inputs,
10924
+ our_funding_outputs,
10925
+ change_script,
10926
+ funding_feerate_per_kw,
10927
+ locktime,
10928
+ original_funding_txo,
10929
+ });
10930
+ self.propose_quiescence(logger, action)
10931
+ .map_err(|e| APIError::APIMisuseError { err: e.to_owned() })
10932
+ }
10933
+
10934
+ #[cfg(splicing)]
10935
+ fn send_splice_init(
10936
+ &mut self, instructions: SpliceInstructions,
10937
+ ) -> Result<msgs::SpliceInit, String> {
10938
+ let SpliceInstructions {
10939
+ adjusted_funding_contribution,
10940
+ our_funding_inputs,
10941
+ our_funding_outputs,
10942
+ change_script,
10943
+ funding_feerate_per_kw,
10944
+ locktime,
10945
+ original_funding_txo,
10946
+ } = instructions;
10947
+
10948
+ // Check if a splice has been initiated already.
10949
+ // Note: only a single outstanding splice is supported (per spec)
10950
+ if self.pending_splice.is_some() {
10951
+ return Err(format!(
10952
+ "Channel {} cannot be spliced, as it has already a splice pending",
10953
+ self.context.channel_id(),
10954
+ ));
10955
+ }
10956
+
10957
+ let prev_funding_input = self.funding.to_splice_funding_input();
10881
10958
let funding_negotiation_context = FundingNegotiationContext {
10882
10959
is_initiator: true,
10883
10960
our_funding_contribution: adjusted_funding_contribution,
@@ -11820,23 +11897,21 @@ where
11820
11897
);
11821
11898
}
11822
11899
11823
- #[cfg(any(test, fuzzing))]
11900
+ #[cfg(any(splicing, test, fuzzing))]
11824
11901
#[rustfmt::skip]
11825
11902
pub fn propose_quiescence<L: Deref>(
11826
11903
&mut self, logger: &L, action: QuiescentAction,
11827
- ) -> Result<Option<msgs::Stfu>, ChannelError >
11904
+ ) -> Result<Option<msgs::Stfu>, &'static str >
11828
11905
where
11829
11906
L::Target: Logger,
11830
11907
{
11831
11908
log_debug!(logger, "Attempting to initiate quiescence");
11832
11909
11833
11910
if !self.context.is_usable() {
11834
- return Err(ChannelError::Ignore(
11835
- "Channel is not in a usable state to propose quiescence".to_owned()
11836
- ));
11911
+ return Err("Channel is not in a usable state to propose quiescence");
11837
11912
}
11838
11913
if self.quiescent_action.is_some() {
11839
- return Err(ChannelError::Ignore( "Channel is already quiescing".to_owned()) );
11914
+ return Err("Channel already has a pending quiescent action and cannot start another" );
11840
11915
}
11841
11916
11842
11917
self.quiescent_action = Some(action);
@@ -11857,7 +11932,7 @@ where
11857
11932
11858
11933
// Assumes we are either awaiting quiescence or our counterparty has requested quiescence.
11859
11934
#[rustfmt::skip]
11860
- pub fn send_stfu<L: Deref>(&mut self, logger: &L) -> Result<msgs::Stfu, ChannelError >
11935
+ pub fn send_stfu<L: Deref>(&mut self, logger: &L) -> Result<msgs::Stfu, &'static str >
11861
11936
where
11862
11937
L::Target: Logger,
11863
11938
{
@@ -11871,9 +11946,7 @@ where
11871
11946
if self.context.is_waiting_on_peer_pending_channel_update()
11872
11947
|| self.context.is_monitor_or_signer_pending_channel_update()
11873
11948
{
11874
- return Err(ChannelError::Ignore(
11875
- "We cannot send `stfu` while state machine is pending".to_owned()
11876
- ));
11949
+ return Err("We cannot send `stfu` while state machine is pending")
11877
11950
}
11878
11951
11879
11952
let initiator = if self.context.channel_state.is_remote_stfu_sent() {
@@ -11899,7 +11972,7 @@ where
11899
11972
#[rustfmt::skip]
11900
11973
pub fn stfu<L: Deref>(
11901
11974
&mut self, msg: &msgs::Stfu, logger: &L
11902
- ) -> Result<Option<msgs::Stfu >, ChannelError> where L::Target: Logger {
11975
+ ) -> Result<Option<StfuResponse >, ChannelError> where L::Target: Logger {
11903
11976
if self.context.channel_state.is_quiescent() {
11904
11977
return Err(ChannelError::Warn("Channel is already quiescent".to_owned()));
11905
11978
}
@@ -11930,7 +12003,10 @@ where
11930
12003
self.context.channel_state.set_remote_stfu_sent();
11931
12004
11932
12005
log_debug!(logger, "Received counterparty stfu proposing quiescence");
11933
- return self.send_stfu(logger).map(|stfu| Some(stfu));
12006
+ return self
12007
+ .send_stfu(logger)
12008
+ .map(|stfu| Some(StfuResponse::Stfu(stfu)))
12009
+ .map_err(|e| ChannelError::Ignore(e.to_owned()));
11934
12010
}
11935
12011
11936
12012
// We already sent `stfu` and are now processing theirs. It may be in response to ours, or
@@ -11971,6 +12047,13 @@ where
11971
12047
"Internal Error: Didn't have anything to do after reaching quiescence".to_owned()
11972
12048
));
11973
12049
},
12050
+ Some(QuiescentAction::Splice(_instructions)) => {
12051
+ #[cfg(splicing)]
12052
+ return self.send_splice_init(_instructions)
12053
+ .map(|splice_init| Some(StfuResponse::SpliceInit(splice_init)))
12054
+ .map_err(|e| ChannelError::WarnAndDisconnect(e.to_owned()));
12055
+ },
12056
+ #[cfg(any(test, fuzzing))]
11974
12057
Some(QuiescentAction::DoNothing) => {
11975
12058
// In quiescence test we want to just hang out here, letting the test manually
11976
12059
// leave quiescence.
@@ -12003,7 +12086,10 @@ where
12003
12086
|| (self.context.channel_state.is_remote_stfu_sent()
12004
12087
&& !self.context.channel_state.is_local_stfu_sent())
12005
12088
{
12006
- return self.send_stfu(logger).map(|stfu| Some(stfu));
12089
+ return self
12090
+ .send_stfu(logger)
12091
+ .map(|stfu| Some(stfu))
12092
+ .map_err(|e| ChannelError::Ignore(e.to_owned()));
12007
12093
}
12008
12094
12009
12095
// We're either:
0 commit comments