@@ -2448,13 +2448,46 @@ impl PendingSplice {
24482448 }
24492449}
24502450
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+
24512471pub(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))]
24532474 DoNothing,
24542475}
24552476
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))]
24562484impl_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} => (),
24582491);
24592492
24602493/// Wrapper around a [`Transaction`] useful for caching the result of [`Transaction::compute_txid`].
@@ -10748,9 +10781,13 @@ where
1074810781 /// - `change_script`: an option change output script. If `None` and needed, one will be
1074910782 /// generated by `SignerProvider::get_destination_script`.
1075010783 #[cfg(splicing)]
10751- pub fn splice_channel(
10784+ pub fn splice_channel<L: Deref> (
1075210785 &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+ {
1075410791 if self.holder_commitment_point.current_point().is_none() {
1075510792 return Err(APIError::APIMisuseError {
1075610793 err: format!(
@@ -10762,7 +10799,7 @@ where
1076210799
1076310800 // Check if a splice has been initiated already.
1076410801 // 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() {
1076610803 return Err(APIError::APIMisuseError {
1076710804 err: format!(
1076810805 "Channel {} cannot be spliced, as it has already a splice pending",
@@ -10780,8 +10817,6 @@ where
1078010817 });
1078110818 }
1078210819
10783- // TODO(splicing): check for quiescence
10784-
1078510820 let our_funding_contribution = contribution.value();
1078610821 if our_funding_contribution == SignedAmount::ZERO {
1078710822 return Err(APIError::APIMisuseError {
@@ -10876,8 +10911,50 @@ where
1087610911 }
1087710912 }
1087810913
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+
1088010919 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();
1088110958 let funding_negotiation_context = FundingNegotiationContext {
1088210959 is_initiator: true,
1088310960 our_funding_contribution: adjusted_funding_contribution,
@@ -11820,23 +11897,21 @@ where
1182011897 );
1182111898 }
1182211899
11823- #[cfg(any(test, fuzzing))]
11900+ #[cfg(any(splicing, test, fuzzing))]
1182411901 #[rustfmt::skip]
1182511902 pub fn propose_quiescence<L: Deref>(
1182611903 &mut self, logger: &L, action: QuiescentAction,
11827- ) -> Result<Option<msgs::Stfu>, ChannelError >
11904+ ) -> Result<Option<msgs::Stfu>, &'static str >
1182811905 where
1182911906 L::Target: Logger,
1183011907 {
1183111908 log_debug!(logger, "Attempting to initiate quiescence");
1183211909
1183311910 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");
1183711912 }
1183811913 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" );
1184011915 }
1184111916
1184211917 self.quiescent_action = Some(action);
@@ -11857,7 +11932,7 @@ where
1185711932
1185811933 // Assumes we are either awaiting quiescence or our counterparty has requested quiescence.
1185911934 #[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 >
1186111936 where
1186211937 L::Target: Logger,
1186311938 {
@@ -11871,9 +11946,7 @@ where
1187111946 if self.context.is_waiting_on_peer_pending_channel_update()
1187211947 || self.context.is_monitor_or_signer_pending_channel_update()
1187311948 {
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")
1187711950 }
1187811951
1187911952 let initiator = if self.context.channel_state.is_remote_stfu_sent() {
@@ -11899,7 +11972,7 @@ where
1189911972 #[rustfmt::skip]
1190011973 pub fn stfu<L: Deref>(
1190111974 &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 {
1190311976 if self.context.channel_state.is_quiescent() {
1190411977 return Err(ChannelError::Warn("Channel is already quiescent".to_owned()));
1190511978 }
@@ -11930,7 +12003,10 @@ where
1193012003 self.context.channel_state.set_remote_stfu_sent();
1193112004
1193212005 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()));
1193412010 }
1193512011
1193612012 // We already sent `stfu` and are now processing theirs. It may be in response to ours, or
@@ -11971,6 +12047,13 @@ where
1197112047 "Internal Error: Didn't have anything to do after reaching quiescence".to_owned()
1197212048 ));
1197312049 },
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))]
1197412057 Some(QuiescentAction::DoNothing) => {
1197512058 // In quiescence test we want to just hang out here, letting the test manually
1197612059 // leave quiescence.
@@ -12003,7 +12086,10 @@ where
1200312086 || (self.context.channel_state.is_remote_stfu_sent()
1200412087 && !self.context.channel_state.is_local_stfu_sent())
1200512088 {
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()));
1200712093 }
1200812094
1200912095 // We're either:
0 commit comments