@@ -7039,48 +7039,29 @@ pub struct SpliceFundingFailed {
70397039 pub contribution: Option<FundingContribution>,
70407040}
70417041
7042- macro_rules! maybe_create_splice_funding_failed {
7043- ($funded_channel: expr, $pending_splice: expr, $pending_splice_ref: expr, $get: ident, $contributed_inputs_and_outputs: ident) => {{
7044- $pending_splice
7045- .and_then(|pending_splice| pending_splice.funding_negotiation.$get())
7046- .and_then(|funding_negotiation| {
7047- let is_initiator = funding_negotiation.is_initiator();
7048-
7049- let (mut contributed_inputs, mut contributed_outputs) = match funding_negotiation {
7050- FundingNegotiation::AwaitingAck { context, .. } => {
7051- context.$contributed_inputs_and_outputs()
7052- },
7053- FundingNegotiation::ConstructingTransaction {
7054- interactive_tx_constructor,
7055- ..
7056- } => interactive_tx_constructor.$contributed_inputs_and_outputs(),
7057- FundingNegotiation::AwaitingSignatures { .. } => $funded_channel
7058- .context
7059- .interactive_tx_signing_session
7060- .$get()
7061- .expect("We have a pending splice awaiting signatures")
7062- .$contributed_inputs_and_outputs(),
7063- };
7064-
7065- if let Some(pending_splice) = $pending_splice_ref {
7066- for input in pending_splice.prior_contributed_inputs() {
7067- contributed_inputs.retain(|i| *i != input);
7068- }
7069- for output in pending_splice.prior_contributed_outputs() {
7070- contributed_outputs.retain(|o| o.script_pubkey != output.script_pubkey);
7071- }
7072- }
7073-
7074- if !is_initiator && contributed_inputs.is_empty() && contributed_outputs.is_empty()
7075- {
7076- return None;
7077- }
7078-
7079- let contribution =
7080- $pending_splice_ref.and_then(|ps| ps.contributions.last().cloned());
7081-
7082- Some(SpliceFundingFailed { contributed_inputs, contributed_outputs, contribution })
7083- })
7042+ macro_rules! splice_funding_failed_for {
7043+ ($self: expr, $is_initiator: expr, $contribution: expr,
7044+ $contributed_inputs: ident, $contributed_outputs: ident) => {{
7045+ let contribution = $contribution;
7046+ let existing_inputs =
7047+ $self.pending_splice.as_ref().into_iter().flat_map(|ps| ps.$contributed_inputs());
7048+ let existing_outputs =
7049+ $self.pending_splice.as_ref().into_iter().flat_map(|ps| ps.$contributed_outputs());
7050+ let filtered =
7051+ contribution.clone().into_unique_contributions(existing_inputs, existing_outputs);
7052+ match filtered {
7053+ None if !$is_initiator => None,
7054+ None => Some(SpliceFundingFailed {
7055+ contributed_inputs: vec![],
7056+ contributed_outputs: vec![],
7057+ contribution: Some(contribution),
7058+ }),
7059+ Some((contributed_inputs, contributed_outputs)) => Some(SpliceFundingFailed {
7060+ contributed_inputs,
7061+ contributed_outputs,
7062+ contribution: Some(contribution),
7063+ }),
7064+ }
70847065 }};
70857066}
70867067
@@ -7110,21 +7091,16 @@ where
71107091 /// Builds a [`SpliceFundingFailed`] from a contribution, filtering out inputs/outputs
71117092 /// that are still committed to a prior splice round.
71127093 fn splice_funding_failed_for(&self, contribution: FundingContribution) -> SpliceFundingFailed {
7113- let cloned_contribution = contribution.clone();
7114- let (mut inputs, mut outputs) = contribution.into_contributed_inputs_and_outputs();
7115- if let Some(ref pending_splice) = self.pending_splice {
7116- for input in pending_splice.contributed_inputs() {
7117- inputs.retain(|i| *i != input);
7118- }
7119- for output in pending_splice.contributed_outputs() {
7120- outputs.retain(|o| o.script_pubkey != output.script_pubkey);
7121- }
7122- }
7123- SpliceFundingFailed {
7124- contributed_inputs: inputs,
7125- contributed_outputs: outputs,
7126- contribution: Some(cloned_contribution),
7127- }
7094+ // The contribution was never pushed to `contributions`, so `contributed_inputs()` and
7095+ // `contributed_outputs()` return only prior rounds' entries for filtering.
7096+ splice_funding_failed_for!(
7097+ self,
7098+ true,
7099+ contribution,
7100+ contributed_inputs,
7101+ contributed_outputs
7102+ )
7103+ .expect("is_initiator is true so this always returns Some")
71287104 }
71297105
71307106 fn quiescent_action_into_error(&self, action: QuiescentAction) -> QuiescentError {
@@ -7268,21 +7244,19 @@ where
72687244 );
72697245 }
72707246
7271- let splice_funding_failed = maybe_create_splice_funding_failed!(
7272- self,
7273- self.pending_splice.as_mut(),
7274- self.pending_splice.as_ref(),
7275- take,
7276- into_contributed_inputs_and_outputs
7277- );
7278-
7279- // Pop the current round's contribution, if any (acceptors may not have one). This
7280- // must happen after `maybe_create_splice_funding_failed` for correct filtering.
7247+ // Take the funding negotiation and pop the current round's contribution, if any
7248+ // (acceptors may not have one).
72817249 let pending_splice = self
72827250 .pending_splice
72837251 .as_mut()
72847252 .expect("reset_pending_splice_state requires pending_splice");
7285- if let Some(contribution) = pending_splice.contributions.pop() {
7253+ let is_initiator = pending_splice
7254+ .funding_negotiation
7255+ .take()
7256+ .map(|negotiation| negotiation.is_initiator())
7257+ .unwrap_or(false);
7258+ let contribution = pending_splice.contributions.pop();
7259+ if let Some(ref contribution) = contribution {
72867260 debug_assert!(
72877261 pending_splice
72887262 .last_funding_feerate_sat_per_1000_weight
@@ -7292,6 +7266,18 @@ where
72927266 );
72937267 }
72947268
7269+ // After pop, `contributed_inputs()` / `contributed_outputs()` return only prior
7270+ // rounds for filtering.
7271+ let splice_funding_failed = contribution.and_then(|contribution| {
7272+ splice_funding_failed_for!(
7273+ self,
7274+ is_initiator,
7275+ contribution,
7276+ contributed_inputs,
7277+ contributed_outputs
7278+ )
7279+ });
7280+
72957281 if self.pending_funding().is_empty() {
72967282 self.pending_splice.take();
72977283 }
@@ -7309,12 +7295,19 @@ where
73097295 return None;
73107296 }
73117297
7312- maybe_create_splice_funding_failed!(
7298+ let pending_splice = self.pending_splice.as_ref()?;
7299+ let is_initiator = pending_splice
7300+ .funding_negotiation
7301+ .as_ref()
7302+ .map(|negotiation| negotiation.is_initiator())
7303+ .unwrap_or(false);
7304+ let contribution = pending_splice.contributions.last().cloned()?;
7305+ splice_funding_failed_for!(
73137306 self,
7314- self.pending_splice.as_ref() ,
7315- self.pending_splice.as_ref() ,
7316- as_ref ,
7317- to_contributed_inputs_and_outputs
7307+ is_initiator ,
7308+ contribution ,
7309+ prior_contributed_inputs ,
7310+ prior_contributed_outputs
73187311 )
73197312 }
73207313
0 commit comments