@@ -7056,48 +7056,29 @@ impl SpliceFundingFailed {
70567056 }
70577057}
70587058
7059- macro_rules! maybe_create_splice_funding_failed {
7060- ($funded_channel: expr, $pending_splice: expr, $pending_splice_ref: expr, $get: ident, $contributed_inputs_and_outputs: ident) => {{
7061- $pending_splice
7062- .and_then(|pending_splice| pending_splice.funding_negotiation.$get())
7063- .and_then(|funding_negotiation| {
7064- let is_initiator = funding_negotiation.is_initiator();
7065-
7066- let (mut contributed_inputs, mut contributed_outputs) = match funding_negotiation {
7067- FundingNegotiation::AwaitingAck { context, .. } => {
7068- context.$contributed_inputs_and_outputs()
7069- },
7070- FundingNegotiation::ConstructingTransaction {
7071- interactive_tx_constructor,
7072- ..
7073- } => interactive_tx_constructor.$contributed_inputs_and_outputs(),
7074- FundingNegotiation::AwaitingSignatures { .. } => $funded_channel
7075- .context
7076- .interactive_tx_signing_session
7077- .$get()
7078- .expect("We have a pending splice awaiting signatures")
7079- .$contributed_inputs_and_outputs(),
7080- };
7081-
7082- if let Some(pending_splice) = $pending_splice_ref {
7083- for input in pending_splice.prior_contributed_inputs() {
7084- contributed_inputs.retain(|i| *i != input);
7085- }
7086- for output in pending_splice.prior_contributed_outputs() {
7087- contributed_outputs.retain(|o| o.script_pubkey != output.script_pubkey);
7088- }
7089- }
7090-
7091- if !is_initiator && contributed_inputs.is_empty() && contributed_outputs.is_empty()
7092- {
7093- return None;
7094- }
7095-
7096- let contribution =
7097- $pending_splice_ref.and_then(|ps| ps.contributions.last().cloned());
7098-
7099- Some(SpliceFundingFailed { contributed_inputs, contributed_outputs, contribution })
7100- })
7059+ macro_rules! splice_funding_failed_for {
7060+ ($self: expr, $is_initiator: expr, $contribution: expr,
7061+ $contributed_inputs: ident, $contributed_outputs: ident) => {{
7062+ let contribution = $contribution;
7063+ let existing_inputs =
7064+ $self.pending_splice.as_ref().into_iter().flat_map(|ps| ps.$contributed_inputs());
7065+ let existing_outputs =
7066+ $self.pending_splice.as_ref().into_iter().flat_map(|ps| ps.$contributed_outputs());
7067+ let filtered =
7068+ contribution.clone().into_unique_contributions(existing_inputs, existing_outputs);
7069+ match filtered {
7070+ None if !$is_initiator => None,
7071+ None => Some(SpliceFundingFailed {
7072+ contributed_inputs: vec![],
7073+ contributed_outputs: vec![],
7074+ contribution: Some(contribution),
7075+ }),
7076+ Some((contributed_inputs, contributed_outputs)) => Some(SpliceFundingFailed {
7077+ contributed_inputs,
7078+ contributed_outputs,
7079+ contribution: Some(contribution),
7080+ }),
7081+ }
71017082 }};
71027083}
71037084
@@ -7127,21 +7108,16 @@ where
71277108 /// Builds a [`SpliceFundingFailed`] from a contribution, filtering out inputs/outputs
71287109 /// that are still committed to a prior splice round.
71297110 fn splice_funding_failed_for(&self, contribution: FundingContribution) -> SpliceFundingFailed {
7130- let cloned_contribution = contribution.clone();
7131- let (mut inputs, mut outputs) = contribution.into_contributed_inputs_and_outputs();
7132- if let Some(ref pending_splice) = self.pending_splice {
7133- for input in pending_splice.contributed_inputs() {
7134- inputs.retain(|i| *i != input);
7135- }
7136- for output in pending_splice.contributed_outputs() {
7137- outputs.retain(|o| o.script_pubkey != output.script_pubkey);
7138- }
7139- }
7140- SpliceFundingFailed {
7141- contributed_inputs: inputs,
7142- contributed_outputs: outputs,
7143- contribution: Some(cloned_contribution),
7144- }
7111+ // The contribution was never pushed to `contributions`, so `contributed_inputs()` and
7112+ // `contributed_outputs()` return only prior rounds' entries for filtering.
7113+ splice_funding_failed_for!(
7114+ self,
7115+ true,
7116+ contribution,
7117+ contributed_inputs,
7118+ contributed_outputs
7119+ )
7120+ .expect("is_initiator is true so this always returns Some")
71457121 }
71467122
71477123 fn quiescent_action_into_error(&self, action: QuiescentAction) -> QuiescentError {
@@ -7285,21 +7261,19 @@ where
72857261 );
72867262 }
72877263
7288- let splice_funding_failed = maybe_create_splice_funding_failed!(
7289- self,
7290- self.pending_splice.as_mut(),
7291- self.pending_splice.as_ref(),
7292- take,
7293- into_contributed_inputs_and_outputs
7294- );
7295-
7296- // Pop the current round's contribution, if any (acceptors may not have one). This
7297- // must happen after `maybe_create_splice_funding_failed` for correct filtering.
7264+ // Take the funding negotiation and pop the current round's contribution, if any
7265+ // (acceptors may not have one).
72987266 let pending_splice = self
72997267 .pending_splice
73007268 .as_mut()
73017269 .expect("reset_pending_splice_state requires pending_splice");
7302- if let Some(contribution) = pending_splice.contributions.pop() {
7270+ let is_initiator = pending_splice
7271+ .funding_negotiation
7272+ .take()
7273+ .map(|negotiation| negotiation.is_initiator())
7274+ .unwrap_or(false);
7275+ let contribution = pending_splice.contributions.pop();
7276+ if let Some(ref contribution) = contribution {
73037277 debug_assert!(
73047278 pending_splice
73057279 .last_funding_feerate_sat_per_1000_weight
@@ -7309,6 +7283,18 @@ where
73097283 );
73107284 }
73117285
7286+ // After pop, `contributed_inputs()` / `contributed_outputs()` return only prior
7287+ // rounds for filtering.
7288+ let splice_funding_failed = contribution.and_then(|contribution| {
7289+ splice_funding_failed_for!(
7290+ self,
7291+ is_initiator,
7292+ contribution,
7293+ contributed_inputs,
7294+ contributed_outputs
7295+ )
7296+ });
7297+
73127298 if self.pending_funding().is_empty() {
73137299 self.pending_splice.take();
73147300 }
@@ -7326,12 +7312,19 @@ where
73267312 return None;
73277313 }
73287314
7329- maybe_create_splice_funding_failed!(
7315+ let pending_splice = self.pending_splice.as_ref()?;
7316+ let is_initiator = pending_splice
7317+ .funding_negotiation
7318+ .as_ref()
7319+ .map(|negotiation| negotiation.is_initiator())
7320+ .unwrap_or(false);
7321+ let contribution = pending_splice.contributions.last().cloned()?;
7322+ splice_funding_failed_for!(
73307323 self,
7331- self.pending_splice.as_ref() ,
7332- self.pending_splice.as_ref() ,
7333- as_ref ,
7334- to_contributed_inputs_and_outputs
7324+ is_initiator ,
7325+ contribution ,
7326+ prior_contributed_inputs ,
7327+ prior_contributed_outputs
73357328 )
73367329 }
73377330
0 commit comments